index.js 2.3 MB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650665166526653665466556656665766586659666066616662666366646665666666676668666966706671667266736674667566766677667866796680668166826683668466856686668766886689669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719672067216722672367246725672667276728672967306731673267336734673567366737673867396740674167426743674467456746674767486749675067516752675367546755675667576758675967606761676267636764676567666767676867696770677167726773677467756776677767786779678067816782678367846785678667876788678967906791679267936794679567966797679867996800680168026803680468056806680768086809681068116812681368146815681668176818681968206821682268236824682568266827682868296830683168326833683468356836683768386839684068416842684368446845684668476848684968506851685268536854685568566857685868596860686168626863686468656866686768686869687068716872687368746875687668776878687968806881688268836884688568866887688868896890689168926893689468956896689768986899690069016902690369046905690669076908690969106911691269136914691569166917691869196920692169226923692469256926692769286929693069316932693369346935693669376938693969406941694269436944694569466947694869496950695169526953695469556956695769586959696069616962696369646965696669676968696969706971697269736974697569766977697869796980698169826983698469856986698769886989699069916992699369946995699669976998699970007001700270037004700570067007700870097010701170127013701470157016701770187019702070217022702370247025702670277028702970307031703270337034703570367037703870397040704170427043704470457046704770487049705070517052705370547055705670577058705970607061706270637064706570667067706870697070707170727073707470757076707770787079708070817082708370847085708670877088708970907091709270937094709570967097709870997100710171027103710471057106710771087109711071117112711371147115711671177118711971207121712271237124712571267127712871297130713171327133713471357136713771387139714071417142714371447145714671477148714971507151715271537154715571567157715871597160716171627163716471657166716771687169717071717172717371747175717671777178717971807181718271837184718571867187718871897190719171927193719471957196719771987199720072017202720372047205720672077208720972107211721272137214721572167217721872197220722172227223722472257226722772287229723072317232723372347235723672377238723972407241724272437244724572467247724872497250725172527253725472557256725772587259726072617262726372647265726672677268726972707271727272737274727572767277727872797280728172827283728472857286728772887289729072917292729372947295729672977298729973007301730273037304730573067307730873097310731173127313731473157316731773187319732073217322732373247325732673277328732973307331733273337334733573367337733873397340734173427343734473457346734773487349735073517352735373547355735673577358735973607361736273637364736573667367736873697370737173727373737473757376737773787379738073817382738373847385738673877388738973907391739273937394739573967397739873997400740174027403740474057406740774087409741074117412741374147415741674177418741974207421742274237424742574267427742874297430743174327433743474357436743774387439744074417442744374447445744674477448744974507451745274537454745574567457745874597460746174627463746474657466746774687469747074717472747374747475747674777478747974807481748274837484748574867487748874897490749174927493749474957496749774987499750075017502750375047505750675077508750975107511751275137514751575167517751875197520752175227523752475257526752775287529753075317532753375347535753675377538753975407541754275437544754575467547754875497550755175527553755475557556755775587559756075617562756375647565756675677568756975707571757275737574757575767577757875797580758175827583758475857586758775887589759075917592759375947595759675977598759976007601760276037604760576067607760876097610761176127613761476157616761776187619762076217622762376247625762676277628762976307631763276337634763576367637763876397640764176427643764476457646764776487649765076517652765376547655765676577658765976607661766276637664766576667667766876697670767176727673767476757676767776787679768076817682768376847685768676877688768976907691769276937694769576967697769876997700770177027703770477057706770777087709771077117712771377147715771677177718771977207721772277237724772577267727772877297730773177327733773477357736773777387739774077417742774377447745774677477748774977507751775277537754775577567757775877597760776177627763776477657766776777687769777077717772777377747775777677777778777977807781778277837784778577867787778877897790779177927793779477957796779777987799780078017802780378047805780678077808780978107811781278137814781578167817781878197820782178227823782478257826782778287829783078317832783378347835783678377838783978407841784278437844784578467847784878497850785178527853785478557856785778587859786078617862786378647865786678677868786978707871787278737874787578767877787878797880788178827883788478857886788778887889789078917892789378947895789678977898789979007901790279037904790579067907790879097910791179127913791479157916791779187919792079217922792379247925792679277928792979307931793279337934793579367937793879397940794179427943794479457946794779487949795079517952795379547955795679577958795979607961796279637964796579667967796879697970797179727973797479757976797779787979798079817982798379847985798679877988798979907991799279937994799579967997799879998000800180028003800480058006800780088009801080118012801380148015801680178018801980208021802280238024802580268027802880298030803180328033803480358036803780388039804080418042804380448045804680478048804980508051805280538054805580568057805880598060806180628063806480658066806780688069807080718072807380748075807680778078807980808081808280838084808580868087808880898090809180928093809480958096809780988099810081018102810381048105810681078108810981108111811281138114811581168117811881198120812181228123812481258126812781288129813081318132813381348135813681378138813981408141814281438144814581468147814881498150815181528153815481558156815781588159816081618162816381648165816681678168816981708171817281738174817581768177817881798180818181828183818481858186818781888189819081918192819381948195819681978198819982008201820282038204820582068207820882098210821182128213821482158216821782188219822082218222822382248225822682278228822982308231823282338234823582368237823882398240824182428243824482458246824782488249825082518252825382548255825682578258825982608261826282638264826582668267826882698270827182728273827482758276827782788279828082818282828382848285828682878288828982908291829282938294829582968297829882998300830183028303830483058306830783088309831083118312831383148315831683178318831983208321832283238324832583268327832883298330833183328333833483358336833783388339834083418342834383448345834683478348834983508351835283538354835583568357835883598360836183628363836483658366836783688369837083718372837383748375837683778378837983808381838283838384838583868387838883898390839183928393839483958396839783988399840084018402840384048405840684078408840984108411841284138414841584168417841884198420842184228423842484258426842784288429843084318432843384348435843684378438843984408441844284438444844584468447844884498450845184528453845484558456845784588459846084618462846384648465846684678468846984708471847284738474847584768477847884798480848184828483848484858486848784888489849084918492849384948495849684978498849985008501850285038504850585068507850885098510851185128513851485158516851785188519852085218522852385248525852685278528852985308531853285338534853585368537853885398540854185428543854485458546854785488549855085518552855385548555855685578558855985608561856285638564856585668567856885698570857185728573857485758576857785788579858085818582858385848585858685878588858985908591859285938594859585968597859885998600860186028603860486058606860786088609861086118612861386148615861686178618861986208621862286238624862586268627862886298630863186328633863486358636863786388639864086418642864386448645864686478648864986508651865286538654865586568657865886598660866186628663866486658666866786688669867086718672867386748675867686778678867986808681868286838684868586868687868886898690869186928693869486958696869786988699870087018702870387048705870687078708870987108711871287138714871587168717871887198720872187228723872487258726872787288729873087318732873387348735873687378738873987408741874287438744874587468747874887498750875187528753875487558756875787588759876087618762876387648765876687678768876987708771877287738774877587768777877887798780878187828783878487858786878787888789879087918792879387948795879687978798879988008801880288038804880588068807880888098810881188128813881488158816881788188819882088218822882388248825882688278828882988308831883288338834883588368837883888398840884188428843884488458846884788488849885088518852885388548855885688578858885988608861886288638864886588668867886888698870887188728873887488758876887788788879888088818882888388848885888688878888888988908891889288938894889588968897889888998900890189028903890489058906890789088909891089118912891389148915891689178918891989208921892289238924892589268927892889298930893189328933893489358936893789388939894089418942894389448945894689478948894989508951895289538954895589568957895889598960896189628963896489658966896789688969897089718972897389748975897689778978897989808981898289838984898589868987898889898990899189928993899489958996899789988999900090019002900390049005900690079008900990109011901290139014901590169017901890199020902190229023902490259026902790289029903090319032903390349035903690379038903990409041904290439044904590469047904890499050905190529053905490559056905790589059906090619062906390649065906690679068906990709071907290739074907590769077907890799080908190829083908490859086908790889089909090919092909390949095909690979098909991009101910291039104910591069107910891099110911191129113911491159116911791189119912091219122912391249125912691279128912991309131913291339134913591369137913891399140914191429143914491459146914791489149915091519152915391549155915691579158915991609161916291639164916591669167916891699170917191729173917491759176917791789179918091819182918391849185918691879188918991909191919291939194919591969197919891999200920192029203920492059206920792089209921092119212921392149215921692179218921992209221922292239224922592269227922892299230923192329233923492359236923792389239924092419242924392449245924692479248924992509251925292539254925592569257925892599260926192629263926492659266926792689269927092719272927392749275927692779278927992809281928292839284928592869287928892899290929192929293929492959296929792989299930093019302930393049305930693079308930993109311931293139314931593169317931893199320932193229323932493259326932793289329933093319332933393349335933693379338933993409341934293439344934593469347934893499350935193529353935493559356935793589359936093619362936393649365936693679368936993709371937293739374937593769377937893799380938193829383938493859386938793889389939093919392939393949395939693979398939994009401940294039404940594069407940894099410941194129413941494159416941794189419942094219422942394249425942694279428942994309431943294339434943594369437943894399440944194429443944494459446944794489449945094519452945394549455945694579458945994609461946294639464946594669467946894699470947194729473947494759476947794789479948094819482948394849485948694879488948994909491949294939494949594969497949894999500950195029503950495059506950795089509951095119512951395149515951695179518951995209521952295239524952595269527952895299530953195329533953495359536953795389539954095419542954395449545954695479548954995509551955295539554955595569557955895599560956195629563956495659566956795689569957095719572957395749575957695779578957995809581958295839584958595869587958895899590959195929593959495959596959795989599960096019602960396049605960696079608960996109611961296139614961596169617961896199620962196229623962496259626962796289629963096319632963396349635963696379638963996409641964296439644964596469647964896499650965196529653965496559656965796589659966096619662966396649665966696679668966996709671967296739674967596769677967896799680968196829683968496859686968796889689969096919692969396949695969696979698969997009701970297039704970597069707970897099710971197129713971497159716971797189719972097219722972397249725972697279728972997309731973297339734973597369737973897399740974197429743974497459746974797489749975097519752975397549755975697579758975997609761976297639764976597669767976897699770977197729773977497759776977797789779978097819782978397849785978697879788978997909791979297939794979597969797979897999800980198029803980498059806980798089809981098119812981398149815981698179818981998209821982298239824982598269827982898299830983198329833983498359836983798389839984098419842984398449845984698479848984998509851985298539854985598569857985898599860986198629863986498659866986798689869987098719872987398749875987698779878987998809881988298839884988598869887988898899890989198929893989498959896989798989899990099019902990399049905990699079908990999109911991299139914991599169917991899199920992199229923992499259926992799289929993099319932993399349935993699379938993999409941994299439944994599469947994899499950995199529953995499559956995799589959996099619962996399649965996699679968996999709971997299739974997599769977997899799980998199829983998499859986998799889989999099919992999399949995999699979998999910000100011000210003100041000510006100071000810009100101001110012100131001410015100161001710018100191002010021100221002310024100251002610027100281002910030100311003210033100341003510036100371003810039100401004110042100431004410045100461004710048100491005010051100521005310054100551005610057100581005910060100611006210063100641006510066100671006810069100701007110072100731007410075100761007710078100791008010081100821008310084100851008610087100881008910090100911009210093100941009510096100971009810099101001010110102101031010410105101061010710108101091011010111101121011310114101151011610117101181011910120101211012210123101241012510126101271012810129101301013110132101331013410135101361013710138101391014010141101421014310144101451014610147101481014910150101511015210153101541015510156101571015810159101601016110162101631016410165101661016710168101691017010171101721017310174101751017610177101781017910180101811018210183101841018510186101871018810189101901019110192101931019410195101961019710198101991020010201102021020310204102051020610207102081020910210102111021210213102141021510216102171021810219102201022110222102231022410225102261022710228102291023010231102321023310234102351023610237102381023910240102411024210243102441024510246102471024810249102501025110252102531025410255102561025710258102591026010261102621026310264102651026610267102681026910270102711027210273102741027510276102771027810279102801028110282102831028410285102861028710288102891029010291102921029310294102951029610297102981029910300103011030210303103041030510306103071030810309103101031110312103131031410315103161031710318103191032010321103221032310324103251032610327103281032910330103311033210333103341033510336103371033810339103401034110342103431034410345103461034710348103491035010351103521035310354103551035610357103581035910360103611036210363103641036510366103671036810369103701037110372103731037410375103761037710378103791038010381103821038310384103851038610387103881038910390103911039210393103941039510396103971039810399104001040110402104031040410405104061040710408104091041010411104121041310414104151041610417104181041910420104211042210423104241042510426104271042810429104301043110432104331043410435104361043710438104391044010441104421044310444104451044610447104481044910450104511045210453104541045510456104571045810459104601046110462104631046410465104661046710468104691047010471104721047310474104751047610477104781047910480104811048210483104841048510486104871048810489104901049110492104931049410495104961049710498104991050010501105021050310504105051050610507105081050910510105111051210513105141051510516105171051810519105201052110522105231052410525105261052710528105291053010531105321053310534105351053610537105381053910540105411054210543105441054510546105471054810549105501055110552105531055410555105561055710558105591056010561105621056310564105651056610567105681056910570105711057210573105741057510576105771057810579105801058110582105831058410585105861058710588105891059010591105921059310594105951059610597105981059910600106011060210603106041060510606106071060810609106101061110612106131061410615106161061710618106191062010621106221062310624106251062610627106281062910630106311063210633106341063510636106371063810639106401064110642106431064410645106461064710648106491065010651106521065310654106551065610657106581065910660106611066210663106641066510666106671066810669106701067110672106731067410675106761067710678106791068010681106821068310684106851068610687106881068910690106911069210693106941069510696106971069810699107001070110702107031070410705107061070710708107091071010711107121071310714107151071610717107181071910720107211072210723107241072510726107271072810729107301073110732107331073410735107361073710738107391074010741107421074310744107451074610747107481074910750107511075210753107541075510756107571075810759107601076110762107631076410765107661076710768107691077010771107721077310774107751077610777107781077910780107811078210783107841078510786107871078810789107901079110792107931079410795107961079710798107991080010801108021080310804108051080610807108081080910810108111081210813108141081510816108171081810819108201082110822108231082410825108261082710828108291083010831108321083310834108351083610837108381083910840108411084210843108441084510846108471084810849108501085110852108531085410855108561085710858108591086010861108621086310864108651086610867108681086910870108711087210873108741087510876108771087810879108801088110882108831088410885108861088710888108891089010891108921089310894108951089610897108981089910900109011090210903109041090510906109071090810909109101091110912109131091410915109161091710918109191092010921109221092310924109251092610927109281092910930109311093210933109341093510936109371093810939109401094110942109431094410945109461094710948109491095010951109521095310954109551095610957109581095910960109611096210963109641096510966109671096810969109701097110972109731097410975109761097710978109791098010981109821098310984109851098610987109881098910990109911099210993109941099510996109971099810999110001100111002110031100411005110061100711008110091101011011110121101311014110151101611017110181101911020110211102211023110241102511026110271102811029110301103111032110331103411035110361103711038110391104011041110421104311044110451104611047110481104911050110511105211053110541105511056110571105811059110601106111062110631106411065110661106711068110691107011071110721107311074110751107611077110781107911080110811108211083110841108511086110871108811089110901109111092110931109411095110961109711098110991110011101111021110311104111051110611107111081110911110111111111211113111141111511116111171111811119111201112111122111231112411125111261112711128111291113011131111321113311134111351113611137111381113911140111411114211143111441114511146111471114811149111501115111152111531115411155111561115711158111591116011161111621116311164111651116611167111681116911170111711117211173111741117511176111771117811179111801118111182111831118411185111861118711188111891119011191111921119311194111951119611197111981119911200112011120211203112041120511206112071120811209112101121111212112131121411215112161121711218112191122011221112221122311224112251122611227112281122911230112311123211233112341123511236112371123811239112401124111242112431124411245112461124711248112491125011251112521125311254112551125611257112581125911260112611126211263112641126511266112671126811269112701127111272112731127411275112761127711278112791128011281112821128311284112851128611287112881128911290112911129211293112941129511296112971129811299113001130111302113031130411305113061130711308113091131011311113121131311314113151131611317113181131911320113211132211323113241132511326113271132811329113301133111332113331133411335113361133711338113391134011341113421134311344113451134611347113481134911350113511135211353113541135511356113571135811359113601136111362113631136411365113661136711368113691137011371113721137311374113751137611377113781137911380113811138211383113841138511386113871138811389113901139111392113931139411395113961139711398113991140011401114021140311404114051140611407114081140911410114111141211413114141141511416114171141811419114201142111422114231142411425114261142711428114291143011431114321143311434114351143611437114381143911440114411144211443114441144511446114471144811449114501145111452114531145411455114561145711458114591146011461114621146311464114651146611467114681146911470114711147211473114741147511476114771147811479114801148111482114831148411485114861148711488114891149011491114921149311494114951149611497114981149911500115011150211503115041150511506115071150811509115101151111512115131151411515115161151711518115191152011521115221152311524115251152611527115281152911530115311153211533115341153511536115371153811539115401154111542115431154411545115461154711548115491155011551115521155311554115551155611557115581155911560115611156211563115641156511566115671156811569115701157111572115731157411575115761157711578115791158011581115821158311584115851158611587115881158911590115911159211593115941159511596115971159811599116001160111602116031160411605116061160711608116091161011611116121161311614116151161611617116181161911620116211162211623116241162511626116271162811629116301163111632116331163411635116361163711638116391164011641116421164311644116451164611647116481164911650116511165211653116541165511656116571165811659116601166111662116631166411665116661166711668116691167011671116721167311674116751167611677116781167911680116811168211683116841168511686116871168811689116901169111692116931169411695116961169711698116991170011701117021170311704117051170611707117081170911710117111171211713117141171511716117171171811719117201172111722117231172411725117261172711728117291173011731117321173311734117351173611737117381173911740117411174211743117441174511746117471174811749117501175111752117531175411755117561175711758117591176011761117621176311764117651176611767117681176911770117711177211773117741177511776117771177811779117801178111782117831178411785117861178711788117891179011791117921179311794117951179611797117981179911800118011180211803118041180511806118071180811809118101181111812118131181411815118161181711818118191182011821118221182311824118251182611827118281182911830118311183211833118341183511836118371183811839118401184111842118431184411845118461184711848118491185011851118521185311854118551185611857118581185911860118611186211863118641186511866118671186811869118701187111872118731187411875118761187711878118791188011881118821188311884118851188611887118881188911890118911189211893118941189511896118971189811899119001190111902119031190411905119061190711908119091191011911119121191311914119151191611917119181191911920119211192211923119241192511926119271192811929119301193111932119331193411935119361193711938119391194011941119421194311944119451194611947119481194911950119511195211953119541195511956119571195811959119601196111962119631196411965119661196711968119691197011971119721197311974119751197611977119781197911980119811198211983119841198511986119871198811989119901199111992119931199411995119961199711998119991200012001120021200312004120051200612007120081200912010120111201212013120141201512016120171201812019120201202112022120231202412025120261202712028120291203012031120321203312034120351203612037120381203912040120411204212043120441204512046120471204812049120501205112052120531205412055120561205712058120591206012061120621206312064120651206612067120681206912070120711207212073120741207512076120771207812079120801208112082120831208412085120861208712088120891209012091120921209312094120951209612097120981209912100121011210212103121041210512106121071210812109121101211112112121131211412115121161211712118121191212012121121221212312124121251212612127121281212912130121311213212133121341213512136121371213812139121401214112142121431214412145121461214712148121491215012151121521215312154121551215612157121581215912160121611216212163121641216512166121671216812169121701217112172121731217412175121761217712178121791218012181121821218312184121851218612187121881218912190121911219212193121941219512196121971219812199122001220112202122031220412205122061220712208122091221012211122121221312214122151221612217122181221912220122211222212223122241222512226122271222812229122301223112232122331223412235122361223712238122391224012241122421224312244122451224612247122481224912250122511225212253122541225512256122571225812259122601226112262122631226412265122661226712268122691227012271122721227312274122751227612277122781227912280122811228212283122841228512286122871228812289122901229112292122931229412295122961229712298122991230012301123021230312304123051230612307123081230912310123111231212313123141231512316123171231812319123201232112322123231232412325123261232712328123291233012331123321233312334123351233612337123381233912340123411234212343123441234512346123471234812349123501235112352123531235412355123561235712358123591236012361123621236312364123651236612367123681236912370123711237212373123741237512376123771237812379123801238112382123831238412385123861238712388123891239012391123921239312394123951239612397123981239912400124011240212403124041240512406124071240812409124101241112412124131241412415124161241712418124191242012421124221242312424124251242612427124281242912430124311243212433124341243512436124371243812439124401244112442124431244412445124461244712448124491245012451124521245312454124551245612457124581245912460124611246212463124641246512466124671246812469124701247112472124731247412475124761247712478124791248012481124821248312484124851248612487124881248912490124911249212493124941249512496124971249812499125001250112502125031250412505125061250712508125091251012511125121251312514125151251612517125181251912520125211252212523125241252512526125271252812529125301253112532125331253412535125361253712538125391254012541125421254312544125451254612547125481254912550125511255212553125541255512556125571255812559125601256112562125631256412565125661256712568125691257012571125721257312574125751257612577125781257912580125811258212583125841258512586125871258812589125901259112592125931259412595125961259712598125991260012601126021260312604126051260612607126081260912610126111261212613126141261512616126171261812619126201262112622126231262412625126261262712628126291263012631126321263312634126351263612637126381263912640126411264212643126441264512646126471264812649126501265112652126531265412655126561265712658126591266012661126621266312664126651266612667126681266912670126711267212673126741267512676126771267812679126801268112682126831268412685126861268712688126891269012691126921269312694126951269612697126981269912700127011270212703127041270512706127071270812709127101271112712127131271412715127161271712718127191272012721127221272312724127251272612727127281272912730127311273212733127341273512736127371273812739127401274112742127431274412745127461274712748127491275012751127521275312754127551275612757127581275912760127611276212763127641276512766127671276812769127701277112772127731277412775127761277712778127791278012781127821278312784127851278612787127881278912790127911279212793127941279512796127971279812799128001280112802128031280412805128061280712808128091281012811128121281312814128151281612817128181281912820128211282212823128241282512826128271282812829128301283112832128331283412835128361283712838128391284012841128421284312844128451284612847128481284912850128511285212853128541285512856128571285812859128601286112862128631286412865128661286712868128691287012871128721287312874128751287612877128781287912880128811288212883128841288512886128871288812889128901289112892128931289412895128961289712898128991290012901129021290312904129051290612907129081290912910129111291212913129141291512916129171291812919129201292112922129231292412925129261292712928129291293012931129321293312934129351293612937129381293912940129411294212943129441294512946129471294812949129501295112952129531295412955129561295712958129591296012961129621296312964129651296612967129681296912970129711297212973129741297512976129771297812979129801298112982129831298412985129861298712988129891299012991129921299312994129951299612997129981299913000130011300213003130041300513006130071300813009130101301113012130131301413015130161301713018130191302013021130221302313024130251302613027130281302913030130311303213033130341303513036130371303813039130401304113042130431304413045130461304713048130491305013051130521305313054130551305613057130581305913060130611306213063130641306513066130671306813069130701307113072130731307413075130761307713078130791308013081130821308313084130851308613087130881308913090130911309213093130941309513096130971309813099131001310113102131031310413105131061310713108131091311013111131121311313114131151311613117131181311913120131211312213123131241312513126131271312813129131301313113132131331313413135131361313713138131391314013141131421314313144131451314613147131481314913150131511315213153131541315513156131571315813159131601316113162131631316413165131661316713168131691317013171131721317313174131751317613177131781317913180131811318213183131841318513186131871318813189131901319113192131931319413195131961319713198131991320013201132021320313204132051320613207132081320913210132111321213213132141321513216132171321813219132201322113222132231322413225132261322713228132291323013231132321323313234132351323613237132381323913240132411324213243132441324513246132471324813249132501325113252132531325413255132561325713258132591326013261132621326313264132651326613267132681326913270132711327213273132741327513276132771327813279132801328113282132831328413285132861328713288132891329013291132921329313294132951329613297132981329913300133011330213303133041330513306133071330813309133101331113312133131331413315133161331713318133191332013321133221332313324133251332613327133281332913330133311333213333133341333513336133371333813339133401334113342133431334413345133461334713348133491335013351133521335313354133551335613357133581335913360133611336213363133641336513366133671336813369133701337113372133731337413375133761337713378133791338013381133821338313384133851338613387133881338913390133911339213393133941339513396133971339813399134001340113402134031340413405134061340713408134091341013411134121341313414134151341613417134181341913420134211342213423134241342513426134271342813429134301343113432134331343413435134361343713438134391344013441134421344313444134451344613447134481344913450134511345213453134541345513456134571345813459134601346113462134631346413465134661346713468134691347013471134721347313474134751347613477134781347913480134811348213483134841348513486134871348813489134901349113492134931349413495134961349713498134991350013501135021350313504135051350613507135081350913510135111351213513135141351513516135171351813519135201352113522135231352413525135261352713528135291353013531135321353313534135351353613537135381353913540135411354213543135441354513546135471354813549135501355113552135531355413555135561355713558135591356013561135621356313564135651356613567135681356913570135711357213573135741357513576135771357813579135801358113582135831358413585135861358713588135891359013591135921359313594135951359613597135981359913600136011360213603136041360513606136071360813609136101361113612136131361413615136161361713618136191362013621136221362313624136251362613627136281362913630136311363213633136341363513636136371363813639136401364113642136431364413645136461364713648136491365013651136521365313654136551365613657136581365913660136611366213663136641366513666136671366813669136701367113672136731367413675136761367713678136791368013681136821368313684136851368613687136881368913690136911369213693136941369513696136971369813699137001370113702137031370413705137061370713708137091371013711137121371313714137151371613717137181371913720137211372213723137241372513726137271372813729137301373113732137331373413735137361373713738137391374013741137421374313744137451374613747137481374913750137511375213753137541375513756137571375813759137601376113762137631376413765137661376713768137691377013771137721377313774137751377613777137781377913780137811378213783137841378513786137871378813789137901379113792137931379413795137961379713798137991380013801138021380313804138051380613807138081380913810138111381213813138141381513816138171381813819138201382113822138231382413825138261382713828138291383013831138321383313834138351383613837138381383913840138411384213843138441384513846138471384813849138501385113852138531385413855138561385713858138591386013861138621386313864138651386613867138681386913870138711387213873138741387513876138771387813879138801388113882138831388413885138861388713888138891389013891138921389313894138951389613897138981389913900139011390213903139041390513906139071390813909139101391113912139131391413915139161391713918139191392013921139221392313924139251392613927139281392913930139311393213933139341393513936139371393813939139401394113942139431394413945139461394713948139491395013951139521395313954139551395613957139581395913960139611396213963139641396513966139671396813969139701397113972139731397413975139761397713978139791398013981139821398313984139851398613987139881398913990139911399213993139941399513996139971399813999140001400114002140031400414005140061400714008140091401014011140121401314014140151401614017140181401914020140211402214023140241402514026140271402814029140301403114032140331403414035140361403714038140391404014041140421404314044140451404614047140481404914050140511405214053140541405514056140571405814059140601406114062140631406414065140661406714068140691407014071140721407314074140751407614077140781407914080140811408214083140841408514086140871408814089140901409114092140931409414095140961409714098140991410014101141021410314104141051410614107141081410914110141111411214113141141411514116141171411814119141201412114122141231412414125141261412714128141291413014131141321413314134141351413614137141381413914140141411414214143141441414514146141471414814149141501415114152141531415414155141561415714158141591416014161141621416314164141651416614167141681416914170141711417214173141741417514176141771417814179141801418114182141831418414185141861418714188141891419014191141921419314194141951419614197141981419914200142011420214203142041420514206142071420814209142101421114212142131421414215142161421714218142191422014221142221422314224142251422614227142281422914230142311423214233142341423514236142371423814239142401424114242142431424414245142461424714248142491425014251142521425314254142551425614257142581425914260142611426214263142641426514266142671426814269142701427114272142731427414275142761427714278142791428014281142821428314284142851428614287142881428914290142911429214293142941429514296142971429814299143001430114302143031430414305143061430714308143091431014311143121431314314143151431614317143181431914320143211432214323143241432514326143271432814329143301433114332143331433414335143361433714338143391434014341143421434314344143451434614347143481434914350143511435214353143541435514356143571435814359143601436114362143631436414365143661436714368143691437014371143721437314374143751437614377143781437914380143811438214383143841438514386143871438814389143901439114392143931439414395143961439714398143991440014401144021440314404144051440614407144081440914410144111441214413144141441514416144171441814419144201442114422144231442414425144261442714428144291443014431144321443314434144351443614437144381443914440144411444214443144441444514446144471444814449144501445114452144531445414455144561445714458144591446014461144621446314464144651446614467144681446914470144711447214473144741447514476144771447814479144801448114482144831448414485144861448714488144891449014491144921449314494144951449614497144981449914500145011450214503145041450514506145071450814509145101451114512145131451414515145161451714518145191452014521145221452314524145251452614527145281452914530145311453214533145341453514536145371453814539145401454114542145431454414545145461454714548145491455014551145521455314554145551455614557145581455914560145611456214563145641456514566145671456814569145701457114572145731457414575145761457714578145791458014581145821458314584145851458614587145881458914590145911459214593145941459514596145971459814599146001460114602146031460414605146061460714608146091461014611146121461314614146151461614617146181461914620146211462214623146241462514626146271462814629146301463114632146331463414635146361463714638146391464014641146421464314644146451464614647146481464914650146511465214653146541465514656146571465814659146601466114662146631466414665146661466714668146691467014671146721467314674146751467614677146781467914680146811468214683146841468514686146871468814689146901469114692146931469414695146961469714698146991470014701147021470314704147051470614707147081470914710147111471214713147141471514716147171471814719147201472114722147231472414725147261472714728147291473014731147321473314734147351473614737147381473914740147411474214743147441474514746147471474814749147501475114752147531475414755147561475714758147591476014761147621476314764147651476614767147681476914770147711477214773147741477514776147771477814779147801478114782147831478414785147861478714788147891479014791147921479314794147951479614797147981479914800148011480214803148041480514806148071480814809148101481114812148131481414815148161481714818148191482014821148221482314824148251482614827148281482914830148311483214833148341483514836148371483814839148401484114842148431484414845148461484714848148491485014851148521485314854148551485614857148581485914860148611486214863148641486514866148671486814869148701487114872148731487414875148761487714878148791488014881148821488314884148851488614887148881488914890148911489214893148941489514896148971489814899149001490114902149031490414905149061490714908149091491014911149121491314914149151491614917149181491914920149211492214923149241492514926149271492814929149301493114932149331493414935149361493714938149391494014941149421494314944149451494614947149481494914950149511495214953149541495514956149571495814959149601496114962149631496414965149661496714968149691497014971149721497314974149751497614977149781497914980149811498214983149841498514986149871498814989149901499114992149931499414995149961499714998149991500015001150021500315004150051500615007150081500915010150111501215013150141501515016150171501815019150201502115022150231502415025150261502715028150291503015031150321503315034150351503615037150381503915040150411504215043150441504515046150471504815049150501505115052150531505415055150561505715058150591506015061150621506315064150651506615067150681506915070150711507215073150741507515076150771507815079150801508115082150831508415085150861508715088150891509015091150921509315094150951509615097150981509915100151011510215103151041510515106151071510815109151101511115112151131511415115151161511715118151191512015121151221512315124151251512615127151281512915130151311513215133151341513515136151371513815139151401514115142151431514415145151461514715148151491515015151151521515315154151551515615157151581515915160151611516215163151641516515166151671516815169151701517115172151731517415175151761517715178151791518015181151821518315184151851518615187151881518915190151911519215193151941519515196151971519815199152001520115202152031520415205152061520715208152091521015211152121521315214152151521615217152181521915220152211522215223152241522515226152271522815229152301523115232152331523415235152361523715238152391524015241152421524315244152451524615247152481524915250152511525215253152541525515256152571525815259152601526115262152631526415265152661526715268152691527015271152721527315274152751527615277152781527915280152811528215283152841528515286152871528815289152901529115292152931529415295152961529715298152991530015301153021530315304153051530615307153081530915310153111531215313153141531515316153171531815319153201532115322153231532415325153261532715328153291533015331153321533315334153351533615337153381533915340153411534215343153441534515346153471534815349153501535115352153531535415355153561535715358153591536015361153621536315364153651536615367153681536915370153711537215373153741537515376153771537815379153801538115382153831538415385153861538715388153891539015391153921539315394153951539615397153981539915400154011540215403154041540515406154071540815409154101541115412154131541415415154161541715418154191542015421154221542315424154251542615427154281542915430154311543215433154341543515436154371543815439154401544115442154431544415445154461544715448154491545015451154521545315454154551545615457154581545915460154611546215463154641546515466154671546815469154701547115472154731547415475154761547715478154791548015481154821548315484154851548615487154881548915490154911549215493154941549515496154971549815499155001550115502155031550415505155061550715508155091551015511155121551315514155151551615517155181551915520155211552215523155241552515526155271552815529155301553115532155331553415535155361553715538155391554015541155421554315544155451554615547155481554915550155511555215553155541555515556155571555815559155601556115562155631556415565155661556715568155691557015571155721557315574155751557615577155781557915580155811558215583155841558515586155871558815589155901559115592155931559415595155961559715598155991560015601156021560315604156051560615607156081560915610156111561215613156141561515616156171561815619156201562115622156231562415625156261562715628156291563015631156321563315634156351563615637156381563915640156411564215643156441564515646156471564815649156501565115652156531565415655156561565715658156591566015661156621566315664156651566615667156681566915670156711567215673156741567515676156771567815679156801568115682156831568415685156861568715688156891569015691156921569315694156951569615697156981569915700157011570215703157041570515706157071570815709157101571115712157131571415715157161571715718157191572015721157221572315724157251572615727157281572915730157311573215733157341573515736157371573815739157401574115742157431574415745157461574715748157491575015751157521575315754157551575615757157581575915760157611576215763157641576515766157671576815769157701577115772157731577415775157761577715778157791578015781157821578315784157851578615787157881578915790157911579215793157941579515796157971579815799158001580115802158031580415805158061580715808158091581015811158121581315814158151581615817158181581915820158211582215823158241582515826158271582815829158301583115832158331583415835158361583715838158391584015841158421584315844158451584615847158481584915850158511585215853158541585515856158571585815859158601586115862158631586415865158661586715868158691587015871158721587315874158751587615877158781587915880158811588215883158841588515886158871588815889158901589115892158931589415895158961589715898158991590015901159021590315904159051590615907159081590915910159111591215913159141591515916159171591815919159201592115922159231592415925159261592715928159291593015931159321593315934159351593615937159381593915940159411594215943159441594515946159471594815949159501595115952159531595415955159561595715958159591596015961159621596315964159651596615967159681596915970159711597215973159741597515976159771597815979159801598115982159831598415985159861598715988159891599015991159921599315994159951599615997159981599916000160011600216003160041600516006160071600816009160101601116012160131601416015160161601716018160191602016021160221602316024160251602616027160281602916030160311603216033160341603516036160371603816039160401604116042160431604416045160461604716048160491605016051160521605316054160551605616057160581605916060160611606216063160641606516066160671606816069160701607116072160731607416075160761607716078160791608016081160821608316084160851608616087160881608916090160911609216093160941609516096160971609816099161001610116102161031610416105161061610716108161091611016111161121611316114161151611616117161181611916120161211612216123161241612516126161271612816129161301613116132161331613416135161361613716138161391614016141161421614316144161451614616147161481614916150161511615216153161541615516156161571615816159161601616116162161631616416165161661616716168161691617016171161721617316174161751617616177161781617916180161811618216183161841618516186161871618816189161901619116192161931619416195161961619716198161991620016201162021620316204162051620616207162081620916210162111621216213162141621516216162171621816219162201622116222162231622416225162261622716228162291623016231162321623316234162351623616237162381623916240162411624216243162441624516246162471624816249162501625116252162531625416255162561625716258162591626016261162621626316264162651626616267162681626916270162711627216273162741627516276162771627816279162801628116282162831628416285162861628716288162891629016291162921629316294162951629616297162981629916300163011630216303163041630516306163071630816309163101631116312163131631416315163161631716318163191632016321163221632316324163251632616327163281632916330163311633216333163341633516336163371633816339163401634116342163431634416345163461634716348163491635016351163521635316354163551635616357163581635916360163611636216363163641636516366163671636816369163701637116372163731637416375163761637716378163791638016381163821638316384163851638616387163881638916390163911639216393163941639516396163971639816399164001640116402164031640416405164061640716408164091641016411164121641316414164151641616417164181641916420164211642216423164241642516426164271642816429164301643116432164331643416435164361643716438164391644016441164421644316444164451644616447164481644916450164511645216453164541645516456164571645816459164601646116462164631646416465164661646716468164691647016471164721647316474164751647616477164781647916480164811648216483164841648516486164871648816489164901649116492164931649416495164961649716498164991650016501165021650316504165051650616507165081650916510165111651216513165141651516516165171651816519165201652116522165231652416525165261652716528165291653016531165321653316534165351653616537165381653916540165411654216543165441654516546165471654816549165501655116552165531655416555165561655716558165591656016561165621656316564165651656616567165681656916570165711657216573165741657516576165771657816579165801658116582165831658416585165861658716588165891659016591165921659316594165951659616597165981659916600166011660216603166041660516606166071660816609166101661116612166131661416615166161661716618166191662016621166221662316624166251662616627166281662916630166311663216633166341663516636166371663816639166401664116642166431664416645166461664716648166491665016651166521665316654166551665616657166581665916660166611666216663166641666516666166671666816669166701667116672166731667416675166761667716678166791668016681166821668316684166851668616687166881668916690166911669216693166941669516696166971669816699167001670116702167031670416705167061670716708167091671016711167121671316714167151671616717167181671916720167211672216723167241672516726167271672816729167301673116732167331673416735167361673716738167391674016741167421674316744167451674616747167481674916750167511675216753167541675516756167571675816759167601676116762167631676416765167661676716768167691677016771167721677316774167751677616777167781677916780167811678216783167841678516786167871678816789167901679116792167931679416795167961679716798167991680016801168021680316804168051680616807168081680916810168111681216813168141681516816168171681816819168201682116822168231682416825168261682716828168291683016831168321683316834168351683616837168381683916840168411684216843168441684516846168471684816849168501685116852168531685416855168561685716858168591686016861168621686316864168651686616867168681686916870168711687216873168741687516876168771687816879168801688116882168831688416885168861688716888168891689016891168921689316894168951689616897168981689916900169011690216903169041690516906169071690816909169101691116912169131691416915169161691716918169191692016921169221692316924169251692616927169281692916930169311693216933169341693516936169371693816939169401694116942169431694416945169461694716948169491695016951169521695316954169551695616957169581695916960169611696216963169641696516966169671696816969169701697116972169731697416975169761697716978169791698016981169821698316984169851698616987169881698916990169911699216993169941699516996169971699816999170001700117002170031700417005170061700717008170091701017011170121701317014170151701617017170181701917020170211702217023170241702517026170271702817029170301703117032170331703417035170361703717038170391704017041170421704317044170451704617047170481704917050170511705217053170541705517056170571705817059170601706117062170631706417065170661706717068170691707017071170721707317074170751707617077170781707917080170811708217083170841708517086170871708817089170901709117092170931709417095170961709717098170991710017101171021710317104171051710617107171081710917110171111711217113171141711517116171171711817119171201712117122171231712417125171261712717128171291713017131171321713317134171351713617137171381713917140171411714217143171441714517146171471714817149171501715117152171531715417155171561715717158171591716017161171621716317164171651716617167171681716917170171711717217173171741717517176171771717817179171801718117182171831718417185171861718717188171891719017191171921719317194171951719617197171981719917200172011720217203172041720517206172071720817209172101721117212172131721417215172161721717218172191722017221172221722317224172251722617227172281722917230172311723217233172341723517236172371723817239172401724117242172431724417245172461724717248172491725017251172521725317254172551725617257172581725917260172611726217263172641726517266172671726817269172701727117272172731727417275172761727717278172791728017281172821728317284172851728617287172881728917290172911729217293172941729517296172971729817299173001730117302173031730417305173061730717308173091731017311173121731317314173151731617317173181731917320173211732217323173241732517326173271732817329173301733117332173331733417335173361733717338173391734017341173421734317344173451734617347173481734917350173511735217353173541735517356173571735817359173601736117362173631736417365173661736717368173691737017371173721737317374173751737617377173781737917380173811738217383173841738517386173871738817389173901739117392173931739417395173961739717398173991740017401174021740317404174051740617407174081740917410174111741217413174141741517416174171741817419174201742117422174231742417425174261742717428174291743017431174321743317434174351743617437174381743917440174411744217443174441744517446174471744817449174501745117452174531745417455174561745717458174591746017461174621746317464174651746617467174681746917470174711747217473174741747517476174771747817479174801748117482174831748417485174861748717488174891749017491174921749317494174951749617497174981749917500175011750217503175041750517506175071750817509175101751117512175131751417515175161751717518175191752017521175221752317524175251752617527175281752917530175311753217533175341753517536175371753817539175401754117542175431754417545175461754717548175491755017551175521755317554175551755617557175581755917560175611756217563175641756517566175671756817569175701757117572175731757417575175761757717578175791758017581175821758317584175851758617587175881758917590175911759217593175941759517596175971759817599176001760117602176031760417605176061760717608176091761017611176121761317614176151761617617176181761917620176211762217623176241762517626176271762817629176301763117632176331763417635176361763717638176391764017641176421764317644176451764617647176481764917650176511765217653176541765517656176571765817659176601766117662176631766417665176661766717668176691767017671176721767317674176751767617677176781767917680176811768217683176841768517686176871768817689176901769117692176931769417695176961769717698176991770017701177021770317704177051770617707177081770917710177111771217713177141771517716177171771817719177201772117722177231772417725177261772717728177291773017731177321773317734177351773617737177381773917740177411774217743177441774517746177471774817749177501775117752177531775417755177561775717758177591776017761177621776317764177651776617767177681776917770177711777217773177741777517776177771777817779177801778117782177831778417785177861778717788177891779017791177921779317794177951779617797177981779917800178011780217803178041780517806178071780817809178101781117812178131781417815178161781717818178191782017821178221782317824178251782617827178281782917830178311783217833178341783517836178371783817839178401784117842178431784417845178461784717848178491785017851178521785317854178551785617857178581785917860178611786217863178641786517866178671786817869178701787117872178731787417875178761787717878178791788017881178821788317884178851788617887178881788917890178911789217893178941789517896178971789817899179001790117902179031790417905179061790717908179091791017911179121791317914179151791617917179181791917920179211792217923179241792517926179271792817929179301793117932179331793417935179361793717938179391794017941179421794317944179451794617947179481794917950179511795217953179541795517956179571795817959179601796117962179631796417965179661796717968179691797017971179721797317974179751797617977179781797917980179811798217983179841798517986179871798817989179901799117992179931799417995179961799717998179991800018001180021800318004180051800618007180081800918010180111801218013180141801518016180171801818019180201802118022180231802418025180261802718028180291803018031180321803318034180351803618037180381803918040180411804218043180441804518046180471804818049180501805118052180531805418055180561805718058180591806018061180621806318064180651806618067180681806918070180711807218073180741807518076180771807818079180801808118082180831808418085180861808718088180891809018091180921809318094180951809618097180981809918100181011810218103181041810518106181071810818109181101811118112181131811418115181161811718118181191812018121181221812318124181251812618127181281812918130181311813218133181341813518136181371813818139181401814118142181431814418145181461814718148181491815018151181521815318154181551815618157181581815918160181611816218163181641816518166181671816818169181701817118172181731817418175181761817718178181791818018181181821818318184181851818618187181881818918190181911819218193181941819518196181971819818199182001820118202182031820418205182061820718208182091821018211182121821318214182151821618217182181821918220182211822218223182241822518226182271822818229182301823118232182331823418235182361823718238182391824018241182421824318244182451824618247182481824918250182511825218253182541825518256182571825818259182601826118262182631826418265182661826718268182691827018271182721827318274182751827618277182781827918280182811828218283182841828518286182871828818289182901829118292182931829418295182961829718298182991830018301183021830318304183051830618307183081830918310183111831218313183141831518316183171831818319183201832118322183231832418325183261832718328183291833018331183321833318334183351833618337183381833918340183411834218343183441834518346183471834818349183501835118352183531835418355183561835718358183591836018361183621836318364183651836618367183681836918370183711837218373183741837518376183771837818379183801838118382183831838418385183861838718388183891839018391183921839318394183951839618397183981839918400184011840218403184041840518406184071840818409184101841118412184131841418415184161841718418184191842018421184221842318424184251842618427184281842918430184311843218433184341843518436184371843818439184401844118442184431844418445184461844718448184491845018451184521845318454184551845618457184581845918460184611846218463184641846518466184671846818469184701847118472184731847418475184761847718478184791848018481184821848318484184851848618487184881848918490184911849218493184941849518496184971849818499185001850118502185031850418505185061850718508185091851018511185121851318514185151851618517185181851918520185211852218523185241852518526185271852818529185301853118532185331853418535185361853718538185391854018541185421854318544185451854618547185481854918550185511855218553185541855518556185571855818559185601856118562185631856418565185661856718568185691857018571185721857318574185751857618577185781857918580185811858218583185841858518586185871858818589185901859118592185931859418595185961859718598185991860018601186021860318604186051860618607186081860918610186111861218613186141861518616186171861818619186201862118622186231862418625186261862718628186291863018631186321863318634186351863618637186381863918640186411864218643186441864518646186471864818649186501865118652186531865418655186561865718658186591866018661186621866318664186651866618667186681866918670186711867218673186741867518676186771867818679186801868118682186831868418685186861868718688186891869018691186921869318694186951869618697186981869918700187011870218703187041870518706187071870818709187101871118712187131871418715187161871718718187191872018721187221872318724187251872618727187281872918730187311873218733187341873518736187371873818739187401874118742187431874418745187461874718748187491875018751187521875318754187551875618757187581875918760187611876218763187641876518766187671876818769187701877118772187731877418775187761877718778187791878018781187821878318784187851878618787187881878918790187911879218793187941879518796187971879818799188001880118802188031880418805188061880718808188091881018811188121881318814188151881618817188181881918820188211882218823188241882518826188271882818829188301883118832188331883418835188361883718838188391884018841188421884318844188451884618847188481884918850188511885218853188541885518856188571885818859188601886118862188631886418865188661886718868188691887018871188721887318874188751887618877188781887918880188811888218883188841888518886188871888818889188901889118892188931889418895188961889718898188991890018901189021890318904189051890618907189081890918910189111891218913189141891518916189171891818919189201892118922189231892418925189261892718928189291893018931189321893318934189351893618937189381893918940189411894218943189441894518946189471894818949189501895118952189531895418955189561895718958189591896018961189621896318964189651896618967189681896918970189711897218973189741897518976189771897818979189801898118982189831898418985189861898718988189891899018991189921899318994189951899618997189981899919000190011900219003190041900519006190071900819009190101901119012190131901419015190161901719018190191902019021190221902319024190251902619027190281902919030190311903219033190341903519036190371903819039190401904119042190431904419045190461904719048190491905019051190521905319054190551905619057190581905919060190611906219063190641906519066190671906819069190701907119072190731907419075190761907719078190791908019081190821908319084190851908619087190881908919090190911909219093190941909519096190971909819099191001910119102191031910419105191061910719108191091911019111191121911319114191151911619117191181911919120191211912219123191241912519126191271912819129191301913119132191331913419135191361913719138191391914019141191421914319144191451914619147191481914919150191511915219153191541915519156191571915819159191601916119162191631916419165191661916719168191691917019171191721917319174191751917619177191781917919180191811918219183191841918519186191871918819189191901919119192191931919419195191961919719198191991920019201192021920319204192051920619207192081920919210192111921219213192141921519216192171921819219192201922119222192231922419225192261922719228192291923019231192321923319234192351923619237192381923919240192411924219243192441924519246192471924819249192501925119252192531925419255192561925719258192591926019261192621926319264192651926619267192681926919270192711927219273192741927519276192771927819279192801928119282192831928419285192861928719288192891929019291192921929319294192951929619297192981929919300193011930219303193041930519306193071930819309193101931119312193131931419315193161931719318193191932019321193221932319324193251932619327193281932919330193311933219333193341933519336193371933819339193401934119342193431934419345193461934719348193491935019351193521935319354193551935619357193581935919360193611936219363193641936519366193671936819369193701937119372193731937419375193761937719378193791938019381193821938319384193851938619387193881938919390193911939219393193941939519396193971939819399194001940119402194031940419405194061940719408194091941019411194121941319414194151941619417194181941919420194211942219423194241942519426194271942819429194301943119432194331943419435194361943719438194391944019441194421944319444194451944619447194481944919450194511945219453194541945519456194571945819459194601946119462194631946419465194661946719468194691947019471194721947319474194751947619477194781947919480194811948219483194841948519486194871948819489194901949119492194931949419495194961949719498194991950019501195021950319504195051950619507195081950919510195111951219513195141951519516195171951819519195201952119522195231952419525195261952719528195291953019531195321953319534195351953619537195381953919540195411954219543195441954519546195471954819549195501955119552195531955419555195561955719558195591956019561195621956319564195651956619567195681956919570195711957219573195741957519576195771957819579195801958119582195831958419585195861958719588195891959019591195921959319594195951959619597195981959919600196011960219603196041960519606196071960819609196101961119612196131961419615196161961719618196191962019621196221962319624196251962619627196281962919630196311963219633196341963519636196371963819639196401964119642196431964419645196461964719648196491965019651196521965319654196551965619657196581965919660196611966219663196641966519666196671966819669196701967119672196731967419675196761967719678196791968019681196821968319684196851968619687196881968919690196911969219693196941969519696196971969819699197001970119702197031970419705197061970719708197091971019711197121971319714197151971619717197181971919720197211972219723197241972519726197271972819729197301973119732197331973419735197361973719738197391974019741197421974319744197451974619747197481974919750197511975219753197541975519756197571975819759197601976119762197631976419765197661976719768197691977019771197721977319774197751977619777197781977919780197811978219783197841978519786197871978819789197901979119792197931979419795197961979719798197991980019801198021980319804198051980619807198081980919810198111981219813198141981519816198171981819819198201982119822198231982419825198261982719828198291983019831198321983319834198351983619837198381983919840198411984219843198441984519846198471984819849198501985119852198531985419855198561985719858198591986019861198621986319864198651986619867198681986919870198711987219873198741987519876198771987819879198801988119882198831988419885198861988719888198891989019891198921989319894198951989619897198981989919900199011990219903199041990519906199071990819909199101991119912199131991419915199161991719918199191992019921199221992319924199251992619927199281992919930199311993219933199341993519936199371993819939199401994119942199431994419945199461994719948199491995019951199521995319954199551995619957199581995919960199611996219963199641996519966199671996819969199701997119972199731997419975199761997719978199791998019981199821998319984199851998619987199881998919990199911999219993199941999519996199971999819999200002000120002200032000420005200062000720008200092001020011200122001320014200152001620017200182001920020200212002220023200242002520026200272002820029200302003120032200332003420035200362003720038200392004020041200422004320044200452004620047200482004920050200512005220053200542005520056200572005820059200602006120062200632006420065200662006720068200692007020071200722007320074200752007620077200782007920080200812008220083200842008520086200872008820089200902009120092200932009420095200962009720098200992010020101201022010320104201052010620107201082010920110201112011220113201142011520116201172011820119201202012120122201232012420125201262012720128201292013020131201322013320134201352013620137201382013920140201412014220143201442014520146201472014820149201502015120152201532015420155201562015720158201592016020161201622016320164201652016620167201682016920170201712017220173201742017520176201772017820179201802018120182201832018420185201862018720188201892019020191201922019320194201952019620197201982019920200202012020220203202042020520206202072020820209202102021120212202132021420215202162021720218202192022020221202222022320224202252022620227202282022920230202312023220233202342023520236202372023820239202402024120242202432024420245202462024720248202492025020251202522025320254202552025620257202582025920260202612026220263202642026520266202672026820269202702027120272202732027420275202762027720278202792028020281202822028320284202852028620287202882028920290202912029220293202942029520296202972029820299203002030120302203032030420305203062030720308203092031020311203122031320314203152031620317203182031920320203212032220323203242032520326203272032820329203302033120332203332033420335203362033720338203392034020341203422034320344203452034620347203482034920350203512035220353203542035520356203572035820359203602036120362203632036420365203662036720368203692037020371203722037320374203752037620377203782037920380203812038220383203842038520386203872038820389203902039120392203932039420395203962039720398203992040020401204022040320404204052040620407204082040920410204112041220413204142041520416204172041820419204202042120422204232042420425204262042720428204292043020431204322043320434204352043620437204382043920440204412044220443204442044520446204472044820449204502045120452204532045420455204562045720458204592046020461204622046320464204652046620467204682046920470204712047220473204742047520476204772047820479204802048120482204832048420485204862048720488204892049020491204922049320494204952049620497204982049920500205012050220503205042050520506205072050820509205102051120512205132051420515205162051720518205192052020521205222052320524205252052620527205282052920530205312053220533205342053520536205372053820539205402054120542205432054420545205462054720548205492055020551205522055320554205552055620557205582055920560205612056220563205642056520566205672056820569205702057120572205732057420575205762057720578205792058020581205822058320584205852058620587205882058920590205912059220593205942059520596205972059820599206002060120602206032060420605206062060720608206092061020611206122061320614206152061620617206182061920620206212062220623206242062520626206272062820629206302063120632206332063420635206362063720638206392064020641206422064320644206452064620647206482064920650206512065220653206542065520656206572065820659206602066120662206632066420665206662066720668206692067020671206722067320674206752067620677206782067920680206812068220683206842068520686206872068820689206902069120692206932069420695206962069720698206992070020701207022070320704207052070620707207082070920710207112071220713207142071520716207172071820719207202072120722207232072420725207262072720728207292073020731207322073320734207352073620737207382073920740207412074220743207442074520746207472074820749207502075120752207532075420755207562075720758207592076020761207622076320764207652076620767207682076920770207712077220773207742077520776207772077820779207802078120782207832078420785207862078720788207892079020791207922079320794207952079620797207982079920800208012080220803208042080520806208072080820809208102081120812208132081420815208162081720818208192082020821208222082320824208252082620827208282082920830208312083220833208342083520836208372083820839208402084120842208432084420845208462084720848208492085020851208522085320854208552085620857208582085920860208612086220863208642086520866208672086820869208702087120872208732087420875208762087720878208792088020881208822088320884208852088620887208882088920890208912089220893208942089520896208972089820899209002090120902209032090420905209062090720908209092091020911209122091320914209152091620917209182091920920209212092220923209242092520926209272092820929209302093120932209332093420935209362093720938209392094020941209422094320944209452094620947209482094920950209512095220953209542095520956209572095820959209602096120962209632096420965209662096720968209692097020971209722097320974209752097620977209782097920980209812098220983209842098520986209872098820989209902099120992209932099420995209962099720998209992100021001210022100321004210052100621007210082100921010210112101221013210142101521016210172101821019210202102121022210232102421025210262102721028210292103021031210322103321034210352103621037210382103921040210412104221043210442104521046210472104821049210502105121052210532105421055210562105721058210592106021061210622106321064210652106621067210682106921070210712107221073210742107521076210772107821079210802108121082210832108421085210862108721088210892109021091210922109321094210952109621097210982109921100211012110221103211042110521106211072110821109211102111121112211132111421115211162111721118211192112021121211222112321124211252112621127211282112921130211312113221133211342113521136211372113821139211402114121142211432114421145211462114721148211492115021151211522115321154211552115621157211582115921160211612116221163211642116521166211672116821169211702117121172211732117421175211762117721178211792118021181211822118321184211852118621187211882118921190211912119221193211942119521196211972119821199212002120121202212032120421205212062120721208212092121021211212122121321214212152121621217212182121921220212212122221223212242122521226212272122821229212302123121232212332123421235212362123721238212392124021241212422124321244212452124621247212482124921250212512125221253212542125521256212572125821259212602126121262212632126421265212662126721268212692127021271212722127321274212752127621277212782127921280212812128221283212842128521286212872128821289212902129121292212932129421295212962129721298212992130021301213022130321304213052130621307213082130921310213112131221313213142131521316213172131821319213202132121322213232132421325213262132721328213292133021331213322133321334213352133621337213382133921340213412134221343213442134521346213472134821349213502135121352213532135421355213562135721358213592136021361213622136321364213652136621367213682136921370213712137221373213742137521376213772137821379213802138121382213832138421385213862138721388213892139021391213922139321394213952139621397213982139921400214012140221403214042140521406214072140821409214102141121412214132141421415214162141721418214192142021421214222142321424214252142621427214282142921430214312143221433214342143521436214372143821439214402144121442214432144421445214462144721448214492145021451214522145321454214552145621457214582145921460214612146221463214642146521466214672146821469214702147121472214732147421475214762147721478214792148021481214822148321484214852148621487214882148921490214912149221493214942149521496214972149821499215002150121502215032150421505215062150721508215092151021511215122151321514215152151621517215182151921520215212152221523215242152521526215272152821529215302153121532215332153421535215362153721538215392154021541215422154321544215452154621547215482154921550215512155221553215542155521556215572155821559215602156121562215632156421565215662156721568215692157021571215722157321574215752157621577215782157921580215812158221583215842158521586215872158821589215902159121592215932159421595215962159721598215992160021601216022160321604216052160621607216082160921610216112161221613216142161521616216172161821619216202162121622216232162421625216262162721628216292163021631216322163321634216352163621637216382163921640216412164221643216442164521646216472164821649216502165121652216532165421655216562165721658216592166021661216622166321664216652166621667216682166921670216712167221673216742167521676216772167821679216802168121682216832168421685216862168721688216892169021691216922169321694216952169621697216982169921700217012170221703217042170521706217072170821709217102171121712217132171421715217162171721718217192172021721217222172321724217252172621727217282172921730217312173221733217342173521736217372173821739217402174121742217432174421745217462174721748217492175021751217522175321754217552175621757217582175921760217612176221763217642176521766217672176821769217702177121772217732177421775217762177721778217792178021781217822178321784217852178621787217882178921790217912179221793217942179521796217972179821799218002180121802218032180421805218062180721808218092181021811218122181321814218152181621817218182181921820218212182221823218242182521826218272182821829218302183121832218332183421835218362183721838218392184021841218422184321844218452184621847218482184921850218512185221853218542185521856218572185821859218602186121862218632186421865218662186721868218692187021871218722187321874218752187621877218782187921880218812188221883218842188521886218872188821889218902189121892218932189421895218962189721898218992190021901219022190321904219052190621907219082190921910219112191221913219142191521916219172191821919219202192121922219232192421925219262192721928219292193021931219322193321934219352193621937219382193921940219412194221943219442194521946219472194821949219502195121952219532195421955219562195721958219592196021961219622196321964219652196621967219682196921970219712197221973219742197521976219772197821979219802198121982219832198421985219862198721988219892199021991219922199321994219952199621997219982199922000220012200222003220042200522006220072200822009220102201122012220132201422015220162201722018220192202022021220222202322024220252202622027220282202922030220312203222033220342203522036220372203822039220402204122042220432204422045220462204722048220492205022051220522205322054220552205622057220582205922060220612206222063220642206522066220672206822069220702207122072220732207422075220762207722078220792208022081220822208322084220852208622087220882208922090220912209222093220942209522096220972209822099221002210122102221032210422105221062210722108221092211022111221122211322114221152211622117221182211922120221212212222123221242212522126221272212822129221302213122132221332213422135221362213722138221392214022141221422214322144221452214622147221482214922150221512215222153221542215522156221572215822159221602216122162221632216422165221662216722168221692217022171221722217322174221752217622177221782217922180221812218222183221842218522186221872218822189221902219122192221932219422195221962219722198221992220022201222022220322204222052220622207222082220922210222112221222213222142221522216222172221822219222202222122222222232222422225222262222722228222292223022231222322223322234222352223622237222382223922240222412224222243222442224522246222472224822249222502225122252222532225422255222562225722258222592226022261222622226322264222652226622267222682226922270222712227222273222742227522276222772227822279222802228122282222832228422285222862228722288222892229022291222922229322294222952229622297222982229922300223012230222303223042230522306223072230822309223102231122312223132231422315223162231722318223192232022321223222232322324223252232622327223282232922330223312233222333223342233522336223372233822339223402234122342223432234422345223462234722348223492235022351223522235322354223552235622357223582235922360223612236222363223642236522366223672236822369223702237122372223732237422375223762237722378223792238022381223822238322384223852238622387223882238922390223912239222393223942239522396223972239822399224002240122402224032240422405224062240722408224092241022411224122241322414224152241622417224182241922420224212242222423224242242522426224272242822429224302243122432224332243422435224362243722438224392244022441224422244322444224452244622447224482244922450224512245222453224542245522456224572245822459224602246122462224632246422465224662246722468224692247022471224722247322474224752247622477224782247922480224812248222483224842248522486224872248822489224902249122492224932249422495224962249722498224992250022501225022250322504225052250622507225082250922510225112251222513225142251522516225172251822519225202252122522225232252422525225262252722528225292253022531225322253322534225352253622537225382253922540225412254222543225442254522546225472254822549225502255122552225532255422555225562255722558225592256022561225622256322564225652256622567225682256922570225712257222573225742257522576225772257822579225802258122582225832258422585225862258722588225892259022591225922259322594225952259622597225982259922600226012260222603226042260522606226072260822609226102261122612226132261422615226162261722618226192262022621226222262322624226252262622627226282262922630226312263222633226342263522636226372263822639226402264122642226432264422645226462264722648226492265022651226522265322654226552265622657226582265922660226612266222663226642266522666226672266822669226702267122672226732267422675226762267722678226792268022681226822268322684226852268622687226882268922690226912269222693226942269522696226972269822699227002270122702227032270422705227062270722708227092271022711227122271322714227152271622717227182271922720227212272222723227242272522726227272272822729227302273122732227332273422735227362273722738227392274022741227422274322744227452274622747227482274922750227512275222753227542275522756227572275822759227602276122762227632276422765227662276722768227692277022771227722277322774227752277622777227782277922780227812278222783227842278522786227872278822789227902279122792227932279422795227962279722798227992280022801228022280322804228052280622807228082280922810228112281222813228142281522816228172281822819228202282122822228232282422825228262282722828228292283022831228322283322834228352283622837228382283922840228412284222843228442284522846228472284822849228502285122852228532285422855228562285722858228592286022861228622286322864228652286622867228682286922870228712287222873228742287522876228772287822879228802288122882228832288422885228862288722888228892289022891228922289322894228952289622897228982289922900229012290222903229042290522906229072290822909229102291122912229132291422915229162291722918229192292022921229222292322924229252292622927229282292922930229312293222933229342293522936229372293822939229402294122942229432294422945229462294722948229492295022951229522295322954229552295622957229582295922960229612296222963229642296522966229672296822969229702297122972229732297422975229762297722978229792298022981229822298322984229852298622987229882298922990229912299222993229942299522996229972299822999230002300123002230032300423005230062300723008230092301023011230122301323014230152301623017230182301923020230212302223023230242302523026230272302823029230302303123032230332303423035230362303723038230392304023041230422304323044230452304623047230482304923050230512305223053230542305523056230572305823059230602306123062230632306423065230662306723068230692307023071230722307323074230752307623077230782307923080230812308223083230842308523086230872308823089230902309123092230932309423095230962309723098230992310023101231022310323104231052310623107231082310923110231112311223113231142311523116231172311823119231202312123122231232312423125231262312723128231292313023131231322313323134231352313623137231382313923140231412314223143231442314523146231472314823149231502315123152231532315423155231562315723158231592316023161231622316323164231652316623167231682316923170231712317223173231742317523176231772317823179231802318123182231832318423185231862318723188231892319023191231922319323194231952319623197231982319923200232012320223203232042320523206232072320823209232102321123212232132321423215232162321723218232192322023221232222322323224232252322623227232282322923230232312323223233232342323523236232372323823239232402324123242232432324423245232462324723248232492325023251232522325323254232552325623257232582325923260232612326223263232642326523266232672326823269232702327123272232732327423275232762327723278232792328023281232822328323284232852328623287232882328923290232912329223293232942329523296232972329823299233002330123302233032330423305233062330723308233092331023311233122331323314233152331623317233182331923320233212332223323233242332523326233272332823329233302333123332233332333423335233362333723338233392334023341233422334323344233452334623347233482334923350233512335223353233542335523356233572335823359233602336123362233632336423365233662336723368233692337023371233722337323374233752337623377233782337923380233812338223383233842338523386233872338823389233902339123392233932339423395233962339723398233992340023401234022340323404234052340623407234082340923410234112341223413234142341523416234172341823419234202342123422234232342423425234262342723428234292343023431234322343323434234352343623437234382343923440234412344223443234442344523446234472344823449234502345123452234532345423455234562345723458234592346023461234622346323464234652346623467234682346923470234712347223473234742347523476234772347823479234802348123482234832348423485234862348723488234892349023491234922349323494234952349623497234982349923500235012350223503235042350523506235072350823509235102351123512235132351423515235162351723518235192352023521235222352323524235252352623527235282352923530235312353223533235342353523536235372353823539235402354123542235432354423545235462354723548235492355023551235522355323554235552355623557235582355923560235612356223563235642356523566235672356823569235702357123572235732357423575235762357723578235792358023581235822358323584235852358623587235882358923590235912359223593235942359523596235972359823599236002360123602236032360423605236062360723608236092361023611236122361323614236152361623617236182361923620236212362223623236242362523626236272362823629236302363123632236332363423635236362363723638236392364023641236422364323644236452364623647236482364923650236512365223653236542365523656236572365823659236602366123662236632366423665236662366723668236692367023671236722367323674236752367623677236782367923680236812368223683236842368523686236872368823689236902369123692236932369423695236962369723698236992370023701237022370323704237052370623707237082370923710237112371223713237142371523716237172371823719237202372123722237232372423725237262372723728237292373023731237322373323734237352373623737237382373923740237412374223743237442374523746237472374823749237502375123752237532375423755237562375723758237592376023761237622376323764237652376623767237682376923770237712377223773237742377523776237772377823779237802378123782237832378423785237862378723788237892379023791237922379323794237952379623797237982379923800238012380223803238042380523806238072380823809238102381123812238132381423815238162381723818238192382023821238222382323824238252382623827238282382923830238312383223833238342383523836238372383823839238402384123842238432384423845238462384723848238492385023851238522385323854238552385623857238582385923860238612386223863238642386523866238672386823869238702387123872238732387423875238762387723878238792388023881238822388323884238852388623887238882388923890238912389223893238942389523896238972389823899239002390123902239032390423905239062390723908239092391023911239122391323914239152391623917239182391923920239212392223923239242392523926239272392823929239302393123932239332393423935239362393723938239392394023941239422394323944239452394623947239482394923950239512395223953239542395523956239572395823959239602396123962239632396423965239662396723968239692397023971239722397323974239752397623977239782397923980239812398223983239842398523986239872398823989239902399123992239932399423995239962399723998239992400024001240022400324004240052400624007240082400924010240112401224013240142401524016240172401824019240202402124022240232402424025240262402724028240292403024031240322403324034240352403624037240382403924040240412404224043240442404524046240472404824049240502405124052240532405424055240562405724058240592406024061240622406324064240652406624067240682406924070240712407224073240742407524076240772407824079240802408124082240832408424085240862408724088240892409024091240922409324094240952409624097240982409924100241012410224103241042410524106241072410824109241102411124112241132411424115241162411724118241192412024121241222412324124241252412624127241282412924130241312413224133241342413524136241372413824139241402414124142241432414424145241462414724148241492415024151241522415324154241552415624157241582415924160241612416224163241642416524166241672416824169241702417124172241732417424175241762417724178241792418024181241822418324184241852418624187241882418924190241912419224193241942419524196241972419824199242002420124202242032420424205242062420724208242092421024211242122421324214242152421624217242182421924220242212422224223242242422524226242272422824229242302423124232242332423424235242362423724238242392424024241242422424324244242452424624247242482424924250242512425224253242542425524256242572425824259242602426124262242632426424265242662426724268242692427024271242722427324274242752427624277242782427924280242812428224283242842428524286242872428824289242902429124292242932429424295242962429724298242992430024301243022430324304243052430624307243082430924310243112431224313243142431524316243172431824319243202432124322243232432424325243262432724328243292433024331243322433324334243352433624337243382433924340243412434224343243442434524346243472434824349243502435124352243532435424355243562435724358243592436024361243622436324364243652436624367243682436924370243712437224373243742437524376243772437824379243802438124382243832438424385243862438724388243892439024391243922439324394243952439624397243982439924400244012440224403244042440524406244072440824409244102441124412244132441424415244162441724418244192442024421244222442324424244252442624427244282442924430244312443224433244342443524436244372443824439244402444124442244432444424445244462444724448244492445024451244522445324454244552445624457244582445924460244612446224463244642446524466244672446824469244702447124472244732447424475244762447724478244792448024481244822448324484244852448624487244882448924490244912449224493244942449524496244972449824499245002450124502245032450424505245062450724508245092451024511245122451324514245152451624517245182451924520245212452224523245242452524526245272452824529245302453124532245332453424535245362453724538245392454024541245422454324544245452454624547245482454924550245512455224553245542455524556245572455824559245602456124562245632456424565245662456724568245692457024571245722457324574245752457624577245782457924580245812458224583245842458524586245872458824589245902459124592245932459424595245962459724598245992460024601246022460324604246052460624607246082460924610246112461224613246142461524616246172461824619246202462124622246232462424625246262462724628246292463024631246322463324634246352463624637246382463924640246412464224643246442464524646246472464824649246502465124652246532465424655246562465724658246592466024661246622466324664246652466624667246682466924670246712467224673246742467524676246772467824679246802468124682246832468424685246862468724688246892469024691246922469324694246952469624697246982469924700247012470224703247042470524706247072470824709247102471124712247132471424715247162471724718247192472024721247222472324724247252472624727247282472924730247312473224733247342473524736247372473824739247402474124742247432474424745247462474724748247492475024751247522475324754247552475624757247582475924760247612476224763247642476524766247672476824769247702477124772247732477424775247762477724778247792478024781247822478324784247852478624787247882478924790247912479224793247942479524796247972479824799248002480124802248032480424805248062480724808248092481024811248122481324814248152481624817248182481924820248212482224823248242482524826248272482824829248302483124832248332483424835248362483724838248392484024841248422484324844248452484624847248482484924850248512485224853248542485524856248572485824859248602486124862248632486424865248662486724868248692487024871248722487324874248752487624877248782487924880248812488224883248842488524886248872488824889248902489124892248932489424895248962489724898248992490024901249022490324904249052490624907249082490924910249112491224913249142491524916249172491824919249202492124922249232492424925249262492724928249292493024931249322493324934249352493624937249382493924940249412494224943249442494524946249472494824949249502495124952249532495424955249562495724958249592496024961249622496324964249652496624967249682496924970249712497224973249742497524976249772497824979249802498124982249832498424985249862498724988249892499024991249922499324994249952499624997249982499925000250012500225003250042500525006250072500825009250102501125012250132501425015250162501725018250192502025021250222502325024250252502625027250282502925030250312503225033250342503525036250372503825039250402504125042250432504425045250462504725048250492505025051250522505325054250552505625057250582505925060250612506225063250642506525066250672506825069250702507125072250732507425075250762507725078250792508025081250822508325084250852508625087250882508925090250912509225093250942509525096250972509825099251002510125102251032510425105251062510725108251092511025111251122511325114251152511625117251182511925120251212512225123251242512525126251272512825129251302513125132251332513425135251362513725138251392514025141251422514325144251452514625147251482514925150251512515225153251542515525156251572515825159251602516125162251632516425165251662516725168251692517025171251722517325174251752517625177251782517925180251812518225183251842518525186251872518825189251902519125192251932519425195251962519725198251992520025201252022520325204252052520625207252082520925210252112521225213252142521525216252172521825219252202522125222252232522425225252262522725228252292523025231252322523325234252352523625237252382523925240252412524225243252442524525246252472524825249252502525125252252532525425255252562525725258252592526025261252622526325264252652526625267252682526925270252712527225273252742527525276252772527825279252802528125282252832528425285252862528725288252892529025291252922529325294252952529625297252982529925300253012530225303253042530525306253072530825309253102531125312253132531425315253162531725318253192532025321253222532325324253252532625327253282532925330253312533225333253342533525336253372533825339253402534125342253432534425345253462534725348253492535025351253522535325354253552535625357253582535925360253612536225363253642536525366253672536825369253702537125372253732537425375253762537725378253792538025381253822538325384253852538625387253882538925390253912539225393253942539525396253972539825399254002540125402254032540425405254062540725408254092541025411254122541325414254152541625417254182541925420254212542225423254242542525426254272542825429254302543125432254332543425435254362543725438254392544025441254422544325444254452544625447254482544925450254512545225453254542545525456254572545825459254602546125462254632546425465254662546725468254692547025471254722547325474254752547625477254782547925480254812548225483254842548525486254872548825489254902549125492254932549425495254962549725498254992550025501255022550325504255052550625507255082550925510255112551225513255142551525516255172551825519255202552125522255232552425525255262552725528255292553025531255322553325534255352553625537255382553925540255412554225543255442554525546255472554825549255502555125552255532555425555255562555725558255592556025561255622556325564255652556625567255682556925570255712557225573255742557525576255772557825579255802558125582255832558425585255862558725588255892559025591255922559325594255952559625597255982559925600256012560225603256042560525606256072560825609256102561125612256132561425615256162561725618256192562025621256222562325624256252562625627256282562925630256312563225633256342563525636256372563825639256402564125642256432564425645256462564725648256492565025651256522565325654256552565625657256582565925660256612566225663256642566525666256672566825669256702567125672256732567425675256762567725678256792568025681256822568325684256852568625687256882568925690256912569225693256942569525696256972569825699257002570125702257032570425705257062570725708257092571025711257122571325714257152571625717257182571925720257212572225723257242572525726257272572825729257302573125732257332573425735257362573725738257392574025741257422574325744257452574625747257482574925750257512575225753257542575525756257572575825759257602576125762257632576425765257662576725768257692577025771257722577325774257752577625777257782577925780257812578225783257842578525786257872578825789257902579125792257932579425795257962579725798257992580025801258022580325804258052580625807258082580925810258112581225813258142581525816258172581825819258202582125822258232582425825258262582725828258292583025831258322583325834258352583625837258382583925840258412584225843258442584525846258472584825849258502585125852258532585425855258562585725858258592586025861258622586325864258652586625867258682586925870258712587225873258742587525876258772587825879258802588125882258832588425885258862588725888258892589025891258922589325894258952589625897258982589925900259012590225903259042590525906259072590825909259102591125912259132591425915259162591725918259192592025921259222592325924259252592625927259282592925930259312593225933259342593525936259372593825939259402594125942259432594425945259462594725948259492595025951259522595325954259552595625957259582595925960259612596225963259642596525966259672596825969259702597125972259732597425975259762597725978259792598025981259822598325984259852598625987259882598925990259912599225993259942599525996259972599825999260002600126002260032600426005260062600726008260092601026011260122601326014260152601626017260182601926020260212602226023260242602526026260272602826029260302603126032260332603426035260362603726038260392604026041260422604326044260452604626047260482604926050260512605226053260542605526056260572605826059260602606126062260632606426065260662606726068260692607026071260722607326074260752607626077260782607926080260812608226083260842608526086260872608826089260902609126092260932609426095260962609726098260992610026101261022610326104261052610626107261082610926110261112611226113261142611526116261172611826119261202612126122261232612426125261262612726128261292613026131261322613326134261352613626137261382613926140261412614226143261442614526146261472614826149261502615126152261532615426155261562615726158261592616026161261622616326164261652616626167261682616926170261712617226173261742617526176261772617826179261802618126182261832618426185261862618726188261892619026191261922619326194261952619626197261982619926200262012620226203262042620526206262072620826209262102621126212262132621426215262162621726218262192622026221262222622326224262252622626227262282622926230262312623226233262342623526236262372623826239262402624126242262432624426245262462624726248262492625026251262522625326254262552625626257262582625926260262612626226263262642626526266262672626826269262702627126272262732627426275262762627726278262792628026281262822628326284262852628626287262882628926290262912629226293262942629526296262972629826299263002630126302263032630426305263062630726308263092631026311263122631326314263152631626317263182631926320263212632226323263242632526326263272632826329263302633126332263332633426335263362633726338263392634026341263422634326344263452634626347263482634926350263512635226353263542635526356263572635826359263602636126362263632636426365263662636726368263692637026371263722637326374263752637626377263782637926380263812638226383263842638526386263872638826389263902639126392263932639426395263962639726398263992640026401264022640326404264052640626407264082640926410264112641226413264142641526416264172641826419264202642126422264232642426425264262642726428264292643026431264322643326434264352643626437264382643926440264412644226443264442644526446264472644826449264502645126452264532645426455264562645726458264592646026461264622646326464264652646626467264682646926470264712647226473264742647526476264772647826479264802648126482264832648426485264862648726488264892649026491264922649326494264952649626497264982649926500265012650226503265042650526506265072650826509265102651126512265132651426515265162651726518265192652026521265222652326524265252652626527265282652926530265312653226533265342653526536265372653826539265402654126542265432654426545265462654726548265492655026551265522655326554265552655626557265582655926560265612656226563265642656526566265672656826569265702657126572265732657426575265762657726578265792658026581265822658326584265852658626587265882658926590265912659226593265942659526596265972659826599266002660126602266032660426605266062660726608266092661026611266122661326614266152661626617266182661926620266212662226623266242662526626266272662826629266302663126632266332663426635266362663726638266392664026641266422664326644266452664626647266482664926650266512665226653266542665526656266572665826659266602666126662266632666426665266662666726668266692667026671266722667326674266752667626677266782667926680266812668226683266842668526686266872668826689266902669126692266932669426695266962669726698266992670026701267022670326704267052670626707267082670926710267112671226713267142671526716267172671826719267202672126722267232672426725267262672726728267292673026731267322673326734267352673626737267382673926740267412674226743267442674526746267472674826749267502675126752267532675426755267562675726758267592676026761267622676326764267652676626767267682676926770267712677226773267742677526776267772677826779267802678126782267832678426785267862678726788267892679026791267922679326794267952679626797267982679926800268012680226803268042680526806268072680826809268102681126812268132681426815268162681726818268192682026821268222682326824268252682626827268282682926830268312683226833268342683526836268372683826839268402684126842268432684426845268462684726848268492685026851268522685326854268552685626857268582685926860268612686226863268642686526866268672686826869268702687126872268732687426875268762687726878268792688026881268822688326884268852688626887268882688926890268912689226893268942689526896268972689826899269002690126902269032690426905269062690726908269092691026911269122691326914269152691626917269182691926920269212692226923269242692526926269272692826929269302693126932269332693426935269362693726938269392694026941269422694326944269452694626947269482694926950269512695226953269542695526956269572695826959269602696126962269632696426965269662696726968269692697026971269722697326974269752697626977269782697926980269812698226983269842698526986269872698826989269902699126992269932699426995269962699726998269992700027001270022700327004270052700627007270082700927010270112701227013270142701527016270172701827019270202702127022270232702427025270262702727028270292703027031270322703327034270352703627037270382703927040270412704227043270442704527046270472704827049270502705127052270532705427055270562705727058270592706027061270622706327064270652706627067270682706927070270712707227073270742707527076270772707827079270802708127082270832708427085270862708727088270892709027091270922709327094270952709627097270982709927100271012710227103271042710527106271072710827109271102711127112271132711427115271162711727118271192712027121271222712327124271252712627127271282712927130271312713227133271342713527136271372713827139271402714127142271432714427145271462714727148271492715027151271522715327154271552715627157271582715927160271612716227163271642716527166271672716827169271702717127172271732717427175271762717727178271792718027181271822718327184271852718627187271882718927190271912719227193271942719527196271972719827199272002720127202272032720427205272062720727208272092721027211272122721327214272152721627217272182721927220272212722227223272242722527226272272722827229272302723127232272332723427235272362723727238272392724027241272422724327244272452724627247272482724927250272512725227253272542725527256272572725827259272602726127262272632726427265272662726727268272692727027271272722727327274272752727627277272782727927280272812728227283272842728527286272872728827289272902729127292272932729427295272962729727298272992730027301273022730327304273052730627307273082730927310273112731227313273142731527316273172731827319273202732127322273232732427325273262732727328273292733027331273322733327334273352733627337273382733927340273412734227343273442734527346273472734827349273502735127352273532735427355273562735727358273592736027361273622736327364273652736627367273682736927370273712737227373273742737527376273772737827379273802738127382273832738427385273862738727388273892739027391273922739327394273952739627397273982739927400274012740227403274042740527406274072740827409274102741127412274132741427415274162741727418274192742027421274222742327424274252742627427274282742927430274312743227433274342743527436274372743827439274402744127442274432744427445274462744727448274492745027451274522745327454274552745627457274582745927460274612746227463274642746527466274672746827469274702747127472274732747427475274762747727478274792748027481274822748327484274852748627487274882748927490274912749227493274942749527496274972749827499275002750127502275032750427505275062750727508275092751027511275122751327514275152751627517275182751927520275212752227523275242752527526275272752827529275302753127532275332753427535275362753727538275392754027541275422754327544275452754627547275482754927550275512755227553275542755527556275572755827559275602756127562275632756427565275662756727568275692757027571275722757327574275752757627577275782757927580275812758227583275842758527586275872758827589275902759127592275932759427595275962759727598275992760027601276022760327604276052760627607276082760927610276112761227613276142761527616276172761827619276202762127622276232762427625276262762727628276292763027631276322763327634276352763627637276382763927640276412764227643276442764527646276472764827649276502765127652276532765427655276562765727658276592766027661276622766327664276652766627667276682766927670276712767227673276742767527676276772767827679276802768127682276832768427685276862768727688276892769027691276922769327694276952769627697276982769927700277012770227703277042770527706277072770827709277102771127712277132771427715277162771727718277192772027721277222772327724277252772627727277282772927730277312773227733277342773527736277372773827739277402774127742277432774427745277462774727748277492775027751277522775327754277552775627757277582775927760277612776227763277642776527766277672776827769277702777127772277732777427775277762777727778277792778027781277822778327784277852778627787277882778927790277912779227793277942779527796277972779827799278002780127802278032780427805278062780727808278092781027811278122781327814278152781627817278182781927820278212782227823278242782527826278272782827829278302783127832278332783427835278362783727838278392784027841278422784327844278452784627847278482784927850278512785227853278542785527856278572785827859278602786127862278632786427865278662786727868278692787027871278722787327874278752787627877278782787927880278812788227883278842788527886278872788827889278902789127892278932789427895278962789727898278992790027901279022790327904279052790627907279082790927910279112791227913279142791527916279172791827919279202792127922279232792427925279262792727928279292793027931279322793327934279352793627937279382793927940279412794227943279442794527946279472794827949279502795127952279532795427955279562795727958279592796027961279622796327964279652796627967279682796927970279712797227973279742797527976279772797827979279802798127982279832798427985279862798727988279892799027991279922799327994279952799627997279982799928000280012800228003280042800528006280072800828009280102801128012280132801428015280162801728018280192802028021280222802328024280252802628027280282802928030280312803228033280342803528036280372803828039280402804128042280432804428045280462804728048280492805028051280522805328054280552805628057280582805928060280612806228063280642806528066280672806828069280702807128072280732807428075280762807728078280792808028081280822808328084280852808628087280882808928090280912809228093280942809528096280972809828099281002810128102281032810428105281062810728108281092811028111281122811328114281152811628117281182811928120281212812228123281242812528126281272812828129281302813128132281332813428135281362813728138281392814028141281422814328144281452814628147281482814928150281512815228153281542815528156281572815828159281602816128162281632816428165281662816728168281692817028171281722817328174281752817628177281782817928180281812818228183281842818528186281872818828189281902819128192281932819428195281962819728198281992820028201282022820328204282052820628207282082820928210282112821228213282142821528216282172821828219282202822128222282232822428225282262822728228282292823028231282322823328234282352823628237282382823928240282412824228243282442824528246282472824828249282502825128252282532825428255282562825728258282592826028261282622826328264282652826628267282682826928270282712827228273282742827528276282772827828279282802828128282282832828428285282862828728288282892829028291282922829328294282952829628297282982829928300283012830228303283042830528306283072830828309283102831128312283132831428315283162831728318283192832028321283222832328324283252832628327283282832928330283312833228333283342833528336283372833828339283402834128342283432834428345283462834728348283492835028351283522835328354283552835628357283582835928360283612836228363283642836528366283672836828369283702837128372283732837428375283762837728378283792838028381283822838328384283852838628387283882838928390283912839228393283942839528396283972839828399284002840128402284032840428405284062840728408284092841028411284122841328414284152841628417284182841928420284212842228423284242842528426284272842828429284302843128432284332843428435284362843728438284392844028441284422844328444284452844628447284482844928450284512845228453284542845528456284572845828459284602846128462284632846428465284662846728468284692847028471284722847328474284752847628477284782847928480284812848228483284842848528486284872848828489284902849128492284932849428495284962849728498284992850028501285022850328504285052850628507285082850928510285112851228513285142851528516285172851828519285202852128522285232852428525285262852728528285292853028531285322853328534285352853628537285382853928540285412854228543285442854528546285472854828549285502855128552285532855428555285562855728558285592856028561285622856328564285652856628567285682856928570285712857228573285742857528576285772857828579285802858128582285832858428585285862858728588285892859028591285922859328594285952859628597285982859928600286012860228603286042860528606286072860828609286102861128612286132861428615286162861728618286192862028621286222862328624286252862628627286282862928630286312863228633286342863528636286372863828639286402864128642286432864428645286462864728648286492865028651286522865328654286552865628657286582865928660286612866228663286642866528666286672866828669286702867128672286732867428675286762867728678286792868028681286822868328684286852868628687286882868928690286912869228693286942869528696286972869828699287002870128702287032870428705287062870728708287092871028711287122871328714287152871628717287182871928720287212872228723287242872528726287272872828729287302873128732287332873428735287362873728738287392874028741287422874328744287452874628747287482874928750287512875228753287542875528756287572875828759287602876128762287632876428765287662876728768287692877028771287722877328774287752877628777287782877928780287812878228783287842878528786287872878828789287902879128792287932879428795287962879728798287992880028801288022880328804288052880628807288082880928810288112881228813288142881528816288172881828819288202882128822288232882428825288262882728828288292883028831288322883328834288352883628837288382883928840288412884228843288442884528846288472884828849288502885128852288532885428855288562885728858288592886028861288622886328864288652886628867288682886928870288712887228873288742887528876288772887828879288802888128882288832888428885288862888728888288892889028891288922889328894288952889628897288982889928900289012890228903289042890528906289072890828909289102891128912289132891428915289162891728918289192892028921289222892328924289252892628927289282892928930289312893228933289342893528936289372893828939289402894128942289432894428945289462894728948289492895028951289522895328954289552895628957289582895928960289612896228963289642896528966289672896828969289702897128972289732897428975289762897728978289792898028981289822898328984289852898628987289882898928990289912899228993289942899528996289972899828999290002900129002290032900429005290062900729008290092901029011290122901329014290152901629017290182901929020290212902229023290242902529026290272902829029290302903129032290332903429035290362903729038290392904029041290422904329044290452904629047290482904929050290512905229053290542905529056290572905829059290602906129062290632906429065290662906729068290692907029071290722907329074290752907629077290782907929080290812908229083290842908529086290872908829089290902909129092290932909429095290962909729098290992910029101291022910329104291052910629107291082910929110291112911229113291142911529116291172911829119291202912129122291232912429125291262912729128291292913029131291322913329134291352913629137291382913929140291412914229143291442914529146291472914829149291502915129152291532915429155291562915729158291592916029161291622916329164291652916629167291682916929170291712917229173291742917529176291772917829179291802918129182291832918429185291862918729188291892919029191291922919329194291952919629197291982919929200292012920229203292042920529206292072920829209292102921129212292132921429215292162921729218292192922029221292222922329224292252922629227292282922929230292312923229233292342923529236292372923829239292402924129242292432924429245292462924729248292492925029251292522925329254292552925629257292582925929260292612926229263292642926529266292672926829269292702927129272292732927429275292762927729278292792928029281292822928329284292852928629287292882928929290292912929229293292942929529296292972929829299293002930129302293032930429305293062930729308293092931029311293122931329314293152931629317293182931929320293212932229323293242932529326293272932829329293302933129332293332933429335293362933729338293392934029341293422934329344293452934629347293482934929350293512935229353293542935529356293572935829359293602936129362293632936429365293662936729368293692937029371293722937329374293752937629377293782937929380293812938229383293842938529386293872938829389293902939129392293932939429395293962939729398293992940029401294022940329404294052940629407294082940929410294112941229413294142941529416294172941829419294202942129422294232942429425294262942729428294292943029431294322943329434294352943629437294382943929440294412944229443294442944529446294472944829449294502945129452294532945429455294562945729458294592946029461294622946329464294652946629467294682946929470294712947229473294742947529476294772947829479294802948129482294832948429485294862948729488294892949029491294922949329494294952949629497294982949929500295012950229503295042950529506295072950829509295102951129512295132951429515295162951729518295192952029521295222952329524295252952629527295282952929530295312953229533295342953529536295372953829539295402954129542295432954429545295462954729548295492955029551295522955329554295552955629557295582955929560295612956229563295642956529566295672956829569295702957129572295732957429575295762957729578295792958029581295822958329584295852958629587295882958929590295912959229593295942959529596295972959829599296002960129602296032960429605296062960729608296092961029611296122961329614296152961629617296182961929620296212962229623296242962529626296272962829629296302963129632296332963429635296362963729638296392964029641296422964329644296452964629647296482964929650296512965229653296542965529656296572965829659296602966129662296632966429665296662966729668296692967029671296722967329674296752967629677296782967929680296812968229683296842968529686296872968829689296902969129692296932969429695296962969729698296992970029701297022970329704297052970629707297082970929710297112971229713297142971529716297172971829719297202972129722297232972429725297262972729728297292973029731297322973329734297352973629737297382973929740297412974229743297442974529746297472974829749297502975129752297532975429755297562975729758297592976029761297622976329764297652976629767297682976929770297712977229773297742977529776297772977829779297802978129782297832978429785297862978729788297892979029791297922979329794297952979629797297982979929800298012980229803298042980529806298072980829809298102981129812298132981429815298162981729818298192982029821298222982329824298252982629827298282982929830298312983229833298342983529836298372983829839298402984129842298432984429845298462984729848298492985029851298522985329854298552985629857298582985929860298612986229863298642986529866298672986829869298702987129872298732987429875298762987729878298792988029881298822988329884298852988629887298882988929890298912989229893298942989529896298972989829899299002990129902299032990429905299062990729908299092991029911299122991329914299152991629917299182991929920299212992229923299242992529926299272992829929299302993129932299332993429935299362993729938299392994029941299422994329944299452994629947299482994929950299512995229953299542995529956299572995829959299602996129962299632996429965299662996729968299692997029971299722997329974299752997629977299782997929980299812998229983299842998529986299872998829989299902999129992299932999429995299962999729998299993000030001300023000330004300053000630007300083000930010300113001230013300143001530016300173001830019300203002130022300233002430025300263002730028300293003030031300323003330034300353003630037300383003930040300413004230043300443004530046300473004830049300503005130052300533005430055300563005730058300593006030061300623006330064300653006630067300683006930070300713007230073300743007530076300773007830079300803008130082300833008430085300863008730088300893009030091300923009330094300953009630097300983009930100301013010230103301043010530106301073010830109301103011130112301133011430115301163011730118301193012030121301223012330124301253012630127301283012930130301313013230133301343013530136301373013830139301403014130142301433014430145301463014730148301493015030151301523015330154301553015630157301583015930160301613016230163301643016530166301673016830169301703017130172301733017430175301763017730178301793018030181301823018330184301853018630187301883018930190301913019230193301943019530196301973019830199302003020130202302033020430205302063020730208302093021030211302123021330214302153021630217302183021930220302213022230223302243022530226302273022830229302303023130232302333023430235302363023730238302393024030241302423024330244302453024630247302483024930250302513025230253302543025530256302573025830259302603026130262302633026430265302663026730268302693027030271302723027330274302753027630277302783027930280302813028230283302843028530286302873028830289302903029130292302933029430295302963029730298302993030030301303023030330304303053030630307303083030930310303113031230313303143031530316303173031830319303203032130322303233032430325303263032730328303293033030331303323033330334303353033630337303383033930340303413034230343303443034530346303473034830349303503035130352303533035430355303563035730358303593036030361303623036330364303653036630367303683036930370303713037230373303743037530376303773037830379303803038130382303833038430385303863038730388303893039030391303923039330394303953039630397303983039930400304013040230403304043040530406304073040830409304103041130412304133041430415304163041730418304193042030421304223042330424304253042630427304283042930430304313043230433304343043530436304373043830439304403044130442304433044430445304463044730448304493045030451304523045330454304553045630457304583045930460304613046230463304643046530466304673046830469304703047130472304733047430475304763047730478304793048030481304823048330484304853048630487304883048930490304913049230493304943049530496304973049830499305003050130502305033050430505305063050730508305093051030511305123051330514305153051630517305183051930520305213052230523305243052530526305273052830529305303053130532305333053430535305363053730538305393054030541305423054330544305453054630547305483054930550305513055230553305543055530556305573055830559305603056130562305633056430565305663056730568305693057030571305723057330574305753057630577305783057930580305813058230583305843058530586305873058830589305903059130592305933059430595305963059730598305993060030601306023060330604306053060630607306083060930610306113061230613306143061530616306173061830619306203062130622306233062430625306263062730628306293063030631306323063330634306353063630637306383063930640306413064230643306443064530646306473064830649306503065130652306533065430655306563065730658306593066030661306623066330664306653066630667306683066930670306713067230673306743067530676306773067830679306803068130682306833068430685306863068730688306893069030691306923069330694306953069630697306983069930700307013070230703307043070530706307073070830709307103071130712307133071430715307163071730718307193072030721307223072330724307253072630727307283072930730307313073230733307343073530736307373073830739307403074130742307433074430745307463074730748307493075030751307523075330754307553075630757307583075930760307613076230763307643076530766307673076830769307703077130772307733077430775307763077730778307793078030781307823078330784307853078630787307883078930790307913079230793307943079530796307973079830799308003080130802308033080430805308063080730808308093081030811308123081330814308153081630817308183081930820308213082230823308243082530826308273082830829308303083130832308333083430835308363083730838308393084030841308423084330844308453084630847308483084930850308513085230853308543085530856308573085830859308603086130862308633086430865308663086730868308693087030871308723087330874308753087630877308783087930880308813088230883308843088530886308873088830889308903089130892308933089430895308963089730898308993090030901309023090330904309053090630907309083090930910309113091230913309143091530916309173091830919309203092130922309233092430925309263092730928309293093030931309323093330934309353093630937309383093930940309413094230943309443094530946309473094830949309503095130952309533095430955309563095730958309593096030961309623096330964309653096630967309683096930970309713097230973309743097530976309773097830979309803098130982309833098430985309863098730988309893099030991309923099330994309953099630997309983099931000310013100231003310043100531006310073100831009310103101131012310133101431015310163101731018310193102031021310223102331024310253102631027310283102931030310313103231033310343103531036310373103831039310403104131042310433104431045310463104731048310493105031051310523105331054310553105631057310583105931060310613106231063310643106531066310673106831069310703107131072310733107431075310763107731078310793108031081310823108331084310853108631087310883108931090310913109231093310943109531096310973109831099311003110131102311033110431105311063110731108311093111031111311123111331114311153111631117311183111931120311213112231123311243112531126311273112831129311303113131132311333113431135311363113731138311393114031141311423114331144311453114631147311483114931150311513115231153311543115531156311573115831159311603116131162311633116431165311663116731168311693117031171311723117331174311753117631177311783117931180311813118231183311843118531186311873118831189311903119131192311933119431195311963119731198311993120031201312023120331204312053120631207312083120931210312113121231213312143121531216312173121831219312203122131222312233122431225312263122731228312293123031231312323123331234312353123631237312383123931240312413124231243312443124531246312473124831249312503125131252312533125431255312563125731258312593126031261312623126331264312653126631267312683126931270312713127231273312743127531276312773127831279312803128131282312833128431285312863128731288312893129031291312923129331294312953129631297312983129931300313013130231303313043130531306313073130831309313103131131312313133131431315313163131731318313193132031321313223132331324313253132631327313283132931330313313133231333313343133531336313373133831339313403134131342313433134431345313463134731348313493135031351313523135331354313553135631357313583135931360313613136231363313643136531366313673136831369313703137131372313733137431375313763137731378313793138031381313823138331384313853138631387313883138931390313913139231393313943139531396313973139831399314003140131402314033140431405314063140731408314093141031411314123141331414314153141631417314183141931420314213142231423314243142531426314273142831429314303143131432314333143431435314363143731438314393144031441314423144331444314453144631447314483144931450314513145231453314543145531456314573145831459314603146131462314633146431465314663146731468314693147031471314723147331474314753147631477314783147931480314813148231483314843148531486314873148831489314903149131492314933149431495314963149731498314993150031501315023150331504315053150631507315083150931510315113151231513315143151531516315173151831519315203152131522315233152431525315263152731528315293153031531315323153331534315353153631537315383153931540315413154231543315443154531546315473154831549315503155131552315533155431555315563155731558315593156031561315623156331564315653156631567315683156931570315713157231573315743157531576315773157831579315803158131582315833158431585315863158731588315893159031591315923159331594315953159631597315983159931600316013160231603316043160531606316073160831609316103161131612316133161431615316163161731618316193162031621316223162331624316253162631627316283162931630316313163231633316343163531636316373163831639316403164131642316433164431645316463164731648316493165031651316523165331654316553165631657316583165931660316613166231663316643166531666316673166831669316703167131672316733167431675316763167731678316793168031681316823168331684316853168631687316883168931690316913169231693316943169531696316973169831699317003170131702317033170431705317063170731708317093171031711317123171331714317153171631717317183171931720317213172231723317243172531726317273172831729317303173131732317333173431735317363173731738317393174031741317423174331744317453174631747317483174931750317513175231753317543175531756317573175831759317603176131762317633176431765317663176731768317693177031771317723177331774317753177631777317783177931780317813178231783317843178531786317873178831789317903179131792317933179431795317963179731798317993180031801318023180331804318053180631807318083180931810318113181231813318143181531816318173181831819318203182131822318233182431825318263182731828318293183031831318323183331834318353183631837318383183931840318413184231843318443184531846318473184831849318503185131852318533185431855318563185731858318593186031861318623186331864318653186631867318683186931870318713187231873318743187531876318773187831879318803188131882318833188431885318863188731888318893189031891318923189331894318953189631897318983189931900319013190231903319043190531906319073190831909319103191131912319133191431915319163191731918319193192031921319223192331924319253192631927319283192931930319313193231933319343193531936319373193831939319403194131942319433194431945319463194731948319493195031951319523195331954319553195631957319583195931960319613196231963319643196531966319673196831969319703197131972319733197431975319763197731978319793198031981319823198331984319853198631987319883198931990319913199231993319943199531996319973199831999320003200132002320033200432005320063200732008320093201032011320123201332014320153201632017320183201932020320213202232023320243202532026320273202832029320303203132032320333203432035320363203732038320393204032041320423204332044320453204632047320483204932050320513205232053320543205532056320573205832059320603206132062320633206432065320663206732068320693207032071320723207332074320753207632077320783207932080320813208232083320843208532086320873208832089320903209132092320933209432095320963209732098320993210032101321023210332104321053210632107321083210932110321113211232113321143211532116321173211832119321203212132122321233212432125321263212732128321293213032131321323213332134321353213632137321383213932140321413214232143321443214532146321473214832149321503215132152321533215432155321563215732158321593216032161321623216332164321653216632167321683216932170321713217232173321743217532176321773217832179321803218132182321833218432185321863218732188321893219032191321923219332194321953219632197321983219932200322013220232203322043220532206322073220832209322103221132212322133221432215322163221732218322193222032221322223222332224322253222632227322283222932230322313223232233322343223532236322373223832239322403224132242322433224432245322463224732248322493225032251322523225332254322553225632257322583225932260322613226232263322643226532266322673226832269322703227132272322733227432275322763227732278322793228032281322823228332284322853228632287322883228932290322913229232293322943229532296322973229832299323003230132302323033230432305323063230732308323093231032311323123231332314323153231632317323183231932320323213232232323323243232532326323273232832329323303233132332323333233432335323363233732338323393234032341323423234332344323453234632347323483234932350323513235232353323543235532356323573235832359323603236132362323633236432365323663236732368323693237032371323723237332374323753237632377323783237932380323813238232383323843238532386323873238832389323903239132392323933239432395323963239732398323993240032401324023240332404324053240632407324083240932410324113241232413324143241532416324173241832419324203242132422324233242432425324263242732428324293243032431324323243332434324353243632437324383243932440324413244232443324443244532446324473244832449324503245132452324533245432455324563245732458324593246032461324623246332464324653246632467324683246932470324713247232473324743247532476324773247832479324803248132482324833248432485324863248732488324893249032491324923249332494324953249632497324983249932500325013250232503325043250532506325073250832509325103251132512325133251432515325163251732518325193252032521325223252332524325253252632527325283252932530325313253232533325343253532536325373253832539325403254132542325433254432545325463254732548325493255032551325523255332554325553255632557325583255932560325613256232563325643256532566325673256832569325703257132572325733257432575325763257732578325793258032581325823258332584325853258632587325883258932590325913259232593325943259532596325973259832599326003260132602326033260432605326063260732608326093261032611326123261332614326153261632617326183261932620326213262232623326243262532626326273262832629326303263132632326333263432635326363263732638326393264032641326423264332644326453264632647326483264932650326513265232653326543265532656326573265832659326603266132662326633266432665326663266732668326693267032671326723267332674326753267632677326783267932680326813268232683326843268532686326873268832689326903269132692326933269432695326963269732698326993270032701327023270332704327053270632707327083270932710327113271232713327143271532716327173271832719327203272132722327233272432725327263272732728327293273032731327323273332734327353273632737327383273932740327413274232743327443274532746327473274832749327503275132752327533275432755327563275732758327593276032761327623276332764327653276632767327683276932770327713277232773327743277532776327773277832779327803278132782327833278432785327863278732788327893279032791327923279332794327953279632797327983279932800328013280232803328043280532806328073280832809328103281132812328133281432815328163281732818328193282032821328223282332824328253282632827328283282932830328313283232833328343283532836328373283832839328403284132842328433284432845328463284732848328493285032851328523285332854328553285632857328583285932860328613286232863328643286532866328673286832869328703287132872328733287432875328763287732878328793288032881328823288332884328853288632887328883288932890328913289232893328943289532896328973289832899329003290132902329033290432905329063290732908329093291032911329123291332914329153291632917329183291932920329213292232923329243292532926329273292832929329303293132932329333293432935329363293732938329393294032941329423294332944329453294632947329483294932950329513295232953329543295532956329573295832959329603296132962329633296432965329663296732968329693297032971329723297332974329753297632977329783297932980329813298232983329843298532986329873298832989329903299132992329933299432995329963299732998329993300033001330023300333004330053300633007330083300933010330113301233013330143301533016330173301833019330203302133022330233302433025330263302733028330293303033031330323303333034330353303633037330383303933040330413304233043330443304533046330473304833049330503305133052330533305433055330563305733058330593306033061330623306333064330653306633067330683306933070330713307233073330743307533076330773307833079330803308133082330833308433085330863308733088330893309033091330923309333094330953309633097330983309933100331013310233103331043310533106331073310833109331103311133112331133311433115331163311733118331193312033121331223312333124331253312633127331283312933130331313313233133331343313533136331373313833139331403314133142331433314433145331463314733148331493315033151331523315333154331553315633157331583315933160331613316233163331643316533166331673316833169331703317133172331733317433175331763317733178331793318033181331823318333184331853318633187331883318933190331913319233193331943319533196331973319833199332003320133202332033320433205332063320733208332093321033211332123321333214332153321633217332183321933220332213322233223332243322533226332273322833229332303323133232332333323433235332363323733238332393324033241332423324333244332453324633247332483324933250332513325233253332543325533256332573325833259332603326133262332633326433265332663326733268332693327033271332723327333274332753327633277332783327933280332813328233283332843328533286332873328833289332903329133292332933329433295332963329733298332993330033301333023330333304333053330633307333083330933310333113331233313333143331533316333173331833319333203332133322333233332433325333263332733328333293333033331333323333333334333353333633337333383333933340333413334233343333443334533346333473334833349333503335133352333533335433355333563335733358333593336033361333623336333364333653336633367333683336933370333713337233373333743337533376333773337833379333803338133382333833338433385333863338733388333893339033391333923339333394333953339633397333983339933400334013340233403334043340533406334073340833409334103341133412334133341433415334163341733418334193342033421334223342333424334253342633427334283342933430334313343233433334343343533436334373343833439334403344133442334433344433445334463344733448334493345033451334523345333454334553345633457334583345933460334613346233463334643346533466334673346833469334703347133472334733347433475334763347733478334793348033481334823348333484334853348633487334883348933490334913349233493334943349533496334973349833499335003350133502335033350433505335063350733508335093351033511335123351333514335153351633517335183351933520335213352233523335243352533526335273352833529335303353133532335333353433535335363353733538335393354033541335423354333544335453354633547335483354933550335513355233553335543355533556335573355833559335603356133562335633356433565335663356733568335693357033571335723357333574335753357633577335783357933580335813358233583335843358533586335873358833589335903359133592335933359433595335963359733598335993360033601336023360333604336053360633607336083360933610336113361233613336143361533616336173361833619336203362133622336233362433625336263362733628336293363033631336323363333634336353363633637336383363933640336413364233643336443364533646336473364833649336503365133652336533365433655336563365733658336593366033661336623366333664336653366633667336683366933670336713367233673336743367533676336773367833679336803368133682336833368433685336863368733688336893369033691336923369333694336953369633697336983369933700337013370233703337043370533706337073370833709337103371133712337133371433715337163371733718337193372033721337223372333724337253372633727337283372933730337313373233733337343373533736337373373833739337403374133742337433374433745337463374733748337493375033751337523375333754337553375633757337583375933760337613376233763337643376533766337673376833769337703377133772337733377433775337763377733778337793378033781337823378333784337853378633787337883378933790337913379233793337943379533796337973379833799338003380133802338033380433805338063380733808338093381033811338123381333814338153381633817338183381933820338213382233823338243382533826338273382833829338303383133832338333383433835338363383733838338393384033841338423384333844338453384633847338483384933850338513385233853338543385533856338573385833859338603386133862338633386433865338663386733868338693387033871338723387333874338753387633877338783387933880338813388233883338843388533886338873388833889338903389133892338933389433895338963389733898338993390033901339023390333904339053390633907339083390933910339113391233913339143391533916339173391833919339203392133922339233392433925339263392733928339293393033931339323393333934339353393633937339383393933940339413394233943339443394533946339473394833949339503395133952339533395433955339563395733958339593396033961339623396333964339653396633967339683396933970339713397233973339743397533976339773397833979339803398133982339833398433985339863398733988339893399033991339923399333994339953399633997339983399934000340013400234003340043400534006340073400834009340103401134012340133401434015340163401734018340193402034021340223402334024340253402634027340283402934030340313403234033340343403534036340373403834039340403404134042340433404434045340463404734048340493405034051340523405334054340553405634057340583405934060340613406234063340643406534066340673406834069340703407134072340733407434075340763407734078340793408034081340823408334084340853408634087340883408934090340913409234093340943409534096340973409834099341003410134102341033410434105341063410734108341093411034111341123411334114341153411634117341183411934120341213412234123341243412534126341273412834129341303413134132341333413434135341363413734138341393414034141341423414334144341453414634147341483414934150341513415234153341543415534156341573415834159341603416134162341633416434165341663416734168341693417034171341723417334174341753417634177341783417934180341813418234183341843418534186341873418834189341903419134192341933419434195341963419734198341993420034201342023420334204342053420634207342083420934210342113421234213342143421534216342173421834219342203422134222342233422434225342263422734228342293423034231342323423334234342353423634237342383423934240342413424234243342443424534246342473424834249342503425134252342533425434255342563425734258342593426034261342623426334264342653426634267342683426934270342713427234273342743427534276342773427834279342803428134282342833428434285342863428734288342893429034291342923429334294342953429634297342983429934300343013430234303343043430534306343073430834309343103431134312343133431434315343163431734318343193432034321343223432334324343253432634327343283432934330343313433234333343343433534336343373433834339343403434134342343433434434345343463434734348343493435034351343523435334354343553435634357343583435934360343613436234363343643436534366343673436834369343703437134372343733437434375343763437734378343793438034381343823438334384343853438634387343883438934390343913439234393343943439534396343973439834399344003440134402344033440434405344063440734408344093441034411344123441334414344153441634417344183441934420344213442234423344243442534426344273442834429344303443134432344333443434435344363443734438344393444034441344423444334444344453444634447344483444934450344513445234453344543445534456344573445834459344603446134462344633446434465344663446734468344693447034471344723447334474344753447634477344783447934480344813448234483344843448534486344873448834489344903449134492344933449434495344963449734498344993450034501345023450334504345053450634507345083450934510345113451234513345143451534516345173451834519345203452134522345233452434525345263452734528345293453034531345323453334534345353453634537345383453934540345413454234543345443454534546345473454834549345503455134552345533455434555345563455734558345593456034561345623456334564345653456634567345683456934570345713457234573345743457534576345773457834579345803458134582345833458434585345863458734588345893459034591345923459334594345953459634597345983459934600346013460234603346043460534606346073460834609346103461134612346133461434615346163461734618346193462034621346223462334624346253462634627346283462934630346313463234633346343463534636346373463834639346403464134642346433464434645346463464734648346493465034651346523465334654346553465634657346583465934660346613466234663346643466534666346673466834669346703467134672346733467434675346763467734678346793468034681346823468334684346853468634687346883468934690346913469234693346943469534696346973469834699347003470134702347033470434705347063470734708347093471034711347123471334714347153471634717347183471934720347213472234723347243472534726347273472834729347303473134732347333473434735347363473734738347393474034741347423474334744347453474634747347483474934750347513475234753347543475534756347573475834759347603476134762347633476434765347663476734768347693477034771347723477334774347753477634777347783477934780347813478234783347843478534786347873478834789347903479134792347933479434795347963479734798347993480034801348023480334804348053480634807348083480934810348113481234813348143481534816348173481834819348203482134822348233482434825348263482734828348293483034831348323483334834348353483634837348383483934840348413484234843348443484534846348473484834849348503485134852348533485434855348563485734858348593486034861348623486334864348653486634867348683486934870348713487234873348743487534876348773487834879348803488134882348833488434885348863488734888348893489034891348923489334894348953489634897348983489934900349013490234903349043490534906349073490834909349103491134912349133491434915349163491734918349193492034921349223492334924349253492634927349283492934930349313493234933349343493534936349373493834939349403494134942349433494434945349463494734948349493495034951349523495334954349553495634957349583495934960349613496234963349643496534966349673496834969349703497134972349733497434975349763497734978349793498034981349823498334984349853498634987349883498934990349913499234993349943499534996349973499834999350003500135002350033500435005350063500735008350093501035011350123501335014350153501635017350183501935020350213502235023350243502535026350273502835029350303503135032350333503435035350363503735038350393504035041350423504335044350453504635047350483504935050350513505235053350543505535056350573505835059350603506135062350633506435065350663506735068350693507035071350723507335074350753507635077350783507935080350813508235083350843508535086350873508835089350903509135092350933509435095350963509735098350993510035101351023510335104351053510635107351083510935110351113511235113351143511535116351173511835119351203512135122351233512435125351263512735128351293513035131351323513335134351353513635137351383513935140351413514235143351443514535146351473514835149351503515135152351533515435155351563515735158351593516035161351623516335164351653516635167351683516935170351713517235173351743517535176351773517835179351803518135182351833518435185351863518735188351893519035191351923519335194351953519635197351983519935200352013520235203352043520535206352073520835209352103521135212352133521435215352163521735218352193522035221352223522335224352253522635227352283522935230352313523235233352343523535236352373523835239352403524135242352433524435245352463524735248352493525035251352523525335254352553525635257352583525935260352613526235263352643526535266352673526835269352703527135272352733527435275352763527735278352793528035281352823528335284352853528635287352883528935290352913529235293352943529535296352973529835299353003530135302353033530435305353063530735308353093531035311353123531335314353153531635317353183531935320353213532235323353243532535326353273532835329353303533135332353333533435335353363533735338353393534035341353423534335344353453534635347353483534935350353513535235353353543535535356353573535835359353603536135362353633536435365353663536735368353693537035371353723537335374353753537635377353783537935380353813538235383353843538535386353873538835389353903539135392353933539435395353963539735398353993540035401354023540335404354053540635407354083540935410354113541235413354143541535416354173541835419354203542135422354233542435425354263542735428354293543035431354323543335434354353543635437354383543935440354413544235443354443544535446354473544835449354503545135452354533545435455354563545735458354593546035461354623546335464354653546635467354683546935470354713547235473354743547535476354773547835479354803548135482354833548435485354863548735488354893549035491354923549335494354953549635497354983549935500355013550235503355043550535506355073550835509355103551135512355133551435515355163551735518355193552035521355223552335524355253552635527355283552935530355313553235533355343553535536355373553835539355403554135542355433554435545355463554735548355493555035551355523555335554355553555635557355583555935560355613556235563355643556535566355673556835569355703557135572355733557435575355763557735578355793558035581355823558335584355853558635587355883558935590355913559235593355943559535596355973559835599356003560135602356033560435605356063560735608356093561035611356123561335614356153561635617356183561935620356213562235623356243562535626356273562835629356303563135632356333563435635356363563735638356393564035641356423564335644356453564635647356483564935650356513565235653356543565535656356573565835659356603566135662356633566435665356663566735668356693567035671356723567335674356753567635677356783567935680356813568235683356843568535686356873568835689356903569135692356933569435695356963569735698356993570035701357023570335704357053570635707357083570935710357113571235713357143571535716357173571835719357203572135722357233572435725357263572735728357293573035731357323573335734357353573635737357383573935740357413574235743357443574535746357473574835749357503575135752357533575435755357563575735758357593576035761357623576335764357653576635767357683576935770357713577235773357743577535776357773577835779357803578135782357833578435785357863578735788357893579035791357923579335794357953579635797357983579935800358013580235803358043580535806358073580835809358103581135812358133581435815358163581735818358193582035821358223582335824358253582635827358283582935830358313583235833358343583535836358373583835839358403584135842358433584435845358463584735848358493585035851358523585335854358553585635857358583585935860358613586235863358643586535866358673586835869358703587135872358733587435875358763587735878358793588035881358823588335884358853588635887358883588935890358913589235893358943589535896358973589835899359003590135902359033590435905359063590735908359093591035911359123591335914359153591635917359183591935920359213592235923359243592535926359273592835929359303593135932359333593435935359363593735938359393594035941359423594335944359453594635947359483594935950359513595235953359543595535956359573595835959359603596135962359633596435965359663596735968359693597035971359723597335974359753597635977359783597935980359813598235983359843598535986359873598835989359903599135992359933599435995359963599735998359993600036001360023600336004360053600636007360083600936010360113601236013360143601536016360173601836019360203602136022360233602436025360263602736028360293603036031360323603336034360353603636037360383603936040360413604236043360443604536046360473604836049360503605136052360533605436055360563605736058360593606036061360623606336064360653606636067360683606936070360713607236073360743607536076360773607836079360803608136082360833608436085360863608736088360893609036091360923609336094360953609636097360983609936100361013610236103361043610536106361073610836109361103611136112361133611436115361163611736118361193612036121361223612336124361253612636127361283612936130361313613236133361343613536136361373613836139361403614136142361433614436145361463614736148361493615036151361523615336154361553615636157361583615936160361613616236163361643616536166361673616836169361703617136172361733617436175361763617736178361793618036181361823618336184361853618636187361883618936190361913619236193361943619536196361973619836199362003620136202362033620436205362063620736208362093621036211362123621336214362153621636217362183621936220362213622236223362243622536226362273622836229362303623136232362333623436235362363623736238362393624036241362423624336244362453624636247362483624936250362513625236253362543625536256362573625836259362603626136262362633626436265362663626736268362693627036271362723627336274362753627636277362783627936280362813628236283362843628536286362873628836289362903629136292362933629436295362963629736298362993630036301363023630336304363053630636307363083630936310363113631236313363143631536316363173631836319363203632136322363233632436325363263632736328363293633036331363323633336334363353633636337363383633936340363413634236343363443634536346363473634836349363503635136352363533635436355363563635736358363593636036361363623636336364363653636636367363683636936370363713637236373363743637536376363773637836379363803638136382363833638436385363863638736388363893639036391363923639336394363953639636397363983639936400364013640236403364043640536406364073640836409364103641136412364133641436415364163641736418364193642036421364223642336424364253642636427364283642936430364313643236433364343643536436364373643836439364403644136442364433644436445364463644736448364493645036451364523645336454364553645636457364583645936460364613646236463364643646536466364673646836469364703647136472364733647436475364763647736478364793648036481364823648336484364853648636487364883648936490364913649236493364943649536496364973649836499365003650136502365033650436505365063650736508365093651036511365123651336514365153651636517365183651936520365213652236523365243652536526365273652836529365303653136532365333653436535365363653736538365393654036541365423654336544365453654636547365483654936550365513655236553365543655536556365573655836559365603656136562365633656436565365663656736568365693657036571365723657336574365753657636577365783657936580365813658236583365843658536586365873658836589365903659136592365933659436595365963659736598365993660036601366023660336604366053660636607366083660936610366113661236613366143661536616366173661836619366203662136622366233662436625366263662736628366293663036631366323663336634366353663636637366383663936640366413664236643366443664536646366473664836649366503665136652366533665436655366563665736658366593666036661366623666336664366653666636667366683666936670366713667236673366743667536676366773667836679366803668136682366833668436685366863668736688366893669036691366923669336694366953669636697366983669936700367013670236703367043670536706367073670836709367103671136712367133671436715367163671736718367193672036721367223672336724367253672636727367283672936730367313673236733367343673536736367373673836739367403674136742367433674436745367463674736748367493675036751367523675336754367553675636757367583675936760367613676236763367643676536766367673676836769367703677136772367733677436775367763677736778367793678036781367823678336784367853678636787367883678936790367913679236793367943679536796367973679836799368003680136802368033680436805368063680736808368093681036811368123681336814368153681636817368183681936820368213682236823368243682536826368273682836829368303683136832368333683436835368363683736838368393684036841368423684336844368453684636847368483684936850368513685236853368543685536856368573685836859368603686136862368633686436865368663686736868368693687036871368723687336874368753687636877368783687936880368813688236883368843688536886368873688836889368903689136892368933689436895368963689736898368993690036901369023690336904369053690636907369083690936910369113691236913369143691536916369173691836919369203692136922369233692436925369263692736928369293693036931369323693336934369353693636937369383693936940369413694236943369443694536946369473694836949369503695136952369533695436955369563695736958369593696036961369623696336964369653696636967369683696936970369713697236973369743697536976369773697836979369803698136982369833698436985369863698736988369893699036991369923699336994369953699636997369983699937000370013700237003370043700537006370073700837009370103701137012370133701437015370163701737018370193702037021370223702337024370253702637027370283702937030370313703237033370343703537036370373703837039370403704137042370433704437045370463704737048370493705037051370523705337054370553705637057370583705937060370613706237063370643706537066370673706837069370703707137072370733707437075370763707737078370793708037081370823708337084370853708637087370883708937090370913709237093370943709537096370973709837099371003710137102371033710437105371063710737108371093711037111371123711337114371153711637117371183711937120371213712237123371243712537126371273712837129371303713137132371333713437135371363713737138371393714037141371423714337144371453714637147371483714937150371513715237153371543715537156371573715837159371603716137162371633716437165371663716737168371693717037171371723717337174371753717637177371783717937180371813718237183371843718537186371873718837189371903719137192371933719437195371963719737198371993720037201372023720337204372053720637207372083720937210372113721237213372143721537216372173721837219372203722137222372233722437225372263722737228372293723037231372323723337234372353723637237372383723937240372413724237243372443724537246372473724837249372503725137252372533725437255372563725737258372593726037261372623726337264372653726637267372683726937270372713727237273372743727537276372773727837279372803728137282372833728437285372863728737288372893729037291372923729337294372953729637297372983729937300373013730237303373043730537306373073730837309373103731137312373133731437315373163731737318373193732037321373223732337324373253732637327373283732937330373313733237333373343733537336373373733837339373403734137342373433734437345373463734737348373493735037351373523735337354373553735637357373583735937360373613736237363373643736537366373673736837369373703737137372373733737437375373763737737378373793738037381373823738337384373853738637387373883738937390373913739237393373943739537396373973739837399374003740137402374033740437405374063740737408374093741037411374123741337414374153741637417374183741937420374213742237423374243742537426374273742837429374303743137432374333743437435374363743737438374393744037441374423744337444374453744637447374483744937450374513745237453374543745537456374573745837459374603746137462374633746437465374663746737468374693747037471374723747337474374753747637477374783747937480374813748237483374843748537486374873748837489374903749137492374933749437495374963749737498374993750037501375023750337504375053750637507375083750937510375113751237513375143751537516375173751837519375203752137522375233752437525375263752737528375293753037531375323753337534375353753637537375383753937540375413754237543375443754537546375473754837549375503755137552375533755437555375563755737558375593756037561375623756337564375653756637567375683756937570375713757237573375743757537576375773757837579375803758137582375833758437585375863758737588375893759037591375923759337594375953759637597375983759937600376013760237603376043760537606376073760837609376103761137612376133761437615376163761737618376193762037621376223762337624376253762637627376283762937630376313763237633376343763537636376373763837639376403764137642376433764437645376463764737648376493765037651376523765337654376553765637657376583765937660376613766237663376643766537666376673766837669376703767137672376733767437675376763767737678376793768037681376823768337684376853768637687376883768937690376913769237693376943769537696376973769837699377003770137702377033770437705377063770737708377093771037711377123771337714377153771637717377183771937720377213772237723377243772537726377273772837729377303773137732377333773437735377363773737738377393774037741377423774337744377453774637747377483774937750377513775237753377543775537756377573775837759377603776137762377633776437765377663776737768377693777037771377723777337774377753777637777377783777937780377813778237783377843778537786377873778837789377903779137792377933779437795377963779737798377993780037801378023780337804378053780637807378083780937810378113781237813378143781537816378173781837819378203782137822378233782437825378263782737828378293783037831378323783337834378353783637837378383783937840378413784237843378443784537846378473784837849378503785137852378533785437855378563785737858378593786037861378623786337864378653786637867378683786937870378713787237873378743787537876378773787837879378803788137882378833788437885378863788737888378893789037891378923789337894378953789637897378983789937900379013790237903379043790537906379073790837909379103791137912379133791437915379163791737918379193792037921379223792337924379253792637927379283792937930379313793237933379343793537936379373793837939379403794137942379433794437945379463794737948379493795037951379523795337954379553795637957379583795937960379613796237963379643796537966379673796837969379703797137972379733797437975379763797737978379793798037981379823798337984379853798637987379883798937990379913799237993379943799537996379973799837999380003800138002380033800438005380063800738008380093801038011380123801338014380153801638017380183801938020380213802238023380243802538026380273802838029380303803138032380333803438035380363803738038380393804038041380423804338044380453804638047380483804938050380513805238053380543805538056380573805838059380603806138062380633806438065380663806738068380693807038071380723807338074380753807638077380783807938080380813808238083380843808538086380873808838089380903809138092380933809438095380963809738098380993810038101381023810338104381053810638107381083810938110381113811238113381143811538116381173811838119381203812138122381233812438125381263812738128381293813038131381323813338134381353813638137381383813938140381413814238143381443814538146381473814838149381503815138152381533815438155381563815738158381593816038161381623816338164381653816638167381683816938170381713817238173381743817538176381773817838179381803818138182381833818438185381863818738188381893819038191381923819338194381953819638197381983819938200382013820238203382043820538206382073820838209382103821138212382133821438215382163821738218382193822038221382223822338224382253822638227382283822938230382313823238233382343823538236382373823838239382403824138242382433824438245382463824738248382493825038251382523825338254382553825638257382583825938260382613826238263382643826538266382673826838269382703827138272382733827438275382763827738278382793828038281382823828338284382853828638287382883828938290382913829238293382943829538296382973829838299383003830138302383033830438305383063830738308383093831038311383123831338314383153831638317383183831938320383213832238323383243832538326383273832838329383303833138332383333833438335383363833738338383393834038341383423834338344383453834638347383483834938350383513835238353383543835538356383573835838359383603836138362383633836438365383663836738368383693837038371383723837338374383753837638377383783837938380383813838238383383843838538386383873838838389383903839138392383933839438395383963839738398383993840038401384023840338404384053840638407384083840938410384113841238413384143841538416384173841838419384203842138422384233842438425384263842738428384293843038431384323843338434384353843638437384383843938440384413844238443384443844538446384473844838449384503845138452384533845438455384563845738458384593846038461384623846338464384653846638467384683846938470384713847238473384743847538476384773847838479384803848138482384833848438485384863848738488384893849038491384923849338494384953849638497384983849938500385013850238503385043850538506385073850838509385103851138512385133851438515385163851738518385193852038521385223852338524385253852638527385283852938530385313853238533385343853538536385373853838539385403854138542385433854438545385463854738548385493855038551385523855338554385553855638557385583855938560385613856238563385643856538566385673856838569385703857138572385733857438575385763857738578385793858038581385823858338584385853858638587385883858938590385913859238593385943859538596385973859838599386003860138602386033860438605386063860738608386093861038611386123861338614386153861638617386183861938620386213862238623386243862538626386273862838629386303863138632386333863438635386363863738638386393864038641386423864338644386453864638647386483864938650386513865238653386543865538656386573865838659386603866138662386633866438665386663866738668386693867038671386723867338674386753867638677386783867938680386813868238683386843868538686386873868838689386903869138692386933869438695386963869738698386993870038701387023870338704387053870638707387083870938710387113871238713387143871538716387173871838719387203872138722387233872438725387263872738728387293873038731387323873338734387353873638737387383873938740387413874238743387443874538746387473874838749387503875138752387533875438755387563875738758387593876038761387623876338764387653876638767387683876938770387713877238773387743877538776387773877838779387803878138782387833878438785387863878738788387893879038791387923879338794387953879638797387983879938800388013880238803388043880538806388073880838809388103881138812388133881438815388163881738818388193882038821388223882338824388253882638827388283882938830388313883238833388343883538836388373883838839388403884138842388433884438845388463884738848388493885038851388523885338854388553885638857388583885938860388613886238863388643886538866388673886838869388703887138872388733887438875388763887738878388793888038881388823888338884388853888638887388883888938890388913889238893388943889538896388973889838899389003890138902389033890438905389063890738908389093891038911389123891338914389153891638917389183891938920389213892238923389243892538926389273892838929389303893138932389333893438935389363893738938389393894038941389423894338944389453894638947389483894938950389513895238953389543895538956389573895838959389603896138962389633896438965389663896738968389693897038971389723897338974389753897638977389783897938980389813898238983389843898538986389873898838989389903899138992389933899438995389963899738998389993900039001390023900339004390053900639007390083900939010390113901239013390143901539016390173901839019390203902139022390233902439025390263902739028390293903039031390323903339034390353903639037390383903939040390413904239043390443904539046390473904839049390503905139052390533905439055390563905739058390593906039061390623906339064390653906639067390683906939070390713907239073390743907539076390773907839079390803908139082390833908439085390863908739088390893909039091390923909339094390953909639097390983909939100391013910239103391043910539106391073910839109391103911139112391133911439115391163911739118391193912039121391223912339124391253912639127391283912939130391313913239133391343913539136391373913839139391403914139142391433914439145391463914739148391493915039151391523915339154391553915639157391583915939160391613916239163391643916539166391673916839169391703917139172391733917439175391763917739178391793918039181391823918339184391853918639187391883918939190391913919239193391943919539196391973919839199392003920139202392033920439205392063920739208392093921039211392123921339214392153921639217392183921939220392213922239223392243922539226392273922839229392303923139232392333923439235392363923739238392393924039241392423924339244392453924639247392483924939250392513925239253392543925539256392573925839259392603926139262392633926439265392663926739268392693927039271392723927339274392753927639277392783927939280392813928239283392843928539286392873928839289392903929139292392933929439295392963929739298392993930039301393023930339304393053930639307393083930939310393113931239313393143931539316393173931839319393203932139322393233932439325393263932739328393293933039331393323933339334393353933639337393383933939340393413934239343393443934539346393473934839349393503935139352393533935439355393563935739358393593936039361393623936339364393653936639367393683936939370393713937239373393743937539376393773937839379393803938139382393833938439385393863938739388393893939039391393923939339394393953939639397393983939939400394013940239403394043940539406394073940839409394103941139412394133941439415394163941739418394193942039421394223942339424394253942639427394283942939430394313943239433394343943539436394373943839439394403944139442394433944439445394463944739448394493945039451394523945339454394553945639457394583945939460394613946239463394643946539466394673946839469394703947139472394733947439475394763947739478394793948039481394823948339484394853948639487394883948939490394913949239493394943949539496394973949839499395003950139502395033950439505395063950739508395093951039511395123951339514395153951639517395183951939520395213952239523395243952539526395273952839529395303953139532395333953439535395363953739538395393954039541395423954339544395453954639547395483954939550395513955239553395543955539556395573955839559395603956139562395633956439565395663956739568395693957039571395723957339574395753957639577395783957939580395813958239583395843958539586395873958839589395903959139592395933959439595395963959739598395993960039601396023960339604396053960639607396083960939610396113961239613396143961539616396173961839619396203962139622396233962439625396263962739628396293963039631396323963339634396353963639637396383963939640396413964239643396443964539646396473964839649396503965139652396533965439655396563965739658396593966039661396623966339664396653966639667396683966939670396713967239673396743967539676396773967839679396803968139682396833968439685396863968739688396893969039691396923969339694396953969639697396983969939700397013970239703397043970539706397073970839709397103971139712397133971439715397163971739718397193972039721397223972339724397253972639727397283972939730397313973239733397343973539736397373973839739397403974139742397433974439745397463974739748397493975039751397523975339754397553975639757397583975939760397613976239763397643976539766397673976839769397703977139772397733977439775397763977739778397793978039781397823978339784397853978639787397883978939790397913979239793397943979539796397973979839799398003980139802398033980439805398063980739808398093981039811398123981339814398153981639817398183981939820398213982239823398243982539826398273982839829398303983139832398333983439835398363983739838398393984039841398423984339844398453984639847398483984939850398513985239853398543985539856398573985839859398603986139862398633986439865398663986739868398693987039871398723987339874398753987639877398783987939880398813988239883398843988539886398873988839889398903989139892398933989439895398963989739898398993990039901399023990339904399053990639907399083990939910399113991239913399143991539916399173991839919399203992139922399233992439925399263992739928399293993039931399323993339934399353993639937399383993939940399413994239943399443994539946399473994839949399503995139952399533995439955399563995739958399593996039961399623996339964399653996639967399683996939970399713997239973399743997539976399773997839979399803998139982399833998439985399863998739988399893999039991399923999339994399953999639997399983999940000400014000240003400044000540006400074000840009400104001140012400134001440015400164001740018400194002040021400224002340024400254002640027400284002940030400314003240033400344003540036400374003840039400404004140042400434004440045400464004740048400494005040051400524005340054400554005640057400584005940060400614006240063400644006540066400674006840069400704007140072400734007440075400764007740078400794008040081400824008340084400854008640087400884008940090400914009240093400944009540096400974009840099401004010140102401034010440105401064010740108401094011040111401124011340114401154011640117401184011940120401214012240123401244012540126401274012840129401304013140132401334013440135401364013740138401394014040141401424014340144401454014640147401484014940150401514015240153401544015540156401574015840159401604016140162401634016440165401664016740168401694017040171401724017340174401754017640177401784017940180401814018240183401844018540186401874018840189401904019140192401934019440195401964019740198401994020040201402024020340204402054020640207402084020940210402114021240213402144021540216402174021840219402204022140222402234022440225402264022740228402294023040231402324023340234402354023640237402384023940240402414024240243402444024540246402474024840249402504025140252402534025440255402564025740258402594026040261402624026340264402654026640267402684026940270402714027240273402744027540276402774027840279402804028140282402834028440285402864028740288402894029040291402924029340294402954029640297402984029940300403014030240303403044030540306403074030840309403104031140312403134031440315403164031740318403194032040321403224032340324403254032640327403284032940330403314033240333403344033540336403374033840339403404034140342403434034440345403464034740348403494035040351403524035340354403554035640357403584035940360403614036240363403644036540366403674036840369403704037140372403734037440375403764037740378403794038040381403824038340384403854038640387403884038940390403914039240393403944039540396403974039840399404004040140402404034040440405404064040740408404094041040411404124041340414404154041640417404184041940420404214042240423404244042540426404274042840429404304043140432404334043440435404364043740438404394044040441404424044340444404454044640447404484044940450404514045240453404544045540456404574045840459404604046140462404634046440465404664046740468404694047040471404724047340474404754047640477404784047940480404814048240483404844048540486404874048840489404904049140492404934049440495404964049740498404994050040501405024050340504405054050640507405084050940510405114051240513405144051540516405174051840519405204052140522405234052440525405264052740528405294053040531405324053340534405354053640537405384053940540405414054240543405444054540546405474054840549405504055140552405534055440555405564055740558405594056040561405624056340564405654056640567405684056940570405714057240573405744057540576405774057840579405804058140582405834058440585405864058740588405894059040591405924059340594405954059640597405984059940600406014060240603406044060540606406074060840609406104061140612406134061440615406164061740618406194062040621406224062340624406254062640627406284062940630406314063240633406344063540636406374063840639406404064140642406434064440645406464064740648406494065040651406524065340654406554065640657406584065940660406614066240663406644066540666406674066840669406704067140672406734067440675406764067740678406794068040681406824068340684406854068640687406884068940690406914069240693406944069540696406974069840699407004070140702407034070440705407064070740708407094071040711407124071340714407154071640717407184071940720407214072240723407244072540726407274072840729407304073140732407334073440735407364073740738407394074040741407424074340744407454074640747407484074940750407514075240753407544075540756407574075840759407604076140762407634076440765407664076740768407694077040771407724077340774407754077640777407784077940780407814078240783407844078540786407874078840789407904079140792407934079440795407964079740798407994080040801408024080340804408054080640807408084080940810408114081240813408144081540816408174081840819408204082140822408234082440825408264082740828408294083040831408324083340834408354083640837408384083940840408414084240843408444084540846408474084840849408504085140852408534085440855408564085740858408594086040861408624086340864408654086640867408684086940870408714087240873408744087540876408774087840879408804088140882408834088440885408864088740888408894089040891408924089340894408954089640897408984089940900409014090240903409044090540906409074090840909409104091140912409134091440915409164091740918409194092040921409224092340924409254092640927409284092940930409314093240933409344093540936409374093840939409404094140942409434094440945409464094740948409494095040951409524095340954409554095640957409584095940960409614096240963409644096540966409674096840969409704097140972409734097440975409764097740978409794098040981409824098340984409854098640987409884098940990409914099240993409944099540996409974099840999410004100141002410034100441005410064100741008410094101041011410124101341014410154101641017410184101941020410214102241023410244102541026410274102841029410304103141032410334103441035410364103741038410394104041041410424104341044410454104641047410484104941050410514105241053410544105541056410574105841059410604106141062410634106441065410664106741068410694107041071410724107341074410754107641077410784107941080410814108241083410844108541086410874108841089410904109141092410934109441095410964109741098410994110041101411024110341104411054110641107411084110941110411114111241113411144111541116411174111841119411204112141122411234112441125411264112741128411294113041131411324113341134411354113641137411384113941140411414114241143411444114541146411474114841149411504115141152411534115441155411564115741158411594116041161411624116341164411654116641167411684116941170411714117241173411744117541176411774117841179411804118141182411834118441185411864118741188411894119041191411924119341194411954119641197411984119941200412014120241203412044120541206412074120841209412104121141212412134121441215412164121741218412194122041221412224122341224412254122641227412284122941230412314123241233412344123541236412374123841239412404124141242412434124441245412464124741248412494125041251412524125341254412554125641257412584125941260412614126241263412644126541266412674126841269412704127141272412734127441275412764127741278412794128041281412824128341284412854128641287412884128941290412914129241293412944129541296412974129841299413004130141302413034130441305413064130741308413094131041311413124131341314413154131641317413184131941320413214132241323413244132541326413274132841329413304133141332413334133441335413364133741338413394134041341413424134341344413454134641347413484134941350413514135241353413544135541356413574135841359413604136141362413634136441365413664136741368413694137041371413724137341374413754137641377413784137941380413814138241383413844138541386413874138841389413904139141392413934139441395413964139741398413994140041401414024140341404414054140641407414084140941410414114141241413414144141541416414174141841419414204142141422414234142441425414264142741428414294143041431414324143341434414354143641437414384143941440414414144241443414444144541446414474144841449414504145141452414534145441455414564145741458414594146041461414624146341464414654146641467414684146941470414714147241473414744147541476414774147841479414804148141482414834148441485414864148741488414894149041491414924149341494414954149641497414984149941500415014150241503415044150541506415074150841509415104151141512415134151441515415164151741518415194152041521415224152341524415254152641527415284152941530415314153241533415344153541536415374153841539415404154141542415434154441545415464154741548415494155041551415524155341554415554155641557415584155941560415614156241563415644156541566415674156841569415704157141572415734157441575415764157741578415794158041581415824158341584415854158641587415884158941590415914159241593415944159541596415974159841599416004160141602416034160441605416064160741608416094161041611416124161341614416154161641617416184161941620416214162241623416244162541626416274162841629416304163141632416334163441635416364163741638416394164041641416424164341644416454164641647416484164941650416514165241653416544165541656416574165841659416604166141662416634166441665416664166741668416694167041671416724167341674416754167641677416784167941680416814168241683416844168541686416874168841689416904169141692416934169441695416964169741698416994170041701417024170341704417054170641707417084170941710417114171241713417144171541716417174171841719417204172141722417234172441725417264172741728417294173041731417324173341734417354173641737417384173941740417414174241743417444174541746417474174841749417504175141752417534175441755417564175741758417594176041761417624176341764417654176641767417684176941770417714177241773417744177541776417774177841779417804178141782417834178441785417864178741788417894179041791417924179341794417954179641797417984179941800418014180241803418044180541806418074180841809418104181141812418134181441815418164181741818418194182041821418224182341824418254182641827418284182941830418314183241833418344183541836418374183841839418404184141842418434184441845418464184741848418494185041851418524185341854418554185641857418584185941860418614186241863418644186541866418674186841869418704187141872418734187441875418764187741878418794188041881418824188341884418854188641887418884188941890418914189241893418944189541896418974189841899419004190141902419034190441905419064190741908419094191041911419124191341914419154191641917419184191941920419214192241923419244192541926419274192841929419304193141932419334193441935419364193741938419394194041941419424194341944419454194641947419484194941950419514195241953419544195541956419574195841959419604196141962419634196441965419664196741968419694197041971419724197341974419754197641977419784197941980419814198241983419844198541986419874198841989419904199141992419934199441995419964199741998419994200042001420024200342004420054200642007420084200942010420114201242013420144201542016420174201842019420204202142022420234202442025420264202742028420294203042031420324203342034420354203642037420384203942040420414204242043420444204542046420474204842049420504205142052420534205442055420564205742058420594206042061420624206342064420654206642067420684206942070420714207242073420744207542076420774207842079420804208142082420834208442085420864208742088420894209042091420924209342094420954209642097420984209942100421014210242103421044210542106421074210842109421104211142112421134211442115421164211742118421194212042121421224212342124421254212642127421284212942130421314213242133421344213542136421374213842139421404214142142421434214442145421464214742148421494215042151421524215342154421554215642157421584215942160421614216242163421644216542166421674216842169421704217142172421734217442175421764217742178421794218042181421824218342184421854218642187421884218942190421914219242193421944219542196421974219842199422004220142202422034220442205422064220742208422094221042211422124221342214422154221642217422184221942220422214222242223422244222542226422274222842229422304223142232422334223442235422364223742238422394224042241422424224342244422454224642247422484224942250422514225242253422544225542256422574225842259422604226142262422634226442265422664226742268422694227042271422724227342274422754227642277422784227942280422814228242283422844228542286422874228842289422904229142292422934229442295422964229742298422994230042301423024230342304423054230642307423084230942310423114231242313423144231542316423174231842319423204232142322423234232442325423264232742328423294233042331423324233342334423354233642337423384233942340423414234242343423444234542346423474234842349423504235142352423534235442355423564235742358423594236042361423624236342364423654236642367423684236942370423714237242373423744237542376423774237842379423804238142382423834238442385423864238742388423894239042391423924239342394423954239642397423984239942400424014240242403424044240542406424074240842409424104241142412424134241442415424164241742418424194242042421424224242342424424254242642427424284242942430424314243242433424344243542436424374243842439424404244142442424434244442445424464244742448424494245042451424524245342454424554245642457424584245942460424614246242463424644246542466424674246842469424704247142472424734247442475424764247742478424794248042481424824248342484424854248642487424884248942490424914249242493424944249542496424974249842499425004250142502425034250442505425064250742508425094251042511425124251342514425154251642517425184251942520425214252242523425244252542526425274252842529425304253142532425334253442535425364253742538425394254042541425424254342544425454254642547425484254942550425514255242553425544255542556425574255842559425604256142562425634256442565425664256742568425694257042571425724257342574425754257642577425784257942580425814258242583425844258542586425874258842589425904259142592425934259442595425964259742598425994260042601426024260342604426054260642607426084260942610426114261242613426144261542616426174261842619426204262142622426234262442625426264262742628426294263042631426324263342634426354263642637426384263942640426414264242643426444264542646426474264842649426504265142652426534265442655426564265742658426594266042661426624266342664426654266642667426684266942670426714267242673426744267542676426774267842679426804268142682426834268442685426864268742688426894269042691426924269342694426954269642697426984269942700427014270242703427044270542706427074270842709427104271142712427134271442715427164271742718427194272042721427224272342724427254272642727427284272942730427314273242733427344273542736427374273842739427404274142742427434274442745427464274742748427494275042751427524275342754427554275642757427584275942760427614276242763427644276542766427674276842769427704277142772427734277442775427764277742778427794278042781427824278342784427854278642787427884278942790427914279242793427944279542796427974279842799428004280142802428034280442805428064280742808428094281042811428124281342814428154281642817428184281942820428214282242823428244282542826428274282842829428304283142832428334283442835428364283742838428394284042841428424284342844428454284642847428484284942850428514285242853428544285542856428574285842859428604286142862428634286442865428664286742868428694287042871428724287342874428754287642877428784287942880428814288242883428844288542886428874288842889428904289142892428934289442895428964289742898428994290042901429024290342904429054290642907429084290942910429114291242913429144291542916429174291842919429204292142922429234292442925429264292742928429294293042931429324293342934429354293642937429384293942940429414294242943429444294542946429474294842949429504295142952429534295442955429564295742958429594296042961429624296342964429654296642967429684296942970429714297242973429744297542976429774297842979429804298142982429834298442985429864298742988429894299042991429924299342994429954299642997429984299943000430014300243003430044300543006430074300843009430104301143012430134301443015430164301743018430194302043021430224302343024430254302643027430284302943030430314303243033430344303543036430374303843039430404304143042430434304443045430464304743048430494305043051430524305343054430554305643057430584305943060430614306243063430644306543066430674306843069430704307143072430734307443075430764307743078430794308043081430824308343084430854308643087430884308943090430914309243093430944309543096430974309843099431004310143102431034310443105431064310743108431094311043111431124311343114431154311643117431184311943120431214312243123431244312543126431274312843129431304313143132431334313443135431364313743138431394314043141431424314343144431454314643147431484314943150431514315243153431544315543156431574315843159431604316143162431634316443165431664316743168431694317043171431724317343174431754317643177431784317943180431814318243183431844318543186431874318843189431904319143192431934319443195431964319743198431994320043201432024320343204432054320643207432084320943210432114321243213432144321543216432174321843219432204322143222432234322443225432264322743228432294323043231432324323343234432354323643237432384323943240432414324243243432444324543246432474324843249432504325143252432534325443255432564325743258432594326043261432624326343264432654326643267432684326943270432714327243273432744327543276432774327843279432804328143282432834328443285432864328743288432894329043291432924329343294432954329643297432984329943300433014330243303433044330543306433074330843309433104331143312433134331443315433164331743318433194332043321433224332343324433254332643327433284332943330433314333243333433344333543336433374333843339433404334143342433434334443345433464334743348433494335043351433524335343354433554335643357433584335943360433614336243363433644336543366433674336843369433704337143372433734337443375433764337743378433794338043381433824338343384433854338643387433884338943390433914339243393433944339543396433974339843399434004340143402434034340443405434064340743408434094341043411434124341343414434154341643417434184341943420434214342243423434244342543426434274342843429434304343143432434334343443435434364343743438434394344043441434424344343444434454344643447434484344943450434514345243453434544345543456434574345843459434604346143462434634346443465434664346743468434694347043471434724347343474434754347643477434784347943480434814348243483434844348543486434874348843489434904349143492434934349443495434964349743498434994350043501435024350343504435054350643507435084350943510435114351243513435144351543516435174351843519435204352143522435234352443525435264352743528435294353043531435324353343534435354353643537435384353943540435414354243543435444354543546435474354843549435504355143552435534355443555435564355743558435594356043561435624356343564435654356643567435684356943570435714357243573435744357543576435774357843579435804358143582435834358443585435864358743588435894359043591435924359343594435954359643597435984359943600436014360243603436044360543606436074360843609436104361143612436134361443615436164361743618436194362043621436224362343624436254362643627436284362943630436314363243633436344363543636436374363843639436404364143642436434364443645436464364743648436494365043651436524365343654436554365643657436584365943660436614366243663436644366543666436674366843669436704367143672436734367443675436764367743678436794368043681436824368343684436854368643687436884368943690436914369243693436944369543696436974369843699437004370143702437034370443705437064370743708437094371043711437124371343714437154371643717437184371943720437214372243723437244372543726437274372843729437304373143732437334373443735437364373743738437394374043741437424374343744437454374643747437484374943750437514375243753437544375543756437574375843759437604376143762437634376443765437664376743768437694377043771437724377343774437754377643777437784377943780437814378243783437844378543786437874378843789437904379143792437934379443795437964379743798437994380043801438024380343804438054380643807438084380943810438114381243813438144381543816438174381843819438204382143822438234382443825438264382743828438294383043831438324383343834438354383643837438384383943840438414384243843438444384543846438474384843849438504385143852438534385443855438564385743858438594386043861438624386343864438654386643867438684386943870438714387243873438744387543876438774387843879438804388143882438834388443885438864388743888438894389043891438924389343894438954389643897438984389943900439014390243903439044390543906439074390843909439104391143912439134391443915439164391743918439194392043921439224392343924439254392643927439284392943930439314393243933439344393543936439374393843939439404394143942439434394443945439464394743948439494395043951439524395343954439554395643957439584395943960439614396243963439644396543966439674396843969439704397143972439734397443975439764397743978439794398043981439824398343984439854398643987439884398943990439914399243993439944399543996439974399843999440004400144002440034400444005440064400744008440094401044011440124401344014440154401644017440184401944020440214402244023440244402544026440274402844029440304403144032440334403444035440364403744038440394404044041440424404344044440454404644047440484404944050440514405244053440544405544056440574405844059440604406144062440634406444065440664406744068440694407044071440724407344074440754407644077440784407944080440814408244083440844408544086440874408844089440904409144092440934409444095440964409744098440994410044101441024410344104441054410644107441084410944110441114411244113441144411544116441174411844119441204412144122441234412444125441264412744128441294413044131441324413344134441354413644137441384413944140441414414244143441444414544146441474414844149441504415144152441534415444155441564415744158441594416044161441624416344164441654416644167441684416944170441714417244173441744417544176441774417844179441804418144182441834418444185441864418744188441894419044191441924419344194441954419644197441984419944200442014420244203442044420544206442074420844209442104421144212442134421444215442164421744218442194422044221442224422344224442254422644227442284422944230442314423244233442344423544236442374423844239442404424144242442434424444245442464424744248442494425044251442524425344254442554425644257442584425944260442614426244263442644426544266442674426844269442704427144272442734427444275442764427744278442794428044281442824428344284442854428644287442884428944290442914429244293442944429544296442974429844299443004430144302443034430444305443064430744308443094431044311443124431344314443154431644317443184431944320443214432244323443244432544326443274432844329443304433144332443334433444335443364433744338443394434044341443424434344344443454434644347443484434944350443514435244353443544435544356443574435844359443604436144362443634436444365443664436744368443694437044371443724437344374443754437644377443784437944380443814438244383443844438544386443874438844389443904439144392443934439444395443964439744398443994440044401444024440344404444054440644407444084440944410444114441244413444144441544416444174441844419444204442144422444234442444425444264442744428444294443044431444324443344434444354443644437444384443944440444414444244443444444444544446444474444844449444504445144452444534445444455444564445744458444594446044461444624446344464444654446644467444684446944470444714447244473444744447544476444774447844479444804448144482444834448444485444864448744488444894449044491444924449344494444954449644497444984449944500445014450244503445044450544506445074450844509445104451144512445134451444515445164451744518445194452044521445224452344524445254452644527445284452944530445314453244533445344453544536445374453844539445404454144542445434454444545445464454744548445494455044551445524455344554445554455644557445584455944560445614456244563445644456544566445674456844569445704457144572445734457444575445764457744578445794458044581445824458344584445854458644587445884458944590445914459244593445944459544596445974459844599446004460144602446034460444605446064460744608446094461044611446124461344614446154461644617446184461944620446214462244623446244462544626446274462844629446304463144632446334463444635446364463744638446394464044641446424464344644446454464644647446484464944650446514465244653446544465544656446574465844659446604466144662446634466444665446664466744668446694467044671446724467344674446754467644677446784467944680446814468244683446844468544686446874468844689446904469144692446934469444695446964469744698446994470044701447024470344704447054470644707447084470944710447114471244713447144471544716447174471844719447204472144722447234472444725447264472744728447294473044731447324473344734447354473644737447384473944740447414474244743447444474544746447474474844749447504475144752447534475444755447564475744758447594476044761447624476344764447654476644767447684476944770447714477244773447744477544776447774477844779447804478144782447834478444785447864478744788447894479044791447924479344794447954479644797447984479944800448014480244803448044480544806448074480844809448104481144812448134481444815448164481744818448194482044821448224482344824448254482644827448284482944830448314483244833448344483544836448374483844839448404484144842448434484444845448464484744848448494485044851448524485344854448554485644857448584485944860448614486244863448644486544866448674486844869448704487144872448734487444875448764487744878448794488044881448824488344884448854488644887448884488944890448914489244893448944489544896448974489844899449004490144902449034490444905449064490744908449094491044911449124491344914449154491644917449184491944920449214492244923449244492544926449274492844929449304493144932449334493444935449364493744938449394494044941449424494344944449454494644947449484494944950449514495244953449544495544956449574495844959449604496144962449634496444965449664496744968449694497044971449724497344974449754497644977449784497944980449814498244983449844498544986449874498844989449904499144992449934499444995449964499744998449994500045001450024500345004450054500645007450084500945010450114501245013450144501545016450174501845019450204502145022450234502445025450264502745028450294503045031450324503345034450354503645037450384503945040450414504245043450444504545046450474504845049450504505145052450534505445055450564505745058450594506045061450624506345064450654506645067450684506945070450714507245073450744507545076450774507845079450804508145082450834508445085450864508745088450894509045091450924509345094450954509645097450984509945100451014510245103451044510545106451074510845109451104511145112451134511445115451164511745118451194512045121451224512345124451254512645127451284512945130451314513245133451344513545136451374513845139451404514145142451434514445145451464514745148451494515045151451524515345154451554515645157451584515945160451614516245163451644516545166451674516845169451704517145172451734517445175451764517745178451794518045181451824518345184451854518645187451884518945190451914519245193451944519545196451974519845199452004520145202452034520445205452064520745208452094521045211452124521345214452154521645217452184521945220452214522245223452244522545226452274522845229452304523145232452334523445235452364523745238452394524045241452424524345244452454524645247452484524945250452514525245253452544525545256452574525845259452604526145262452634526445265452664526745268452694527045271452724527345274452754527645277452784527945280452814528245283452844528545286452874528845289452904529145292452934529445295452964529745298452994530045301453024530345304453054530645307453084530945310453114531245313453144531545316453174531845319453204532145322453234532445325453264532745328453294533045331453324533345334453354533645337453384533945340453414534245343453444534545346453474534845349453504535145352453534535445355453564535745358453594536045361453624536345364453654536645367453684536945370453714537245373453744537545376453774537845379453804538145382453834538445385453864538745388453894539045391453924539345394453954539645397453984539945400454014540245403454044540545406454074540845409454104541145412454134541445415454164541745418454194542045421454224542345424454254542645427454284542945430454314543245433454344543545436454374543845439454404544145442454434544445445454464544745448454494545045451454524545345454454554545645457454584545945460454614546245463454644546545466454674546845469454704547145472454734547445475454764547745478454794548045481454824548345484454854548645487454884548945490454914549245493454944549545496454974549845499455004550145502455034550445505455064550745508455094551045511455124551345514455154551645517455184551945520455214552245523455244552545526455274552845529455304553145532455334553445535455364553745538455394554045541455424554345544455454554645547455484554945550455514555245553455544555545556455574555845559455604556145562455634556445565455664556745568455694557045571455724557345574455754557645577455784557945580455814558245583455844558545586455874558845589455904559145592455934559445595455964559745598455994560045601456024560345604456054560645607456084560945610456114561245613456144561545616456174561845619456204562145622456234562445625456264562745628456294563045631456324563345634456354563645637456384563945640456414564245643456444564545646456474564845649456504565145652456534565445655456564565745658456594566045661456624566345664456654566645667456684566945670456714567245673456744567545676456774567845679456804568145682456834568445685456864568745688456894569045691456924569345694456954569645697456984569945700457014570245703457044570545706457074570845709457104571145712457134571445715457164571745718457194572045721457224572345724457254572645727457284572945730457314573245733457344573545736457374573845739457404574145742457434574445745457464574745748457494575045751457524575345754457554575645757457584575945760457614576245763457644576545766457674576845769457704577145772457734577445775457764577745778457794578045781457824578345784457854578645787457884578945790457914579245793457944579545796457974579845799458004580145802458034580445805458064580745808458094581045811458124581345814458154581645817458184581945820458214582245823458244582545826458274582845829458304583145832458334583445835458364583745838458394584045841458424584345844458454584645847458484584945850458514585245853458544585545856458574585845859458604586145862458634586445865458664586745868458694587045871458724587345874458754587645877458784587945880458814588245883458844588545886458874588845889458904589145892458934589445895458964589745898458994590045901459024590345904459054590645907459084590945910459114591245913459144591545916459174591845919459204592145922459234592445925459264592745928459294593045931459324593345934459354593645937459384593945940459414594245943459444594545946459474594845949459504595145952459534595445955459564595745958459594596045961459624596345964459654596645967459684596945970459714597245973459744597545976459774597845979459804598145982459834598445985459864598745988459894599045991459924599345994459954599645997459984599946000460014600246003460044600546006460074600846009460104601146012460134601446015460164601746018460194602046021460224602346024460254602646027460284602946030460314603246033460344603546036460374603846039460404604146042460434604446045460464604746048460494605046051460524605346054460554605646057460584605946060460614606246063460644606546066460674606846069460704607146072460734607446075460764607746078460794608046081460824608346084460854608646087460884608946090460914609246093460944609546096460974609846099461004610146102461034610446105461064610746108461094611046111461124611346114461154611646117461184611946120461214612246123461244612546126461274612846129461304613146132461334613446135461364613746138461394614046141461424614346144461454614646147461484614946150461514615246153461544615546156461574615846159461604616146162461634616446165461664616746168461694617046171461724617346174461754617646177461784617946180461814618246183461844618546186461874618846189461904619146192461934619446195461964619746198461994620046201462024620346204462054620646207462084620946210462114621246213462144621546216462174621846219462204622146222462234622446225462264622746228462294623046231462324623346234462354623646237462384623946240462414624246243462444624546246462474624846249462504625146252462534625446255462564625746258462594626046261462624626346264462654626646267462684626946270462714627246273462744627546276462774627846279462804628146282462834628446285462864628746288462894629046291462924629346294462954629646297462984629946300463014630246303463044630546306463074630846309463104631146312463134631446315463164631746318463194632046321463224632346324463254632646327463284632946330463314633246333463344633546336463374633846339463404634146342463434634446345463464634746348463494635046351463524635346354463554635646357463584635946360463614636246363463644636546366463674636846369463704637146372463734637446375463764637746378463794638046381463824638346384463854638646387463884638946390463914639246393463944639546396463974639846399464004640146402464034640446405464064640746408464094641046411464124641346414464154641646417464184641946420464214642246423464244642546426464274642846429464304643146432464334643446435464364643746438464394644046441464424644346444464454644646447464484644946450464514645246453464544645546456464574645846459464604646146462464634646446465464664646746468464694647046471464724647346474464754647646477464784647946480464814648246483464844648546486464874648846489464904649146492464934649446495464964649746498464994650046501465024650346504465054650646507465084650946510465114651246513465144651546516465174651846519465204652146522465234652446525465264652746528465294653046531465324653346534465354653646537465384653946540465414654246543465444654546546465474654846549465504655146552465534655446555465564655746558465594656046561465624656346564465654656646567465684656946570465714657246573465744657546576465774657846579465804658146582465834658446585465864658746588465894659046591465924659346594465954659646597465984659946600466014660246603466044660546606466074660846609466104661146612466134661446615466164661746618466194662046621466224662346624466254662646627466284662946630466314663246633466344663546636466374663846639466404664146642466434664446645466464664746648466494665046651466524665346654466554665646657466584665946660466614666246663466644666546666466674666846669466704667146672466734667446675466764667746678466794668046681466824668346684466854668646687466884668946690466914669246693466944669546696466974669846699467004670146702467034670446705467064670746708467094671046711467124671346714467154671646717467184671946720467214672246723467244672546726467274672846729467304673146732467334673446735467364673746738467394674046741467424674346744467454674646747467484674946750467514675246753467544675546756467574675846759467604676146762467634676446765467664676746768467694677046771467724677346774467754677646777467784677946780467814678246783467844678546786467874678846789467904679146792467934679446795467964679746798467994680046801468024680346804468054680646807468084680946810468114681246813468144681546816468174681846819468204682146822468234682446825468264682746828468294683046831468324683346834468354683646837468384683946840468414684246843468444684546846468474684846849468504685146852468534685446855468564685746858468594686046861468624686346864468654686646867468684686946870468714687246873468744687546876468774687846879468804688146882468834688446885468864688746888468894689046891468924689346894468954689646897468984689946900469014690246903469044690546906469074690846909469104691146912469134691446915469164691746918469194692046921469224692346924469254692646927469284692946930469314693246933469344693546936469374693846939469404694146942469434694446945469464694746948469494695046951469524695346954469554695646957469584695946960469614696246963469644696546966469674696846969469704697146972469734697446975469764697746978469794698046981469824698346984469854698646987469884698946990469914699246993469944699546996469974699846999470004700147002470034700447005470064700747008470094701047011470124701347014470154701647017470184701947020470214702247023470244702547026470274702847029470304703147032470334703447035470364703747038470394704047041470424704347044470454704647047470484704947050470514705247053470544705547056470574705847059470604706147062470634706447065470664706747068470694707047071470724707347074470754707647077470784707947080470814708247083470844708547086470874708847089470904709147092470934709447095470964709747098470994710047101471024710347104471054710647107471084710947110471114711247113471144711547116471174711847119471204712147122471234712447125471264712747128471294713047131471324713347134471354713647137471384713947140471414714247143471444714547146471474714847149471504715147152471534715447155471564715747158471594716047161471624716347164471654716647167471684716947170471714717247173471744717547176471774717847179471804718147182471834718447185471864718747188471894719047191471924719347194471954719647197471984719947200472014720247203472044720547206472074720847209472104721147212472134721447215472164721747218472194722047221472224722347224472254722647227472284722947230472314723247233472344723547236472374723847239472404724147242472434724447245472464724747248472494725047251472524725347254472554725647257472584725947260472614726247263472644726547266472674726847269472704727147272472734727447275472764727747278472794728047281472824728347284472854728647287472884728947290472914729247293472944729547296472974729847299473004730147302473034730447305473064730747308473094731047311473124731347314473154731647317473184731947320473214732247323473244732547326473274732847329473304733147332473334733447335473364733747338473394734047341473424734347344473454734647347473484734947350473514735247353473544735547356473574735847359473604736147362473634736447365473664736747368473694737047371473724737347374473754737647377473784737947380473814738247383473844738547386473874738847389473904739147392473934739447395473964739747398473994740047401474024740347404474054740647407474084740947410474114741247413474144741547416474174741847419474204742147422474234742447425474264742747428474294743047431474324743347434474354743647437474384743947440474414744247443474444744547446474474744847449474504745147452474534745447455474564745747458474594746047461474624746347464474654746647467474684746947470474714747247473474744747547476474774747847479474804748147482474834748447485474864748747488474894749047491474924749347494474954749647497474984749947500475014750247503475044750547506475074750847509475104751147512475134751447515475164751747518475194752047521475224752347524475254752647527475284752947530475314753247533475344753547536475374753847539475404754147542475434754447545475464754747548475494755047551475524755347554475554755647557475584755947560475614756247563475644756547566475674756847569475704757147572475734757447575475764757747578475794758047581475824758347584475854758647587475884758947590475914759247593475944759547596475974759847599476004760147602476034760447605476064760747608476094761047611476124761347614476154761647617476184761947620476214762247623476244762547626476274762847629476304763147632476334763447635476364763747638476394764047641476424764347644476454764647647476484764947650476514765247653476544765547656476574765847659476604766147662476634766447665476664766747668476694767047671476724767347674476754767647677476784767947680476814768247683476844768547686476874768847689476904769147692476934769447695476964769747698476994770047701477024770347704477054770647707477084770947710477114771247713477144771547716477174771847719477204772147722477234772447725477264772747728477294773047731477324773347734477354773647737477384773947740477414774247743477444774547746477474774847749477504775147752477534775447755477564775747758477594776047761477624776347764477654776647767477684776947770477714777247773477744777547776477774777847779477804778147782477834778447785477864778747788477894779047791477924779347794477954779647797477984779947800478014780247803478044780547806478074780847809478104781147812478134781447815478164781747818478194782047821478224782347824478254782647827478284782947830478314783247833478344783547836478374783847839478404784147842478434784447845478464784747848478494785047851478524785347854478554785647857478584785947860478614786247863478644786547866478674786847869478704787147872478734787447875478764787747878478794788047881478824788347884478854788647887478884788947890478914789247893478944789547896478974789847899479004790147902479034790447905479064790747908479094791047911479124791347914479154791647917479184791947920479214792247923479244792547926479274792847929479304793147932479334793447935479364793747938479394794047941479424794347944479454794647947479484794947950479514795247953479544795547956479574795847959479604796147962479634796447965479664796747968479694797047971479724797347974479754797647977479784797947980479814798247983479844798547986479874798847989479904799147992479934799447995479964799747998479994800048001480024800348004480054800648007480084800948010480114801248013480144801548016480174801848019480204802148022480234802448025480264802748028480294803048031480324803348034480354803648037480384803948040480414804248043480444804548046480474804848049480504805148052480534805448055480564805748058480594806048061480624806348064480654806648067480684806948070480714807248073480744807548076480774807848079480804808148082480834808448085480864808748088480894809048091480924809348094480954809648097480984809948100481014810248103481044810548106481074810848109481104811148112481134811448115481164811748118481194812048121481224812348124481254812648127481284812948130481314813248133481344813548136481374813848139481404814148142481434814448145481464814748148481494815048151481524815348154481554815648157481584815948160481614816248163481644816548166481674816848169481704817148172481734817448175481764817748178481794818048181481824818348184481854818648187481884818948190481914819248193481944819548196481974819848199482004820148202482034820448205482064820748208482094821048211482124821348214482154821648217482184821948220482214822248223482244822548226482274822848229482304823148232482334823448235482364823748238482394824048241482424824348244482454824648247482484824948250482514825248253482544825548256482574825848259482604826148262482634826448265482664826748268482694827048271482724827348274482754827648277482784827948280482814828248283482844828548286482874828848289482904829148292482934829448295482964829748298482994830048301483024830348304483054830648307483084830948310483114831248313483144831548316483174831848319483204832148322483234832448325483264832748328483294833048331483324833348334483354833648337483384833948340483414834248343483444834548346483474834848349483504835148352483534835448355483564835748358483594836048361483624836348364483654836648367483684836948370483714837248373483744837548376483774837848379483804838148382483834838448385483864838748388483894839048391483924839348394483954839648397483984839948400484014840248403484044840548406484074840848409484104841148412484134841448415484164841748418484194842048421484224842348424484254842648427484284842948430484314843248433484344843548436484374843848439484404844148442484434844448445484464844748448484494845048451484524845348454484554845648457484584845948460484614846248463484644846548466484674846848469484704847148472484734847448475484764847748478484794848048481484824848348484484854848648487484884848948490484914849248493484944849548496484974849848499485004850148502485034850448505485064850748508485094851048511485124851348514485154851648517485184851948520485214852248523485244852548526485274852848529485304853148532485334853448535485364853748538485394854048541485424854348544485454854648547485484854948550485514855248553485544855548556485574855848559485604856148562485634856448565485664856748568485694857048571485724857348574485754857648577485784857948580485814858248583485844858548586485874858848589485904859148592485934859448595485964859748598485994860048601486024860348604486054860648607486084860948610486114861248613486144861548616486174861848619486204862148622486234862448625486264862748628486294863048631486324863348634486354863648637486384863948640486414864248643486444864548646486474864848649486504865148652486534865448655486564865748658486594866048661486624866348664486654866648667486684866948670486714867248673486744867548676486774867848679486804868148682486834868448685486864868748688486894869048691486924869348694486954869648697486984869948700487014870248703487044870548706487074870848709487104871148712487134871448715487164871748718487194872048721487224872348724487254872648727487284872948730487314873248733487344873548736487374873848739487404874148742487434874448745487464874748748487494875048751487524875348754487554875648757487584875948760487614876248763487644876548766487674876848769487704877148772487734877448775487764877748778487794878048781487824878348784487854878648787487884878948790487914879248793487944879548796487974879848799488004880148802488034880448805488064880748808488094881048811488124881348814488154881648817488184881948820488214882248823488244882548826488274882848829488304883148832488334883448835488364883748838488394884048841488424884348844488454884648847488484884948850488514885248853488544885548856488574885848859488604886148862488634886448865488664886748868488694887048871488724887348874488754887648877488784887948880488814888248883488844888548886488874888848889488904889148892488934889448895488964889748898488994890048901489024890348904489054890648907489084890948910489114891248913489144891548916489174891848919489204892148922489234892448925489264892748928489294893048931489324893348934489354893648937489384893948940489414894248943489444894548946489474894848949489504895148952489534895448955489564895748958489594896048961489624896348964489654896648967489684896948970489714897248973489744897548976489774897848979489804898148982489834898448985489864898748988489894899048991489924899348994489954899648997489984899949000490014900249003490044900549006490074900849009490104901149012490134901449015490164901749018490194902049021490224902349024490254902649027490284902949030490314903249033490344903549036490374903849039490404904149042490434904449045490464904749048490494905049051490524905349054490554905649057490584905949060490614906249063490644906549066490674906849069490704907149072490734907449075490764907749078490794908049081490824908349084490854908649087490884908949090490914909249093490944909549096490974909849099491004910149102491034910449105491064910749108491094911049111491124911349114491154911649117491184911949120491214912249123491244912549126491274912849129491304913149132491334913449135491364913749138491394914049141491424914349144491454914649147491484914949150491514915249153491544915549156491574915849159491604916149162491634916449165491664916749168491694917049171491724917349174491754917649177491784917949180491814918249183491844918549186491874918849189491904919149192491934919449195491964919749198491994920049201492024920349204492054920649207492084920949210492114921249213492144921549216492174921849219492204922149222492234922449225492264922749228492294923049231492324923349234492354923649237492384923949240492414924249243492444924549246492474924849249492504925149252492534925449255492564925749258492594926049261492624926349264492654926649267492684926949270492714927249273492744927549276492774927849279492804928149282492834928449285492864928749288492894929049291492924929349294492954929649297492984929949300493014930249303493044930549306493074930849309493104931149312493134931449315493164931749318493194932049321493224932349324493254932649327493284932949330493314933249333493344933549336493374933849339493404934149342493434934449345493464934749348493494935049351493524935349354493554935649357493584935949360493614936249363493644936549366493674936849369493704937149372493734937449375493764937749378493794938049381493824938349384493854938649387493884938949390493914939249393493944939549396493974939849399494004940149402494034940449405494064940749408494094941049411494124941349414494154941649417494184941949420494214942249423494244942549426494274942849429494304943149432494334943449435494364943749438494394944049441494424944349444494454944649447494484944949450494514945249453494544945549456494574945849459494604946149462494634946449465494664946749468494694947049471494724947349474494754947649477494784947949480494814948249483494844948549486494874948849489494904949149492494934949449495494964949749498494994950049501495024950349504495054950649507495084950949510495114951249513495144951549516495174951849519495204952149522495234952449525495264952749528495294953049531495324953349534495354953649537495384953949540495414954249543495444954549546495474954849549495504955149552495534955449555495564955749558495594956049561495624956349564495654956649567495684956949570495714957249573495744957549576495774957849579495804958149582495834958449585495864958749588495894959049591495924959349594495954959649597495984959949600496014960249603496044960549606496074960849609496104961149612496134961449615496164961749618496194962049621496224962349624496254962649627496284962949630496314963249633496344963549636496374963849639496404964149642496434964449645496464964749648496494965049651496524965349654496554965649657496584965949660496614966249663496644966549666496674966849669496704967149672496734967449675496764967749678496794968049681496824968349684496854968649687496884968949690496914969249693496944969549696496974969849699497004970149702497034970449705497064970749708497094971049711497124971349714497154971649717497184971949720497214972249723497244972549726497274972849729497304973149732497334973449735497364973749738497394974049741497424974349744497454974649747497484974949750497514975249753497544975549756497574975849759497604976149762497634976449765497664976749768497694977049771497724977349774497754977649777497784977949780497814978249783497844978549786497874978849789497904979149792497934979449795497964979749798497994980049801498024980349804498054980649807498084980949810498114981249813498144981549816498174981849819498204982149822498234982449825498264982749828498294983049831498324983349834498354983649837498384983949840498414984249843498444984549846498474984849849498504985149852498534985449855498564985749858498594986049861498624986349864498654986649867498684986949870498714987249873498744987549876498774987849879
  1. /*!
  2. * (C) Ionic http://ionicframework.com - MIT License
  3. */
  4. 'use strict';
  5. Object.defineProperty(exports, '__esModule', { value: true });
  6. var stream = require('stream');
  7. function hydrateFactory($stencilWindow, $stencilHydrateOpts, $stencilHydrateResults, $stencilAfterHydrate, $stencilHydrateResolve) {
  8. var globalThis = $stencilWindow;
  9. var self = $stencilWindow;
  10. var top = $stencilWindow;
  11. var parent = $stencilWindow;
  12. var addEventListener = $stencilWindow.addEventListener.bind($stencilWindow);
  13. var alert = $stencilWindow.alert.bind($stencilWindow);
  14. var blur = $stencilWindow.blur.bind($stencilWindow);
  15. var cancelAnimationFrame = $stencilWindow.cancelAnimationFrame.bind($stencilWindow);
  16. var cancelIdleCallback = $stencilWindow.cancelIdleCallback.bind($stencilWindow);
  17. var clearInterval = $stencilWindow.clearInterval.bind($stencilWindow);
  18. var clearTimeout = $stencilWindow.clearTimeout.bind($stencilWindow);
  19. var close = () => {};
  20. var confirm = $stencilWindow.confirm.bind($stencilWindow);
  21. var dispatchEvent = $stencilWindow.dispatchEvent.bind($stencilWindow);
  22. var focus = $stencilWindow.focus.bind($stencilWindow);
  23. var getComputedStyle = $stencilWindow.getComputedStyle.bind($stencilWindow);
  24. var matchMedia = $stencilWindow.matchMedia.bind($stencilWindow);
  25. var open = $stencilWindow.open.bind($stencilWindow);
  26. var prompt = $stencilWindow.prompt.bind($stencilWindow);
  27. var removeEventListener = $stencilWindow.removeEventListener.bind($stencilWindow);
  28. var requestAnimationFrame = $stencilWindow.requestAnimationFrame.bind($stencilWindow);
  29. var requestIdleCallback = $stencilWindow.requestIdleCallback.bind($stencilWindow);
  30. var setInterval = $stencilWindow.setInterval.bind($stencilWindow);
  31. var setTimeout = $stencilWindow.setTimeout.bind($stencilWindow);
  32. var CharacterData = $stencilWindow.CharacterData;
  33. var CSS = $stencilWindow.CSS;
  34. var CustomEvent = $stencilWindow.CustomEvent;
  35. var Document = $stencilWindow.Document;
  36. var DocumentFragment = $stencilWindow.DocumentFragment;
  37. var DocumentType = $stencilWindow.DocumentType;
  38. var DOMTokenList = $stencilWindow.DOMTokenList;
  39. var Element = $stencilWindow.Element;
  40. var Event = $stencilWindow.Event;
  41. var HTMLAnchorElement = $stencilWindow.HTMLAnchorElement;
  42. var HTMLBaseElement = $stencilWindow.HTMLBaseElement;
  43. var HTMLButtonElement = $stencilWindow.HTMLButtonElement;
  44. var HTMLCanvasElement = $stencilWindow.HTMLCanvasElement;
  45. var HTMLElement = $stencilWindow.HTMLElement;
  46. var HTMLFormElement = $stencilWindow.HTMLFormElement;
  47. var HTMLImageElement = $stencilWindow.HTMLImageElement;
  48. var HTMLInputElement = $stencilWindow.HTMLInputElement;
  49. var HTMLLinkElement = $stencilWindow.HTMLLinkElement;
  50. var HTMLMetaElement = $stencilWindow.HTMLMetaElement;
  51. var HTMLScriptElement = $stencilWindow.HTMLScriptElement;
  52. var HTMLStyleElement = $stencilWindow.HTMLStyleElement;
  53. var HTMLTemplateElement = $stencilWindow.HTMLTemplateElement;
  54. var HTMLTitleElement = $stencilWindow.HTMLTitleElement;
  55. var IntersectionObserver = $stencilWindow.IntersectionObserver;
  56. var KeyboardEvent = $stencilWindow.KeyboardEvent;
  57. var MouseEvent = $stencilWindow.MouseEvent;
  58. var Node = $stencilWindow.Node;
  59. var NodeList = $stencilWindow.NodeList;
  60. var URL = $stencilWindow.URL;
  61. var console = $stencilWindow.console;
  62. var customElements = $stencilWindow.customElements;
  63. var history = $stencilWindow.history;
  64. var localStorage = $stencilWindow.localStorage;
  65. var location = $stencilWindow.location;
  66. var navigator = $stencilWindow.navigator;
  67. var performance = $stencilWindow.performance;
  68. var sessionStorage = $stencilWindow.sessionStorage;
  69. var devicePixelRatio = $stencilWindow.devicePixelRatio;
  70. var innerHeight = $stencilWindow.innerHeight;
  71. var innerWidth = $stencilWindow.innerWidth;
  72. var origin = $stencilWindow.origin;
  73. var pageXOffset = $stencilWindow.pageXOffset;
  74. var pageYOffset = $stencilWindow.pageYOffset;
  75. var screen = $stencilWindow.screen;
  76. var screenLeft = $stencilWindow.screenLeft;
  77. var screenTop = $stencilWindow.screenTop;
  78. var screenX = $stencilWindow.screenX;
  79. var screenY = $stencilWindow.screenY;
  80. var scrollX = $stencilWindow.scrollX;
  81. var scrollY = $stencilWindow.scrollY;
  82. var exports = {};
  83. var fetch, FetchError, Headers, Request, Response;
  84. if (typeof $stencilWindow.fetch === 'function') {
  85. fetch = $stencilWindow.fetch;
  86. } else {
  87. fetch = $stencilWindow.fetch = function() { throw new Error('fetch() is not implemented'); };
  88. }
  89. if (typeof $stencilWindow.FetchError === 'function') {
  90. FetchError = $stencilWindow.FetchError;
  91. } else {
  92. FetchError = $stencilWindow.FetchError = class FetchError { constructor() { throw new Error('FetchError is not implemented'); } };
  93. }
  94. if (typeof $stencilWindow.Headers === 'function') {
  95. Headers = $stencilWindow.Headers;
  96. } else {
  97. Headers = $stencilWindow.Headers = class Headers { constructor() { throw new Error('Headers is not implemented'); } };
  98. }
  99. if (typeof $stencilWindow.Request === 'function') {
  100. Request = $stencilWindow.Request;
  101. } else {
  102. Request = $stencilWindow.Request = class Request { constructor() { throw new Error('Request is not implemented'); } };
  103. }
  104. if (typeof $stencilWindow.Response === 'function') {
  105. Response = $stencilWindow.Response;
  106. } else {
  107. Response = $stencilWindow.Response = class Response { constructor() { throw new Error('Response is not implemented'); } };
  108. }
  109. function hydrateAppClosure($stencilWindow) {
  110. const window = $stencilWindow;
  111. const document = $stencilWindow.document;
  112. /*hydrateAppClosure start*/
  113. const NAMESPACE = 'ionic';
  114. const BUILD = /* ionic */ { allRenderFn: false, appendChildSlotFix: false, asyncLoading: true, attachStyles: true, cloneNodeFix: false, cmpDidLoad: true, cmpDidRender: true, cmpDidUnload: false, cmpDidUpdate: true, cmpShouldUpdate: false, cmpWillLoad: true, cmpWillRender: true, cmpWillUpdate: false, connectedCallback: true, constructableCSS: false, cssAnnotations: true, devTools: false, disconnectedCallback: true, element: false, event: true, experimentalScopedSlotChanges: false, experimentalSlotFixes: false, formAssociated: false, hasRenderFn: true, hostListener: true, hostListenerTarget: true, hostListenerTargetBody: true, hostListenerTargetDocument: true, hostListenerTargetParent: false, hostListenerTargetWindow: true, hotModuleReplacement: false, hydrateClientSide: true, hydrateServerSide: true, hydratedAttribute: false, hydratedClass: true, hydratedSelectorName: "hydrated", invisiblePrehydration: true, isDebug: false, isDev: false, isTesting: false, lazyLoad: true, lifecycle: true, lifecycleDOMEvents: false, member: true, method: true, mode: true, observeAttribute: true, profile: false, prop: true, propBoolean: true, propMutable: true, propNumber: true, propString: true, reflect: true, scoped: true, scopedSlotTextContentFix: true, scriptDataOpts: false, shadowDelegatesFocus: true, shadowDom: true, shadowDomShim: true, slot: true, slotChildNodesFix: false, slotRelocation: true, state: true, style: true, svg: true, taskQueue: true, updatable: true, vdomAttribute: true, vdomClass: true, vdomFunctional: true, vdomKey: true, vdomListener: true, vdomPropOrAttr: true, vdomRef: true, vdomRender: true, vdomStyle: true, vdomText: true, vdomXlink: true, watchCallback: true };
  115. /*
  116. Stencil Hydrate Platform v4.20.0 | MIT Licensed | https://stenciljs.com
  117. */
  118. var __defProp = Object.defineProperty;
  119. var __export = (target, all) => {
  120. for (var name in all)
  121. __defProp(target, name, { get: all[name], enumerable: true });
  122. };
  123. // src/utils/constants.ts
  124. var EMPTY_OBJ = {};
  125. var SVG_NS = "http://www.w3.org/2000/svg";
  126. var HTML_NS = "http://www.w3.org/1999/xhtml";
  127. // src/utils/helpers.ts
  128. var isDef = (v) => v != null;
  129. var isComplexType = (o) => {
  130. o = typeof o;
  131. return o === "object" || o === "function";
  132. };
  133. // src/utils/query-nonce-meta-tag-content.ts
  134. function queryNonceMetaTagContent(doc2) {
  135. var _a, _b, _c;
  136. return (_c = (_b = (_a = doc2.head) == null ? void 0 : _a.querySelector('meta[name="csp-nonce"]')) == null ? void 0 : _b.getAttribute("content")) != null ? _c : void 0;
  137. }
  138. // src/utils/result.ts
  139. var result_exports = {};
  140. __export(result_exports, {
  141. err: () => err,
  142. map: () => map,
  143. ok: () => ok,
  144. unwrap: () => unwrap,
  145. unwrapErr: () => unwrapErr
  146. });
  147. var ok = (value) => ({
  148. isOk: true,
  149. isErr: false,
  150. value
  151. });
  152. var err = (value) => ({
  153. isOk: false,
  154. isErr: true,
  155. value
  156. });
  157. function map(result, fn) {
  158. if (result.isOk) {
  159. const val = fn(result.value);
  160. if (val instanceof Promise) {
  161. return val.then((newVal) => ok(newVal));
  162. } else {
  163. return ok(val);
  164. }
  165. }
  166. if (result.isErr) {
  167. const value = result.value;
  168. return err(value);
  169. }
  170. throw "should never get here";
  171. }
  172. var unwrap = (result) => {
  173. if (result.isOk) {
  174. return result.value;
  175. } else {
  176. throw result.value;
  177. }
  178. };
  179. var unwrapErr = (result) => {
  180. if (result.isErr) {
  181. return result.value;
  182. } else {
  183. throw result.value;
  184. }
  185. };
  186. var createTime = (fnName, tagName = "") => {
  187. {
  188. return () => {
  189. return;
  190. };
  191. }
  192. };
  193. var uniqueTime = (key, measureText) => {
  194. {
  195. return () => {
  196. return;
  197. };
  198. }
  199. };
  200. // src/runtime/runtime-constants.ts
  201. var CONTENT_REF_ID = "r";
  202. var ORG_LOCATION_ID = "o";
  203. var SLOT_NODE_ID = "s";
  204. var TEXT_NODE_ID = "t";
  205. var HYDRATE_ID = "s-id";
  206. var HYDRATED_STYLE_ID = "sty-id";
  207. var HYDRATE_CHILD_ID = "c-id";
  208. var SLOT_FB_CSS = "slot-fb{display:contents}slot-fb[hidden]{display:none}";
  209. var XLINK_NS = "http://www.w3.org/1999/xlink";
  210. var h = (nodeName, vnodeData, ...children) => {
  211. let child = null;
  212. let key = null;
  213. let slotName = null;
  214. let simple = false;
  215. let lastSimple = false;
  216. const vNodeChildren = [];
  217. const walk = (c) => {
  218. for (let i2 = 0; i2 < c.length; i2++) {
  219. child = c[i2];
  220. if (Array.isArray(child)) {
  221. walk(child);
  222. } else if (child != null && typeof child !== "boolean") {
  223. if (simple = typeof nodeName !== "function" && !isComplexType(child)) {
  224. child = String(child);
  225. }
  226. if (simple && lastSimple) {
  227. vNodeChildren[vNodeChildren.length - 1].$text$ += child;
  228. } else {
  229. vNodeChildren.push(simple ? newVNode(null, child) : child);
  230. }
  231. lastSimple = simple;
  232. }
  233. }
  234. };
  235. walk(children);
  236. if (vnodeData) {
  237. if (vnodeData.key) {
  238. key = vnodeData.key;
  239. }
  240. if (vnodeData.name) {
  241. slotName = vnodeData.name;
  242. }
  243. {
  244. const classData = vnodeData.className || vnodeData.class;
  245. if (classData) {
  246. vnodeData.class = typeof classData !== "object" ? classData : Object.keys(classData).filter((k) => classData[k]).join(" ");
  247. }
  248. }
  249. }
  250. if (typeof nodeName === "function") {
  251. return nodeName(
  252. vnodeData === null ? {} : vnodeData,
  253. vNodeChildren,
  254. vdomFnUtils
  255. );
  256. }
  257. const vnode = newVNode(nodeName, null);
  258. vnode.$attrs$ = vnodeData;
  259. if (vNodeChildren.length > 0) {
  260. vnode.$children$ = vNodeChildren;
  261. }
  262. {
  263. vnode.$key$ = key;
  264. }
  265. {
  266. vnode.$name$ = slotName;
  267. }
  268. return vnode;
  269. };
  270. var newVNode = (tag, text) => {
  271. const vnode = {
  272. $flags$: 0,
  273. $tag$: tag,
  274. $text$: text,
  275. $elm$: null,
  276. $children$: null
  277. };
  278. {
  279. vnode.$attrs$ = null;
  280. }
  281. {
  282. vnode.$key$ = null;
  283. }
  284. {
  285. vnode.$name$ = null;
  286. }
  287. return vnode;
  288. };
  289. var Host = {};
  290. var isHost = (node) => node && node.$tag$ === Host;
  291. var vdomFnUtils = {
  292. forEach: (children, cb) => children.map(convertToPublic).forEach(cb),
  293. map: (children, cb) => children.map(convertToPublic).map(cb).map(convertToPrivate)
  294. };
  295. var convertToPublic = (node) => ({
  296. vattrs: node.$attrs$,
  297. vchildren: node.$children$,
  298. vkey: node.$key$,
  299. vname: node.$name$,
  300. vtag: node.$tag$,
  301. vtext: node.$text$
  302. });
  303. var convertToPrivate = (node) => {
  304. if (typeof node.vtag === "function") {
  305. const vnodeData = { ...node.vattrs };
  306. if (node.vkey) {
  307. vnodeData.key = node.vkey;
  308. }
  309. if (node.vname) {
  310. vnodeData.name = node.vname;
  311. }
  312. return h(node.vtag, vnodeData, ...node.vchildren || []);
  313. }
  314. const vnode = newVNode(node.vtag, node.vtext);
  315. vnode.$attrs$ = node.vattrs;
  316. vnode.$children$ = node.vchildren;
  317. vnode.$key$ = node.vkey;
  318. vnode.$name$ = node.vname;
  319. return vnode;
  320. };
  321. // src/runtime/client-hydrate.ts
  322. var initializeClientHydrate = (hostElm, tagName, hostId, hostRef) => {
  323. const endHydrate = createTime("hydrateClient", tagName);
  324. const shadowRoot = hostElm.shadowRoot;
  325. const childRenderNodes = [];
  326. const slotNodes = [];
  327. const shadowRootNodes = shadowRoot ? [] : null;
  328. const vnode = hostRef.$vnode$ = newVNode(tagName, null);
  329. if (!plt.$orgLocNodes$) {
  330. initializeDocumentHydrate(doc$1.body, plt.$orgLocNodes$ = /* @__PURE__ */ new Map());
  331. }
  332. hostElm[HYDRATE_ID] = hostId;
  333. hostElm.removeAttribute(HYDRATE_ID);
  334. clientHydrate(vnode, childRenderNodes, slotNodes, shadowRootNodes, hostElm, hostElm, hostId);
  335. childRenderNodes.map((c) => {
  336. const orgLocationId = c.$hostId$ + "." + c.$nodeId$;
  337. const orgLocationNode = plt.$orgLocNodes$.get(orgLocationId);
  338. const node = c.$elm$;
  339. if (orgLocationNode && supportsShadow && orgLocationNode["s-en"] === "") {
  340. orgLocationNode.parentNode.insertBefore(node, orgLocationNode.nextSibling);
  341. }
  342. if (!shadowRoot) {
  343. node["s-hn"] = tagName;
  344. if (orgLocationNode) {
  345. node["s-ol"] = orgLocationNode;
  346. node["s-ol"]["s-nr"] = node;
  347. }
  348. }
  349. plt.$orgLocNodes$.delete(orgLocationId);
  350. });
  351. if (shadowRoot) {
  352. shadowRootNodes.map((shadowRootNode) => {
  353. if (shadowRootNode) {
  354. shadowRoot.appendChild(shadowRootNode);
  355. }
  356. });
  357. }
  358. endHydrate();
  359. };
  360. var clientHydrate = (parentVNode, childRenderNodes, slotNodes, shadowRootNodes, hostElm, node, hostId) => {
  361. let childNodeType;
  362. let childIdSplt;
  363. let childVNode;
  364. let i2;
  365. if (node.nodeType === 1 /* ElementNode */) {
  366. childNodeType = node.getAttribute(HYDRATE_CHILD_ID);
  367. if (childNodeType) {
  368. childIdSplt = childNodeType.split(".");
  369. if (childIdSplt[0] === hostId || childIdSplt[0] === "0") {
  370. childVNode = {
  371. $flags$: 0,
  372. $hostId$: childIdSplt[0],
  373. $nodeId$: childIdSplt[1],
  374. $depth$: childIdSplt[2],
  375. $index$: childIdSplt[3],
  376. $tag$: node.tagName.toLowerCase(),
  377. $elm$: node,
  378. $attrs$: null,
  379. $children$: null,
  380. $key$: null,
  381. $name$: null,
  382. $text$: null
  383. };
  384. childRenderNodes.push(childVNode);
  385. node.removeAttribute(HYDRATE_CHILD_ID);
  386. if (!parentVNode.$children$) {
  387. parentVNode.$children$ = [];
  388. }
  389. parentVNode.$children$[childVNode.$index$] = childVNode;
  390. parentVNode = childVNode;
  391. if (shadowRootNodes && childVNode.$depth$ === "0") {
  392. shadowRootNodes[childVNode.$index$] = childVNode.$elm$;
  393. }
  394. }
  395. }
  396. if (node.shadowRoot) {
  397. for (i2 = node.shadowRoot.childNodes.length - 1; i2 >= 0; i2--) {
  398. clientHydrate(
  399. parentVNode,
  400. childRenderNodes,
  401. slotNodes,
  402. shadowRootNodes,
  403. hostElm,
  404. node.shadowRoot.childNodes[i2],
  405. hostId
  406. );
  407. }
  408. }
  409. for (i2 = node.childNodes.length - 1; i2 >= 0; i2--) {
  410. clientHydrate(
  411. parentVNode,
  412. childRenderNodes,
  413. slotNodes,
  414. shadowRootNodes,
  415. hostElm,
  416. node.childNodes[i2],
  417. hostId
  418. );
  419. }
  420. } else if (node.nodeType === 8 /* CommentNode */) {
  421. childIdSplt = node.nodeValue.split(".");
  422. if (childIdSplt[1] === hostId || childIdSplt[1] === "0") {
  423. childNodeType = childIdSplt[0];
  424. childVNode = {
  425. $flags$: 0,
  426. $hostId$: childIdSplt[1],
  427. $nodeId$: childIdSplt[2],
  428. $depth$: childIdSplt[3],
  429. $index$: childIdSplt[4],
  430. $elm$: node,
  431. $attrs$: null,
  432. $children$: null,
  433. $key$: null,
  434. $name$: null,
  435. $tag$: null,
  436. $text$: null
  437. };
  438. if (childNodeType === TEXT_NODE_ID) {
  439. childVNode.$elm$ = node.nextSibling;
  440. if (childVNode.$elm$ && childVNode.$elm$.nodeType === 3 /* TextNode */) {
  441. childVNode.$text$ = childVNode.$elm$.textContent;
  442. childRenderNodes.push(childVNode);
  443. node.remove();
  444. if (!parentVNode.$children$) {
  445. parentVNode.$children$ = [];
  446. }
  447. parentVNode.$children$[childVNode.$index$] = childVNode;
  448. if (shadowRootNodes && childVNode.$depth$ === "0") {
  449. shadowRootNodes[childVNode.$index$] = childVNode.$elm$;
  450. }
  451. }
  452. } else if (childVNode.$hostId$ === hostId) {
  453. if (childNodeType === SLOT_NODE_ID) {
  454. childVNode.$tag$ = "slot";
  455. if (childIdSplt[5]) {
  456. node["s-sn"] = childVNode.$name$ = childIdSplt[5];
  457. } else {
  458. node["s-sn"] = "";
  459. }
  460. node["s-sr"] = true;
  461. if (shadowRootNodes) {
  462. childVNode.$elm$ = doc$1.createElement(childVNode.$tag$);
  463. if (childVNode.$name$) {
  464. childVNode.$elm$.setAttribute("name", childVNode.$name$);
  465. }
  466. node.parentNode.insertBefore(childVNode.$elm$, node);
  467. node.remove();
  468. if (childVNode.$depth$ === "0") {
  469. shadowRootNodes[childVNode.$index$] = childVNode.$elm$;
  470. }
  471. }
  472. slotNodes.push(childVNode);
  473. if (!parentVNode.$children$) {
  474. parentVNode.$children$ = [];
  475. }
  476. parentVNode.$children$[childVNode.$index$] = childVNode;
  477. } else if (childNodeType === CONTENT_REF_ID) {
  478. if (shadowRootNodes) {
  479. node.remove();
  480. } else {
  481. hostElm["s-cr"] = node;
  482. node["s-cn"] = true;
  483. }
  484. }
  485. }
  486. }
  487. } else if (parentVNode && parentVNode.$tag$ === "style") {
  488. const vnode = newVNode(null, node.textContent);
  489. vnode.$elm$ = node;
  490. vnode.$index$ = "0";
  491. parentVNode.$children$ = [vnode];
  492. }
  493. };
  494. var initializeDocumentHydrate = (node, orgLocNodes) => {
  495. if (node.nodeType === 1 /* ElementNode */) {
  496. let i2 = 0;
  497. if (node.shadowRoot) {
  498. for (; i2 < node.shadowRoot.childNodes.length; i2++) {
  499. initializeDocumentHydrate(node.shadowRoot.childNodes[i2], orgLocNodes);
  500. }
  501. }
  502. for (i2 = 0; i2 < node.childNodes.length; i2++) {
  503. initializeDocumentHydrate(node.childNodes[i2], orgLocNodes);
  504. }
  505. } else if (node.nodeType === 8 /* CommentNode */) {
  506. const childIdSplt = node.nodeValue.split(".");
  507. if (childIdSplt[0] === ORG_LOCATION_ID) {
  508. orgLocNodes.set(childIdSplt[1] + "." + childIdSplt[2], node);
  509. node.nodeValue = "";
  510. node["s-en"] = childIdSplt[3];
  511. }
  512. }
  513. };
  514. // src/runtime/mode.ts
  515. var computeMode = (elm) => modeResolutionChain.map((h2) => h2(elm)).find((m) => !!m);
  516. var getMode = (ref) => getHostRef(ref).$modeName$;
  517. var parsePropertyValue = (propValue, propType) => {
  518. if (propValue != null && !isComplexType(propValue)) {
  519. if (propType & 4 /* Boolean */) {
  520. return propValue === "false" ? false : propValue === "" || !!propValue;
  521. }
  522. if (propType & 2 /* Number */) {
  523. return parseFloat(propValue);
  524. }
  525. if (propType & 1 /* String */) {
  526. return String(propValue);
  527. }
  528. return propValue;
  529. }
  530. return propValue;
  531. };
  532. var getElement = (ref) => getHostRef(ref).$hostElement$ ;
  533. // src/runtime/event-emitter.ts
  534. var createEvent = (ref, name, flags) => {
  535. const elm = getElement(ref);
  536. return {
  537. emit: (detail) => {
  538. return emitEvent(elm, name, {
  539. bubbles: !!(flags & 4 /* Bubbles */),
  540. composed: !!(flags & 2 /* Composed */),
  541. cancelable: !!(flags & 1 /* Cancellable */),
  542. detail
  543. });
  544. }
  545. };
  546. };
  547. var emitEvent = (elm, name, opts) => {
  548. const ev = plt.ce(name, opts);
  549. elm.dispatchEvent(ev);
  550. return ev;
  551. };
  552. var rootAppliedStyles = /* @__PURE__ */ new WeakMap();
  553. var registerStyle = (scopeId2, cssText, allowCS) => {
  554. let style = styles.get(scopeId2);
  555. {
  556. style = cssText;
  557. }
  558. styles.set(scopeId2, style);
  559. };
  560. var addStyle = (styleContainerNode, cmpMeta, mode) => {
  561. var _a;
  562. const scopeId2 = getScopeId(cmpMeta, mode);
  563. const style = styles.get(scopeId2);
  564. styleContainerNode = styleContainerNode.nodeType === 11 /* DocumentFragment */ ? styleContainerNode : doc$1;
  565. if (style) {
  566. if (typeof style === "string") {
  567. styleContainerNode = styleContainerNode.head || styleContainerNode;
  568. let appliedStyles = rootAppliedStyles.get(styleContainerNode);
  569. let styleElm;
  570. if (!appliedStyles) {
  571. rootAppliedStyles.set(styleContainerNode, appliedStyles = /* @__PURE__ */ new Set());
  572. }
  573. if (!appliedStyles.has(scopeId2)) {
  574. if (styleContainerNode.host && (styleElm = styleContainerNode.querySelector(`[${HYDRATED_STYLE_ID}="${scopeId2}"]`))) {
  575. styleElm.innerHTML = style;
  576. } else {
  577. styleElm = doc$1.createElement("style");
  578. styleElm.innerHTML = style;
  579. const nonce = (_a = plt.$nonce$) != null ? _a : queryNonceMetaTagContent(doc$1);
  580. if (nonce != null) {
  581. styleElm.setAttribute("nonce", nonce);
  582. }
  583. if (cmpMeta.$flags$ & 2 /* scopedCssEncapsulation */) {
  584. styleElm.setAttribute(HYDRATED_STYLE_ID, scopeId2);
  585. }
  586. const injectStyle = (
  587. /**
  588. * we render a scoped component
  589. */
  590. !(cmpMeta.$flags$ & 1 /* shadowDomEncapsulation */) || /**
  591. * we are using shadow dom and render the style tag within the shadowRoot
  592. */
  593. cmpMeta.$flags$ & 1 /* shadowDomEncapsulation */ && styleContainerNode.nodeName !== "HEAD"
  594. );
  595. if (injectStyle) {
  596. styleContainerNode.insertBefore(styleElm, styleContainerNode.querySelector("link"));
  597. }
  598. }
  599. if (cmpMeta.$flags$ & 4 /* hasSlotRelocation */) {
  600. styleElm.innerHTML += SLOT_FB_CSS;
  601. }
  602. if (appliedStyles) {
  603. appliedStyles.add(scopeId2);
  604. }
  605. }
  606. }
  607. }
  608. return scopeId2;
  609. };
  610. var attachStyles = (hostRef) => {
  611. const cmpMeta = hostRef.$cmpMeta$;
  612. const elm = hostRef.$hostElement$;
  613. const flags = cmpMeta.$flags$;
  614. const endAttachStyles = createTime("attachStyles", cmpMeta.$tagName$);
  615. const scopeId2 = addStyle(
  616. elm.shadowRoot ? elm.shadowRoot : elm.getRootNode(),
  617. cmpMeta,
  618. hostRef.$modeName$
  619. );
  620. if (flags & 10 /* needsScopedEncapsulation */ && flags & 2 /* scopedCssEncapsulation */) {
  621. elm["s-sc"] = scopeId2;
  622. elm.classList.add(scopeId2 + "-h");
  623. if (flags & 2 /* scopedCssEncapsulation */) {
  624. elm.classList.add(scopeId2 + "-s");
  625. }
  626. }
  627. endAttachStyles();
  628. };
  629. var getScopeId = (cmp, mode) => "sc-" + (mode && cmp.$flags$ & 32 /* hasMode */ ? cmp.$tagName$ + "-" + mode : cmp.$tagName$);
  630. var setAccessor = (elm, memberName, oldValue, newValue, isSvg, flags) => {
  631. if (oldValue !== newValue) {
  632. let isProp = isMemberInElement(elm, memberName);
  633. let ln = memberName.toLowerCase();
  634. if (memberName === "class") {
  635. const classList = elm.classList;
  636. const oldClasses = parseClassList(oldValue);
  637. const newClasses = parseClassList(newValue);
  638. classList.remove(...oldClasses.filter((c) => c && !newClasses.includes(c)));
  639. classList.add(...newClasses.filter((c) => c && !oldClasses.includes(c)));
  640. } else if (memberName === "style") {
  641. {
  642. for (const prop in oldValue) {
  643. if (!newValue || newValue[prop] == null) {
  644. {
  645. elm.style[prop] = "";
  646. }
  647. }
  648. }
  649. }
  650. for (const prop in newValue) {
  651. if (!oldValue || newValue[prop] !== oldValue[prop]) {
  652. {
  653. elm.style[prop] = newValue[prop];
  654. }
  655. }
  656. }
  657. } else if (memberName === "key") ; else if (memberName === "ref") {
  658. if (newValue) {
  659. newValue(elm);
  660. }
  661. } else if ((!isProp ) && memberName[0] === "o" && memberName[1] === "n") {
  662. if (memberName[2] === "-") {
  663. memberName = memberName.slice(3);
  664. } else if (isMemberInElement(win$2, ln)) {
  665. memberName = ln.slice(2);
  666. } else {
  667. memberName = ln[2] + memberName.slice(3);
  668. }
  669. if (oldValue || newValue) {
  670. const capture = memberName.endsWith(CAPTURE_EVENT_SUFFIX);
  671. memberName = memberName.replace(CAPTURE_EVENT_REGEX, "");
  672. if (oldValue) {
  673. plt.rel(elm, memberName, oldValue, capture);
  674. }
  675. if (newValue) {
  676. plt.ael(elm, memberName, newValue, capture);
  677. }
  678. }
  679. } else {
  680. const isComplex = isComplexType(newValue);
  681. if ((isProp || isComplex && newValue !== null) && !isSvg) {
  682. try {
  683. if (!elm.tagName.includes("-")) {
  684. const n = newValue == null ? "" : newValue;
  685. if (memberName === "list") {
  686. isProp = false;
  687. } else if (oldValue == null || elm[memberName] != n) {
  688. elm[memberName] = n;
  689. }
  690. } else {
  691. elm[memberName] = newValue;
  692. }
  693. } catch (e) {
  694. }
  695. }
  696. let xlink = false;
  697. {
  698. if (ln !== (ln = ln.replace(/^xlink\:?/, ""))) {
  699. memberName = ln;
  700. xlink = true;
  701. }
  702. }
  703. if (newValue == null || newValue === false) {
  704. if (newValue !== false || elm.getAttribute(memberName) === "") {
  705. if (xlink) {
  706. elm.removeAttributeNS(XLINK_NS, memberName);
  707. } else {
  708. elm.removeAttribute(memberName);
  709. }
  710. }
  711. } else if ((!isProp || flags & 4 /* isHost */ || isSvg) && !isComplex) {
  712. newValue = newValue === true ? "" : newValue;
  713. if (xlink) {
  714. elm.setAttributeNS(XLINK_NS, memberName, newValue);
  715. } else {
  716. elm.setAttribute(memberName, newValue);
  717. }
  718. }
  719. }
  720. }
  721. };
  722. var parseClassListRegex = /\s/;
  723. var parseClassList = (value) => !value ? [] : value.split(parseClassListRegex);
  724. var CAPTURE_EVENT_SUFFIX = "Capture";
  725. var CAPTURE_EVENT_REGEX = new RegExp(CAPTURE_EVENT_SUFFIX + "$");
  726. // src/runtime/vdom/update-element.ts
  727. var updateElement = (oldVnode, newVnode, isSvgMode2) => {
  728. const elm = newVnode.$elm$.nodeType === 11 /* DocumentFragment */ && newVnode.$elm$.host ? newVnode.$elm$.host : newVnode.$elm$;
  729. const oldVnodeAttrs = oldVnode && oldVnode.$attrs$ || EMPTY_OBJ;
  730. const newVnodeAttrs = newVnode.$attrs$ || EMPTY_OBJ;
  731. {
  732. for (const memberName of sortedAttrNames(Object.keys(oldVnodeAttrs))) {
  733. if (!(memberName in newVnodeAttrs)) {
  734. setAccessor(elm, memberName, oldVnodeAttrs[memberName], void 0, isSvgMode2, newVnode.$flags$);
  735. }
  736. }
  737. }
  738. for (const memberName of sortedAttrNames(Object.keys(newVnodeAttrs))) {
  739. setAccessor(elm, memberName, oldVnodeAttrs[memberName], newVnodeAttrs[memberName], isSvgMode2, newVnode.$flags$);
  740. }
  741. };
  742. function sortedAttrNames(attrNames) {
  743. return attrNames.includes("ref") ? (
  744. // we need to sort these to ensure that `'ref'` is the last attr
  745. [...attrNames.filter((attr) => attr !== "ref"), "ref"]
  746. ) : (
  747. // no need to sort, return the original array
  748. attrNames
  749. );
  750. }
  751. // src/runtime/vdom/vdom-render.ts
  752. var scopeId;
  753. var contentRef;
  754. var hostTagName;
  755. var useNativeShadowDom = false;
  756. var checkSlotFallbackVisibility = false;
  757. var checkSlotRelocate = false;
  758. var isSvgMode = false;
  759. var createElm = (oldParentVNode, newParentVNode, childIndex, parentElm) => {
  760. var _a;
  761. const newVNode2 = newParentVNode.$children$[childIndex];
  762. let i2 = 0;
  763. let elm;
  764. let childNode;
  765. let oldVNode;
  766. if (!useNativeShadowDom) {
  767. checkSlotRelocate = true;
  768. if (newVNode2.$tag$ === "slot") {
  769. if (scopeId) {
  770. parentElm.classList.add(scopeId + "-s");
  771. }
  772. newVNode2.$flags$ |= newVNode2.$children$ ? (
  773. // slot element has fallback content
  774. // still create an element that "mocks" the slot element
  775. 2 /* isSlotFallback */
  776. ) : (
  777. // slot element does not have fallback content
  778. // create an html comment we'll use to always reference
  779. // where actual slot content should sit next to
  780. 1 /* isSlotReference */
  781. );
  782. }
  783. }
  784. if (newVNode2.$text$ !== null) {
  785. elm = newVNode2.$elm$ = doc$1.createTextNode(newVNode2.$text$);
  786. } else if (newVNode2.$flags$ & 1 /* isSlotReference */) {
  787. elm = newVNode2.$elm$ = slotReferenceDebugNode(newVNode2) ;
  788. } else {
  789. if (!isSvgMode) {
  790. isSvgMode = newVNode2.$tag$ === "svg";
  791. }
  792. elm = newVNode2.$elm$ = doc$1.createElementNS(
  793. isSvgMode ? SVG_NS : HTML_NS,
  794. !useNativeShadowDom && BUILD.slotRelocation && newVNode2.$flags$ & 2 /* isSlotFallback */ ? "slot-fb" : newVNode2.$tag$
  795. ) ;
  796. if (isSvgMode && newVNode2.$tag$ === "foreignObject") {
  797. isSvgMode = false;
  798. }
  799. {
  800. updateElement(null, newVNode2, isSvgMode);
  801. }
  802. const rootNode = elm.getRootNode();
  803. const isElementWithinShadowRoot = !rootNode.querySelector("body");
  804. if (!isElementWithinShadowRoot && BUILD.scoped && isDef(scopeId) && elm["s-si"] !== scopeId) {
  805. elm.classList.add(elm["s-si"] = scopeId);
  806. }
  807. {
  808. updateElementScopeIds(elm, parentElm);
  809. }
  810. if (newVNode2.$children$) {
  811. for (i2 = 0; i2 < newVNode2.$children$.length; ++i2) {
  812. childNode = createElm(oldParentVNode, newVNode2, i2, elm);
  813. if (childNode) {
  814. elm.appendChild(childNode);
  815. }
  816. }
  817. }
  818. {
  819. if (newVNode2.$tag$ === "svg") {
  820. isSvgMode = false;
  821. } else if (elm.tagName === "foreignObject") {
  822. isSvgMode = true;
  823. }
  824. }
  825. }
  826. elm["s-hn"] = hostTagName;
  827. {
  828. if (newVNode2.$flags$ & (2 /* isSlotFallback */ | 1 /* isSlotReference */)) {
  829. elm["s-sr"] = true;
  830. elm["s-cr"] = contentRef;
  831. elm["s-sn"] = newVNode2.$name$ || "";
  832. elm["s-rf"] = (_a = newVNode2.$attrs$) == null ? void 0 : _a.ref;
  833. oldVNode = oldParentVNode && oldParentVNode.$children$ && oldParentVNode.$children$[childIndex];
  834. if (oldVNode && oldVNode.$tag$ === newVNode2.$tag$ && oldParentVNode.$elm$) {
  835. {
  836. putBackInOriginalLocation(oldParentVNode.$elm$, false);
  837. }
  838. }
  839. }
  840. }
  841. return elm;
  842. };
  843. var putBackInOriginalLocation = (parentElm, recursive) => {
  844. plt.$flags$ |= 1 /* isTmpDisconnected */;
  845. const oldSlotChildNodes = Array.from(parentElm.childNodes);
  846. if (parentElm["s-sr"] && BUILD.experimentalSlotFixes) {
  847. let node = parentElm;
  848. while (node = node.nextSibling) {
  849. if (node && node["s-sn"] === parentElm["s-sn"] && node["s-sh"] === hostTagName) {
  850. oldSlotChildNodes.push(node);
  851. }
  852. }
  853. }
  854. for (let i2 = oldSlotChildNodes.length - 1; i2 >= 0; i2--) {
  855. const childNode = oldSlotChildNodes[i2];
  856. if (childNode["s-hn"] !== hostTagName && childNode["s-ol"]) {
  857. insertBefore(parentReferenceNode(childNode), childNode, referenceNode(childNode));
  858. childNode["s-ol"].remove();
  859. childNode["s-ol"] = void 0;
  860. childNode["s-sh"] = void 0;
  861. checkSlotRelocate = true;
  862. }
  863. if (recursive) {
  864. putBackInOriginalLocation(childNode, recursive);
  865. }
  866. }
  867. plt.$flags$ &= ~1 /* isTmpDisconnected */;
  868. };
  869. var addVnodes = (parentElm, before, parentVNode, vnodes, startIdx, endIdx) => {
  870. let containerElm = parentElm["s-cr"] && parentElm["s-cr"].parentNode || parentElm;
  871. let childNode;
  872. if (containerElm.shadowRoot && containerElm.tagName === hostTagName) {
  873. containerElm = containerElm.shadowRoot;
  874. }
  875. for (; startIdx <= endIdx; ++startIdx) {
  876. if (vnodes[startIdx]) {
  877. childNode = createElm(null, parentVNode, startIdx, parentElm);
  878. if (childNode) {
  879. vnodes[startIdx].$elm$ = childNode;
  880. insertBefore(containerElm, childNode, referenceNode(before) );
  881. }
  882. }
  883. }
  884. };
  885. var removeVnodes = (vnodes, startIdx, endIdx) => {
  886. for (let index = startIdx; index <= endIdx; ++index) {
  887. const vnode = vnodes[index];
  888. if (vnode) {
  889. const elm = vnode.$elm$;
  890. nullifyVNodeRefs(vnode);
  891. if (elm) {
  892. {
  893. checkSlotFallbackVisibility = true;
  894. if (elm["s-ol"]) {
  895. elm["s-ol"].remove();
  896. } else {
  897. putBackInOriginalLocation(elm, true);
  898. }
  899. }
  900. elm.remove();
  901. }
  902. }
  903. }
  904. };
  905. var updateChildren = (parentElm, oldCh, newVNode2, newCh, isInitialRender = false) => {
  906. let oldStartIdx = 0;
  907. let newStartIdx = 0;
  908. let idxInOld = 0;
  909. let i2 = 0;
  910. let oldEndIdx = oldCh.length - 1;
  911. let oldStartVnode = oldCh[0];
  912. let oldEndVnode = oldCh[oldEndIdx];
  913. let newEndIdx = newCh.length - 1;
  914. let newStartVnode = newCh[0];
  915. let newEndVnode = newCh[newEndIdx];
  916. let node;
  917. let elmToMove;
  918. while (oldStartIdx <= oldEndIdx && newStartIdx <= newEndIdx) {
  919. if (oldStartVnode == null) {
  920. oldStartVnode = oldCh[++oldStartIdx];
  921. } else if (oldEndVnode == null) {
  922. oldEndVnode = oldCh[--oldEndIdx];
  923. } else if (newStartVnode == null) {
  924. newStartVnode = newCh[++newStartIdx];
  925. } else if (newEndVnode == null) {
  926. newEndVnode = newCh[--newEndIdx];
  927. } else if (isSameVnode(oldStartVnode, newStartVnode, isInitialRender)) {
  928. patch(oldStartVnode, newStartVnode, isInitialRender);
  929. oldStartVnode = oldCh[++oldStartIdx];
  930. newStartVnode = newCh[++newStartIdx];
  931. } else if (isSameVnode(oldEndVnode, newEndVnode, isInitialRender)) {
  932. patch(oldEndVnode, newEndVnode, isInitialRender);
  933. oldEndVnode = oldCh[--oldEndIdx];
  934. newEndVnode = newCh[--newEndIdx];
  935. } else if (isSameVnode(oldStartVnode, newEndVnode, isInitialRender)) {
  936. if ((oldStartVnode.$tag$ === "slot" || newEndVnode.$tag$ === "slot")) {
  937. putBackInOriginalLocation(oldStartVnode.$elm$.parentNode, false);
  938. }
  939. patch(oldStartVnode, newEndVnode, isInitialRender);
  940. insertBefore(parentElm, oldStartVnode.$elm$, oldEndVnode.$elm$.nextSibling);
  941. oldStartVnode = oldCh[++oldStartIdx];
  942. newEndVnode = newCh[--newEndIdx];
  943. } else if (isSameVnode(oldEndVnode, newStartVnode, isInitialRender)) {
  944. if ((oldStartVnode.$tag$ === "slot" || newEndVnode.$tag$ === "slot")) {
  945. putBackInOriginalLocation(oldEndVnode.$elm$.parentNode, false);
  946. }
  947. patch(oldEndVnode, newStartVnode, isInitialRender);
  948. insertBefore(parentElm, oldEndVnode.$elm$, oldStartVnode.$elm$);
  949. oldEndVnode = oldCh[--oldEndIdx];
  950. newStartVnode = newCh[++newStartIdx];
  951. } else {
  952. idxInOld = -1;
  953. {
  954. for (i2 = oldStartIdx; i2 <= oldEndIdx; ++i2) {
  955. if (oldCh[i2] && oldCh[i2].$key$ !== null && oldCh[i2].$key$ === newStartVnode.$key$) {
  956. idxInOld = i2;
  957. break;
  958. }
  959. }
  960. }
  961. if (idxInOld >= 0) {
  962. elmToMove = oldCh[idxInOld];
  963. if (elmToMove.$tag$ !== newStartVnode.$tag$) {
  964. node = createElm(oldCh && oldCh[newStartIdx], newVNode2, idxInOld, parentElm);
  965. } else {
  966. patch(elmToMove, newStartVnode, isInitialRender);
  967. oldCh[idxInOld] = void 0;
  968. node = elmToMove.$elm$;
  969. }
  970. newStartVnode = newCh[++newStartIdx];
  971. } else {
  972. node = createElm(oldCh && oldCh[newStartIdx], newVNode2, newStartIdx, parentElm);
  973. newStartVnode = newCh[++newStartIdx];
  974. }
  975. if (node) {
  976. {
  977. insertBefore(parentReferenceNode(oldStartVnode.$elm$), node, referenceNode(oldStartVnode.$elm$));
  978. }
  979. }
  980. }
  981. }
  982. if (oldStartIdx > oldEndIdx) {
  983. addVnodes(
  984. parentElm,
  985. newCh[newEndIdx + 1] == null ? null : newCh[newEndIdx + 1].$elm$,
  986. newVNode2,
  987. newCh,
  988. newStartIdx,
  989. newEndIdx
  990. );
  991. } else if (newStartIdx > newEndIdx) {
  992. removeVnodes(oldCh, oldStartIdx, oldEndIdx);
  993. }
  994. };
  995. var isSameVnode = (leftVNode, rightVNode, isInitialRender = false) => {
  996. if (leftVNode.$tag$ === rightVNode.$tag$) {
  997. if (leftVNode.$tag$ === "slot") {
  998. if (
  999. // The component gets hydrated and no VDOM has been initialized.
  1000. // Here the comparison can't happen as $name$ property is not set for `leftNode`.
  1001. "$nodeId$" in leftVNode && isInitialRender && // `leftNode` is not from type HTMLComment which would cause many
  1002. // hydration comments to be removed
  1003. leftVNode.$elm$.nodeType !== 8
  1004. ) {
  1005. return false;
  1006. }
  1007. return leftVNode.$name$ === rightVNode.$name$;
  1008. }
  1009. if (!isInitialRender) {
  1010. return leftVNode.$key$ === rightVNode.$key$;
  1011. }
  1012. return true;
  1013. }
  1014. return false;
  1015. };
  1016. var referenceNode = (node) => {
  1017. return node && node["s-ol"] || node;
  1018. };
  1019. var parentReferenceNode = (node) => (node["s-ol"] ? node["s-ol"] : node).parentNode;
  1020. var patch = (oldVNode, newVNode2, isInitialRender = false) => {
  1021. const elm = newVNode2.$elm$ = oldVNode.$elm$;
  1022. const oldChildren = oldVNode.$children$;
  1023. const newChildren = newVNode2.$children$;
  1024. const tag = newVNode2.$tag$;
  1025. const text = newVNode2.$text$;
  1026. let defaultHolder;
  1027. if (text === null) {
  1028. {
  1029. isSvgMode = tag === "svg" ? true : tag === "foreignObject" ? false : isSvgMode;
  1030. }
  1031. {
  1032. if (tag === "slot" && !useNativeShadowDom) ; else {
  1033. updateElement(oldVNode, newVNode2, isSvgMode);
  1034. }
  1035. }
  1036. if (oldChildren !== null && newChildren !== null) {
  1037. updateChildren(elm, oldChildren, newVNode2, newChildren, isInitialRender);
  1038. } else if (newChildren !== null) {
  1039. if (oldVNode.$text$ !== null) {
  1040. elm.textContent = "";
  1041. }
  1042. addVnodes(elm, null, newVNode2, newChildren, 0, newChildren.length - 1);
  1043. } else if (
  1044. // don't do this on initial render as it can cause non-hydrated content to be removed
  1045. !isInitialRender && BUILD.updatable && oldChildren !== null
  1046. ) {
  1047. removeVnodes(oldChildren, 0, oldChildren.length - 1);
  1048. }
  1049. if (isSvgMode && tag === "svg") {
  1050. isSvgMode = false;
  1051. }
  1052. } else if ((defaultHolder = elm["s-cr"])) {
  1053. defaultHolder.parentNode.textContent = text;
  1054. } else if (oldVNode.$text$ !== text) {
  1055. elm.data = text;
  1056. }
  1057. };
  1058. var updateFallbackSlotVisibility = (elm) => {
  1059. const childNodes = elm.childNodes;
  1060. for (const childNode of childNodes) {
  1061. if (childNode.nodeType === 1 /* ElementNode */) {
  1062. if (childNode["s-sr"]) {
  1063. const slotName = childNode["s-sn"];
  1064. childNode.hidden = false;
  1065. for (const siblingNode of childNodes) {
  1066. if (siblingNode !== childNode) {
  1067. if (siblingNode["s-hn"] !== childNode["s-hn"] || slotName !== "") {
  1068. if (siblingNode.nodeType === 1 /* ElementNode */ && (slotName === siblingNode.getAttribute("slot") || slotName === siblingNode["s-sn"]) || siblingNode.nodeType === 3 /* TextNode */ && slotName === siblingNode["s-sn"]) {
  1069. childNode.hidden = true;
  1070. break;
  1071. }
  1072. } else {
  1073. if (siblingNode.nodeType === 1 /* ElementNode */ || siblingNode.nodeType === 3 /* TextNode */ && siblingNode.textContent.trim() !== "") {
  1074. childNode.hidden = true;
  1075. break;
  1076. }
  1077. }
  1078. }
  1079. }
  1080. }
  1081. updateFallbackSlotVisibility(childNode);
  1082. }
  1083. }
  1084. };
  1085. var relocateNodes = [];
  1086. var markSlotContentForRelocation = (elm) => {
  1087. let node;
  1088. let hostContentNodes;
  1089. let j;
  1090. for (const childNode of elm.childNodes) {
  1091. if (childNode["s-sr"] && (node = childNode["s-cr"]) && node.parentNode) {
  1092. hostContentNodes = node.parentNode.childNodes;
  1093. const slotName = childNode["s-sn"];
  1094. for (j = hostContentNodes.length - 1; j >= 0; j--) {
  1095. node = hostContentNodes[j];
  1096. if (!node["s-cn"] && !node["s-nr"] && node["s-hn"] !== childNode["s-hn"] && (!BUILD.experimentalSlotFixes )) {
  1097. if (isNodeLocatedInSlot(node, slotName)) {
  1098. let relocateNodeData = relocateNodes.find((r) => r.$nodeToRelocate$ === node);
  1099. checkSlotFallbackVisibility = true;
  1100. node["s-sn"] = node["s-sn"] || slotName;
  1101. if (relocateNodeData) {
  1102. relocateNodeData.$nodeToRelocate$["s-sh"] = childNode["s-hn"];
  1103. relocateNodeData.$slotRefNode$ = childNode;
  1104. } else {
  1105. node["s-sh"] = childNode["s-hn"];
  1106. relocateNodes.push({
  1107. $slotRefNode$: childNode,
  1108. $nodeToRelocate$: node
  1109. });
  1110. }
  1111. if (node["s-sr"]) {
  1112. relocateNodes.map((relocateNode) => {
  1113. if (isNodeLocatedInSlot(relocateNode.$nodeToRelocate$, node["s-sn"])) {
  1114. relocateNodeData = relocateNodes.find((r) => r.$nodeToRelocate$ === node);
  1115. if (relocateNodeData && !relocateNode.$slotRefNode$) {
  1116. relocateNode.$slotRefNode$ = relocateNodeData.$slotRefNode$;
  1117. }
  1118. }
  1119. });
  1120. }
  1121. } else if (!relocateNodes.some((r) => r.$nodeToRelocate$ === node)) {
  1122. relocateNodes.push({
  1123. $nodeToRelocate$: node
  1124. });
  1125. }
  1126. }
  1127. }
  1128. }
  1129. if (childNode.nodeType === 1 /* ElementNode */) {
  1130. markSlotContentForRelocation(childNode);
  1131. }
  1132. }
  1133. };
  1134. var isNodeLocatedInSlot = (nodeToRelocate, slotName) => {
  1135. if (nodeToRelocate.nodeType === 1 /* ElementNode */) {
  1136. if (nodeToRelocate.getAttribute("slot") === null && slotName === "") {
  1137. return true;
  1138. }
  1139. if (nodeToRelocate.getAttribute("slot") === slotName) {
  1140. return true;
  1141. }
  1142. return false;
  1143. }
  1144. if (nodeToRelocate["s-sn"] === slotName) {
  1145. return true;
  1146. }
  1147. return slotName === "";
  1148. };
  1149. var nullifyVNodeRefs = (vNode) => {
  1150. {
  1151. vNode.$attrs$ && vNode.$attrs$.ref && vNode.$attrs$.ref(null);
  1152. vNode.$children$ && vNode.$children$.map(nullifyVNodeRefs);
  1153. }
  1154. };
  1155. var insertBefore = (parent, newNode, reference) => {
  1156. const inserted = parent == null ? void 0 : parent.insertBefore(newNode, reference);
  1157. {
  1158. updateElementScopeIds(newNode, parent);
  1159. }
  1160. return inserted;
  1161. };
  1162. var findScopeIds = (element) => {
  1163. const scopeIds = [];
  1164. if (element) {
  1165. scopeIds.push(
  1166. ...element["s-scs"] || [],
  1167. element["s-si"],
  1168. element["s-sc"],
  1169. ...findScopeIds(element.parentElement)
  1170. );
  1171. }
  1172. return scopeIds;
  1173. };
  1174. var updateElementScopeIds = (element, parent, iterateChildNodes = false) => {
  1175. var _a;
  1176. if (element && parent && element.nodeType === 1 /* ElementNode */) {
  1177. const scopeIds = new Set(findScopeIds(parent).filter(Boolean));
  1178. if (scopeIds.size) {
  1179. (_a = element.classList) == null ? void 0 : _a.add(...element["s-scs"] = [...scopeIds]);
  1180. if (element["s-ol"] || iterateChildNodes) {
  1181. for (const childNode of Array.from(element.childNodes)) {
  1182. updateElementScopeIds(childNode, element, true);
  1183. }
  1184. }
  1185. }
  1186. }
  1187. };
  1188. var renderVdom = (hostRef, renderFnResults, isInitialLoad = false) => {
  1189. var _a, _b, _c, _d;
  1190. const hostElm = hostRef.$hostElement$;
  1191. const cmpMeta = hostRef.$cmpMeta$;
  1192. const oldVNode = hostRef.$vnode$ || newVNode(null, null);
  1193. const rootVnode = isHost(renderFnResults) ? renderFnResults : h(null, null, renderFnResults);
  1194. hostTagName = hostElm.tagName;
  1195. if (cmpMeta.$attrsToReflect$) {
  1196. rootVnode.$attrs$ = rootVnode.$attrs$ || {};
  1197. cmpMeta.$attrsToReflect$.map(
  1198. ([propName, attribute]) => rootVnode.$attrs$[attribute] = hostElm[propName]
  1199. );
  1200. }
  1201. if (isInitialLoad && rootVnode.$attrs$) {
  1202. for (const key of Object.keys(rootVnode.$attrs$)) {
  1203. if (hostElm.hasAttribute(key) && !["key", "ref", "style", "class"].includes(key)) {
  1204. rootVnode.$attrs$[key] = hostElm[key];
  1205. }
  1206. }
  1207. }
  1208. rootVnode.$tag$ = null;
  1209. rootVnode.$flags$ |= 4 /* isHost */;
  1210. hostRef.$vnode$ = rootVnode;
  1211. rootVnode.$elm$ = oldVNode.$elm$ = hostElm.shadowRoot || hostElm ;
  1212. {
  1213. scopeId = hostElm["s-sc"];
  1214. }
  1215. useNativeShadowDom = (cmpMeta.$flags$ & 1 /* shadowDomEncapsulation */) !== 0;
  1216. {
  1217. contentRef = hostElm["s-cr"];
  1218. checkSlotFallbackVisibility = false;
  1219. }
  1220. patch(oldVNode, rootVnode, isInitialLoad);
  1221. {
  1222. plt.$flags$ |= 1 /* isTmpDisconnected */;
  1223. if (checkSlotRelocate) {
  1224. markSlotContentForRelocation(rootVnode.$elm$);
  1225. for (const relocateData of relocateNodes) {
  1226. const nodeToRelocate = relocateData.$nodeToRelocate$;
  1227. if (!nodeToRelocate["s-ol"]) {
  1228. const orgLocationNode = originalLocationDebugNode(nodeToRelocate) ;
  1229. orgLocationNode["s-nr"] = nodeToRelocate;
  1230. insertBefore(nodeToRelocate.parentNode, nodeToRelocate["s-ol"] = orgLocationNode, nodeToRelocate);
  1231. }
  1232. }
  1233. for (const relocateData of relocateNodes) {
  1234. const nodeToRelocate = relocateData.$nodeToRelocate$;
  1235. const slotRefNode = relocateData.$slotRefNode$;
  1236. if (slotRefNode) {
  1237. const parentNodeRef = slotRefNode.parentNode;
  1238. let insertBeforeNode = slotRefNode.nextSibling;
  1239. {
  1240. let orgLocationNode = (_a = nodeToRelocate["s-ol"]) == null ? void 0 : _a.previousSibling;
  1241. while (orgLocationNode) {
  1242. let refNode = (_b = orgLocationNode["s-nr"]) != null ? _b : null;
  1243. if (refNode && refNode["s-sn"] === nodeToRelocate["s-sn"] && parentNodeRef === refNode.parentNode) {
  1244. refNode = refNode.nextSibling;
  1245. while (refNode === nodeToRelocate || (refNode == null ? void 0 : refNode["s-sr"])) {
  1246. refNode = refNode == null ? void 0 : refNode.nextSibling;
  1247. }
  1248. if (!refNode || !refNode["s-nr"]) {
  1249. insertBeforeNode = refNode;
  1250. break;
  1251. }
  1252. }
  1253. orgLocationNode = orgLocationNode.previousSibling;
  1254. }
  1255. }
  1256. if (!insertBeforeNode && parentNodeRef !== nodeToRelocate.parentNode || nodeToRelocate.nextSibling !== insertBeforeNode) {
  1257. if (nodeToRelocate !== insertBeforeNode) {
  1258. if (!nodeToRelocate["s-hn"] && nodeToRelocate["s-ol"]) {
  1259. nodeToRelocate["s-hn"] = nodeToRelocate["s-ol"].parentNode.nodeName;
  1260. }
  1261. insertBefore(parentNodeRef, nodeToRelocate, insertBeforeNode);
  1262. if (nodeToRelocate.nodeType === 1 /* ElementNode */) {
  1263. nodeToRelocate.hidden = (_c = nodeToRelocate["s-ih"]) != null ? _c : false;
  1264. }
  1265. }
  1266. }
  1267. nodeToRelocate && typeof slotRefNode["s-rf"] === "function" && slotRefNode["s-rf"](nodeToRelocate);
  1268. } else {
  1269. if (nodeToRelocate.nodeType === 1 /* ElementNode */) {
  1270. if (isInitialLoad) {
  1271. nodeToRelocate["s-ih"] = (_d = nodeToRelocate.hidden) != null ? _d : false;
  1272. }
  1273. nodeToRelocate.hidden = true;
  1274. }
  1275. }
  1276. }
  1277. }
  1278. if (checkSlotFallbackVisibility) {
  1279. updateFallbackSlotVisibility(rootVnode.$elm$);
  1280. }
  1281. plt.$flags$ &= ~1 /* isTmpDisconnected */;
  1282. relocateNodes.length = 0;
  1283. }
  1284. contentRef = void 0;
  1285. };
  1286. var slotReferenceDebugNode = (slotVNode) => doc$1.createComment(
  1287. `<slot${slotVNode.$name$ ? ' name="' + slotVNode.$name$ + '"' : ""}> (host=${hostTagName.toLowerCase()})`
  1288. );
  1289. var originalLocationDebugNode = (nodeToRelocate) => doc$1.createComment(
  1290. `org-location for ` + (nodeToRelocate.localName ? `<${nodeToRelocate.localName}> (host=${nodeToRelocate["s-hn"]})` : `[${nodeToRelocate.textContent}]`)
  1291. );
  1292. // src/runtime/update-component.ts
  1293. var attachToAncestor = (hostRef, ancestorComponent) => {
  1294. if (ancestorComponent && !hostRef.$onRenderResolve$ && ancestorComponent["s-p"]) {
  1295. ancestorComponent["s-p"].push(new Promise((r) => hostRef.$onRenderResolve$ = r));
  1296. }
  1297. };
  1298. var scheduleUpdate = (hostRef, isInitialLoad) => {
  1299. {
  1300. hostRef.$flags$ |= 16 /* isQueuedForUpdate */;
  1301. }
  1302. if (hostRef.$flags$ & 4 /* isWaitingForChildren */) {
  1303. hostRef.$flags$ |= 512 /* needsRerender */;
  1304. return;
  1305. }
  1306. attachToAncestor(hostRef, hostRef.$ancestorComponent$);
  1307. const dispatch = () => dispatchHooks(hostRef, isInitialLoad);
  1308. return writeTask(dispatch) ;
  1309. };
  1310. var dispatchHooks = (hostRef, isInitialLoad) => {
  1311. const elm = hostRef.$hostElement$;
  1312. const endSchedule = createTime("scheduleUpdate", hostRef.$cmpMeta$.$tagName$);
  1313. const instance = hostRef.$lazyInstance$ ;
  1314. if (!instance) {
  1315. throw new Error(
  1316. `Can't render component <${elm.tagName.toLowerCase()} /> with invalid Stencil runtime! Make sure this imported component is compiled with a \`externalRuntime: true\` flag. For more information, please refer to https://stenciljs.com/docs/custom-elements#externalruntime`
  1317. );
  1318. }
  1319. let maybePromise;
  1320. if (isInitialLoad) {
  1321. {
  1322. hostRef.$flags$ |= 256 /* isListenReady */;
  1323. if (hostRef.$queuedListeners$) {
  1324. hostRef.$queuedListeners$.map(([methodName, event]) => safeCall$1(instance, methodName, event));
  1325. hostRef.$queuedListeners$ = void 0;
  1326. }
  1327. }
  1328. {
  1329. maybePromise = safeCall$1(instance, "componentWillLoad");
  1330. }
  1331. }
  1332. {
  1333. maybePromise = enqueue(maybePromise, () => safeCall$1(instance, "componentWillRender"));
  1334. }
  1335. endSchedule();
  1336. return enqueue(maybePromise, () => updateComponent(hostRef, instance, isInitialLoad));
  1337. };
  1338. var enqueue = (maybePromise, fn) => isPromisey(maybePromise) ? maybePromise.then(fn).catch((err2) => {
  1339. console.error(err2);
  1340. fn();
  1341. }) : fn();
  1342. var isPromisey = (maybePromise) => maybePromise instanceof Promise || maybePromise && maybePromise.then && typeof maybePromise.then === "function";
  1343. var updateComponent = async (hostRef, instance, isInitialLoad) => {
  1344. var _a;
  1345. const elm = hostRef.$hostElement$;
  1346. const endUpdate = createTime("update", hostRef.$cmpMeta$.$tagName$);
  1347. const rc = elm["s-rc"];
  1348. if (isInitialLoad) {
  1349. attachStyles(hostRef);
  1350. }
  1351. const endRender = createTime("render", hostRef.$cmpMeta$.$tagName$);
  1352. {
  1353. await callRender(hostRef, instance, elm, isInitialLoad);
  1354. }
  1355. {
  1356. try {
  1357. serverSideConnected(elm);
  1358. if (isInitialLoad) {
  1359. if (hostRef.$cmpMeta$.$flags$ & 1 /* shadowDomEncapsulation */) {
  1360. elm["s-en"] = "";
  1361. } else if (hostRef.$cmpMeta$.$flags$ & 2 /* scopedCssEncapsulation */) {
  1362. elm["s-en"] = "c";
  1363. }
  1364. }
  1365. } catch (e) {
  1366. consoleError(e, elm);
  1367. }
  1368. }
  1369. if (rc) {
  1370. rc.map((cb) => cb());
  1371. elm["s-rc"] = void 0;
  1372. }
  1373. endRender();
  1374. endUpdate();
  1375. {
  1376. const childrenPromises = (_a = elm["s-p"]) != null ? _a : [];
  1377. const postUpdate = () => postUpdateComponent(hostRef);
  1378. if (childrenPromises.length === 0) {
  1379. postUpdate();
  1380. } else {
  1381. Promise.all(childrenPromises).then(postUpdate);
  1382. hostRef.$flags$ |= 4 /* isWaitingForChildren */;
  1383. childrenPromises.length = 0;
  1384. }
  1385. }
  1386. };
  1387. var callRender = (hostRef, instance, elm, isInitialLoad) => {
  1388. try {
  1389. instance = instance.render && instance.render();
  1390. {
  1391. hostRef.$flags$ &= ~16 /* isQueuedForUpdate */;
  1392. }
  1393. {
  1394. hostRef.$flags$ |= 2 /* hasRendered */;
  1395. }
  1396. {
  1397. {
  1398. {
  1399. return Promise.resolve(instance).then((value) => renderVdom(hostRef, value, isInitialLoad));
  1400. }
  1401. }
  1402. }
  1403. } catch (e) {
  1404. consoleError(e, hostRef.$hostElement$);
  1405. }
  1406. return null;
  1407. };
  1408. var postUpdateComponent = (hostRef) => {
  1409. const tagName = hostRef.$cmpMeta$.$tagName$;
  1410. const elm = hostRef.$hostElement$;
  1411. const endPostUpdate = createTime("postUpdate", tagName);
  1412. const instance = hostRef.$lazyInstance$ ;
  1413. const ancestorComponent = hostRef.$ancestorComponent$;
  1414. {
  1415. safeCall$1(instance, "componentDidRender");
  1416. }
  1417. if (!(hostRef.$flags$ & 64 /* hasLoadedComponent */)) {
  1418. hostRef.$flags$ |= 64 /* hasLoadedComponent */;
  1419. {
  1420. addHydratedFlag(elm);
  1421. }
  1422. {
  1423. safeCall$1(instance, "componentDidLoad");
  1424. }
  1425. endPostUpdate();
  1426. {
  1427. hostRef.$onReadyResolve$(elm);
  1428. if (!ancestorComponent) {
  1429. appDidLoad();
  1430. }
  1431. }
  1432. } else {
  1433. {
  1434. safeCall$1(instance, "componentDidUpdate");
  1435. }
  1436. endPostUpdate();
  1437. }
  1438. {
  1439. hostRef.$onInstanceResolve$(elm);
  1440. }
  1441. {
  1442. if (hostRef.$onRenderResolve$) {
  1443. hostRef.$onRenderResolve$();
  1444. hostRef.$onRenderResolve$ = void 0;
  1445. }
  1446. if (hostRef.$flags$ & 512 /* needsRerender */) {
  1447. nextTick(() => scheduleUpdate(hostRef, false));
  1448. }
  1449. hostRef.$flags$ &= ~(4 /* isWaitingForChildren */ | 512 /* needsRerender */);
  1450. }
  1451. };
  1452. var forceUpdate = (ref) => {
  1453. return false;
  1454. };
  1455. var appDidLoad = (who) => {
  1456. {
  1457. addHydratedFlag(doc$1.documentElement);
  1458. }
  1459. nextTick(() => emitEvent(win$2, "appload", { detail: { namespace: NAMESPACE } }));
  1460. };
  1461. var safeCall$1 = (instance, method, arg) => {
  1462. if (instance && instance[method]) {
  1463. try {
  1464. return instance[method](arg);
  1465. } catch (e) {
  1466. consoleError(e);
  1467. }
  1468. }
  1469. return void 0;
  1470. };
  1471. var addHydratedFlag = (elm) => {
  1472. var _a;
  1473. return elm.classList.add((_a = BUILD.hydratedSelectorName) != null ? _a : "hydrated") ;
  1474. };
  1475. var serverSideConnected = (elm) => {
  1476. const children = elm.children;
  1477. if (children != null) {
  1478. for (let i2 = 0, ii = children.length; i2 < ii; i2++) {
  1479. const childElm = children[i2];
  1480. if (typeof childElm.connectedCallback === "function") {
  1481. childElm.connectedCallback();
  1482. }
  1483. serverSideConnected(childElm);
  1484. }
  1485. }
  1486. };
  1487. // src/runtime/set-value.ts
  1488. var getValue = (ref, propName) => getHostRef(ref).$instanceValues$.get(propName);
  1489. var setValue = (ref, propName, newVal, cmpMeta) => {
  1490. const hostRef = getHostRef(ref);
  1491. if (!hostRef) {
  1492. throw new Error(
  1493. `Couldn't find host element for "${cmpMeta.$tagName$}" as it is unknown to this Stencil runtime. This usually happens when integrating a 3rd party Stencil component with another Stencil component or application. Please reach out to the maintainers of the 3rd party Stencil component or report this on the Stencil Discord server (https://chat.stenciljs.com) or comment on this similar [GitHub issue](https://github.com/ionic-team/stencil/issues/5457).`
  1494. );
  1495. }
  1496. const elm = hostRef.$hostElement$ ;
  1497. const oldVal = hostRef.$instanceValues$.get(propName);
  1498. const flags = hostRef.$flags$;
  1499. const instance = hostRef.$lazyInstance$ ;
  1500. newVal = parsePropertyValue(newVal, cmpMeta.$members$[propName][0]);
  1501. const areBothNaN = Number.isNaN(oldVal) && Number.isNaN(newVal);
  1502. const didValueChange = newVal !== oldVal && !areBothNaN;
  1503. if ((!(flags & 8 /* isConstructingInstance */) || oldVal === void 0) && didValueChange) {
  1504. hostRef.$instanceValues$.set(propName, newVal);
  1505. if (instance) {
  1506. if (cmpMeta.$watchers$ && flags & 128 /* isWatchReady */) {
  1507. const watchMethods = cmpMeta.$watchers$[propName];
  1508. if (watchMethods) {
  1509. watchMethods.map((watchMethodName) => {
  1510. try {
  1511. instance[watchMethodName](newVal, oldVal, propName);
  1512. } catch (e) {
  1513. consoleError(e, elm);
  1514. }
  1515. });
  1516. }
  1517. }
  1518. if ((flags & (2 /* hasRendered */ | 16 /* isQueuedForUpdate */)) === 2 /* hasRendered */) {
  1519. scheduleUpdate(hostRef, false);
  1520. }
  1521. }
  1522. }
  1523. };
  1524. // src/runtime/proxy-component.ts
  1525. var proxyComponent = (Cstr, cmpMeta, flags) => {
  1526. var _a, _b;
  1527. const prototype = Cstr.prototype;
  1528. if (cmpMeta.$members$ || (cmpMeta.$watchers$ || Cstr.watchers)) {
  1529. if (Cstr.watchers && !cmpMeta.$watchers$) {
  1530. cmpMeta.$watchers$ = Cstr.watchers;
  1531. }
  1532. const members = Object.entries((_a = cmpMeta.$members$) != null ? _a : {});
  1533. members.map(([memberName, [memberFlags]]) => {
  1534. if ((memberFlags & 31 /* Prop */ || (flags & 2 /* proxyState */) && memberFlags & 32 /* State */)) {
  1535. Object.defineProperty(prototype, memberName, {
  1536. get() {
  1537. return getValue(this, memberName);
  1538. },
  1539. set(newValue) {
  1540. setValue(this, memberName, newValue, cmpMeta);
  1541. },
  1542. configurable: true,
  1543. enumerable: true
  1544. });
  1545. } else if (flags & 1 /* isElementConstructor */ && memberFlags & 64 /* Method */) {
  1546. Object.defineProperty(prototype, memberName, {
  1547. value(...args) {
  1548. var _a2;
  1549. const ref = getHostRef(this);
  1550. return (_a2 = ref == null ? void 0 : ref.$onInstancePromise$) == null ? void 0 : _a2.then(() => {
  1551. var _a3;
  1552. return (_a3 = ref.$lazyInstance$) == null ? void 0 : _a3[memberName](...args);
  1553. });
  1554. }
  1555. });
  1556. }
  1557. });
  1558. if ((flags & 1 /* isElementConstructor */)) {
  1559. const attrNameToPropName = /* @__PURE__ */ new Map();
  1560. prototype.attributeChangedCallback = function(attrName, oldValue, newValue) {
  1561. plt.jmp(() => {
  1562. var _a2;
  1563. const propName = attrNameToPropName.get(attrName);
  1564. if (this.hasOwnProperty(propName)) {
  1565. newValue = this[propName];
  1566. delete this[propName];
  1567. } else if (prototype.hasOwnProperty(propName) && typeof this[propName] === "number" && // cast type to number to avoid TS compiler issues
  1568. this[propName] == newValue) {
  1569. return;
  1570. } else if (propName == null) {
  1571. const hostRef = getHostRef(this);
  1572. const flags2 = hostRef == null ? void 0 : hostRef.$flags$;
  1573. if (flags2 && !(flags2 & 8 /* isConstructingInstance */) && flags2 & 128 /* isWatchReady */ && newValue !== oldValue) {
  1574. const instance = hostRef.$lazyInstance$ ;
  1575. const entry = (_a2 = cmpMeta.$watchers$) == null ? void 0 : _a2[attrName];
  1576. entry == null ? void 0 : entry.forEach((callbackName) => {
  1577. if (instance[callbackName] != null) {
  1578. instance[callbackName].call(instance, newValue, oldValue, attrName);
  1579. }
  1580. });
  1581. }
  1582. return;
  1583. }
  1584. this[propName] = newValue === null && typeof this[propName] === "boolean" ? false : newValue;
  1585. });
  1586. };
  1587. Cstr.observedAttributes = Array.from(
  1588. /* @__PURE__ */ new Set([
  1589. ...Object.keys((_b = cmpMeta.$watchers$) != null ? _b : {}),
  1590. ...members.filter(([_, m]) => m[0] & 15 /* HasAttribute */).map(([propName, m]) => {
  1591. var _a2;
  1592. const attrName = m[1] || propName;
  1593. attrNameToPropName.set(attrName, propName);
  1594. if (m[0] & 512 /* ReflectAttr */) {
  1595. (_a2 = cmpMeta.$attrsToReflect$) == null ? void 0 : _a2.push([propName, attrName]);
  1596. }
  1597. return attrName;
  1598. })
  1599. ])
  1600. );
  1601. }
  1602. }
  1603. return Cstr;
  1604. };
  1605. // src/runtime/initialize-component.ts
  1606. var initializeComponent = async (elm, hostRef, cmpMeta, hmrVersionId) => {
  1607. let Cstr;
  1608. if ((hostRef.$flags$ & 32 /* hasInitializedComponent */) === 0) {
  1609. hostRef.$flags$ |= 32 /* hasInitializedComponent */;
  1610. const bundleId = cmpMeta.$lazyBundleId$;
  1611. if (bundleId) {
  1612. const CstrImport = loadModule(cmpMeta);
  1613. if (CstrImport && "then" in CstrImport) {
  1614. const endLoad = uniqueTime();
  1615. Cstr = await CstrImport;
  1616. endLoad();
  1617. } else {
  1618. Cstr = CstrImport;
  1619. }
  1620. if (!Cstr) {
  1621. throw new Error(`Constructor for "${cmpMeta.$tagName$}#${hostRef.$modeName$}" was not found`);
  1622. }
  1623. if (!Cstr.isProxied) {
  1624. {
  1625. cmpMeta.$watchers$ = Cstr.watchers;
  1626. }
  1627. proxyComponent(Cstr, cmpMeta, 2 /* proxyState */);
  1628. Cstr.isProxied = true;
  1629. }
  1630. const endNewInstance = createTime("createInstance", cmpMeta.$tagName$);
  1631. {
  1632. hostRef.$flags$ |= 8 /* isConstructingInstance */;
  1633. }
  1634. try {
  1635. new Cstr(hostRef);
  1636. } catch (e) {
  1637. consoleError(e);
  1638. }
  1639. {
  1640. hostRef.$flags$ &= ~8 /* isConstructingInstance */;
  1641. }
  1642. {
  1643. hostRef.$flags$ |= 128 /* isWatchReady */;
  1644. }
  1645. endNewInstance();
  1646. fireConnectedCallback(hostRef.$lazyInstance$);
  1647. } else {
  1648. Cstr = elm.constructor;
  1649. const cmpTag = elm.localName;
  1650. customElements.whenDefined(cmpTag).then(() => hostRef.$flags$ |= 128 /* isWatchReady */);
  1651. }
  1652. if (Cstr && Cstr.style) {
  1653. let style;
  1654. if (typeof Cstr.style === "string") {
  1655. style = Cstr.style;
  1656. } else if (typeof Cstr.style !== "string") {
  1657. hostRef.$modeName$ = computeMode(elm);
  1658. if (hostRef.$modeName$) {
  1659. style = Cstr.style[hostRef.$modeName$];
  1660. }
  1661. if (hostRef.$modeName$) {
  1662. elm.setAttribute("s-mode", hostRef.$modeName$);
  1663. }
  1664. }
  1665. const scopeId2 = getScopeId(cmpMeta, hostRef.$modeName$);
  1666. if (!styles.has(scopeId2)) {
  1667. const endRegisterStyles = createTime("registerStyles", cmpMeta.$tagName$);
  1668. registerStyle(scopeId2, style);
  1669. endRegisterStyles();
  1670. }
  1671. }
  1672. }
  1673. const ancestorComponent = hostRef.$ancestorComponent$;
  1674. const schedule = () => scheduleUpdate(hostRef, true);
  1675. if (ancestorComponent && ancestorComponent["s-rc"]) {
  1676. ancestorComponent["s-rc"].push(schedule);
  1677. } else {
  1678. schedule();
  1679. }
  1680. };
  1681. var fireConnectedCallback = (instance) => {
  1682. {
  1683. safeCall$1(instance, "connectedCallback");
  1684. }
  1685. };
  1686. // src/runtime/connected-callback.ts
  1687. var connectedCallback = (elm) => {
  1688. if ((plt.$flags$ & 1 /* isTmpDisconnected */) === 0) {
  1689. const hostRef = getHostRef(elm);
  1690. const cmpMeta = hostRef.$cmpMeta$;
  1691. const endConnected = createTime("connectedCallback", cmpMeta.$tagName$);
  1692. if (!(hostRef.$flags$ & 1 /* hasConnected */)) {
  1693. hostRef.$flags$ |= 1 /* hasConnected */;
  1694. let hostId;
  1695. {
  1696. hostId = elm.getAttribute(HYDRATE_ID);
  1697. if (hostId) {
  1698. if (cmpMeta.$flags$ & 1 /* shadowDomEncapsulation */) {
  1699. const scopeId2 = addStyle(elm.shadowRoot, cmpMeta, elm.getAttribute("s-mode")) ;
  1700. elm.classList.remove(scopeId2 + "-h", scopeId2 + "-s");
  1701. }
  1702. initializeClientHydrate(elm, cmpMeta.$tagName$, hostId, hostRef);
  1703. }
  1704. }
  1705. if (!hostId) {
  1706. {
  1707. setContentReference(elm);
  1708. }
  1709. }
  1710. {
  1711. let ancestorComponent = elm;
  1712. while (ancestorComponent = ancestorComponent.parentNode || ancestorComponent.host) {
  1713. if (ancestorComponent.nodeType === 1 /* ElementNode */ && ancestorComponent.hasAttribute("s-id") && ancestorComponent["s-p"] || ancestorComponent["s-p"]) {
  1714. attachToAncestor(hostRef, hostRef.$ancestorComponent$ = ancestorComponent);
  1715. break;
  1716. }
  1717. }
  1718. }
  1719. {
  1720. initializeComponent(elm, hostRef, cmpMeta);
  1721. }
  1722. } else {
  1723. addHostEventListeners(elm, hostRef, cmpMeta.$listeners$);
  1724. if (hostRef == null ? void 0 : hostRef.$lazyInstance$) {
  1725. fireConnectedCallback(hostRef.$lazyInstance$);
  1726. } else if (hostRef == null ? void 0 : hostRef.$onReadyPromise$) {
  1727. hostRef.$onReadyPromise$.then(() => fireConnectedCallback(hostRef.$lazyInstance$));
  1728. }
  1729. }
  1730. endConnected();
  1731. }
  1732. };
  1733. var setContentReference = (elm) => {
  1734. const contentRefElm = elm["s-cr"] = doc$1.createComment(
  1735. ""
  1736. );
  1737. contentRefElm["s-cn"] = true;
  1738. insertBefore(elm, contentRefElm, elm.firstChild);
  1739. };
  1740. var addHostEventListeners = (elm, hostRef, listeners, attachParentListeners) => {
  1741. if (listeners) {
  1742. listeners.map(([flags, name, method]) => {
  1743. const target = getHostListenerTarget(elm, flags) ;
  1744. const handler = hostListenerProxy(hostRef, method);
  1745. const opts = hostListenerOpts(flags);
  1746. plt.ael(target, name, handler, opts);
  1747. (hostRef.$rmListeners$ = hostRef.$rmListeners$ || []).push(() => plt.rel(target, name, handler, opts));
  1748. });
  1749. }
  1750. };
  1751. var hostListenerProxy = (hostRef, methodName) => (ev) => {
  1752. var _a;
  1753. try {
  1754. {
  1755. if (hostRef.$flags$ & 256 /* isListenReady */) {
  1756. (_a = hostRef.$lazyInstance$) == null ? void 0 : _a[methodName](ev);
  1757. } else {
  1758. (hostRef.$queuedListeners$ = hostRef.$queuedListeners$ || []).push([methodName, ev]);
  1759. }
  1760. }
  1761. } catch (e) {
  1762. consoleError(e);
  1763. }
  1764. };
  1765. var getHostListenerTarget = (elm, flags) => {
  1766. if (flags & 4 /* TargetDocument */) return doc$1;
  1767. if (flags & 8 /* TargetWindow */) return win$2;
  1768. if (flags & 16 /* TargetBody */) return doc$1.body;
  1769. return elm;
  1770. };
  1771. var hostListenerOpts = (flags) => (flags & 2 /* Capture */) !== 0;
  1772. // src/runtime/vdom/vdom-annotations.ts
  1773. var insertVdomAnnotations = (doc2, staticComponents) => {
  1774. if (doc2 != null) {
  1775. const docData = {
  1776. hostIds: 0,
  1777. rootLevelIds: 0,
  1778. staticComponents: new Set(staticComponents)
  1779. };
  1780. const orgLocationNodes = [];
  1781. parseVNodeAnnotations(doc2, doc2.body, docData, orgLocationNodes);
  1782. orgLocationNodes.forEach((orgLocationNode) => {
  1783. var _a;
  1784. if (orgLocationNode != null && orgLocationNode["s-nr"]) {
  1785. const nodeRef = orgLocationNode["s-nr"];
  1786. let hostId = nodeRef["s-host-id"];
  1787. let nodeId = nodeRef["s-node-id"];
  1788. let childId = `${hostId}.${nodeId}`;
  1789. if (hostId == null) {
  1790. hostId = 0;
  1791. docData.rootLevelIds++;
  1792. nodeId = docData.rootLevelIds;
  1793. childId = `${hostId}.${nodeId}`;
  1794. if (nodeRef.nodeType === 1 /* ElementNode */) {
  1795. nodeRef.setAttribute(HYDRATE_CHILD_ID, childId);
  1796. } else if (nodeRef.nodeType === 3 /* TextNode */) {
  1797. if (hostId === 0) {
  1798. const textContent = (_a = nodeRef.nodeValue) == null ? void 0 : _a.trim();
  1799. if (textContent === "") {
  1800. orgLocationNode.remove();
  1801. return;
  1802. }
  1803. }
  1804. const commentBeforeTextNode = doc2.createComment(childId);
  1805. commentBeforeTextNode.nodeValue = `${TEXT_NODE_ID}.${childId}`;
  1806. insertBefore(nodeRef.parentNode, commentBeforeTextNode, nodeRef);
  1807. }
  1808. }
  1809. let orgLocationNodeId = `${ORG_LOCATION_ID}.${childId}`;
  1810. const orgLocationParentNode = orgLocationNode.parentElement;
  1811. if (orgLocationParentNode) {
  1812. if (orgLocationParentNode["s-en"] === "") {
  1813. orgLocationNodeId += `.`;
  1814. } else if (orgLocationParentNode["s-en"] === "c") {
  1815. orgLocationNodeId += `.c`;
  1816. }
  1817. }
  1818. orgLocationNode.nodeValue = orgLocationNodeId;
  1819. }
  1820. });
  1821. }
  1822. };
  1823. var parseVNodeAnnotations = (doc2, node, docData, orgLocationNodes) => {
  1824. var _a;
  1825. if (node == null) {
  1826. return;
  1827. }
  1828. if (node["s-nr"] != null) {
  1829. orgLocationNodes.push(node);
  1830. }
  1831. if (node.nodeType === 1 /* ElementNode */) {
  1832. const childNodes = [...Array.from(node.childNodes), ...Array.from(((_a = node.shadowRoot) == null ? void 0 : _a.childNodes) || [])];
  1833. childNodes.forEach((childNode) => {
  1834. const hostRef = getHostRef(childNode);
  1835. if (hostRef != null && !docData.staticComponents.has(childNode.nodeName.toLowerCase())) {
  1836. const cmpData = {
  1837. nodeIds: 0
  1838. };
  1839. insertVNodeAnnotations(doc2, childNode, hostRef.$vnode$, docData, cmpData);
  1840. }
  1841. parseVNodeAnnotations(doc2, childNode, docData, orgLocationNodes);
  1842. });
  1843. }
  1844. };
  1845. var insertVNodeAnnotations = (doc2, hostElm, vnode, docData, cmpData) => {
  1846. if (vnode != null) {
  1847. const hostId = ++docData.hostIds;
  1848. hostElm.setAttribute(HYDRATE_ID, hostId);
  1849. if (hostElm["s-cr"] != null) {
  1850. hostElm["s-cr"].nodeValue = `${CONTENT_REF_ID}.${hostId}`;
  1851. }
  1852. if (vnode.$children$ != null) {
  1853. const depth = 0;
  1854. vnode.$children$.forEach((vnodeChild, index) => {
  1855. insertChildVNodeAnnotations(doc2, vnodeChild, cmpData, hostId, depth, index);
  1856. });
  1857. }
  1858. if (hostElm && vnode && vnode.$elm$ && !hostElm.hasAttribute(HYDRATE_CHILD_ID)) {
  1859. const parent = hostElm.parentElement;
  1860. if (parent && parent.childNodes) {
  1861. const parentChildNodes = Array.from(parent.childNodes);
  1862. const comment = parentChildNodes.find(
  1863. (node) => node.nodeType === 8 /* CommentNode */ && node["s-sr"]
  1864. );
  1865. if (comment) {
  1866. const index = parentChildNodes.indexOf(hostElm) - 1;
  1867. vnode.$elm$.setAttribute(
  1868. HYDRATE_CHILD_ID,
  1869. `${comment["s-host-id"]}.${comment["s-node-id"]}.0.${index}`
  1870. );
  1871. }
  1872. }
  1873. }
  1874. }
  1875. };
  1876. var insertChildVNodeAnnotations = (doc2, vnodeChild, cmpData, hostId, depth, index) => {
  1877. const childElm = vnodeChild.$elm$;
  1878. if (childElm == null) {
  1879. return;
  1880. }
  1881. const nodeId = cmpData.nodeIds++;
  1882. const childId = `${hostId}.${nodeId}.${depth}.${index}`;
  1883. childElm["s-host-id"] = hostId;
  1884. childElm["s-node-id"] = nodeId;
  1885. if (childElm.nodeType === 1 /* ElementNode */) {
  1886. childElm.setAttribute(HYDRATE_CHILD_ID, childId);
  1887. } else if (childElm.nodeType === 3 /* TextNode */) {
  1888. const parentNode = childElm.parentNode;
  1889. const nodeName = parentNode == null ? void 0 : parentNode.nodeName;
  1890. if (nodeName !== "STYLE" && nodeName !== "SCRIPT") {
  1891. const textNodeId = `${TEXT_NODE_ID}.${childId}`;
  1892. const commentBeforeTextNode = doc2.createComment(textNodeId);
  1893. insertBefore(parentNode, commentBeforeTextNode, childElm);
  1894. }
  1895. } else if (childElm.nodeType === 8 /* CommentNode */) {
  1896. if (childElm["s-sr"]) {
  1897. const slotName = childElm["s-sn"] || "";
  1898. const slotNodeId = `${SLOT_NODE_ID}.${childId}.${slotName}`;
  1899. childElm.nodeValue = slotNodeId;
  1900. }
  1901. }
  1902. if (vnodeChild.$children$ != null) {
  1903. const childDepth = depth + 1;
  1904. vnodeChild.$children$.forEach((vnode, index2) => {
  1905. insertChildVNodeAnnotations(doc2, vnode, cmpData, hostId, childDepth, index2);
  1906. });
  1907. }
  1908. };
  1909. // src/hydrate/platform/h-async.ts
  1910. var hAsync = (nodeName, vnodeData, ...children) => {
  1911. if (Array.isArray(children) && children.length > 0) {
  1912. const flatChildren = children.flat(Infinity);
  1913. if (flatChildren.some((child) => child instanceof Promise)) {
  1914. return Promise.all(flatChildren).then((resolvedChildren) => {
  1915. return h(nodeName, vnodeData, ...resolvedChildren);
  1916. }).catch((err2) => {
  1917. return h(nodeName, vnodeData);
  1918. });
  1919. }
  1920. return h(nodeName, vnodeData, ...flatChildren);
  1921. }
  1922. return h(nodeName, vnodeData);
  1923. };
  1924. function proxyHostElement(elm, cmpMeta) {
  1925. if (typeof elm.componentOnReady !== "function") {
  1926. elm.componentOnReady = componentOnReady$1;
  1927. }
  1928. if (typeof elm.forceUpdate !== "function") {
  1929. elm.forceUpdate = forceUpdate2;
  1930. }
  1931. if (!elm.shadowRoot && !!(cmpMeta.$flags$ & 1 /* shadowDomEncapsulation */)) {
  1932. {
  1933. elm.attachShadow({
  1934. mode: "open",
  1935. delegatesFocus: !!(cmpMeta.$flags$ & 16 /* shadowDelegatesFocus */)
  1936. });
  1937. }
  1938. }
  1939. if (cmpMeta.$members$ != null) {
  1940. const hostRef = getHostRef(elm);
  1941. const members = Object.entries(cmpMeta.$members$);
  1942. members.forEach(([memberName, m]) => {
  1943. var _a, _b;
  1944. const memberFlags = m[0];
  1945. if (memberFlags & 31 /* Prop */) {
  1946. const attributeName = m[1] || memberName;
  1947. let attrValue = elm.getAttribute(attributeName);
  1948. if ((attrValue == null ? void 0 : attrValue.startsWith("{")) && attrValue.endsWith("}") || (attrValue == null ? void 0 : attrValue.startsWith("[")) && attrValue.endsWith("]")) {
  1949. try {
  1950. attrValue = JSON.parse(attrValue);
  1951. } catch (e) {
  1952. }
  1953. }
  1954. if (attrValue != null) {
  1955. const parsedAttrValue = parsePropertyValue(attrValue, memberFlags);
  1956. (_a = hostRef == null ? void 0 : hostRef.$instanceValues$) == null ? void 0 : _a.set(memberName, parsedAttrValue);
  1957. }
  1958. const ownValue = elm[memberName];
  1959. if (ownValue !== void 0) {
  1960. (_b = hostRef == null ? void 0 : hostRef.$instanceValues$) == null ? void 0 : _b.set(memberName, ownValue);
  1961. delete elm[memberName];
  1962. }
  1963. Object.defineProperty(elm, memberName, {
  1964. get() {
  1965. return getValue(this, memberName);
  1966. },
  1967. set(newValue) {
  1968. setValue(this, memberName, newValue, cmpMeta);
  1969. },
  1970. configurable: true,
  1971. enumerable: true
  1972. });
  1973. } else if (memberFlags & 64 /* Method */) {
  1974. Object.defineProperty(elm, memberName, {
  1975. value(...args) {
  1976. var _a2;
  1977. const ref = getHostRef(this);
  1978. return (_a2 = ref == null ? void 0 : ref.$onInstancePromise$) == null ? void 0 : _a2.then(() => {
  1979. var _a3;
  1980. return (_a3 = ref == null ? void 0 : ref.$lazyInstance$) == null ? void 0 : _a3[memberName](...args);
  1981. }).catch(consoleError);
  1982. }
  1983. });
  1984. }
  1985. });
  1986. }
  1987. }
  1988. function componentOnReady$1() {
  1989. var _a;
  1990. return (_a = getHostRef(this)) == null ? void 0 : _a.$onReadyPromise$;
  1991. }
  1992. function forceUpdate2() {
  1993. }
  1994. // src/hydrate/platform/hydrate-app.ts
  1995. function hydrateApp(win2, opts, results, afterHydrate, resolve) {
  1996. const connectedElements = /* @__PURE__ */ new Set();
  1997. const createdElements = /* @__PURE__ */ new Set();
  1998. const waitingElements = /* @__PURE__ */ new Set();
  1999. const orgDocumentCreateElement = win2.document.createElement;
  2000. const orgDocumentCreateElementNS = win2.document.createElementNS;
  2001. const resolved2 = Promise.resolve();
  2002. let tmrId;
  2003. let ranCompleted = false;
  2004. function hydratedComplete() {
  2005. globalThis.clearTimeout(tmrId);
  2006. createdElements.clear();
  2007. connectedElements.clear();
  2008. if (!ranCompleted) {
  2009. ranCompleted = true;
  2010. try {
  2011. if (opts.clientHydrateAnnotations) {
  2012. insertVdomAnnotations(win2.document, opts.staticComponents);
  2013. }
  2014. win2.dispatchEvent(new win2.Event("DOMContentLoaded"));
  2015. win2.document.createElement = orgDocumentCreateElement;
  2016. win2.document.createElementNS = orgDocumentCreateElementNS;
  2017. } catch (e) {
  2018. renderCatchError(opts, results, e);
  2019. }
  2020. }
  2021. afterHydrate(win2, opts, results, resolve);
  2022. }
  2023. function hydratedError(err2) {
  2024. renderCatchError(opts, results, err2);
  2025. hydratedComplete();
  2026. }
  2027. function timeoutExceeded() {
  2028. hydratedError(`Hydrate exceeded timeout${waitingOnElementsMsg(waitingElements)}`);
  2029. }
  2030. try {
  2031. let patchedConnectedCallback2 = function() {
  2032. return connectElement2(this);
  2033. }, patchElement2 = function(elm) {
  2034. if (isValidComponent(elm, opts)) {
  2035. const hostRef = getHostRef(elm);
  2036. if (!hostRef) {
  2037. const Cstr = loadModule(
  2038. {
  2039. $tagName$: elm.nodeName.toLowerCase(),
  2040. $flags$: null
  2041. });
  2042. if (Cstr != null && Cstr.cmpMeta != null) {
  2043. createdElements.add(elm);
  2044. elm.connectedCallback = patchedConnectedCallback2;
  2045. registerHost(elm, Cstr.cmpMeta);
  2046. proxyHostElement(elm, Cstr.cmpMeta);
  2047. }
  2048. }
  2049. }
  2050. }, patchChild2 = function(elm) {
  2051. if (elm != null && elm.nodeType === 1) {
  2052. patchElement2(elm);
  2053. const children = elm.children;
  2054. for (let i2 = 0, ii = children.length; i2 < ii; i2++) {
  2055. patchChild2(children[i2]);
  2056. }
  2057. }
  2058. }, connectElement2 = function(elm) {
  2059. createdElements.delete(elm);
  2060. if (isValidComponent(elm, opts) && results.hydratedCount < opts.maxHydrateCount) {
  2061. if (!connectedElements.has(elm) && shouldHydrate(elm)) {
  2062. connectedElements.add(elm);
  2063. return hydrateComponent.call(elm, win2, results, elm.nodeName, elm, waitingElements);
  2064. }
  2065. }
  2066. return resolved2;
  2067. }, waitLoop2 = function() {
  2068. const toConnect = Array.from(createdElements).filter((elm) => elm.parentElement);
  2069. if (toConnect.length > 0) {
  2070. return Promise.all(toConnect.map(connectElement2)).then(waitLoop2);
  2071. }
  2072. return resolved2;
  2073. };
  2074. win2.document.createElement = function patchedCreateElement(tagName) {
  2075. const elm = orgDocumentCreateElement.call(win2.document, tagName);
  2076. patchElement2(elm);
  2077. return elm;
  2078. };
  2079. win2.document.createElementNS = function patchedCreateElement(namespaceURI, tagName) {
  2080. const elm = orgDocumentCreateElementNS.call(win2.document, namespaceURI, tagName);
  2081. patchElement2(elm);
  2082. return elm;
  2083. };
  2084. tmrId = globalThis.setTimeout(timeoutExceeded, opts.timeout);
  2085. plt.$resourcesUrl$ = new URL(opts.resourcesUrl || "./", doc$1.baseURI).href;
  2086. patchChild2(win2.document.body);
  2087. waitLoop2().then(hydratedComplete).catch(hydratedError);
  2088. } catch (e) {
  2089. hydratedError(e);
  2090. }
  2091. }
  2092. async function hydrateComponent(win2, results, tagName, elm, waitingElements) {
  2093. tagName = tagName.toLowerCase();
  2094. const Cstr = loadModule(
  2095. {
  2096. $tagName$: tagName,
  2097. $flags$: null
  2098. });
  2099. if (Cstr != null) {
  2100. const cmpMeta = Cstr.cmpMeta;
  2101. if (cmpMeta != null) {
  2102. waitingElements.add(elm);
  2103. const hostRef = getHostRef(this);
  2104. addHostEventListeners(this, hostRef, cmpMeta.$listeners$);
  2105. try {
  2106. connectedCallback(elm);
  2107. await elm.componentOnReady();
  2108. results.hydratedCount++;
  2109. const ref = getHostRef(elm);
  2110. const modeName = !ref.$modeName$ ? "$" : ref.$modeName$;
  2111. if (!results.components.some((c) => c.tag === tagName && c.mode === modeName)) {
  2112. results.components.push({
  2113. tag: tagName,
  2114. mode: modeName,
  2115. count: 0,
  2116. depth: -1
  2117. });
  2118. }
  2119. } catch (e) {
  2120. win2.console.error(e);
  2121. }
  2122. waitingElements.delete(elm);
  2123. }
  2124. }
  2125. }
  2126. function isValidComponent(elm, opts) {
  2127. if (elm != null && elm.nodeType === 1) {
  2128. const tagName = elm.nodeName;
  2129. if (typeof tagName === "string" && tagName.includes("-")) {
  2130. if (opts.excludeComponents.includes(tagName.toLowerCase())) {
  2131. return false;
  2132. }
  2133. return true;
  2134. }
  2135. }
  2136. return false;
  2137. }
  2138. function shouldHydrate(elm) {
  2139. if (elm.nodeType === 9) {
  2140. return true;
  2141. }
  2142. if (NO_HYDRATE_TAGS.has(elm.nodeName)) {
  2143. return false;
  2144. }
  2145. if (elm.hasAttribute("no-prerender")) {
  2146. return false;
  2147. }
  2148. const parentNode = elm.parentNode;
  2149. if (parentNode == null) {
  2150. return true;
  2151. }
  2152. return shouldHydrate(parentNode);
  2153. }
  2154. var NO_HYDRATE_TAGS = /* @__PURE__ */ new Set([
  2155. "CODE",
  2156. "HEAD",
  2157. "IFRAME",
  2158. "INPUT",
  2159. "OBJECT",
  2160. "OUTPUT",
  2161. "NOSCRIPT",
  2162. "PRE",
  2163. "SCRIPT",
  2164. "SELECT",
  2165. "STYLE",
  2166. "TEMPLATE",
  2167. "TEXTAREA"
  2168. ]);
  2169. function renderCatchError(opts, results, err2) {
  2170. const diagnostic = {
  2171. level: "error",
  2172. type: "build",
  2173. header: "Hydrate Error",
  2174. messageText: "",
  2175. relFilePath: void 0,
  2176. absFilePath: void 0,
  2177. lines: []
  2178. };
  2179. if (opts.url) {
  2180. try {
  2181. const u = new URL(opts.url);
  2182. if (u.pathname !== "/") {
  2183. diagnostic.header += ": " + u.pathname;
  2184. }
  2185. } catch (e) {
  2186. }
  2187. }
  2188. if (err2 != null) {
  2189. if (err2.stack != null) {
  2190. diagnostic.messageText = err2.stack.toString();
  2191. } else if (err2.message != null) {
  2192. diagnostic.messageText = err2.message.toString();
  2193. } else {
  2194. diagnostic.messageText = err2.toString();
  2195. }
  2196. }
  2197. results.diagnostics.push(diagnostic);
  2198. }
  2199. function printTag(elm) {
  2200. let tag = `<${elm.nodeName.toLowerCase()}`;
  2201. if (Array.isArray(elm.attributes)) {
  2202. for (let i2 = 0; i2 < elm.attributes.length; i2++) {
  2203. const attr = elm.attributes[i2];
  2204. tag += ` ${attr.name}`;
  2205. if (attr.value !== "") {
  2206. tag += `="${attr.value}"`;
  2207. }
  2208. }
  2209. }
  2210. tag += `>`;
  2211. return tag;
  2212. }
  2213. function waitingOnElementMsg(waitingElement) {
  2214. let msg = "";
  2215. if (waitingElement) {
  2216. const lines = [];
  2217. msg = " - waiting on:";
  2218. let elm = waitingElement;
  2219. while (elm && elm.nodeType !== 9 && elm.nodeName !== "BODY") {
  2220. lines.unshift(printTag(elm));
  2221. elm = elm.parentElement;
  2222. }
  2223. let indent = "";
  2224. for (const ln of lines) {
  2225. indent += " ";
  2226. msg += `
  2227. ${indent}${ln}`;
  2228. }
  2229. }
  2230. return msg;
  2231. }
  2232. function waitingOnElementsMsg(waitingElements) {
  2233. return Array.from(waitingElements).map(waitingOnElementMsg);
  2234. }
  2235. var cmpModules = /* @__PURE__ */ new Map();
  2236. var getModule = (tagName) => {
  2237. if (typeof tagName === "string") {
  2238. tagName = tagName.toLowerCase();
  2239. const cmpModule = cmpModules.get(tagName);
  2240. if (cmpModule != null) {
  2241. return cmpModule[tagName];
  2242. }
  2243. }
  2244. return null;
  2245. };
  2246. var loadModule = (cmpMeta, _hostRef, _hmrVersionId) => {
  2247. return getModule(cmpMeta.$tagName$);
  2248. };
  2249. var isMemberInElement = (elm, memberName) => {
  2250. if (elm != null) {
  2251. if (memberName in elm) {
  2252. return true;
  2253. }
  2254. const cstr = getModule(elm.nodeName);
  2255. if (cstr != null) {
  2256. const hostRef = cstr;
  2257. if (hostRef != null && hostRef.cmpMeta != null && hostRef.cmpMeta.$members$ != null) {
  2258. return memberName in hostRef.cmpMeta.$members$;
  2259. }
  2260. }
  2261. }
  2262. return false;
  2263. };
  2264. var registerComponents = (Cstrs) => {
  2265. for (const Cstr of Cstrs) {
  2266. const exportName = Cstr.cmpMeta.$tagName$;
  2267. cmpModules.set(exportName, {
  2268. [exportName]: Cstr
  2269. });
  2270. }
  2271. };
  2272. var win$2 = window;
  2273. var doc$1 = win$2.document;
  2274. var readTask = (cb) => {
  2275. nextTick(() => {
  2276. try {
  2277. cb();
  2278. } catch (e) {
  2279. consoleError(e);
  2280. }
  2281. });
  2282. };
  2283. var writeTask = (cb) => {
  2284. nextTick(() => {
  2285. try {
  2286. cb();
  2287. } catch (e) {
  2288. consoleError(e);
  2289. }
  2290. });
  2291. };
  2292. var resolved = /* @__PURE__ */ Promise.resolve();
  2293. var nextTick = (cb) => resolved.then(cb);
  2294. var defaultConsoleError = (e) => {
  2295. if (e != null) {
  2296. console.error(e.stack || e.message || e);
  2297. }
  2298. };
  2299. var consoleError = (e, el) => (defaultConsoleError)(e, el);
  2300. var plt = {
  2301. $flags$: 0,
  2302. $resourcesUrl$: "",
  2303. jmp: (h2) => h2(),
  2304. raf: (h2) => requestAnimationFrame(h2),
  2305. ael: (el, eventName, listener, opts) => el.addEventListener(eventName, listener, opts),
  2306. rel: (el, eventName, listener, opts) => el.removeEventListener(eventName, listener, opts),
  2307. ce: (eventName, opts) => new win$2.CustomEvent(eventName, opts)
  2308. };
  2309. var supportsShadow = BUILD.shadowDom;
  2310. var hostRefs = /* @__PURE__ */ new WeakMap();
  2311. var getHostRef = (ref) => hostRefs.get(ref);
  2312. var registerInstance = (lazyInstance, hostRef) => hostRefs.set(hostRef.$lazyInstance$ = lazyInstance, hostRef);
  2313. var registerHost = (elm, cmpMeta) => {
  2314. const hostRef = {
  2315. $flags$: 0,
  2316. $cmpMeta$: cmpMeta,
  2317. $hostElement$: elm,
  2318. $instanceValues$: /* @__PURE__ */ new Map(),
  2319. $renderCount$: 0
  2320. };
  2321. hostRef.$onInstancePromise$ = new Promise((r) => hostRef.$onInstanceResolve$ = r);
  2322. hostRef.$onReadyPromise$ = new Promise((r) => hostRef.$onReadyResolve$ = r);
  2323. elm["s-p"] = [];
  2324. elm["s-rc"] = [];
  2325. return hostRefs.set(elm, hostRef);
  2326. };
  2327. var Build = {
  2328. isDev: false,
  2329. isBrowser: false,
  2330. isServer: true,
  2331. isTesting: false
  2332. };
  2333. var styles = /* @__PURE__ */ new Map();
  2334. var modeResolutionChain = [];
  2335. // TODO(FW-2832): types
  2336. class Config {
  2337. constructor() {
  2338. this.m = new Map();
  2339. }
  2340. reset(configObj) {
  2341. this.m = new Map(Object.entries(configObj));
  2342. }
  2343. get(key, fallback) {
  2344. const value = this.m.get(key);
  2345. return value !== undefined ? value : fallback;
  2346. }
  2347. getBoolean(key, fallback = false) {
  2348. const val = this.m.get(key);
  2349. if (val === undefined) {
  2350. return fallback;
  2351. }
  2352. if (typeof val === 'string') {
  2353. return val === 'true';
  2354. }
  2355. return !!val;
  2356. }
  2357. getNumber(key, fallback) {
  2358. const val = parseFloat(this.m.get(key));
  2359. return isNaN(val) ? (fallback !== undefined ? fallback : NaN) : val;
  2360. }
  2361. set(key, value) {
  2362. this.m.set(key, value);
  2363. }
  2364. }
  2365. const config = /*@__PURE__*/ new Config();
  2366. var LogLevel;
  2367. (function (LogLevel) {
  2368. LogLevel["OFF"] = "OFF";
  2369. LogLevel["ERROR"] = "ERROR";
  2370. LogLevel["WARN"] = "WARN";
  2371. })(LogLevel || (LogLevel = {}));
  2372. /**
  2373. * Logs a warning to the console with an Ionic prefix
  2374. * to indicate the library that is warning the developer.
  2375. *
  2376. * @param message - The string message to be logged to the console.
  2377. */
  2378. const printIonWarning = (message, ...params) => {
  2379. const logLevel = config.get('logLevel', LogLevel.WARN);
  2380. if ([LogLevel.WARN].includes(logLevel)) {
  2381. return console.warn(`[Ionic Warning]: ${message}`, ...params);
  2382. }
  2383. };
  2384. /**
  2385. * Logs an error to the console with an Ionic prefix
  2386. * to indicate the library that is warning the developer.
  2387. *
  2388. * @param message - The string message to be logged to the console.
  2389. * @param params - Additional arguments to supply to the console.error.
  2390. */
  2391. const printIonError = (message, ...params) => {
  2392. const logLevel = config.get('logLevel', LogLevel.ERROR);
  2393. if ([LogLevel.ERROR, LogLevel.WARN].includes(logLevel)) {
  2394. return console.error(`[Ionic Error]: ${message}`, ...params);
  2395. }
  2396. };
  2397. /**
  2398. * Prints an error informing developers that an implementation requires an element to be used
  2399. * within a specific selector.
  2400. *
  2401. * @param el The web component element this is requiring the element.
  2402. * @param targetSelectors The selector or selectors that were not found.
  2403. */
  2404. const printRequiredElementError = (el, ...targetSelectors) => {
  2405. return console.error(`<${el.tagName.toLowerCase()}> must be used inside ${targetSelectors.join(' or ')}.`);
  2406. };
  2407. const transitionEndAsync = (el, expectedDuration = 0) => {
  2408. return new Promise((resolve) => {
  2409. transitionEnd(el, expectedDuration, resolve);
  2410. });
  2411. };
  2412. /**
  2413. * Allows developer to wait for a transition
  2414. * to finish and fallback to a timer if the
  2415. * transition is cancelled or otherwise
  2416. * never finishes. Also see transitionEndAsync
  2417. * which is an await-able version of this.
  2418. */
  2419. const transitionEnd = (el, expectedDuration = 0, callback) => {
  2420. let unRegTrans;
  2421. let animationTimeout;
  2422. const opts = { passive: true };
  2423. const ANIMATION_FALLBACK_TIMEOUT = 500;
  2424. const unregister = () => {
  2425. if (unRegTrans) {
  2426. unRegTrans();
  2427. }
  2428. };
  2429. const onTransitionEnd = (ev) => {
  2430. if (ev === undefined || el === ev.target) {
  2431. unregister();
  2432. callback(ev);
  2433. }
  2434. };
  2435. if (el) {
  2436. el.addEventListener('webkitTransitionEnd', onTransitionEnd, opts);
  2437. el.addEventListener('transitionend', onTransitionEnd, opts);
  2438. animationTimeout = setTimeout(onTransitionEnd, expectedDuration + ANIMATION_FALLBACK_TIMEOUT);
  2439. unRegTrans = () => {
  2440. if (animationTimeout !== undefined) {
  2441. clearTimeout(animationTimeout);
  2442. animationTimeout = undefined;
  2443. }
  2444. el.removeEventListener('webkitTransitionEnd', onTransitionEnd, opts);
  2445. el.removeEventListener('transitionend', onTransitionEnd, opts);
  2446. };
  2447. }
  2448. return unregister;
  2449. };
  2450. /**
  2451. * Waits for a component to be ready for
  2452. * both custom element and non-custom element builds.
  2453. * If non-custom element build, el.componentOnReady
  2454. * will be used.
  2455. * For custom element builds, we wait a frame
  2456. * so that the inner contents of the component
  2457. * have a chance to render.
  2458. *
  2459. * Use this utility rather than calling
  2460. * el.componentOnReady yourself.
  2461. */
  2462. const componentOnReady = (el, callback) => {
  2463. if (el.componentOnReady) {
  2464. // eslint-disable-next-line custom-rules/no-component-on-ready-method
  2465. el.componentOnReady().then((resolvedEl) => callback(resolvedEl));
  2466. }
  2467. else {
  2468. raf(() => callback(el));
  2469. }
  2470. };
  2471. /**
  2472. * This functions checks if a Stencil component is using
  2473. * the lazy loaded build of Stencil. Returns `true` if
  2474. * the component is lazy loaded. Returns `false` otherwise.
  2475. */
  2476. const hasLazyBuild = (stencilEl) => {
  2477. return stencilEl.componentOnReady !== undefined;
  2478. };
  2479. /**
  2480. * Elements inside of web components sometimes need to inherit global attributes
  2481. * set on the host. For example, the inner input in `ion-input` should inherit
  2482. * the `title` attribute that developers set directly on `ion-input`. This
  2483. * helper function should be called in componentWillLoad and assigned to a variable
  2484. * that is later used in the render function.
  2485. *
  2486. * This does not need to be reactive as changing attributes on the host element
  2487. * does not trigger a re-render.
  2488. */
  2489. const inheritAttributes$1 = (el, attributes = []) => {
  2490. const attributeObject = {};
  2491. attributes.forEach((attr) => {
  2492. if (el.hasAttribute(attr)) {
  2493. const value = el.getAttribute(attr);
  2494. if (value !== null) {
  2495. attributeObject[attr] = el.getAttribute(attr);
  2496. }
  2497. el.removeAttribute(attr);
  2498. }
  2499. });
  2500. return attributeObject;
  2501. };
  2502. /**
  2503. * List of available ARIA attributes + `role`.
  2504. * Removed deprecated attributes.
  2505. * https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes
  2506. */
  2507. const ariaAttributes = [
  2508. 'role',
  2509. 'aria-activedescendant',
  2510. 'aria-atomic',
  2511. 'aria-autocomplete',
  2512. 'aria-braillelabel',
  2513. 'aria-brailleroledescription',
  2514. 'aria-busy',
  2515. 'aria-checked',
  2516. 'aria-colcount',
  2517. 'aria-colindex',
  2518. 'aria-colindextext',
  2519. 'aria-colspan',
  2520. 'aria-controls',
  2521. 'aria-current',
  2522. 'aria-describedby',
  2523. 'aria-description',
  2524. 'aria-details',
  2525. 'aria-disabled',
  2526. 'aria-errormessage',
  2527. 'aria-expanded',
  2528. 'aria-flowto',
  2529. 'aria-haspopup',
  2530. 'aria-hidden',
  2531. 'aria-invalid',
  2532. 'aria-keyshortcuts',
  2533. 'aria-label',
  2534. 'aria-labelledby',
  2535. 'aria-level',
  2536. 'aria-live',
  2537. 'aria-multiline',
  2538. 'aria-multiselectable',
  2539. 'aria-orientation',
  2540. 'aria-owns',
  2541. 'aria-placeholder',
  2542. 'aria-posinset',
  2543. 'aria-pressed',
  2544. 'aria-readonly',
  2545. 'aria-relevant',
  2546. 'aria-required',
  2547. 'aria-roledescription',
  2548. 'aria-rowcount',
  2549. 'aria-rowindex',
  2550. 'aria-rowindextext',
  2551. 'aria-rowspan',
  2552. 'aria-selected',
  2553. 'aria-setsize',
  2554. 'aria-sort',
  2555. 'aria-valuemax',
  2556. 'aria-valuemin',
  2557. 'aria-valuenow',
  2558. 'aria-valuetext',
  2559. ];
  2560. /**
  2561. * Returns an array of aria attributes that should be copied from
  2562. * the shadow host element to a target within the light DOM.
  2563. * @param el The element that the attributes should be copied from.
  2564. * @param ignoreList The list of aria-attributes to ignore reflecting and removing from the host.
  2565. * Use this in instances where we manually specify aria attributes on the `<Host>` element.
  2566. */
  2567. const inheritAriaAttributes = (el, ignoreList) => {
  2568. let attributesToInherit = ariaAttributes;
  2569. if (ignoreList && ignoreList.length > 0) {
  2570. attributesToInherit = attributesToInherit.filter((attr) => !ignoreList.includes(attr));
  2571. }
  2572. return inheritAttributes$1(el, attributesToInherit);
  2573. };
  2574. const addEventListener$1 = (el, eventName, callback, opts) => {
  2575. return el.addEventListener(eventName, callback, opts);
  2576. };
  2577. const removeEventListener = (el, eventName, callback, opts) => {
  2578. return el.removeEventListener(eventName, callback, opts);
  2579. };
  2580. /**
  2581. * Gets the root context of a shadow dom element
  2582. * On newer browsers this will be the shadowRoot,
  2583. * but for older browser this may just be the
  2584. * element itself.
  2585. *
  2586. * Useful for whenever you need to explicitly
  2587. * do "myElement.shadowRoot!.querySelector(...)".
  2588. */
  2589. const getElementRoot = (el, fallback = el) => {
  2590. return el.shadowRoot || fallback;
  2591. };
  2592. /**
  2593. * Patched version of requestAnimationFrame that avoids ngzone
  2594. * Use only when you know ngzone should not run
  2595. */
  2596. const raf = (h) => {
  2597. if (typeof __zone_symbol__requestAnimationFrame === 'function') {
  2598. return __zone_symbol__requestAnimationFrame(h);
  2599. }
  2600. if (typeof requestAnimationFrame === 'function') {
  2601. return requestAnimationFrame(h);
  2602. }
  2603. return setTimeout(h);
  2604. };
  2605. const hasShadowDom = (el) => {
  2606. return !!el.shadowRoot && !!el.attachShadow;
  2607. };
  2608. const focusVisibleElement = (el) => {
  2609. el.focus();
  2610. /**
  2611. * When programmatically focusing an element,
  2612. * the focus-visible utility will not run because
  2613. * it is expecting a keyboard event to have triggered this;
  2614. * however, there are times when we need to manually control
  2615. * this behavior so we call the `setFocus` method on ion-app
  2616. * which will let us explicitly set the elements to focus.
  2617. */
  2618. if (el.classList.contains('ion-focusable')) {
  2619. const app = el.closest('ion-app');
  2620. if (app) {
  2621. app.setFocus([el]);
  2622. }
  2623. }
  2624. };
  2625. /**
  2626. * This method is used to add a hidden input to a host element that contains
  2627. * a Shadow DOM. It does not add the input inside of the Shadow root which
  2628. * allows it to be picked up inside of forms. It should contain the same
  2629. * values as the host element.
  2630. *
  2631. * @param always Add a hidden input even if the container does not use Shadow
  2632. * @param container The element where the input will be added
  2633. * @param name The name of the input
  2634. * @param value The value of the input
  2635. * @param disabled If true, the input is disabled
  2636. */
  2637. const renderHiddenInput = (always, container, name, value, disabled) => {
  2638. if (always || hasShadowDom(container)) {
  2639. let input = container.querySelector('input.aux-input');
  2640. if (!input) {
  2641. input = container.ownerDocument.createElement('input');
  2642. input.type = 'hidden';
  2643. input.classList.add('aux-input');
  2644. container.appendChild(input);
  2645. }
  2646. input.disabled = disabled;
  2647. input.name = name;
  2648. input.value = value || '';
  2649. }
  2650. };
  2651. const clamp = (min, n, max) => {
  2652. return Math.max(min, Math.min(n, max));
  2653. };
  2654. const assert = (actual, reason) => {
  2655. if (!actual) {
  2656. const message = 'ASSERT: ' + reason;
  2657. printIonError(message);
  2658. debugger; // eslint-disable-line
  2659. throw new Error(message);
  2660. }
  2661. };
  2662. /**
  2663. * @hidden
  2664. * Given a side, return if it should be on the end
  2665. * based on the value of dir
  2666. * @param side the side
  2667. * @param isRTL whether the application dir is rtl
  2668. */
  2669. const isEndSide = (side) => {
  2670. const isRTL = document.dir === 'rtl';
  2671. switch (side) {
  2672. case 'start':
  2673. return isRTL;
  2674. case 'end':
  2675. return !isRTL;
  2676. default:
  2677. throw new Error(`"${side}" is not a valid value for [side]. Use "start" or "end" instead.`);
  2678. }
  2679. };
  2680. const debounceEvent = (event, wait) => {
  2681. const original = event._original || event;
  2682. return {
  2683. _original: event,
  2684. emit: debounce(original.emit.bind(original), wait),
  2685. };
  2686. };
  2687. const debounce = (func, wait = 0) => {
  2688. let timer;
  2689. return (...args) => {
  2690. clearTimeout(timer);
  2691. timer = setTimeout(func, wait, ...args);
  2692. };
  2693. };
  2694. /**
  2695. * Check whether the two string maps are shallow equal.
  2696. *
  2697. * undefined is treated as an empty map.
  2698. *
  2699. * @returns whether the keys are the same and the values are shallow equal.
  2700. */
  2701. const shallowEqualStringMap = (map1, map2) => {
  2702. map1 !== null && map1 !== void 0 ? map1 : (map1 = {});
  2703. map2 !== null && map2 !== void 0 ? map2 : (map2 = {});
  2704. if (map1 === map2) {
  2705. return true;
  2706. }
  2707. const keys1 = Object.keys(map1);
  2708. if (keys1.length !== Object.keys(map2).length) {
  2709. return false;
  2710. }
  2711. for (const k1 of keys1) {
  2712. if (!(k1 in map2)) {
  2713. return false;
  2714. }
  2715. if (map1[k1] !== map2[k1]) {
  2716. return false;
  2717. }
  2718. }
  2719. return true;
  2720. };
  2721. /**
  2722. * Checks input for usable number. Not NaN and not Infinite.
  2723. */
  2724. const isSafeNumber = (input) => {
  2725. return typeof input === 'number' && !isNaN(input) && isFinite(input);
  2726. };
  2727. /* Ionicons v7.2.2, ES Modules */
  2728. const arrowBackSharp = "data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' class='ionicon' viewBox='0 0 512 512'><path stroke-linecap='square' stroke-miterlimit='10' stroke-width='48' d='M244 400L100 256l144-144M120 256h292' class='ionicon-fill-none'/></svg>";
  2729. const arrowDown = "data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' class='ionicon' viewBox='0 0 512 512'><path stroke-linecap='round' stroke-linejoin='round' stroke-width='48' d='M112 268l144 144 144-144M256 392V100' class='ionicon-fill-none'/></svg>";
  2730. const caretBackSharp = "data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' class='ionicon' viewBox='0 0 512 512'><path d='M368 64L144 256l224 192V64z'/></svg>";
  2731. const caretDownSharp = "data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' class='ionicon' viewBox='0 0 512 512'><path d='M64 144l192 224 192-224H64z'/></svg>";
  2732. const caretUpSharp = "data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' class='ionicon' viewBox='0 0 512 512'><path d='M448 368L256 144 64 368h384z'/></svg>";
  2733. const checkmarkOutline = "data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' class='ionicon' viewBox='0 0 512 512'><path stroke-linecap='round' stroke-linejoin='round' d='M416 128L192 384l-96-96' class='ionicon-fill-none ionicon-stroke-width'/></svg>";
  2734. const chevronBack = "data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' class='ionicon' viewBox='0 0 512 512'><path stroke-linecap='round' stroke-linejoin='round' stroke-width='48' d='M328 112L184 256l144 144' class='ionicon-fill-none'/></svg>";
  2735. const chevronDown = "data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' class='ionicon' viewBox='0 0 512 512'><path stroke-linecap='round' stroke-linejoin='round' stroke-width='48' d='M112 184l144 144 144-144' class='ionicon-fill-none'/></svg>";
  2736. const chevronExpand = "data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' class='ionicon' viewBox='0 0 512 512'><path d='M136 208l120-104 120 104M136 304l120 104 120-104' stroke-width='48' stroke-linecap='round' stroke-linejoin='round' class='ionicon-fill-none'/></svg>";
  2737. const chevronForward = "data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' class='ionicon' viewBox='0 0 512 512'><path stroke-linecap='round' stroke-linejoin='round' stroke-width='48' d='M184 112l144 144-144 144' class='ionicon-fill-none'/></svg>";
  2738. const chevronForwardOutline = "data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' class='ionicon' viewBox='0 0 512 512'><path stroke-linecap='round' stroke-linejoin='round' stroke-width='48' d='M184 112l144 144-144 144' class='ionicon-fill-none'/></svg>";
  2739. const close = "data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' class='ionicon' viewBox='0 0 512 512'><path d='M289.94 256l95-95A24 24 0 00351 127l-95 95-95-95a24 24 0 00-34 34l95 95-95 95a24 24 0 1034 34l95-95 95 95a24 24 0 0034-34z'/></svg>";
  2740. const closeCircle = "data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' class='ionicon' viewBox='0 0 512 512'><path d='M256 48C141.31 48 48 141.31 48 256s93.31 208 208 208 208-93.31 208-208S370.69 48 256 48zm75.31 260.69a16 16 0 11-22.62 22.62L256 278.63l-52.69 52.68a16 16 0 01-22.62-22.62L233.37 256l-52.68-52.69a16 16 0 0122.62-22.62L256 233.37l52.69-52.68a16 16 0 0122.62 22.62L278.63 256z'/></svg>";
  2741. const closeSharp = "data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' class='ionicon' viewBox='0 0 512 512'><path d='M400 145.49L366.51 112 256 222.51 145.49 112 112 145.49 222.51 256 112 366.51 145.49 400 256 289.49 366.51 400 400 366.51 289.49 256 400 145.49z'/></svg>";
  2742. const ellipseOutline = "data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' class='ionicon' viewBox='0 0 512 512'><circle cx='256' cy='256' r='192' stroke-linecap='round' stroke-linejoin='round' class='ionicon-fill-none ionicon-stroke-width'/></svg>";
  2743. const ellipsisHorizontal = "data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' class='ionicon' viewBox='0 0 512 512'><circle cx='256' cy='256' r='48'/><circle cx='416' cy='256' r='48'/><circle cx='96' cy='256' r='48'/></svg>";
  2744. const eye = "data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' class='ionicon' viewBox='0 0 512 512'><circle cx='256' cy='256' r='64'/><path d='M490.84 238.6c-26.46-40.92-60.79-75.68-99.27-100.53C349 110.55 302 96 255.66 96c-42.52 0-84.33 12.15-124.27 36.11-40.73 24.43-77.63 60.12-109.68 106.07a31.92 31.92 0 00-.64 35.54c26.41 41.33 60.4 76.14 98.28 100.65C162 402 207.9 416 255.66 416c46.71 0 93.81-14.43 136.2-41.72 38.46-24.77 72.72-59.66 99.08-100.92a32.2 32.2 0 00-.1-34.76zM256 352a96 96 0 1196-96 96.11 96.11 0 01-96 96z'/></svg>";
  2745. const eyeOff = "data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' class='ionicon' viewBox='0 0 512 512'><path d='M432 448a15.92 15.92 0 01-11.31-4.69l-352-352a16 16 0 0122.62-22.62l352 352A16 16 0 01432 448zM248 315.85l-51.79-51.79a2 2 0 00-3.39 1.69 64.11 64.11 0 0053.49 53.49 2 2 0 001.69-3.39zM264 196.15L315.87 248a2 2 0 003.4-1.69 64.13 64.13 0 00-53.55-53.55 2 2 0 00-1.72 3.39z'/><path d='M491 273.36a32.2 32.2 0 00-.1-34.76c-26.46-40.92-60.79-75.68-99.27-100.53C349 110.55 302 96 255.68 96a226.54 226.54 0 00-71.82 11.79 4 4 0 00-1.56 6.63l47.24 47.24a4 4 0 003.82 1.05 96 96 0 01116 116 4 4 0 001.05 3.81l67.95 68a4 4 0 005.4.24 343.81 343.81 0 0067.24-77.4zM256 352a96 96 0 01-93.3-118.63 4 4 0 00-1.05-3.81l-66.84-66.87a4 4 0 00-5.41-.23c-24.39 20.81-47 46.13-67.67 75.72a31.92 31.92 0 00-.64 35.54c26.41 41.33 60.39 76.14 98.28 100.65C162.06 402 207.92 416 255.68 416a238.22 238.22 0 0072.64-11.55 4 4 0 001.61-6.64l-47.47-47.46a4 4 0 00-3.81-1.05A96 96 0 01256 352z'/></svg>";
  2746. const menuOutline = "data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' class='ionicon' viewBox='0 0 512 512'><path stroke-linecap='round' stroke-miterlimit='10' d='M80 160h352M80 256h352M80 352h352' class='ionicon-fill-none ionicon-stroke-width'/></svg>";
  2747. const menuSharp = "data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' class='ionicon' viewBox='0 0 512 512'><path d='M64 384h384v-42.67H64zm0-106.67h384v-42.66H64zM64 128v42.67h384V128z'/></svg>";
  2748. const removeOutline = "data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' class='ionicon' viewBox='0 0 512 512'><path stroke-linecap='round' stroke-linejoin='round' d='M400 256H112' class='ionicon-fill-none ionicon-stroke-width'/></svg>";
  2749. const reorderThreeOutline = "data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' class='ionicon' viewBox='0 0 512 512'><path stroke-linecap='round' stroke-linejoin='round' d='M96 256h320M96 176h320M96 336h320' class='ionicon-fill-none ionicon-stroke-width'/></svg>";
  2750. const reorderTwoSharp = "data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' class='ionicon' viewBox='0 0 512 512'><path stroke-linecap='square' stroke-linejoin='round' stroke-width='44' d='M118 304h276M118 208h276' class='ionicon-fill-none'/></svg>";
  2751. const searchOutline = "data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' class='ionicon' viewBox='0 0 512 512'><path d='M221.09 64a157.09 157.09 0 10157.09 157.09A157.1 157.1 0 00221.09 64z' stroke-miterlimit='10' class='ionicon-fill-none ionicon-stroke-width'/><path stroke-linecap='round' stroke-miterlimit='10' d='M338.29 338.29L448 448' class='ionicon-fill-none ionicon-stroke-width'/></svg>";
  2752. const searchSharp = "data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' class='ionicon' viewBox='0 0 512 512'><path d='M464 428L339.92 303.9a160.48 160.48 0 0030.72-94.58C370.64 120.37 298.27 48 209.32 48S48 120.37 48 209.32s72.37 161.32 161.32 161.32a160.48 160.48 0 0094.58-30.72L428 464zM209.32 319.69a110.38 110.38 0 11110.37-110.37 110.5 110.5 0 01-110.37 110.37z'/></svg>";
  2753. const getPlatforms = (win) => setupPlatforms(win);
  2754. const isPlatform = (winOrPlatform, platform) => {
  2755. if (typeof winOrPlatform === 'string') {
  2756. platform = winOrPlatform;
  2757. winOrPlatform = undefined;
  2758. }
  2759. return getPlatforms(winOrPlatform).includes(platform);
  2760. };
  2761. const setupPlatforms = (win = window) => {
  2762. if (typeof win === 'undefined') {
  2763. return [];
  2764. }
  2765. win.Ionic = win.Ionic || {};
  2766. let platforms = win.Ionic.platforms;
  2767. if (platforms == null) {
  2768. platforms = win.Ionic.platforms = detectPlatforms(win);
  2769. platforms.forEach((p) => win.document.documentElement.classList.add(`plt-${p}`));
  2770. }
  2771. return platforms;
  2772. };
  2773. const detectPlatforms = (win) => {
  2774. const customPlatformMethods = config.get('platform');
  2775. return Object.keys(PLATFORMS_MAP).filter((p) => {
  2776. const customMethod = customPlatformMethods === null || customPlatformMethods === void 0 ? void 0 : customPlatformMethods[p];
  2777. return typeof customMethod === 'function' ? customMethod(win) : PLATFORMS_MAP[p](win);
  2778. });
  2779. };
  2780. const isMobileWeb = (win) => isMobile(win) && !isHybrid(win);
  2781. const isIpad = (win) => {
  2782. // iOS 12 and below
  2783. if (testUserAgent(win, /iPad/i)) {
  2784. return true;
  2785. }
  2786. // iOS 13+
  2787. if (testUserAgent(win, /Macintosh/i) && isMobile(win)) {
  2788. return true;
  2789. }
  2790. return false;
  2791. };
  2792. const isIphone = (win) => testUserAgent(win, /iPhone/i);
  2793. const isIOS = (win) => testUserAgent(win, /iPhone|iPod/i) || isIpad(win);
  2794. const isAndroid = (win) => testUserAgent(win, /android|sink/i);
  2795. const isAndroidTablet = (win) => {
  2796. return isAndroid(win) && !testUserAgent(win, /mobile/i);
  2797. };
  2798. const isPhablet = (win) => {
  2799. const width = win.innerWidth;
  2800. const height = win.innerHeight;
  2801. const smallest = Math.min(width, height);
  2802. const largest = Math.max(width, height);
  2803. return smallest > 390 && smallest < 520 && largest > 620 && largest < 800;
  2804. };
  2805. const isTablet = (win) => {
  2806. const width = win.innerWidth;
  2807. const height = win.innerHeight;
  2808. const smallest = Math.min(width, height);
  2809. const largest = Math.max(width, height);
  2810. return isIpad(win) || isAndroidTablet(win) || (smallest > 460 && smallest < 820 && largest > 780 && largest < 1400);
  2811. };
  2812. const isMobile = (win) => matchMedia$1(win, '(any-pointer:coarse)');
  2813. const isDesktop = (win) => !isMobile(win);
  2814. const isHybrid = (win) => isCordova(win) || isCapacitorNative(win);
  2815. const isCordova = (win) => !!(win['cordova'] || win['phonegap'] || win['PhoneGap']);
  2816. const isCapacitorNative = (win) => {
  2817. const capacitor = win['Capacitor'];
  2818. // TODO(ROU-11693): Remove when we no longer support Capacitor 2, which does not have isNativePlatform
  2819. return !!((capacitor === null || capacitor === void 0 ? void 0 : capacitor.isNative) || ((capacitor === null || capacitor === void 0 ? void 0 : capacitor.isNativePlatform) && !!capacitor.isNativePlatform()));
  2820. };
  2821. const isElectron = (win) => testUserAgent(win, /electron/i);
  2822. const isPWA = (win) => { var _a; return !!(((_a = win.matchMedia) === null || _a === void 0 ? void 0 : _a.call(win, '(display-mode: standalone)').matches) || win.navigator.standalone); };
  2823. const testUserAgent = (win, expr) => expr.test(win.navigator.userAgent);
  2824. const matchMedia$1 = (win, query) => { var _a; return (_a = win.matchMedia) === null || _a === void 0 ? void 0 : _a.call(win, query).matches; };
  2825. const PLATFORMS_MAP = {
  2826. ipad: isIpad,
  2827. iphone: isIphone,
  2828. ios: isIOS,
  2829. android: isAndroid,
  2830. phablet: isPhablet,
  2831. tablet: isTablet,
  2832. cordova: isCordova,
  2833. capacitor: isCapacitorNative,
  2834. electron: isElectron,
  2835. pwa: isPWA,
  2836. mobile: isMobile,
  2837. mobileweb: isMobileWeb,
  2838. desktop: isDesktop,
  2839. hybrid: isHybrid,
  2840. };
  2841. // TODO(FW-2832): types
  2842. let defaultMode;
  2843. const getIonMode$1 = (ref) => {
  2844. return (ref && getMode(ref)) || defaultMode;
  2845. };
  2846. const accordionIosCss = ":host{display:block;position:relative;width:100%;background-color:var(--ion-background-color, #ffffff);overflow:hidden;z-index:0}:host(.accordion-expanding) ::slotted(ion-item[slot=header]),:host(.accordion-expanded) ::slotted(ion-item[slot=header]){--border-width:0px}:host(.accordion-animated){-webkit-transition:all 300ms cubic-bezier(0.25, 0.8, 0.5, 1);transition:all 300ms cubic-bezier(0.25, 0.8, 0.5, 1)}:host(.accordion-animated) #content{-webkit-transition:max-height 300ms cubic-bezier(0.25, 0.8, 0.5, 1);transition:max-height 300ms cubic-bezier(0.25, 0.8, 0.5, 1)}#content{overflow:hidden;will-change:max-height}:host(.accordion-collapsing) #content{max-height:0 !important}:host(.accordion-collapsed) #content{display:none}:host(.accordion-expanding) #content{max-height:0}:host(.accordion-expanding) #content-wrapper{overflow:auto}:host(.accordion-disabled) #header,:host(.accordion-readonly) #header,:host(.accordion-disabled) #content,:host(.accordion-readonly) #content{pointer-events:none}:host(.accordion-disabled) #header,:host(.accordion-disabled) #content{opacity:0.4}@media (prefers-reduced-motion: reduce){:host,#content{-webkit-transition:none !important;transition:none !important}}:host(.accordion-next) ::slotted(ion-item[slot=header]){--border-width:0.55px 0px 0.55px 0px}";
  2847. var IonAccordionIosStyle0 = accordionIosCss;
  2848. const accordionMdCss = ":host{display:block;position:relative;width:100%;background-color:var(--ion-background-color, #ffffff);overflow:hidden;z-index:0}:host(.accordion-expanding) ::slotted(ion-item[slot=header]),:host(.accordion-expanded) ::slotted(ion-item[slot=header]){--border-width:0px}:host(.accordion-animated){-webkit-transition:all 300ms cubic-bezier(0.25, 0.8, 0.5, 1);transition:all 300ms cubic-bezier(0.25, 0.8, 0.5, 1)}:host(.accordion-animated) #content{-webkit-transition:max-height 300ms cubic-bezier(0.25, 0.8, 0.5, 1);transition:max-height 300ms cubic-bezier(0.25, 0.8, 0.5, 1)}#content{overflow:hidden;will-change:max-height}:host(.accordion-collapsing) #content{max-height:0 !important}:host(.accordion-collapsed) #content{display:none}:host(.accordion-expanding) #content{max-height:0}:host(.accordion-expanding) #content-wrapper{overflow:auto}:host(.accordion-disabled) #header,:host(.accordion-readonly) #header,:host(.accordion-disabled) #content,:host(.accordion-readonly) #content{pointer-events:none}:host(.accordion-disabled) #header,:host(.accordion-disabled) #content{opacity:0.4}@media (prefers-reduced-motion: reduce){:host,#content{-webkit-transition:none !important;transition:none !important}}";
  2849. var IonAccordionMdStyle0 = accordionMdCss;
  2850. /**
  2851. * @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
  2852. *
  2853. * @slot header - Content is placed at the top and is used to
  2854. * expand or collapse the accordion item.
  2855. * @slot content - Content is placed below the header and is
  2856. * shown or hidden based on expanded state.
  2857. *
  2858. * @part header - The wrapper element for the header slot.
  2859. * @part content - The wrapper element for the content slot.
  2860. * @part expanded - The expanded element. Can be used in combination
  2861. * with the `header` and `content` parts (i.e. `::part(header expanded)`).
  2862. */
  2863. class Accordion {
  2864. constructor(hostRef) {
  2865. registerInstance(this, hostRef);
  2866. this.updateListener = () => this.updateState(false);
  2867. this.setItemDefaults = () => {
  2868. const ionItem = this.getSlottedHeaderIonItem();
  2869. if (!ionItem) {
  2870. return;
  2871. }
  2872. /**
  2873. * For a11y purposes, we make
  2874. * the ion-item a button so users
  2875. * can tab to it and use keyboard
  2876. * navigation to get around.
  2877. */
  2878. ionItem.button = true;
  2879. ionItem.detail = false;
  2880. /**
  2881. * By default, the lines in an
  2882. * item should be full here, but
  2883. * only do that if a user has
  2884. * not explicitly overridden them
  2885. */
  2886. if (ionItem.lines === undefined) {
  2887. ionItem.lines = 'full';
  2888. }
  2889. };
  2890. this.getSlottedHeaderIonItem = () => {
  2891. const { headerEl } = this;
  2892. if (!headerEl) {
  2893. return;
  2894. }
  2895. /**
  2896. * Get the first ion-item
  2897. * slotted in the header slot
  2898. */
  2899. const slot = headerEl.querySelector('slot');
  2900. if (!slot) {
  2901. return;
  2902. }
  2903. // This is not defined in unit tests
  2904. if (slot.assignedElements === undefined)
  2905. return;
  2906. return slot.assignedElements().find((el) => el.tagName === 'ION-ITEM');
  2907. };
  2908. this.setAria = (expanded = false) => {
  2909. const ionItem = this.getSlottedHeaderIonItem();
  2910. if (!ionItem) {
  2911. return;
  2912. }
  2913. /**
  2914. * Get the native <button> element inside of
  2915. * ion-item because that is what will be focused
  2916. */
  2917. const root = getElementRoot(ionItem);
  2918. const button = root.querySelector('button');
  2919. if (!button) {
  2920. return;
  2921. }
  2922. button.setAttribute('aria-expanded', `${expanded}`);
  2923. };
  2924. this.slotToggleIcon = () => {
  2925. const ionItem = this.getSlottedHeaderIonItem();
  2926. if (!ionItem) {
  2927. return;
  2928. }
  2929. const { toggleIconSlot, toggleIcon } = this;
  2930. /**
  2931. * Check if there already is a toggle icon.
  2932. * If so, do not add another one.
  2933. */
  2934. const existingToggleIcon = ionItem.querySelector('.ion-accordion-toggle-icon');
  2935. if (existingToggleIcon) {
  2936. return;
  2937. }
  2938. const iconEl = document.createElement('ion-icon');
  2939. iconEl.slot = toggleIconSlot;
  2940. iconEl.lazy = false;
  2941. iconEl.classList.add('ion-accordion-toggle-icon');
  2942. iconEl.icon = toggleIcon;
  2943. iconEl.setAttribute('aria-hidden', 'true');
  2944. ionItem.appendChild(iconEl);
  2945. };
  2946. this.expandAccordion = (initialUpdate = false) => {
  2947. const { contentEl, contentElWrapper } = this;
  2948. if (initialUpdate || contentEl === undefined || contentElWrapper === undefined) {
  2949. this.state = 4 /* AccordionState.Expanded */;
  2950. return;
  2951. }
  2952. if (this.state === 4 /* AccordionState.Expanded */) {
  2953. return;
  2954. }
  2955. if (this.currentRaf !== undefined) {
  2956. cancelAnimationFrame(this.currentRaf);
  2957. }
  2958. if (this.shouldAnimate()) {
  2959. raf(() => {
  2960. this.state = 8 /* AccordionState.Expanding */;
  2961. this.currentRaf = raf(async () => {
  2962. const contentHeight = contentElWrapper.offsetHeight;
  2963. const waitForTransition = transitionEndAsync(contentEl, 2000);
  2964. contentEl.style.setProperty('max-height', `${contentHeight}px`);
  2965. await waitForTransition;
  2966. this.state = 4 /* AccordionState.Expanded */;
  2967. contentEl.style.removeProperty('max-height');
  2968. });
  2969. });
  2970. }
  2971. else {
  2972. this.state = 4 /* AccordionState.Expanded */;
  2973. }
  2974. };
  2975. this.collapseAccordion = (initialUpdate = false) => {
  2976. const { contentEl } = this;
  2977. if (initialUpdate || contentEl === undefined) {
  2978. this.state = 1 /* AccordionState.Collapsed */;
  2979. return;
  2980. }
  2981. if (this.state === 1 /* AccordionState.Collapsed */) {
  2982. return;
  2983. }
  2984. if (this.currentRaf !== undefined) {
  2985. cancelAnimationFrame(this.currentRaf);
  2986. }
  2987. if (this.shouldAnimate()) {
  2988. this.currentRaf = raf(async () => {
  2989. const contentHeight = contentEl.offsetHeight;
  2990. contentEl.style.setProperty('max-height', `${contentHeight}px`);
  2991. raf(async () => {
  2992. const waitForTransition = transitionEndAsync(contentEl, 2000);
  2993. this.state = 2 /* AccordionState.Collapsing */;
  2994. await waitForTransition;
  2995. this.state = 1 /* AccordionState.Collapsed */;
  2996. contentEl.style.removeProperty('max-height');
  2997. });
  2998. });
  2999. }
  3000. else {
  3001. this.state = 1 /* AccordionState.Collapsed */;
  3002. }
  3003. };
  3004. /**
  3005. * Helper function to determine if
  3006. * something should animate.
  3007. * If prefers-reduced-motion is set
  3008. * then we should not animate, regardless
  3009. * of what is set in the config.
  3010. */
  3011. this.shouldAnimate = () => {
  3012. if (typeof window === 'undefined') {
  3013. return false;
  3014. }
  3015. const prefersReducedMotion = matchMedia('(prefers-reduced-motion: reduce)').matches;
  3016. if (prefersReducedMotion) {
  3017. return false;
  3018. }
  3019. const animated = config.get('animated', true);
  3020. if (!animated) {
  3021. return false;
  3022. }
  3023. if (this.accordionGroupEl && !this.accordionGroupEl.animated) {
  3024. return false;
  3025. }
  3026. return true;
  3027. };
  3028. this.updateState = async (initialUpdate = false) => {
  3029. const accordionGroup = this.accordionGroupEl;
  3030. const accordionValue = this.value;
  3031. if (!accordionGroup) {
  3032. return;
  3033. }
  3034. const value = accordionGroup.value;
  3035. const shouldExpand = Array.isArray(value) ? value.includes(accordionValue) : value === accordionValue;
  3036. if (shouldExpand) {
  3037. this.expandAccordion(initialUpdate);
  3038. this.isNext = this.isPrevious = false;
  3039. }
  3040. else {
  3041. this.collapseAccordion(initialUpdate);
  3042. /**
  3043. * When using popout or inset,
  3044. * the collapsed accordion items
  3045. * may need additional border radius
  3046. * applied. Check to see if the
  3047. * next or previous accordion is selected.
  3048. */
  3049. const nextAccordion = this.getNextSibling();
  3050. const nextAccordionValue = nextAccordion === null || nextAccordion === void 0 ? void 0 : nextAccordion.value;
  3051. if (nextAccordionValue !== undefined) {
  3052. this.isPrevious = Array.isArray(value) ? value.includes(nextAccordionValue) : value === nextAccordionValue;
  3053. }
  3054. const previousAccordion = this.getPreviousSibling();
  3055. const previousAccordionValue = previousAccordion === null || previousAccordion === void 0 ? void 0 : previousAccordion.value;
  3056. if (previousAccordionValue !== undefined) {
  3057. this.isNext = Array.isArray(value) ? value.includes(previousAccordionValue) : value === previousAccordionValue;
  3058. }
  3059. }
  3060. };
  3061. this.getNextSibling = () => {
  3062. if (!this.el) {
  3063. return;
  3064. }
  3065. const nextSibling = this.el.nextElementSibling;
  3066. if ((nextSibling === null || nextSibling === void 0 ? void 0 : nextSibling.tagName) !== 'ION-ACCORDION') {
  3067. return;
  3068. }
  3069. return nextSibling;
  3070. };
  3071. this.getPreviousSibling = () => {
  3072. if (!this.el) {
  3073. return;
  3074. }
  3075. const previousSibling = this.el.previousElementSibling;
  3076. if ((previousSibling === null || previousSibling === void 0 ? void 0 : previousSibling.tagName) !== 'ION-ACCORDION') {
  3077. return;
  3078. }
  3079. return previousSibling;
  3080. };
  3081. this.state = 1 /* AccordionState.Collapsed */;
  3082. this.isNext = false;
  3083. this.isPrevious = false;
  3084. this.value = `ion-accordion-${accordionIds++}`;
  3085. this.disabled = false;
  3086. this.readonly = false;
  3087. this.toggleIcon = chevronDown;
  3088. this.toggleIconSlot = 'end';
  3089. }
  3090. valueChanged() {
  3091. this.updateState();
  3092. }
  3093. connectedCallback() {
  3094. var _a;
  3095. const accordionGroupEl = (this.accordionGroupEl = (_a = this.el) === null || _a === void 0 ? void 0 : _a.closest('ion-accordion-group'));
  3096. if (accordionGroupEl) {
  3097. this.updateState(true);
  3098. addEventListener$1(accordionGroupEl, 'ionValueChange', this.updateListener);
  3099. }
  3100. }
  3101. disconnectedCallback() {
  3102. const accordionGroupEl = this.accordionGroupEl;
  3103. if (accordionGroupEl) {
  3104. removeEventListener(accordionGroupEl, 'ionValueChange', this.updateListener);
  3105. }
  3106. }
  3107. componentDidLoad() {
  3108. this.setItemDefaults();
  3109. this.slotToggleIcon();
  3110. /**
  3111. * We need to wait a tick because we
  3112. * just set ionItem.button = true and
  3113. * the button has not have been rendered yet.
  3114. */
  3115. raf(() => {
  3116. /**
  3117. * Set aria label on button inside of ion-item
  3118. * once the inner content has been rendered.
  3119. */
  3120. const expanded = this.state === 4 /* AccordionState.Expanded */ || this.state === 8 /* AccordionState.Expanding */;
  3121. this.setAria(expanded);
  3122. });
  3123. }
  3124. toggleExpanded() {
  3125. const { accordionGroupEl, disabled, readonly, value, state } = this;
  3126. if (disabled || readonly)
  3127. return;
  3128. if (accordionGroupEl) {
  3129. /**
  3130. * Because the accordion group may or may
  3131. * not allow multiple accordions open, we
  3132. * need to request the toggling of this
  3133. * accordion and the accordion group will
  3134. * make the decision on whether or not
  3135. * to allow it.
  3136. */
  3137. const expand = state === 1 /* AccordionState.Collapsed */ || state === 2 /* AccordionState.Collapsing */;
  3138. accordionGroupEl.requestAccordionToggle(value, expand);
  3139. }
  3140. }
  3141. render() {
  3142. const { disabled, readonly } = this;
  3143. const mode = getIonMode$1(this);
  3144. const expanded = this.state === 4 /* AccordionState.Expanded */ || this.state === 8 /* AccordionState.Expanding */;
  3145. const headerPart = expanded ? 'header expanded' : 'header';
  3146. const contentPart = expanded ? 'content expanded' : 'content';
  3147. this.setAria(expanded);
  3148. return (hAsync(Host, { key: '073e1d02c18dcbc20c68648426e87c14750c031d', class: {
  3149. [mode]: true,
  3150. 'accordion-expanding': this.state === 8 /* AccordionState.Expanding */,
  3151. 'accordion-expanded': this.state === 4 /* AccordionState.Expanded */,
  3152. 'accordion-collapsing': this.state === 2 /* AccordionState.Collapsing */,
  3153. 'accordion-collapsed': this.state === 1 /* AccordionState.Collapsed */,
  3154. 'accordion-next': this.isNext,
  3155. 'accordion-previous': this.isPrevious,
  3156. 'accordion-disabled': disabled,
  3157. 'accordion-readonly': readonly,
  3158. 'accordion-animated': this.shouldAnimate(),
  3159. } }, hAsync("div", { key: '9b4cf326de8bb6b4033992903c0c1bfd7eea9bcc', onClick: () => this.toggleExpanded(), id: "header", part: headerPart, "aria-controls": "content", ref: (headerEl) => (this.headerEl = headerEl) }, hAsync("slot", { key: '464c32a37f64655eacf4218284214f5f30b14a1e', name: "header" })), hAsync("div", { key: '8bb52e6a62d7de0106b253201a89a32e79d9a594', id: "content", part: contentPart, role: "region", "aria-labelledby": "header", ref: (contentEl) => (this.contentEl = contentEl) }, hAsync("div", { key: '1d9dfd952ad493754aaeea7a8f625b33c2dd90a0', id: "content-wrapper", ref: (contentElWrapper) => (this.contentElWrapper = contentElWrapper) }, hAsync("slot", { key: '970dfbc55a612d739d0ca3b7b1a08e5c96d0c479', name: "content" })))));
  3160. }
  3161. static get delegatesFocus() { return true; }
  3162. get el() { return getElement(this); }
  3163. static get watchers() { return {
  3164. "value": ["valueChanged"]
  3165. }; }
  3166. static get style() { return {
  3167. ios: IonAccordionIosStyle0,
  3168. md: IonAccordionMdStyle0
  3169. }; }
  3170. static get cmpMeta() { return {
  3171. "$flags$": 57,
  3172. "$tagName$": "ion-accordion",
  3173. "$members$": {
  3174. "value": [1],
  3175. "disabled": [4],
  3176. "readonly": [4],
  3177. "toggleIcon": [1, "toggle-icon"],
  3178. "toggleIconSlot": [1, "toggle-icon-slot"],
  3179. "state": [32],
  3180. "isNext": [32],
  3181. "isPrevious": [32]
  3182. },
  3183. "$listeners$": undefined,
  3184. "$lazyBundleId$": "-",
  3185. "$attrsToReflect$": []
  3186. }; }
  3187. }
  3188. let accordionIds = 0;
  3189. const accordionGroupIosCss = ":host{display:block}:host(.accordion-group-expand-inset){-webkit-margin-start:16px;margin-inline-start:16px;-webkit-margin-end:16px;margin-inline-end:16px;margin-top:16px;margin-bottom:16px}:host(.accordion-group-expand-inset) ::slotted(ion-accordion.accordion-expanding),:host(.accordion-group-expand-inset) ::slotted(ion-accordion.accordion-expanded){border-bottom:none}";
  3190. var IonAccordionGroupIosStyle0 = accordionGroupIosCss;
  3191. const accordionGroupMdCss = ":host{display:block}:host(.accordion-group-expand-inset){-webkit-margin-start:16px;margin-inline-start:16px;-webkit-margin-end:16px;margin-inline-end:16px;margin-top:16px;margin-bottom:16px}:host(.accordion-group-expand-inset) ::slotted(ion-accordion){-webkit-box-shadow:0px 3px 1px -2px rgba(0, 0, 0, 0.2), 0px 2px 2px 0px rgba(0, 0, 0, 0.14), 0px 1px 5px 0px rgba(0, 0, 0, 0.12);box-shadow:0px 3px 1px -2px rgba(0, 0, 0, 0.2), 0px 2px 2px 0px rgba(0, 0, 0, 0.14), 0px 1px 5px 0px rgba(0, 0, 0, 0.12)}:host(.accordion-group-expand-inset) ::slotted(ion-accordion.accordion-expanding),:host(.accordion-group-expand-inset) ::slotted(ion-accordion.accordion-expanded){margin-left:0;margin-right:0;margin-top:16px;margin-bottom:16px;border-radius:6px}:host(.accordion-group-expand-inset) ::slotted(ion-accordion.accordion-previous){border-end-end-radius:6px;border-end-start-radius:6px}:host(.accordion-group-expand-inset) ::slotted(ion-accordion.accordion-next){border-start-start-radius:6px;border-start-end-radius:6px}:host(.accordion-group-expand-inset) ::slotted(ion-accordion):first-of-type{margin-left:0;margin-right:0;margin-top:0;margin-bottom:0}";
  3192. var IonAccordionGroupMdStyle0 = accordionGroupMdCss;
  3193. /**
  3194. * @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
  3195. */
  3196. class AccordionGroup {
  3197. constructor(hostRef) {
  3198. registerInstance(this, hostRef);
  3199. this.ionChange = createEvent(this, "ionChange", 7);
  3200. this.ionValueChange = createEvent(this, "ionValueChange", 7);
  3201. this.animated = true;
  3202. this.multiple = undefined;
  3203. this.value = undefined;
  3204. this.disabled = false;
  3205. this.readonly = false;
  3206. this.expand = 'compact';
  3207. }
  3208. valueChanged() {
  3209. const { value, multiple } = this;
  3210. if (!multiple && Array.isArray(value)) {
  3211. /**
  3212. * We do some processing on the `value` array so
  3213. * that it looks more like an array when logged to
  3214. * the console.
  3215. * Example given ['a', 'b']
  3216. * Default toString() behavior: a,b
  3217. * Custom behavior: ['a', 'b']
  3218. */
  3219. printIonWarning(`[ion-accordion-group] - An array of values was passed, but multiple is "false". This is incorrect usage and may result in unexpected behaviors. To dismiss this warning, pass a string to the "value" property when multiple="false".
  3220. Value Passed: [${value.map((v) => `'${v}'`).join(', ')}]
  3221. `, this.el);
  3222. }
  3223. /**
  3224. * Do not use `value` here as that will be
  3225. * not account for the adjustment we make above.
  3226. */
  3227. this.ionValueChange.emit({ value: this.value });
  3228. }
  3229. async disabledChanged() {
  3230. const { disabled } = this;
  3231. const accordions = await this.getAccordions();
  3232. for (const accordion of accordions) {
  3233. accordion.disabled = disabled;
  3234. }
  3235. }
  3236. async readonlyChanged() {
  3237. const { readonly } = this;
  3238. const accordions = await this.getAccordions();
  3239. for (const accordion of accordions) {
  3240. accordion.readonly = readonly;
  3241. }
  3242. }
  3243. async onKeydown(ev) {
  3244. const activeElement = document.activeElement;
  3245. if (!activeElement) {
  3246. return;
  3247. }
  3248. /**
  3249. * Make sure focus is in the header, not the body, of the accordion. This ensures
  3250. * that if there are any interactable elements in the body, their keyboard
  3251. * interaction doesn't get stolen by the accordion. Example: using up/down keys
  3252. * in ion-textarea.
  3253. */
  3254. const activeAccordionHeader = activeElement.closest('ion-accordion [slot="header"]');
  3255. if (!activeAccordionHeader) {
  3256. return;
  3257. }
  3258. const accordionEl = activeElement.tagName === 'ION-ACCORDION' ? activeElement : activeElement.closest('ion-accordion');
  3259. if (!accordionEl) {
  3260. return;
  3261. }
  3262. const closestGroup = accordionEl.closest('ion-accordion-group');
  3263. if (closestGroup !== this.el) {
  3264. return;
  3265. }
  3266. // If the active accordion is not in the current array of accordions, do not do anything
  3267. const accordions = await this.getAccordions();
  3268. const startingIndex = accordions.findIndex((a) => a === accordionEl);
  3269. if (startingIndex === -1) {
  3270. return;
  3271. }
  3272. let accordion;
  3273. if (ev.key === 'ArrowDown') {
  3274. accordion = this.findNextAccordion(accordions, startingIndex);
  3275. }
  3276. else if (ev.key === 'ArrowUp') {
  3277. accordion = this.findPreviousAccordion(accordions, startingIndex);
  3278. }
  3279. else if (ev.key === 'Home') {
  3280. accordion = accordions[0];
  3281. }
  3282. else if (ev.key === 'End') {
  3283. accordion = accordions[accordions.length - 1];
  3284. }
  3285. if (accordion !== undefined && accordion !== activeElement) {
  3286. accordion.focus();
  3287. }
  3288. }
  3289. async componentDidLoad() {
  3290. if (this.disabled) {
  3291. this.disabledChanged();
  3292. }
  3293. if (this.readonly) {
  3294. this.readonlyChanged();
  3295. }
  3296. /**
  3297. * When binding values in frameworks such as Angular
  3298. * it is possible for the value to be set after the Web Component
  3299. * initializes but before the value watcher is set up in Stencil.
  3300. * As a result, the watcher callback may not be fired.
  3301. * We work around this by manually calling the watcher
  3302. * callback when the component has loaded and the watcher
  3303. * is configured.
  3304. */
  3305. this.valueChanged();
  3306. }
  3307. /**
  3308. * Sets the value property and emits ionChange.
  3309. * This should only be called when the user interacts
  3310. * with the accordion and not for any update
  3311. * to the value property. The exception is when
  3312. * the app sets the value of a single-select
  3313. * accordion group to an array.
  3314. */
  3315. setValue(accordionValue) {
  3316. const value = (this.value = accordionValue);
  3317. this.ionChange.emit({ value });
  3318. }
  3319. /**
  3320. * This method is used to ensure that the value
  3321. * of ion-accordion-group is being set in a valid
  3322. * way. This method should only be called in
  3323. * response to a user generated action.
  3324. * @internal
  3325. */
  3326. async requestAccordionToggle(accordionValue, accordionExpand) {
  3327. const { multiple, value, readonly, disabled } = this;
  3328. if (readonly || disabled) {
  3329. return;
  3330. }
  3331. if (accordionExpand) {
  3332. /**
  3333. * If group accepts multiple values
  3334. * check to see if value is already in
  3335. * in values array. If not, add it
  3336. * to the array.
  3337. */
  3338. if (multiple) {
  3339. const groupValue = value !== null && value !== void 0 ? value : [];
  3340. const processedValue = Array.isArray(groupValue) ? groupValue : [groupValue];
  3341. const valueExists = processedValue.find((v) => v === accordionValue);
  3342. if (valueExists === undefined && accordionValue !== undefined) {
  3343. this.setValue([...processedValue, accordionValue]);
  3344. }
  3345. }
  3346. else {
  3347. this.setValue(accordionValue);
  3348. }
  3349. }
  3350. else {
  3351. /**
  3352. * If collapsing accordion, either filter the value
  3353. * out of the values array or unset the value.
  3354. */
  3355. if (multiple) {
  3356. const groupValue = value !== null && value !== void 0 ? value : [];
  3357. const processedValue = Array.isArray(groupValue) ? groupValue : [groupValue];
  3358. this.setValue(processedValue.filter((v) => v !== accordionValue));
  3359. }
  3360. else {
  3361. this.setValue(undefined);
  3362. }
  3363. }
  3364. }
  3365. findNextAccordion(accordions, startingIndex) {
  3366. const nextAccordion = accordions[startingIndex + 1];
  3367. if (nextAccordion === undefined) {
  3368. return accordions[0];
  3369. }
  3370. return nextAccordion;
  3371. }
  3372. findPreviousAccordion(accordions, startingIndex) {
  3373. const prevAccordion = accordions[startingIndex - 1];
  3374. if (prevAccordion === undefined) {
  3375. return accordions[accordions.length - 1];
  3376. }
  3377. return prevAccordion;
  3378. }
  3379. /**
  3380. * @internal
  3381. */
  3382. async getAccordions() {
  3383. return Array.from(this.el.querySelectorAll(':scope > ion-accordion'));
  3384. }
  3385. render() {
  3386. const { disabled, readonly, expand } = this;
  3387. const mode = getIonMode$1(this);
  3388. return (hAsync(Host, { key: 'd1a79a93179474fbba66fcf11a92f4871dacc975', class: {
  3389. [mode]: true,
  3390. 'accordion-group-disabled': disabled,
  3391. 'accordion-group-readonly': readonly,
  3392. [`accordion-group-expand-${expand}`]: true,
  3393. }, role: "presentation" }, hAsync("slot", { key: 'e6b8954b686d1fbb4fc92adb07fddc97a24b0a31' })));
  3394. }
  3395. get el() { return getElement(this); }
  3396. static get watchers() { return {
  3397. "value": ["valueChanged"],
  3398. "disabled": ["disabledChanged"],
  3399. "readonly": ["readonlyChanged"]
  3400. }; }
  3401. static get style() { return {
  3402. ios: IonAccordionGroupIosStyle0,
  3403. md: IonAccordionGroupMdStyle0
  3404. }; }
  3405. static get cmpMeta() { return {
  3406. "$flags$": 41,
  3407. "$tagName$": "ion-accordion-group",
  3408. "$members$": {
  3409. "animated": [4],
  3410. "multiple": [4],
  3411. "value": [1025],
  3412. "disabled": [4],
  3413. "readonly": [4],
  3414. "expand": [1],
  3415. "requestAccordionToggle": [64],
  3416. "getAccordions": [64]
  3417. },
  3418. "$listeners$": [[0, "keydown", "onKeydown"]],
  3419. "$lazyBundleId$": "-",
  3420. "$attrsToReflect$": []
  3421. }; }
  3422. }
  3423. const win$1 = typeof window !== 'undefined' ? window : undefined;
  3424. const doc = typeof document !== 'undefined' ? document : undefined;
  3425. const getCapacitor = () => {
  3426. if (win$1 !== undefined) {
  3427. return win$1.Capacitor;
  3428. }
  3429. return undefined;
  3430. };
  3431. var ImpactStyle;
  3432. (function (ImpactStyle) {
  3433. /**
  3434. * A collision between large, heavy user interface elements
  3435. *
  3436. * @since 1.0.0
  3437. */
  3438. ImpactStyle["Heavy"] = "HEAVY";
  3439. /**
  3440. * A collision between moderately sized user interface elements
  3441. *
  3442. * @since 1.0.0
  3443. */
  3444. ImpactStyle["Medium"] = "MEDIUM";
  3445. /**
  3446. * A collision between small, light user interface elements
  3447. *
  3448. * @since 1.0.0
  3449. */
  3450. ImpactStyle["Light"] = "LIGHT";
  3451. })(ImpactStyle || (ImpactStyle = {}));
  3452. var NotificationType;
  3453. (function (NotificationType) {
  3454. /**
  3455. * A notification feedback type indicating that a task has completed successfully
  3456. *
  3457. * @since 1.0.0
  3458. */
  3459. NotificationType["Success"] = "SUCCESS";
  3460. /**
  3461. * A notification feedback type indicating that a task has produced a warning
  3462. *
  3463. * @since 1.0.0
  3464. */
  3465. NotificationType["Warning"] = "WARNING";
  3466. /**
  3467. * A notification feedback type indicating that a task has failed
  3468. *
  3469. * @since 1.0.0
  3470. */
  3471. NotificationType["Error"] = "ERROR";
  3472. })(NotificationType || (NotificationType = {}));
  3473. const HapticEngine = {
  3474. getEngine() {
  3475. const capacitor = getCapacitor();
  3476. if (capacitor === null || capacitor === void 0 ? void 0 : capacitor.isPluginAvailable('Haptics')) {
  3477. // Capacitor
  3478. return capacitor.Plugins.Haptics;
  3479. }
  3480. return undefined;
  3481. },
  3482. available() {
  3483. const engine = this.getEngine();
  3484. if (!engine) {
  3485. return false;
  3486. }
  3487. const capacitor = getCapacitor();
  3488. /**
  3489. * Developers can manually import the
  3490. * Haptics plugin in their app which will cause
  3491. * getEngine to return the Haptics engine. However,
  3492. * the Haptics engine will throw an error if
  3493. * used in a web browser that does not support
  3494. * the Vibrate API. This check avoids that error
  3495. * if the browser does not support the Vibrate API.
  3496. */
  3497. if ((capacitor === null || capacitor === void 0 ? void 0 : capacitor.getPlatform()) === 'web') {
  3498. // eslint-disable-next-line @typescript-eslint/prefer-optional-chain
  3499. return typeof navigator !== 'undefined' && navigator.vibrate !== undefined;
  3500. }
  3501. return true;
  3502. },
  3503. impact(options) {
  3504. const engine = this.getEngine();
  3505. if (!engine) {
  3506. return;
  3507. }
  3508. engine.impact({ style: options.style });
  3509. },
  3510. notification(options) {
  3511. const engine = this.getEngine();
  3512. if (!engine) {
  3513. return;
  3514. }
  3515. engine.notification({ type: options.type });
  3516. },
  3517. selection() {
  3518. this.impact({ style: ImpactStyle.Light });
  3519. },
  3520. selectionStart() {
  3521. const engine = this.getEngine();
  3522. if (!engine) {
  3523. return;
  3524. }
  3525. engine.selectionStart();
  3526. },
  3527. selectionChanged() {
  3528. const engine = this.getEngine();
  3529. if (!engine) {
  3530. return;
  3531. }
  3532. engine.selectionChanged();
  3533. },
  3534. selectionEnd() {
  3535. const engine = this.getEngine();
  3536. if (!engine) {
  3537. return;
  3538. }
  3539. engine.selectionEnd();
  3540. },
  3541. };
  3542. /**
  3543. * Check to see if the Haptic Plugin is available
  3544. * @return Returns `true` or false if the plugin is available
  3545. */
  3546. const hapticAvailable = () => {
  3547. return HapticEngine.available();
  3548. };
  3549. /**
  3550. * Trigger a selection changed haptic event. Good for one-time events
  3551. * (not for gestures)
  3552. */
  3553. const hapticSelection = () => {
  3554. hapticAvailable() && HapticEngine.selection();
  3555. };
  3556. /**
  3557. * Tell the haptic engine that a gesture for a selection change is starting.
  3558. */
  3559. const hapticSelectionStart = () => {
  3560. hapticAvailable() && HapticEngine.selectionStart();
  3561. };
  3562. /**
  3563. * Tell the haptic engine that a selection changed during a gesture.
  3564. */
  3565. const hapticSelectionChanged = () => {
  3566. hapticAvailable() && HapticEngine.selectionChanged();
  3567. };
  3568. /**
  3569. * Tell the haptic engine we are done with a gesture. This needs to be
  3570. * called lest resources are not properly recycled.
  3571. */
  3572. const hapticSelectionEnd = () => {
  3573. hapticAvailable() && HapticEngine.selectionEnd();
  3574. };
  3575. /**
  3576. * Use this to indicate success/failure/warning to the user.
  3577. * options should be of the type `{ style: ImpactStyle.LIGHT }` (or `MEDIUM`/`HEAVY`)
  3578. */
  3579. const hapticImpact = (options) => {
  3580. hapticAvailable() && HapticEngine.impact(options);
  3581. };
  3582. class GestureController {
  3583. constructor() {
  3584. this.gestureId = 0;
  3585. this.requestedStart = new Map();
  3586. this.disabledGestures = new Map();
  3587. this.disabledScroll = new Set();
  3588. }
  3589. /**
  3590. * Creates a gesture delegate based on the GestureConfig passed
  3591. */
  3592. createGesture(config) {
  3593. var _a;
  3594. return new GestureDelegate(this, this.newID(), config.name, (_a = config.priority) !== null && _a !== void 0 ? _a : 0, !!config.disableScroll);
  3595. }
  3596. /**
  3597. * Creates a blocker that will block any other gesture events from firing. Set in the ion-gesture component.
  3598. */
  3599. createBlocker(opts = {}) {
  3600. return new BlockerDelegate(this, this.newID(), opts.disable, !!opts.disableScroll);
  3601. }
  3602. start(gestureName, id, priority) {
  3603. if (!this.canStart(gestureName)) {
  3604. this.requestedStart.delete(id);
  3605. return false;
  3606. }
  3607. this.requestedStart.set(id, priority);
  3608. return true;
  3609. }
  3610. capture(gestureName, id, priority) {
  3611. if (!this.start(gestureName, id, priority)) {
  3612. return false;
  3613. }
  3614. const requestedStart = this.requestedStart;
  3615. let maxPriority = -10000;
  3616. requestedStart.forEach((value) => {
  3617. maxPriority = Math.max(maxPriority, value);
  3618. });
  3619. if (maxPriority === priority) {
  3620. this.capturedId = id;
  3621. requestedStart.clear();
  3622. const event = new CustomEvent('ionGestureCaptured', { detail: { gestureName } });
  3623. document.dispatchEvent(event);
  3624. return true;
  3625. }
  3626. requestedStart.delete(id);
  3627. return false;
  3628. }
  3629. release(id) {
  3630. this.requestedStart.delete(id);
  3631. if (this.capturedId === id) {
  3632. this.capturedId = undefined;
  3633. }
  3634. }
  3635. disableGesture(gestureName, id) {
  3636. let set = this.disabledGestures.get(gestureName);
  3637. if (set === undefined) {
  3638. set = new Set();
  3639. this.disabledGestures.set(gestureName, set);
  3640. }
  3641. set.add(id);
  3642. }
  3643. enableGesture(gestureName, id) {
  3644. const set = this.disabledGestures.get(gestureName);
  3645. if (set !== undefined) {
  3646. set.delete(id);
  3647. }
  3648. }
  3649. disableScroll(id) {
  3650. this.disabledScroll.add(id);
  3651. if (this.disabledScroll.size === 1) {
  3652. document.body.classList.add(BACKDROP_NO_SCROLL);
  3653. }
  3654. }
  3655. enableScroll(id) {
  3656. this.disabledScroll.delete(id);
  3657. if (this.disabledScroll.size === 0) {
  3658. document.body.classList.remove(BACKDROP_NO_SCROLL);
  3659. }
  3660. }
  3661. canStart(gestureName) {
  3662. if (this.capturedId !== undefined) {
  3663. // a gesture already captured
  3664. return false;
  3665. }
  3666. if (this.isDisabled(gestureName)) {
  3667. return false;
  3668. }
  3669. return true;
  3670. }
  3671. isCaptured() {
  3672. return this.capturedId !== undefined;
  3673. }
  3674. isScrollDisabled() {
  3675. return this.disabledScroll.size > 0;
  3676. }
  3677. isDisabled(gestureName) {
  3678. const disabled = this.disabledGestures.get(gestureName);
  3679. if (disabled && disabled.size > 0) {
  3680. return true;
  3681. }
  3682. return false;
  3683. }
  3684. newID() {
  3685. this.gestureId++;
  3686. return this.gestureId;
  3687. }
  3688. }
  3689. class GestureDelegate {
  3690. constructor(ctrl, id, name, priority, disableScroll) {
  3691. this.id = id;
  3692. this.name = name;
  3693. this.disableScroll = disableScroll;
  3694. this.priority = priority * 1000000 + id;
  3695. this.ctrl = ctrl;
  3696. }
  3697. canStart() {
  3698. if (!this.ctrl) {
  3699. return false;
  3700. }
  3701. return this.ctrl.canStart(this.name);
  3702. }
  3703. start() {
  3704. if (!this.ctrl) {
  3705. return false;
  3706. }
  3707. return this.ctrl.start(this.name, this.id, this.priority);
  3708. }
  3709. capture() {
  3710. if (!this.ctrl) {
  3711. return false;
  3712. }
  3713. const captured = this.ctrl.capture(this.name, this.id, this.priority);
  3714. if (captured && this.disableScroll) {
  3715. this.ctrl.disableScroll(this.id);
  3716. }
  3717. return captured;
  3718. }
  3719. release() {
  3720. if (this.ctrl) {
  3721. this.ctrl.release(this.id);
  3722. if (this.disableScroll) {
  3723. this.ctrl.enableScroll(this.id);
  3724. }
  3725. }
  3726. }
  3727. destroy() {
  3728. this.release();
  3729. this.ctrl = undefined;
  3730. }
  3731. }
  3732. class BlockerDelegate {
  3733. constructor(ctrl, id, disable, disableScroll) {
  3734. this.id = id;
  3735. this.disable = disable;
  3736. this.disableScroll = disableScroll;
  3737. this.ctrl = ctrl;
  3738. }
  3739. block() {
  3740. if (!this.ctrl) {
  3741. return;
  3742. }
  3743. if (this.disable) {
  3744. for (const gesture of this.disable) {
  3745. this.ctrl.disableGesture(gesture, this.id);
  3746. }
  3747. }
  3748. if (this.disableScroll) {
  3749. this.ctrl.disableScroll(this.id);
  3750. }
  3751. }
  3752. unblock() {
  3753. if (!this.ctrl) {
  3754. return;
  3755. }
  3756. if (this.disable) {
  3757. for (const gesture of this.disable) {
  3758. this.ctrl.enableGesture(gesture, this.id);
  3759. }
  3760. }
  3761. if (this.disableScroll) {
  3762. this.ctrl.enableScroll(this.id);
  3763. }
  3764. }
  3765. destroy() {
  3766. this.unblock();
  3767. this.ctrl = undefined;
  3768. }
  3769. }
  3770. const BACKDROP_NO_SCROLL = 'backdrop-no-scroll';
  3771. const GESTURE_CONTROLLER = new GestureController();
  3772. const addEventListener = (el, // TODO(FW-2832): type
  3773. eventName, callback, opts) => {
  3774. // use event listener options when supported
  3775. // otherwise it's just a boolean for the "capture" arg
  3776. const listenerOpts = supportsPassive(el)
  3777. ? {
  3778. capture: !!opts.capture,
  3779. passive: !!opts.passive,
  3780. }
  3781. : !!opts.capture;
  3782. let add;
  3783. let remove;
  3784. if (el['__zone_symbol__addEventListener']) {
  3785. add = '__zone_symbol__addEventListener';
  3786. remove = '__zone_symbol__removeEventListener';
  3787. }
  3788. else {
  3789. add = 'addEventListener';
  3790. remove = 'removeEventListener';
  3791. }
  3792. el[add](eventName, callback, listenerOpts);
  3793. return () => {
  3794. el[remove](eventName, callback, listenerOpts);
  3795. };
  3796. };
  3797. const supportsPassive = (node) => {
  3798. if (_sPassive === undefined) {
  3799. try {
  3800. const opts = Object.defineProperty({}, 'passive', {
  3801. get: () => {
  3802. _sPassive = true;
  3803. },
  3804. });
  3805. node.addEventListener('optsTest', () => {
  3806. return;
  3807. }, opts);
  3808. }
  3809. catch (e) {
  3810. _sPassive = false;
  3811. }
  3812. }
  3813. return !!_sPassive;
  3814. };
  3815. let _sPassive;
  3816. const MOUSE_WAIT = 2000;
  3817. // TODO(FW-2832): types
  3818. const createPointerEvents = (el, pointerDown, pointerMove, pointerUp, options) => {
  3819. let rmTouchStart;
  3820. let rmTouchMove;
  3821. let rmTouchEnd;
  3822. let rmTouchCancel;
  3823. let rmMouseStart;
  3824. let rmMouseMove;
  3825. let rmMouseUp;
  3826. let lastTouchEvent = 0;
  3827. const handleTouchStart = (ev) => {
  3828. lastTouchEvent = Date.now() + MOUSE_WAIT;
  3829. if (!pointerDown(ev)) {
  3830. return;
  3831. }
  3832. if (!rmTouchMove && pointerMove) {
  3833. rmTouchMove = addEventListener(el, 'touchmove', pointerMove, options);
  3834. }
  3835. /**
  3836. * Events are dispatched on the element that is tapped and bubble up to
  3837. * the reference element in the gesture. In the event that the element this
  3838. * event was first dispatched on is removed from the DOM, the event will no
  3839. * longer bubble up to our reference element. This leaves the gesture in an
  3840. * unusable state. To account for this, the touchend and touchcancel listeners
  3841. * should be added to the event target so that they still fire even if the target
  3842. * is removed from the DOM.
  3843. */
  3844. if (!rmTouchEnd) {
  3845. rmTouchEnd = addEventListener(ev.target, 'touchend', handleTouchEnd, options);
  3846. }
  3847. if (!rmTouchCancel) {
  3848. rmTouchCancel = addEventListener(ev.target, 'touchcancel', handleTouchEnd, options);
  3849. }
  3850. };
  3851. const handleMouseDown = (ev) => {
  3852. if (lastTouchEvent > Date.now()) {
  3853. return;
  3854. }
  3855. if (!pointerDown(ev)) {
  3856. return;
  3857. }
  3858. if (!rmMouseMove && pointerMove) {
  3859. rmMouseMove = addEventListener(getDocument(el), 'mousemove', pointerMove, options);
  3860. }
  3861. if (!rmMouseUp) {
  3862. rmMouseUp = addEventListener(getDocument(el), 'mouseup', handleMouseUp, options);
  3863. }
  3864. };
  3865. const handleTouchEnd = (ev) => {
  3866. stopTouch();
  3867. if (pointerUp) {
  3868. pointerUp(ev);
  3869. }
  3870. };
  3871. const handleMouseUp = (ev) => {
  3872. stopMouse();
  3873. if (pointerUp) {
  3874. pointerUp(ev);
  3875. }
  3876. };
  3877. const stopTouch = () => {
  3878. if (rmTouchMove) {
  3879. rmTouchMove();
  3880. }
  3881. if (rmTouchEnd) {
  3882. rmTouchEnd();
  3883. }
  3884. if (rmTouchCancel) {
  3885. rmTouchCancel();
  3886. }
  3887. rmTouchMove = rmTouchEnd = rmTouchCancel = undefined;
  3888. };
  3889. const stopMouse = () => {
  3890. if (rmMouseMove) {
  3891. rmMouseMove();
  3892. }
  3893. if (rmMouseUp) {
  3894. rmMouseUp();
  3895. }
  3896. rmMouseMove = rmMouseUp = undefined;
  3897. };
  3898. const stop = () => {
  3899. stopTouch();
  3900. stopMouse();
  3901. };
  3902. const enable = (isEnabled = true) => {
  3903. if (!isEnabled) {
  3904. if (rmTouchStart) {
  3905. rmTouchStart();
  3906. }
  3907. if (rmMouseStart) {
  3908. rmMouseStart();
  3909. }
  3910. rmTouchStart = rmMouseStart = undefined;
  3911. stop();
  3912. }
  3913. else {
  3914. if (!rmTouchStart) {
  3915. rmTouchStart = addEventListener(el, 'touchstart', handleTouchStart, options);
  3916. }
  3917. if (!rmMouseStart) {
  3918. rmMouseStart = addEventListener(el, 'mousedown', handleMouseDown, options);
  3919. }
  3920. }
  3921. };
  3922. const destroy = () => {
  3923. enable(false);
  3924. pointerUp = pointerMove = pointerDown = undefined;
  3925. };
  3926. return {
  3927. enable,
  3928. stop,
  3929. destroy,
  3930. };
  3931. };
  3932. const getDocument = (node) => {
  3933. return node instanceof Document ? node : node.ownerDocument;
  3934. };
  3935. const createPanRecognizer = (direction, thresh, maxAngle) => {
  3936. const radians = maxAngle * (Math.PI / 180);
  3937. const isDirX = direction === 'x';
  3938. const maxCosine = Math.cos(radians);
  3939. const threshold = thresh * thresh;
  3940. let startX = 0;
  3941. let startY = 0;
  3942. let dirty = false;
  3943. let isPan = 0;
  3944. return {
  3945. start(x, y) {
  3946. startX = x;
  3947. startY = y;
  3948. isPan = 0;
  3949. dirty = true;
  3950. },
  3951. detect(x, y) {
  3952. if (!dirty) {
  3953. return false;
  3954. }
  3955. const deltaX = x - startX;
  3956. const deltaY = y - startY;
  3957. const distance = deltaX * deltaX + deltaY * deltaY;
  3958. if (distance < threshold) {
  3959. return false;
  3960. }
  3961. const hypotenuse = Math.sqrt(distance);
  3962. const cosine = (isDirX ? deltaX : deltaY) / hypotenuse;
  3963. if (cosine > maxCosine) {
  3964. isPan = 1;
  3965. }
  3966. else if (cosine < -maxCosine) {
  3967. isPan = -1;
  3968. }
  3969. else {
  3970. isPan = 0;
  3971. }
  3972. dirty = false;
  3973. return true;
  3974. },
  3975. isGesture() {
  3976. return isPan !== 0;
  3977. },
  3978. getDirection() {
  3979. return isPan;
  3980. },
  3981. };
  3982. };
  3983. // TODO(FW-2832): types
  3984. const createGesture = (config) => {
  3985. let hasCapturedPan = false;
  3986. let hasStartedPan = false;
  3987. let hasFiredStart = true;
  3988. let isMoveQueued = false;
  3989. const finalConfig = Object.assign({ disableScroll: false, direction: 'x', gesturePriority: 0, passive: true, maxAngle: 40, threshold: 10 }, config);
  3990. const canStart = finalConfig.canStart;
  3991. const onWillStart = finalConfig.onWillStart;
  3992. const onStart = finalConfig.onStart;
  3993. const onEnd = finalConfig.onEnd;
  3994. const notCaptured = finalConfig.notCaptured;
  3995. const onMove = finalConfig.onMove;
  3996. const threshold = finalConfig.threshold;
  3997. const passive = finalConfig.passive;
  3998. const blurOnStart = finalConfig.blurOnStart;
  3999. const detail = {
  4000. type: 'pan',
  4001. startX: 0,
  4002. startY: 0,
  4003. startTime: 0,
  4004. currentX: 0,
  4005. currentY: 0,
  4006. velocityX: 0,
  4007. velocityY: 0,
  4008. deltaX: 0,
  4009. deltaY: 0,
  4010. currentTime: 0,
  4011. event: undefined,
  4012. data: undefined,
  4013. };
  4014. const pan = createPanRecognizer(finalConfig.direction, finalConfig.threshold, finalConfig.maxAngle);
  4015. const gesture = GESTURE_CONTROLLER.createGesture({
  4016. name: config.gestureName,
  4017. priority: config.gesturePriority,
  4018. disableScroll: config.disableScroll,
  4019. });
  4020. const pointerDown = (ev) => {
  4021. const timeStamp = now(ev);
  4022. if (hasStartedPan || !hasFiredStart) {
  4023. return false;
  4024. }
  4025. updateDetail(ev, detail);
  4026. detail.startX = detail.currentX;
  4027. detail.startY = detail.currentY;
  4028. detail.startTime = detail.currentTime = timeStamp;
  4029. detail.velocityX = detail.velocityY = detail.deltaX = detail.deltaY = 0;
  4030. detail.event = ev;
  4031. // Check if gesture can start
  4032. if (canStart && canStart(detail) === false) {
  4033. return false;
  4034. }
  4035. // Release fallback
  4036. gesture.release();
  4037. // Start gesture
  4038. if (!gesture.start()) {
  4039. return false;
  4040. }
  4041. hasStartedPan = true;
  4042. if (threshold === 0) {
  4043. return tryToCapturePan();
  4044. }
  4045. pan.start(detail.startX, detail.startY);
  4046. return true;
  4047. };
  4048. const pointerMove = (ev) => {
  4049. // fast path, if gesture is currently captured
  4050. // do minimum job to get user-land even dispatched
  4051. if (hasCapturedPan) {
  4052. if (!isMoveQueued && hasFiredStart) {
  4053. isMoveQueued = true;
  4054. calcGestureData(detail, ev);
  4055. requestAnimationFrame(fireOnMove);
  4056. }
  4057. return;
  4058. }
  4059. // gesture is currently being detected
  4060. calcGestureData(detail, ev);
  4061. if (pan.detect(detail.currentX, detail.currentY)) {
  4062. if (!pan.isGesture() || !tryToCapturePan()) {
  4063. abortGesture();
  4064. }
  4065. }
  4066. };
  4067. const fireOnMove = () => {
  4068. // Since fireOnMove is called inside a RAF, onEnd() might be called,
  4069. // we must double check hasCapturedPan
  4070. if (!hasCapturedPan) {
  4071. return;
  4072. }
  4073. isMoveQueued = false;
  4074. if (onMove) {
  4075. onMove(detail);
  4076. }
  4077. };
  4078. const tryToCapturePan = () => {
  4079. if (!gesture.capture()) {
  4080. return false;
  4081. }
  4082. hasCapturedPan = true;
  4083. hasFiredStart = false;
  4084. // reset start position since the real user-land event starts here
  4085. // If the pan detector threshold is big, not resetting the start position
  4086. // will cause a jump in the animation equal to the detector threshold.
  4087. // the array of positions used to calculate the gesture velocity does not
  4088. // need to be cleaned, more points in the positions array always results in a
  4089. // more accurate value of the velocity.
  4090. detail.startX = detail.currentX;
  4091. detail.startY = detail.currentY;
  4092. detail.startTime = detail.currentTime;
  4093. if (onWillStart) {
  4094. onWillStart(detail).then(fireOnStart);
  4095. }
  4096. else {
  4097. fireOnStart();
  4098. }
  4099. return true;
  4100. };
  4101. const blurActiveElement = () => {
  4102. if (typeof document !== 'undefined') {
  4103. const activeElement = document.activeElement;
  4104. if (activeElement === null || activeElement === void 0 ? void 0 : activeElement.blur) {
  4105. activeElement.blur();
  4106. }
  4107. }
  4108. };
  4109. const fireOnStart = () => {
  4110. if (blurOnStart) {
  4111. blurActiveElement();
  4112. }
  4113. if (onStart) {
  4114. onStart(detail);
  4115. }
  4116. hasFiredStart = true;
  4117. };
  4118. const reset = () => {
  4119. hasCapturedPan = false;
  4120. hasStartedPan = false;
  4121. isMoveQueued = false;
  4122. hasFiredStart = true;
  4123. gesture.release();
  4124. };
  4125. // END *************************
  4126. const pointerUp = (ev) => {
  4127. const tmpHasCaptured = hasCapturedPan;
  4128. const tmpHasFiredStart = hasFiredStart;
  4129. reset();
  4130. if (!tmpHasFiredStart) {
  4131. return;
  4132. }
  4133. calcGestureData(detail, ev);
  4134. // Try to capture press
  4135. if (tmpHasCaptured) {
  4136. if (onEnd) {
  4137. onEnd(detail);
  4138. }
  4139. return;
  4140. }
  4141. // Not captured any event
  4142. if (notCaptured) {
  4143. notCaptured(detail);
  4144. }
  4145. };
  4146. const pointerEvents = createPointerEvents(finalConfig.el, pointerDown, pointerMove, pointerUp, {
  4147. capture: false,
  4148. passive,
  4149. });
  4150. const abortGesture = () => {
  4151. reset();
  4152. pointerEvents.stop();
  4153. if (notCaptured) {
  4154. notCaptured(detail);
  4155. }
  4156. };
  4157. return {
  4158. enable(enable = true) {
  4159. if (!enable) {
  4160. if (hasCapturedPan) {
  4161. pointerUp(undefined);
  4162. }
  4163. reset();
  4164. }
  4165. pointerEvents.enable(enable);
  4166. },
  4167. destroy() {
  4168. gesture.destroy();
  4169. pointerEvents.destroy();
  4170. },
  4171. };
  4172. };
  4173. const calcGestureData = (detail, ev) => {
  4174. if (!ev) {
  4175. return;
  4176. }
  4177. const prevX = detail.currentX;
  4178. const prevY = detail.currentY;
  4179. const prevT = detail.currentTime;
  4180. updateDetail(ev, detail);
  4181. const currentX = detail.currentX;
  4182. const currentY = detail.currentY;
  4183. const timestamp = (detail.currentTime = now(ev));
  4184. const timeDelta = timestamp - prevT;
  4185. if (timeDelta > 0 && timeDelta < 100) {
  4186. const velocityX = (currentX - prevX) / timeDelta;
  4187. const velocityY = (currentY - prevY) / timeDelta;
  4188. detail.velocityX = velocityX * 0.7 + detail.velocityX * 0.3;
  4189. detail.velocityY = velocityY * 0.7 + detail.velocityY * 0.3;
  4190. }
  4191. detail.deltaX = currentX - detail.startX;
  4192. detail.deltaY = currentY - detail.startY;
  4193. detail.event = ev;
  4194. };
  4195. const updateDetail = (ev, detail) => {
  4196. // get X coordinates for either a mouse click
  4197. // or a touch depending on the given event
  4198. let x = 0;
  4199. let y = 0;
  4200. if (ev) {
  4201. const changedTouches = ev.changedTouches;
  4202. if (changedTouches && changedTouches.length > 0) {
  4203. const touch = changedTouches[0];
  4204. x = touch.clientX;
  4205. y = touch.clientY;
  4206. }
  4207. else if (ev.pageX !== undefined) {
  4208. x = ev.pageX;
  4209. y = ev.pageY;
  4210. }
  4211. }
  4212. detail.currentX = x;
  4213. detail.currentY = y;
  4214. };
  4215. const now = (ev) => {
  4216. return ev.timeStamp || Date.now();
  4217. };
  4218. var index = /*#__PURE__*/Object.freeze({
  4219. __proto__: null,
  4220. createGesture: createGesture,
  4221. GESTURE_CONTROLLER: GESTURE_CONTROLLER
  4222. });
  4223. const createButtonActiveGesture = (el, isButton) => {
  4224. let currentTouchedButton;
  4225. let initialTouchedButton;
  4226. const activateButtonAtPoint = (x, y, hapticFeedbackFn) => {
  4227. if (typeof document === 'undefined') {
  4228. return;
  4229. }
  4230. const target = document.elementFromPoint(x, y);
  4231. if (!target || !isButton(target) || target.disabled) {
  4232. clearActiveButton();
  4233. return;
  4234. }
  4235. if (target !== currentTouchedButton) {
  4236. clearActiveButton();
  4237. setActiveButton(target, hapticFeedbackFn);
  4238. }
  4239. };
  4240. const setActiveButton = (button, hapticFeedbackFn) => {
  4241. currentTouchedButton = button;
  4242. if (!initialTouchedButton) {
  4243. initialTouchedButton = currentTouchedButton;
  4244. }
  4245. const buttonToModify = currentTouchedButton;
  4246. writeTask(() => buttonToModify.classList.add('ion-activated'));
  4247. hapticFeedbackFn();
  4248. };
  4249. const clearActiveButton = (dispatchClick = false) => {
  4250. if (!currentTouchedButton) {
  4251. return;
  4252. }
  4253. const buttonToModify = currentTouchedButton;
  4254. writeTask(() => buttonToModify.classList.remove('ion-activated'));
  4255. /**
  4256. * Clicking on one button, but releasing on another button
  4257. * does not dispatch a click event in browsers, so we
  4258. * need to do it manually here. Some browsers will
  4259. * dispatch a click if clicking on one button, dragging over
  4260. * another button, and releasing on the original button. In that
  4261. * case, we need to make sure we do not cause a double click there.
  4262. */
  4263. if (dispatchClick && initialTouchedButton !== currentTouchedButton) {
  4264. currentTouchedButton.click();
  4265. }
  4266. currentTouchedButton = undefined;
  4267. };
  4268. return createGesture({
  4269. el,
  4270. gestureName: 'buttonActiveDrag',
  4271. threshold: 0,
  4272. onStart: (ev) => activateButtonAtPoint(ev.currentX, ev.currentY, hapticSelectionStart),
  4273. onMove: (ev) => activateButtonAtPoint(ev.currentX, ev.currentY, hapticSelectionChanged),
  4274. onEnd: () => {
  4275. clearActiveButton(true);
  4276. hapticSelectionEnd();
  4277. initialTouchedButton = undefined;
  4278. },
  4279. });
  4280. };
  4281. /**
  4282. * Creates a lock controller.
  4283. *
  4284. * Claiming a lock means that nothing else can acquire the lock until it is released.
  4285. * This can momentarily prevent execution of code that needs to wait for the earlier code to finish.
  4286. * For example, this can be used to prevent multiple transitions from occurring at the same time.
  4287. */
  4288. const createLockController = () => {
  4289. let waitPromise;
  4290. /**
  4291. * When lock() is called, the lock is claimed.
  4292. * Once a lock has been claimed, it cannot be claimed again until it is released.
  4293. * When this function gets resolved, the lock is released, allowing it to be claimed again.
  4294. *
  4295. * @example ```tsx
  4296. * const unlock = await this.lockController.lock();
  4297. * // do other stuff
  4298. * unlock();
  4299. * ```
  4300. */
  4301. const lock = async () => {
  4302. const p = waitPromise;
  4303. let resolve;
  4304. waitPromise = new Promise((r) => (resolve = r));
  4305. if (p !== undefined) {
  4306. await p;
  4307. }
  4308. return resolve;
  4309. };
  4310. return {
  4311. lock,
  4312. };
  4313. };
  4314. /**
  4315. * This query string selects elements that
  4316. * are eligible to receive focus. We select
  4317. * interactive elements that meet the following
  4318. * criteria:
  4319. * 1. Element does not have a negative tabindex
  4320. * 2. Element does not have `hidden`
  4321. * 3. Element does not have `disabled` for non-Ionic components.
  4322. * 4. Element does not have `disabled` or `disabled="true"` for Ionic components.
  4323. * Note: We need this distinction because `disabled="false"` is
  4324. * valid usage for the disabled property on ion-button.
  4325. */
  4326. const focusableQueryString = '[tabindex]:not([tabindex^="-"]):not([hidden]):not([disabled]), input:not([type=hidden]):not([tabindex^="-"]):not([hidden]):not([disabled]), textarea:not([tabindex^="-"]):not([hidden]):not([disabled]), button:not([tabindex^="-"]):not([hidden]):not([disabled]), select:not([tabindex^="-"]):not([hidden]):not([disabled]), ion-checkbox:not([tabindex^="-"]):not([hidden]):not([disabled]), ion-radio:not([tabindex^="-"]):not([hidden]):not([disabled]), .ion-focusable:not([tabindex^="-"]):not([hidden]):not([disabled]), .ion-focusable[disabled="false"]:not([tabindex^="-"]):not([hidden])';
  4327. /**
  4328. * Focuses the first descendant in a context
  4329. * that can receive focus. If none exists,
  4330. * a fallback element will be focused.
  4331. * This fallback is typically an ancestor
  4332. * container such as a menu or overlay so focus does not
  4333. * leave the container we are trying to trap focus in.
  4334. *
  4335. * If no fallback is specified then we focus the container itself.
  4336. */
  4337. const focusFirstDescendant = (ref, fallbackElement) => {
  4338. const firstInput = ref.querySelector(focusableQueryString);
  4339. focusElementInContext(firstInput, fallbackElement !== null && fallbackElement !== void 0 ? fallbackElement : ref);
  4340. };
  4341. /**
  4342. * Focuses the last descendant in a context
  4343. * that can receive focus. If none exists,
  4344. * a fallback element will be focused.
  4345. * This fallback is typically an ancestor
  4346. * container such as a menu or overlay so focus does not
  4347. * leave the container we are trying to trap focus in.
  4348. *
  4349. * If no fallback is specified then we focus the container itself.
  4350. */
  4351. const focusLastDescendant = (ref, fallbackElement) => {
  4352. const inputs = Array.from(ref.querySelectorAll(focusableQueryString));
  4353. const lastInput = inputs.length > 0 ? inputs[inputs.length - 1] : null;
  4354. focusElementInContext(lastInput, fallbackElement !== null && fallbackElement !== void 0 ? fallbackElement : ref);
  4355. };
  4356. /**
  4357. * Focuses a particular element in a context. If the element
  4358. * doesn't have anything focusable associated with it then
  4359. * a fallback element will be focused.
  4360. *
  4361. * This fallback is typically an ancestor
  4362. * container such as a menu or overlay so focus does not
  4363. * leave the container we are trying to trap focus in.
  4364. * This should be used instead of the focus() method
  4365. * on most elements because the focusable element
  4366. * may not be the host element.
  4367. *
  4368. * For example, if an ion-button should be focused
  4369. * then we should actually focus the native <button>
  4370. * element inside of ion-button's shadow root, not
  4371. * the host element itself.
  4372. */
  4373. const focusElementInContext = (hostToFocus, fallbackElement) => {
  4374. let elementToFocus = hostToFocus;
  4375. const shadowRoot = hostToFocus === null || hostToFocus === void 0 ? void 0 : hostToFocus.shadowRoot;
  4376. if (shadowRoot) {
  4377. // If there are no inner focusable elements, just focus the host element.
  4378. elementToFocus = shadowRoot.querySelector(focusableQueryString) || hostToFocus;
  4379. }
  4380. if (elementToFocus) {
  4381. const radioGroup = elementToFocus.closest('ion-radio-group');
  4382. if (radioGroup) {
  4383. radioGroup.setFocus();
  4384. }
  4385. else {
  4386. focusVisibleElement(elementToFocus);
  4387. }
  4388. }
  4389. else {
  4390. // Focus fallback element instead of letting focus escape
  4391. fallbackElement.focus();
  4392. }
  4393. };
  4394. /**
  4395. * CloseWatcher is a newer API that lets
  4396. * use detect the hardware back button event
  4397. * in a web browser: https://caniuse.com/?search=closewatcher
  4398. * However, not every browser supports it yet.
  4399. *
  4400. * This needs to be a function so that we can
  4401. * check the config once it has been set.
  4402. * Otherwise, this code would be evaluated the
  4403. * moment this file is evaluated which could be
  4404. * before the config is set.
  4405. */
  4406. const shouldUseCloseWatcher = () => config.get('experimentalCloseWatcher', false) && win$1 !== undefined && 'CloseWatcher' in win$1;
  4407. const OVERLAY_BACK_BUTTON_PRIORITY = 100;
  4408. const MENU_BACK_BUTTON_PRIORITY = 99; // 1 less than overlay priority since menu is displayed behind overlays
  4409. // TODO(FW-2832): types
  4410. const attachComponent = async (delegate, container, component, cssClasses, componentProps, inline) => {
  4411. var _a;
  4412. if (delegate) {
  4413. return delegate.attachViewToDom(container, component, componentProps, cssClasses);
  4414. }
  4415. if (!inline && typeof component !== 'string' && !(component instanceof HTMLElement)) {
  4416. throw new Error('framework delegate is missing');
  4417. }
  4418. const el = typeof component === 'string' ? (_a = container.ownerDocument) === null || _a === void 0 ? void 0 : _a.createElement(component) : component;
  4419. if (cssClasses) {
  4420. cssClasses.forEach((c) => el.classList.add(c));
  4421. }
  4422. if (componentProps) {
  4423. Object.assign(el, componentProps);
  4424. }
  4425. container.appendChild(el);
  4426. await new Promise((resolve) => componentOnReady(el, resolve));
  4427. return el;
  4428. };
  4429. const detachComponent = (delegate, element) => {
  4430. if (element) {
  4431. if (delegate) {
  4432. const container = element.parentElement;
  4433. return delegate.removeViewFromDom(container, element);
  4434. }
  4435. element.remove();
  4436. }
  4437. return Promise.resolve();
  4438. };
  4439. const CoreDelegate = () => {
  4440. let BaseComponent;
  4441. let Reference;
  4442. const attachViewToDom = async (parentElement, userComponent, userComponentProps = {}, cssClasses = []) => {
  4443. var _a, _b;
  4444. BaseComponent = parentElement;
  4445. let ChildComponent;
  4446. /**
  4447. * If passing in a component via the `component` props
  4448. * we need to append it inside of our overlay component.
  4449. */
  4450. if (userComponent) {
  4451. /**
  4452. * If passing in the tag name, create
  4453. * the element otherwise just get a reference
  4454. * to the component.
  4455. */
  4456. const el = typeof userComponent === 'string' ? (_a = BaseComponent.ownerDocument) === null || _a === void 0 ? void 0 : _a.createElement(userComponent) : userComponent;
  4457. /**
  4458. * Add any css classes passed in
  4459. * via the cssClasses prop on the overlay.
  4460. */
  4461. cssClasses.forEach((c) => el.classList.add(c));
  4462. /**
  4463. * Add any props passed in
  4464. * via the componentProps prop on the overlay.
  4465. */
  4466. Object.assign(el, userComponentProps);
  4467. /**
  4468. * Finally, append the component
  4469. * inside of the overlay component.
  4470. */
  4471. BaseComponent.appendChild(el);
  4472. ChildComponent = el;
  4473. await new Promise((resolve) => componentOnReady(el, resolve));
  4474. }
  4475. else if (BaseComponent.children.length > 0 &&
  4476. (BaseComponent.tagName === 'ION-MODAL' || BaseComponent.tagName === 'ION-POPOVER')) {
  4477. /**
  4478. * The delegate host wrapper el is only needed for modals and popovers
  4479. * because they allow the dev to provide custom content to the overlay.
  4480. */
  4481. const root = (ChildComponent = BaseComponent.children[0]);
  4482. if (!root.classList.contains('ion-delegate-host')) {
  4483. /**
  4484. * If the root element is not a delegate host, it means
  4485. * that the overlay has not been presented yet and we need
  4486. * to create the containing element with the specified classes.
  4487. */
  4488. const el = (_b = BaseComponent.ownerDocument) === null || _b === void 0 ? void 0 : _b.createElement('div');
  4489. // Add a class to track if the root element was created by the delegate.
  4490. el.classList.add('ion-delegate-host');
  4491. cssClasses.forEach((c) => el.classList.add(c));
  4492. // Move each child from the original template to the new parent element.
  4493. el.append(...BaseComponent.children);
  4494. // Append the new parent element to the original parent element.
  4495. BaseComponent.appendChild(el);
  4496. /**
  4497. * Update the ChildComponent to be the
  4498. * newly created div in the event that one
  4499. * does not already exist.
  4500. */
  4501. ChildComponent = el;
  4502. }
  4503. }
  4504. /**
  4505. * Get the root of the app and
  4506. * add the overlay there.
  4507. */
  4508. const app = document.querySelector('ion-app') || document.body;
  4509. /**
  4510. * Create a placeholder comment so that
  4511. * we can return this component to where
  4512. * it was previously.
  4513. */
  4514. Reference = document.createComment('ionic teleport');
  4515. BaseComponent.parentNode.insertBefore(Reference, BaseComponent);
  4516. app.appendChild(BaseComponent);
  4517. /**
  4518. * We return the child component rather than the overlay
  4519. * reference itself since modal and popover will
  4520. * use this to wait for any Ionic components in the child view
  4521. * to be ready (i.e. componentOnReady) when using the
  4522. * lazy loaded component bundle.
  4523. *
  4524. * However, we fall back to returning BaseComponent
  4525. * in the event that a modal or popover is presented
  4526. * with no child content.
  4527. */
  4528. return ChildComponent !== null && ChildComponent !== void 0 ? ChildComponent : BaseComponent;
  4529. };
  4530. const removeViewFromDom = () => {
  4531. /**
  4532. * Return component to where it was previously in the DOM.
  4533. */
  4534. if (BaseComponent && Reference) {
  4535. Reference.parentNode.insertBefore(BaseComponent, Reference);
  4536. Reference.remove();
  4537. }
  4538. return Promise.resolve();
  4539. };
  4540. return { attachViewToDom, removeViewFromDom };
  4541. };
  4542. let lastOverlayIndex = 0;
  4543. let lastId = 0;
  4544. const activeAnimations = new WeakMap();
  4545. const createController = (tagName) => {
  4546. return {
  4547. create(options) {
  4548. return createOverlay(tagName, options);
  4549. },
  4550. dismiss(data, role, id) {
  4551. return dismissOverlay(document, data, role, tagName, id);
  4552. },
  4553. async getTop() {
  4554. return getPresentedOverlay(document, tagName);
  4555. },
  4556. };
  4557. };
  4558. const alertController = /*@__PURE__*/ createController('ion-alert');
  4559. const actionSheetController = /*@__PURE__*/ createController('ion-action-sheet');
  4560. const modalController = /*@__PURE__*/ createController('ion-modal');
  4561. const popoverController = /*@__PURE__*/ createController('ion-popover');
  4562. /**
  4563. * Prepares the overlay element to be presented.
  4564. */
  4565. const prepareOverlay = (el) => {
  4566. if (typeof document !== 'undefined') {
  4567. /**
  4568. * Adds a single instance of event listeners for application behaviors:
  4569. *
  4570. * - Escape Key behavior to dismiss an overlay
  4571. * - Trapping focus within an overlay
  4572. * - Back button behavior to dismiss an overlay
  4573. *
  4574. * This only occurs when the first overlay is created.
  4575. */
  4576. connectListeners(document);
  4577. }
  4578. const overlayIndex = lastOverlayIndex++;
  4579. /**
  4580. * overlayIndex is used in the overlay components to set a zIndex.
  4581. * This ensures that the most recently presented overlay will be
  4582. * on top.
  4583. */
  4584. el.overlayIndex = overlayIndex;
  4585. };
  4586. /**
  4587. * Assigns an incrementing id to an overlay element, that does not
  4588. * already have an id assigned to it.
  4589. *
  4590. * Used to track unique instances of an overlay element.
  4591. */
  4592. const setOverlayId = (el) => {
  4593. if (!el.hasAttribute('id')) {
  4594. el.id = `ion-overlay-${++lastId}`;
  4595. }
  4596. return el.id;
  4597. };
  4598. const createOverlay = (tagName, opts) => {
  4599. // eslint-disable-next-line @typescript-eslint/prefer-optional-chain
  4600. if (typeof window !== 'undefined' && typeof window.customElements !== 'undefined') {
  4601. return window.customElements.whenDefined(tagName).then(() => {
  4602. const element = document.createElement(tagName);
  4603. element.classList.add('overlay-hidden');
  4604. /**
  4605. * Convert the passed in overlay options into props
  4606. * that get passed down into the new overlay.
  4607. */
  4608. Object.assign(element, Object.assign(Object.assign({}, opts), { hasController: true }));
  4609. // append the overlay element to the document body
  4610. getAppRoot(document).appendChild(element);
  4611. return new Promise((resolve) => componentOnReady(element, resolve));
  4612. });
  4613. }
  4614. return Promise.resolve();
  4615. };
  4616. const isOverlayHidden = (overlay) => overlay.classList.contains('overlay-hidden');
  4617. /**
  4618. * Focuses a particular element in an overlay. If the element
  4619. * doesn't have anything focusable associated with it then
  4620. * the overlay itself will be focused.
  4621. * This should be used instead of the focus() method
  4622. * on most elements because the focusable element
  4623. * may not be the host element.
  4624. *
  4625. * For example, if an ion-button should be focused
  4626. * then we should actually focus the native <button>
  4627. * element inside of ion-button's shadow root, not
  4628. * the host element itself.
  4629. */
  4630. const focusElementInOverlay = (hostToFocus, overlay) => {
  4631. let elementToFocus = hostToFocus;
  4632. const shadowRoot = hostToFocus === null || hostToFocus === void 0 ? void 0 : hostToFocus.shadowRoot;
  4633. if (shadowRoot) {
  4634. // If there are no inner focusable elements, just focus the host element.
  4635. elementToFocus = shadowRoot.querySelector(focusableQueryString) || hostToFocus;
  4636. }
  4637. if (elementToFocus) {
  4638. focusVisibleElement(elementToFocus);
  4639. }
  4640. else {
  4641. // Focus overlay instead of letting focus escape
  4642. overlay.focus();
  4643. }
  4644. };
  4645. /**
  4646. * Traps keyboard focus inside of overlay components.
  4647. * Based on https://w3c.github.io/aria-practices/examples/dialog-modal/alertdialog.html
  4648. * This includes the following components: Action Sheet, Alert, Loading, Modal,
  4649. * Picker, and Popover.
  4650. * Should NOT include: Toast
  4651. */
  4652. const trapKeyboardFocus = (ev, doc) => {
  4653. const lastOverlay = getPresentedOverlay(doc, 'ion-alert,ion-action-sheet,ion-loading,ion-modal,ion-picker-legacy,ion-popover');
  4654. const target = ev.target;
  4655. /**
  4656. * If no active overlay, ignore this event.
  4657. *
  4658. * If this component uses the shadow dom,
  4659. * this global listener is pointless
  4660. * since it will not catch the focus
  4661. * traps as they are inside the shadow root.
  4662. * We need to add a listener to the shadow root
  4663. * itself to ensure the focus trap works.
  4664. */
  4665. if (!lastOverlay || !target) {
  4666. return;
  4667. }
  4668. /**
  4669. * If the ion-disable-focus-trap class
  4670. * is present on an overlay, then this component
  4671. * instance has opted out of focus trapping.
  4672. * An example of this is when the sheet modal
  4673. * has a backdrop that is disabled. The content
  4674. * behind the sheet should be focusable until
  4675. * the backdrop is enabled.
  4676. */
  4677. if (lastOverlay.classList.contains(FOCUS_TRAP_DISABLE_CLASS)) {
  4678. return;
  4679. }
  4680. const trapScopedFocus = () => {
  4681. /**
  4682. * If we are focusing the overlay, clear
  4683. * the last focused element so that hitting
  4684. * tab activates the first focusable element
  4685. * in the overlay wrapper.
  4686. */
  4687. if (lastOverlay === target) {
  4688. lastOverlay.lastFocus = undefined;
  4689. /**
  4690. * Toasts can be presented from an overlay.
  4691. * However, focus should still be returned to
  4692. * the overlay when clicking a toast. Normally,
  4693. * focus would be returned to the last focusable
  4694. * descendant in the overlay which may not always be
  4695. * the button that the toast was presented from. In this case,
  4696. * the focus may be returned to an unexpected element.
  4697. * To account for this, we make sure to return focus to the
  4698. * last focused element in the overlay if focus is
  4699. * moved to the toast.
  4700. */
  4701. }
  4702. else if (target.tagName === 'ION-TOAST') {
  4703. focusElementInOverlay(lastOverlay.lastFocus, lastOverlay);
  4704. /**
  4705. * Otherwise, we must be focusing an element
  4706. * inside of the overlay. The two possible options
  4707. * here are an input/button/etc or the ion-focus-trap
  4708. * element. The focus trap element is used to prevent
  4709. * the keyboard focus from leaving the overlay when
  4710. * using Tab or screen assistants.
  4711. */
  4712. }
  4713. else {
  4714. /**
  4715. * We do not want to focus the traps, so get the overlay
  4716. * wrapper element as the traps live outside of the wrapper.
  4717. */
  4718. const overlayRoot = getElementRoot(lastOverlay);
  4719. if (!overlayRoot.contains(target)) {
  4720. return;
  4721. }
  4722. const overlayWrapper = overlayRoot.querySelector('.ion-overlay-wrapper');
  4723. if (!overlayWrapper) {
  4724. return;
  4725. }
  4726. /**
  4727. * If the target is inside the wrapper, let the browser
  4728. * focus as normal and keep a log of the last focused element.
  4729. * Additionally, if the backdrop was tapped we should not
  4730. * move focus back inside the wrapper as that could cause
  4731. * an interactive elements focus state to activate.
  4732. */
  4733. if (overlayWrapper.contains(target) || target === overlayRoot.querySelector('ion-backdrop')) {
  4734. lastOverlay.lastFocus = target;
  4735. }
  4736. else {
  4737. /**
  4738. * Otherwise, we must have focused one of the focus traps.
  4739. * We need to wrap the focus to either the first element
  4740. * or the last element.
  4741. */
  4742. /**
  4743. * Once we call `focusFirstDescendant` and focus the first
  4744. * descendant, another focus event will fire which will
  4745. * cause `lastOverlay.lastFocus` to be updated before
  4746. * we can run the code after that. We will cache the value
  4747. * here to avoid that.
  4748. */
  4749. const lastFocus = lastOverlay.lastFocus;
  4750. // Focus the first element in the overlay wrapper
  4751. focusFirstDescendant(overlayWrapper, lastOverlay);
  4752. /**
  4753. * If the cached last focused element is the
  4754. * same as the active element, then we need
  4755. * to wrap focus to the last descendant. This happens
  4756. * when the first descendant is focused, and the user
  4757. * presses Shift + Tab. The previous line will focus
  4758. * the same descendant again (the first one), causing
  4759. * last focus to equal the active element.
  4760. */
  4761. if (lastFocus === doc.activeElement) {
  4762. focusLastDescendant(overlayWrapper, lastOverlay);
  4763. }
  4764. lastOverlay.lastFocus = doc.activeElement;
  4765. }
  4766. }
  4767. };
  4768. const trapShadowFocus = () => {
  4769. /**
  4770. * If the target is inside the wrapper, let the browser
  4771. * focus as normal and keep a log of the last focused element.
  4772. */
  4773. if (lastOverlay.contains(target)) {
  4774. lastOverlay.lastFocus = target;
  4775. /**
  4776. * Toasts can be presented from an overlay.
  4777. * However, focus should still be returned to
  4778. * the overlay when clicking a toast. Normally,
  4779. * focus would be returned to the last focusable
  4780. * descendant in the overlay which may not always be
  4781. * the button that the toast was presented from. In this case,
  4782. * the focus may be returned to an unexpected element.
  4783. * To account for this, we make sure to return focus to the
  4784. * last focused element in the overlay if focus is
  4785. * moved to the toast.
  4786. */
  4787. }
  4788. else if (target.tagName === 'ION-TOAST') {
  4789. focusElementInOverlay(lastOverlay.lastFocus, lastOverlay);
  4790. }
  4791. else {
  4792. /**
  4793. * Otherwise, we are about to have focus
  4794. * go out of the overlay. We need to wrap
  4795. * the focus to either the first element
  4796. * or the last element.
  4797. */
  4798. /**
  4799. * Once we call `focusFirstDescendant` and focus the first
  4800. * descendant, another focus event will fire which will
  4801. * cause `lastOverlay.lastFocus` to be updated before
  4802. * we can run the code after that. We will cache the value
  4803. * here to avoid that.
  4804. */
  4805. const lastFocus = lastOverlay.lastFocus;
  4806. // Focus the first element in the overlay wrapper
  4807. focusFirstDescendant(lastOverlay);
  4808. /**
  4809. * If the cached last focused element is the
  4810. * same as the active element, then we need
  4811. * to wrap focus to the last descendant. This happens
  4812. * when the first descendant is focused, and the user
  4813. * presses Shift + Tab. The previous line will focus
  4814. * the same descendant again (the first one), causing
  4815. * last focus to equal the active element.
  4816. */
  4817. if (lastFocus === doc.activeElement) {
  4818. focusLastDescendant(lastOverlay);
  4819. }
  4820. lastOverlay.lastFocus = doc.activeElement;
  4821. }
  4822. };
  4823. if (lastOverlay.shadowRoot) {
  4824. trapShadowFocus();
  4825. }
  4826. else {
  4827. trapScopedFocus();
  4828. }
  4829. };
  4830. const connectListeners = (doc) => {
  4831. if (lastOverlayIndex === 0) {
  4832. lastOverlayIndex = 1;
  4833. doc.addEventListener('focus', (ev) => {
  4834. trapKeyboardFocus(ev, doc);
  4835. }, true);
  4836. // handle back-button click
  4837. doc.addEventListener('ionBackButton', (ev) => {
  4838. const lastOverlay = getPresentedOverlay(doc);
  4839. if (lastOverlay === null || lastOverlay === void 0 ? void 0 : lastOverlay.backdropDismiss) {
  4840. ev.detail.register(OVERLAY_BACK_BUTTON_PRIORITY, () => {
  4841. /**
  4842. * Do not return this promise otherwise
  4843. * the hardware back button utility will
  4844. * be blocked until the overlay dismisses.
  4845. * This is important for a modal with canDismiss.
  4846. * If the application presents a confirmation alert
  4847. * in the "canDismiss" callback, then it will be impossible
  4848. * to use the hardware back button to dismiss the alert
  4849. * dialog because the hardware back button utility
  4850. * is blocked on waiting for the modal to dismiss.
  4851. */
  4852. lastOverlay.dismiss(undefined, BACKDROP);
  4853. });
  4854. }
  4855. });
  4856. /**
  4857. * Handle ESC to close overlay.
  4858. * CloseWatcher also handles pressing the Esc
  4859. * key, so if a browser supports CloseWatcher then
  4860. * this behavior will be handled via the ionBackButton
  4861. * event.
  4862. */
  4863. if (!shouldUseCloseWatcher()) {
  4864. doc.addEventListener('keydown', (ev) => {
  4865. if (ev.key === 'Escape') {
  4866. const lastOverlay = getPresentedOverlay(doc);
  4867. if (lastOverlay === null || lastOverlay === void 0 ? void 0 : lastOverlay.backdropDismiss) {
  4868. lastOverlay.dismiss(undefined, BACKDROP);
  4869. }
  4870. }
  4871. });
  4872. }
  4873. }
  4874. };
  4875. const dismissOverlay = (doc, data, role, overlayTag, id) => {
  4876. const overlay = getPresentedOverlay(doc, overlayTag, id);
  4877. if (!overlay) {
  4878. return Promise.reject('overlay does not exist');
  4879. }
  4880. return overlay.dismiss(data, role);
  4881. };
  4882. /**
  4883. * Returns a list of all overlays in the DOM even if they are not presented.
  4884. */
  4885. const getOverlays = (doc, selector) => {
  4886. if (selector === undefined) {
  4887. selector = 'ion-alert,ion-action-sheet,ion-loading,ion-modal,ion-picker-legacy,ion-popover,ion-toast';
  4888. }
  4889. return Array.from(doc.querySelectorAll(selector)).filter((c) => c.overlayIndex > 0);
  4890. };
  4891. /**
  4892. * Returns a list of all presented overlays.
  4893. * Inline overlays can exist in the DOM but not be presented,
  4894. * so there are times when we want to exclude those.
  4895. * @param doc The document to find the element within.
  4896. * @param overlayTag The selector for the overlay, defaults to Ionic overlay components.
  4897. */
  4898. const getPresentedOverlays = (doc, overlayTag) => {
  4899. return getOverlays(doc, overlayTag).filter((o) => !isOverlayHidden(o));
  4900. };
  4901. /**
  4902. * Returns a presented overlay element.
  4903. * @param doc The document to find the element within.
  4904. * @param overlayTag The selector for the overlay, defaults to Ionic overlay components.
  4905. * @param id The unique identifier for the overlay instance.
  4906. * @returns The overlay element or `undefined` if no overlay element is found.
  4907. */
  4908. const getPresentedOverlay = (doc, overlayTag, id) => {
  4909. const overlays = getPresentedOverlays(doc, overlayTag);
  4910. return id === undefined ? overlays[overlays.length - 1] : overlays.find((o) => o.id === id);
  4911. };
  4912. /**
  4913. * When an overlay is presented, the main
  4914. * focus is the overlay not the page content.
  4915. * We need to remove the page content from the
  4916. * accessibility tree otherwise when
  4917. * users use "read screen from top" gestures with
  4918. * TalkBack and VoiceOver, the screen reader will begin
  4919. * to read the content underneath the overlay.
  4920. *
  4921. * We need a container where all page components
  4922. * exist that is separate from where the overlays
  4923. * are added in the DOM. For most apps, this element
  4924. * is the top most ion-router-outlet. In the event
  4925. * that devs are not using a router,
  4926. * they will need to add the "ion-view-container-root"
  4927. * id to the element that contains all of their views.
  4928. *
  4929. * TODO: If Framework supports having multiple top
  4930. * level router outlets we would need to update this.
  4931. * Example: One outlet for side menu and one outlet
  4932. * for main content.
  4933. */
  4934. const setRootAriaHidden = (hidden = false) => {
  4935. const root = getAppRoot(document);
  4936. const viewContainer = root.querySelector('ion-router-outlet, ion-nav, #ion-view-container-root');
  4937. if (!viewContainer) {
  4938. return;
  4939. }
  4940. if (hidden) {
  4941. viewContainer.setAttribute('aria-hidden', 'true');
  4942. }
  4943. else {
  4944. viewContainer.removeAttribute('aria-hidden');
  4945. }
  4946. };
  4947. const present = async (overlay, name, iosEnterAnimation, mdEnterAnimation, opts) => {
  4948. var _a, _b;
  4949. if (overlay.presented) {
  4950. return;
  4951. }
  4952. /**
  4953. * Due to accessibility guidelines, toasts do not have
  4954. * focus traps.
  4955. *
  4956. * All other overlays should have focus traps to prevent
  4957. * the keyboard focus from leaving the overlay.
  4958. */
  4959. if (overlay.el.tagName !== 'ION-TOAST') {
  4960. setRootAriaHidden(true);
  4961. document.body.classList.add(BACKDROP_NO_SCROLL);
  4962. }
  4963. hideUnderlyingOverlaysFromScreenReaders(overlay.el);
  4964. hideAnimatingOverlayFromScreenReaders(overlay.el);
  4965. overlay.presented = true;
  4966. overlay.willPresent.emit();
  4967. (_a = overlay.willPresentShorthand) === null || _a === void 0 ? void 0 : _a.emit();
  4968. const mode = getIonMode$1(overlay);
  4969. // get the user's animation fn if one was provided
  4970. const animationBuilder = overlay.enterAnimation
  4971. ? overlay.enterAnimation
  4972. : config.get(name, mode === 'ios' ? iosEnterAnimation : mdEnterAnimation);
  4973. const completed = await overlayAnimation(overlay, animationBuilder, overlay.el, opts);
  4974. if (completed) {
  4975. overlay.didPresent.emit();
  4976. (_b = overlay.didPresentShorthand) === null || _b === void 0 ? void 0 : _b.emit();
  4977. }
  4978. /**
  4979. * When an overlay that steals focus
  4980. * is dismissed, focus should be returned
  4981. * to the element that was focused
  4982. * prior to the overlay opening. Toast
  4983. * does not steal focus and is excluded
  4984. * from returning focus as a result.
  4985. */
  4986. if (overlay.el.tagName !== 'ION-TOAST') {
  4987. restoreElementFocus(overlay.el);
  4988. }
  4989. /**
  4990. * If the focused element is already
  4991. * inside the overlay component then
  4992. * focus should not be moved from that
  4993. * to the overlay container.
  4994. */
  4995. if (overlay.keyboardClose && (document.activeElement === null || !overlay.el.contains(document.activeElement))) {
  4996. overlay.el.focus();
  4997. }
  4998. /**
  4999. * If this overlay was previously dismissed without being
  5000. * the topmost one (such as by manually calling dismiss()),
  5001. * it would still have aria-hidden on being presented again.
  5002. * Removing it here ensures the overlay is visible to screen
  5003. * readers.
  5004. *
  5005. * If this overlay was being presented, then it was hidden
  5006. * from screen readers during the animation. Now that the
  5007. * animation is complete, we can reveal the overlay to
  5008. * screen readers.
  5009. */
  5010. overlay.el.removeAttribute('aria-hidden');
  5011. };
  5012. /**
  5013. * When an overlay component is dismissed,
  5014. * focus should be returned to the element
  5015. * that presented the overlay. Otherwise
  5016. * focus will be set on the body which
  5017. * means that people using screen readers
  5018. * or tabbing will need to re-navigate
  5019. * to where they were before they
  5020. * opened the overlay.
  5021. */
  5022. const restoreElementFocus = async (overlayEl) => {
  5023. let previousElement = document.activeElement;
  5024. if (!previousElement) {
  5025. return;
  5026. }
  5027. const shadowRoot = previousElement === null || previousElement === void 0 ? void 0 : previousElement.shadowRoot;
  5028. if (shadowRoot) {
  5029. // If there are no inner focusable elements, just focus the host element.
  5030. previousElement = shadowRoot.querySelector(focusableQueryString) || previousElement;
  5031. }
  5032. await overlayEl.onDidDismiss();
  5033. /**
  5034. * After onDidDismiss, the overlay loses focus
  5035. * because it is removed from the document
  5036. *
  5037. * > An element will also lose focus [...]
  5038. * > if the element is removed from the document)
  5039. *
  5040. * https://developer.mozilla.org/en-US/docs/Web/API/Element/blur_event
  5041. *
  5042. * Additionally, `document.activeElement` returns:
  5043. *
  5044. * > The Element which currently has focus,
  5045. * > `<body>` or null if there is
  5046. * > no focused element.
  5047. *
  5048. * https://developer.mozilla.org/en-US/docs/Web/API/Document/activeElement#value
  5049. *
  5050. * However, if the user has already focused
  5051. * an element sometime between onWillDismiss
  5052. * and onDidDismiss (for example, focusing a
  5053. * text box after tapping a button in an
  5054. * action sheet) then don't restore focus to
  5055. * previous element
  5056. */
  5057. if (document.activeElement === null || document.activeElement === document.body) {
  5058. previousElement.focus();
  5059. }
  5060. };
  5061. const dismiss = async (overlay, data, role, name, iosLeaveAnimation, mdLeaveAnimation, opts) => {
  5062. var _a, _b;
  5063. if (!overlay.presented) {
  5064. return false;
  5065. }
  5066. const presentedOverlays = doc !== undefined ? getPresentedOverlays(doc) : [];
  5067. /**
  5068. * For accessibility, toasts lack focus traps and don't receive
  5069. * `aria-hidden` on the root element when presented.
  5070. *
  5071. * All other overlays use focus traps to keep keyboard focus
  5072. * within the overlay, setting `aria-hidden` on the root element
  5073. * to enhance accessibility.
  5074. *
  5075. * Therefore, we must remove `aria-hidden` from the root element
  5076. * when the last non-toast overlay is dismissed.
  5077. */
  5078. const overlaysNotToast = presentedOverlays.filter((o) => o.tagName !== 'ION-TOAST');
  5079. const lastOverlayNotToast = overlaysNotToast.length === 1 && overlaysNotToast[0].id === overlay.el.id;
  5080. /**
  5081. * If this is the last visible overlay that is not a toast
  5082. * then we want to re-add the root to the accessibility tree.
  5083. */
  5084. if (lastOverlayNotToast) {
  5085. setRootAriaHidden(false);
  5086. document.body.classList.remove(BACKDROP_NO_SCROLL);
  5087. }
  5088. overlay.presented = false;
  5089. try {
  5090. /**
  5091. * There is no need to show the overlay to screen readers during
  5092. * the dismiss animation. This is because the overlay will be removed
  5093. * from the DOM after the animation is complete.
  5094. */
  5095. hideAnimatingOverlayFromScreenReaders(overlay.el);
  5096. // Overlay contents should not be clickable during dismiss
  5097. overlay.el.style.setProperty('pointer-events', 'none');
  5098. overlay.willDismiss.emit({ data, role });
  5099. (_a = overlay.willDismissShorthand) === null || _a === void 0 ? void 0 : _a.emit({ data, role });
  5100. const mode = getIonMode$1(overlay);
  5101. const animationBuilder = overlay.leaveAnimation
  5102. ? overlay.leaveAnimation
  5103. : config.get(name, mode === 'ios' ? iosLeaveAnimation : mdLeaveAnimation);
  5104. // If dismissed via gesture, no need to play leaving animation again
  5105. if (role !== GESTURE) {
  5106. await overlayAnimation(overlay, animationBuilder, overlay.el, opts);
  5107. }
  5108. overlay.didDismiss.emit({ data, role });
  5109. (_b = overlay.didDismissShorthand) === null || _b === void 0 ? void 0 : _b.emit({ data, role });
  5110. // Get a reference to all animations currently assigned to this overlay
  5111. // Then tear them down to return the overlay to its initial visual state
  5112. const animations = activeAnimations.get(overlay) || [];
  5113. animations.forEach((ani) => ani.destroy());
  5114. activeAnimations.delete(overlay);
  5115. /**
  5116. * Make overlay hidden again in case it is being reused.
  5117. * We can safely remove pointer-events: none as
  5118. * overlay-hidden will set display: none.
  5119. */
  5120. overlay.el.classList.add('overlay-hidden');
  5121. overlay.el.style.removeProperty('pointer-events');
  5122. /**
  5123. * Clear any focus trapping references
  5124. * when the overlay is dismissed.
  5125. */
  5126. if (overlay.el.lastFocus !== undefined) {
  5127. overlay.el.lastFocus = undefined;
  5128. }
  5129. }
  5130. catch (err) {
  5131. printIonError(`[${overlay.el.tagName.toLowerCase()}] - `, err);
  5132. }
  5133. overlay.el.remove();
  5134. revealOverlaysToScreenReaders();
  5135. return true;
  5136. };
  5137. const getAppRoot = (doc) => {
  5138. return doc.querySelector('ion-app') || doc.body;
  5139. };
  5140. const overlayAnimation = async (overlay, animationBuilder, baseEl, opts) => {
  5141. // Make overlay visible in case it's hidden
  5142. baseEl.classList.remove('overlay-hidden');
  5143. const aniRoot = overlay.el;
  5144. const animation = animationBuilder(aniRoot, opts);
  5145. if (!overlay.animated || !config.getBoolean('animated', true)) {
  5146. animation.duration(0);
  5147. }
  5148. if (overlay.keyboardClose) {
  5149. animation.beforeAddWrite(() => {
  5150. const activeElement = baseEl.ownerDocument.activeElement;
  5151. if (activeElement === null || activeElement === void 0 ? void 0 : activeElement.matches('input,ion-input, ion-textarea')) {
  5152. activeElement.blur();
  5153. }
  5154. });
  5155. }
  5156. const activeAni = activeAnimations.get(overlay) || [];
  5157. activeAnimations.set(overlay, [...activeAni, animation]);
  5158. await animation.play();
  5159. return true;
  5160. };
  5161. const eventMethod = (element, eventName) => {
  5162. let resolve;
  5163. const promise = new Promise((r) => (resolve = r));
  5164. onceEvent(element, eventName, (event) => {
  5165. resolve(event.detail);
  5166. });
  5167. return promise;
  5168. };
  5169. const onceEvent = (element, eventName, callback) => {
  5170. const handler = (ev) => {
  5171. removeEventListener(element, eventName, handler);
  5172. callback(ev);
  5173. };
  5174. addEventListener$1(element, eventName, handler);
  5175. };
  5176. const isCancel = (role) => {
  5177. return role === 'cancel' || role === BACKDROP;
  5178. };
  5179. const defaultGate = (h) => h();
  5180. /**
  5181. * Calls a developer provided method while avoiding
  5182. * Angular Zones. Since the handler is provided by
  5183. * the developer, we should throw any errors
  5184. * received so that developer-provided bug
  5185. * tracking software can log it.
  5186. */
  5187. const safeCall = (handler, arg) => {
  5188. if (typeof handler === 'function') {
  5189. const jmp = config.get('_zoneGate', defaultGate);
  5190. return jmp(() => {
  5191. try {
  5192. return handler(arg);
  5193. }
  5194. catch (e) {
  5195. throw e;
  5196. }
  5197. });
  5198. }
  5199. return undefined;
  5200. };
  5201. const BACKDROP = 'backdrop';
  5202. const GESTURE = 'gesture';
  5203. const OVERLAY_GESTURE_PRIORITY = 39;
  5204. /**
  5205. * Creates a delegate controller.
  5206. *
  5207. * Requires that the component has the following properties:
  5208. * - `el: HTMLElement`
  5209. * - `hasController: boolean`
  5210. * - `delegate?: FrameworkDelegate`
  5211. *
  5212. * @param ref The component class instance.
  5213. */
  5214. const createDelegateController = (ref) => {
  5215. let inline = false;
  5216. let workingDelegate;
  5217. const coreDelegate = CoreDelegate();
  5218. /**
  5219. * Determines whether or not an overlay is being used
  5220. * inline or via a controller/JS and returns the correct delegate.
  5221. * By default, subsequent calls to getDelegate will use
  5222. * a cached version of the delegate.
  5223. * This is useful for calling dismiss after present,
  5224. * so that the correct delegate is given.
  5225. * @param force `true` to force the non-cached version of the delegate.
  5226. * @returns The delegate to use and whether or not the overlay is inline.
  5227. */
  5228. const getDelegate = (force = false) => {
  5229. if (workingDelegate && !force) {
  5230. return {
  5231. delegate: workingDelegate,
  5232. inline,
  5233. };
  5234. }
  5235. const { el, hasController, delegate } = ref;
  5236. /**
  5237. * If using overlay inline
  5238. * we potentially need to use the coreDelegate
  5239. * so that this works in vanilla JS apps.
  5240. * If a developer has presented this component
  5241. * via a controller, then we can assume
  5242. * the component is already in the
  5243. * correct place.
  5244. */
  5245. const parentEl = el.parentNode;
  5246. inline = parentEl !== null && !hasController;
  5247. workingDelegate = inline ? delegate || coreDelegate : delegate;
  5248. return { inline, delegate: workingDelegate };
  5249. };
  5250. /**
  5251. * Attaches a component in the DOM. Teleports the component
  5252. * to the root of the app.
  5253. * @param component The component to optionally construct and append to the element.
  5254. */
  5255. const attachViewToDom = async (component) => {
  5256. const { delegate } = getDelegate(true);
  5257. if (delegate) {
  5258. return await delegate.attachViewToDom(ref.el, component);
  5259. }
  5260. const { hasController } = ref;
  5261. if (hasController && component !== undefined) {
  5262. throw new Error('framework delegate is missing');
  5263. }
  5264. return null;
  5265. };
  5266. /**
  5267. * Moves a component back to its original location in the DOM.
  5268. */
  5269. const removeViewFromDom = () => {
  5270. const { delegate } = getDelegate();
  5271. if (delegate && ref.el !== undefined) {
  5272. delegate.removeViewFromDom(ref.el.parentElement, ref.el);
  5273. }
  5274. };
  5275. return {
  5276. attachViewToDom,
  5277. removeViewFromDom,
  5278. };
  5279. };
  5280. /**
  5281. * Constructs a trigger interaction for an overlay.
  5282. * Presents an overlay when the trigger is clicked.
  5283. *
  5284. * Usage:
  5285. * ```ts
  5286. * triggerController = createTriggerController();
  5287. * triggerController.addClickListener(el, trigger);
  5288. * ```
  5289. */
  5290. const createTriggerController = () => {
  5291. let destroyTriggerInteraction;
  5292. /**
  5293. * Removes the click listener from the trigger element.
  5294. */
  5295. const removeClickListener = () => {
  5296. if (destroyTriggerInteraction) {
  5297. destroyTriggerInteraction();
  5298. destroyTriggerInteraction = undefined;
  5299. }
  5300. };
  5301. /**
  5302. * Adds a click listener to the trigger element.
  5303. * Presents the overlay when the trigger is clicked.
  5304. * @param el The overlay element.
  5305. * @param trigger The ID of the element to add a click listener to.
  5306. */
  5307. const addClickListener = (el, trigger) => {
  5308. removeClickListener();
  5309. const triggerEl = trigger !== undefined ? document.getElementById(trigger) : null;
  5310. if (!triggerEl) {
  5311. printIonWarning(`[${el.tagName.toLowerCase()}] - A trigger element with the ID "${trigger}" was not found in the DOM. The trigger element must be in the DOM when the "trigger" property is set on an overlay component.`, el);
  5312. return;
  5313. }
  5314. const configureTriggerInteraction = (targetEl, overlayEl) => {
  5315. const openOverlay = () => {
  5316. overlayEl.present();
  5317. };
  5318. targetEl.addEventListener('click', openOverlay);
  5319. return () => {
  5320. targetEl.removeEventListener('click', openOverlay);
  5321. };
  5322. };
  5323. destroyTriggerInteraction = configureTriggerInteraction(triggerEl, el);
  5324. };
  5325. return {
  5326. addClickListener,
  5327. removeClickListener,
  5328. };
  5329. };
  5330. /**
  5331. * The overlay that is being animated also needs to hide from screen
  5332. * readers during its animation. This ensures that assistive technologies
  5333. * like TalkBack do not announce or interact with the content until the
  5334. * animation is complete, avoiding confusion for users.
  5335. *
  5336. * When the overlay is presented on an Android device, TalkBack's focus rings
  5337. * may appear in the wrong position due to the transition (specifically
  5338. * `transform` styles). This occurs because the focus rings are initially
  5339. * displayed at the starting position of the elements before the transition
  5340. * begins. This workaround ensures the focus rings do not appear in the
  5341. * incorrect location.
  5342. *
  5343. * If this solution is applied to iOS devices, then it leads to a bug where
  5344. * the overlays cannot be accessed by screen readers. This is due to
  5345. * VoiceOver not being able to update the accessibility tree when the
  5346. * `aria-hidden` is removed.
  5347. *
  5348. * @param overlay - The overlay that is being animated.
  5349. */
  5350. const hideAnimatingOverlayFromScreenReaders = (overlay) => {
  5351. if (doc === undefined)
  5352. return;
  5353. if (isPlatform('android')) {
  5354. /**
  5355. * Once the animation is complete, this attribute will be removed.
  5356. * This is done at the end of the `present` method.
  5357. */
  5358. overlay.setAttribute('aria-hidden', 'true');
  5359. }
  5360. };
  5361. /**
  5362. * Ensure that underlying overlays have aria-hidden if necessary so that screen readers
  5363. * cannot move focus to these elements. Note that we cannot rely on focus/focusin/focusout
  5364. * events here because those events do not fire when the screen readers moves to a non-focusable
  5365. * element such as text.
  5366. * Without this logic screen readers would be able to move focus outside of the top focus-trapped overlay.
  5367. *
  5368. * @param newTopMostOverlay - The overlay that is being presented. Since the overlay has not been
  5369. * fully presented yet at the time this function is called it will not be included in the getPresentedOverlays result.
  5370. */
  5371. const hideUnderlyingOverlaysFromScreenReaders = (newTopMostOverlay) => {
  5372. var _a;
  5373. if (doc === undefined)
  5374. return;
  5375. const overlays = getPresentedOverlays(doc);
  5376. for (let i = overlays.length - 1; i >= 0; i--) {
  5377. const presentedOverlay = overlays[i];
  5378. const nextPresentedOverlay = (_a = overlays[i + 1]) !== null && _a !== void 0 ? _a : newTopMostOverlay;
  5379. /**
  5380. * If next overlay has aria-hidden then all remaining overlays will have it too.
  5381. * Or, if the next overlay is a Toast that does not have aria-hidden then current overlay
  5382. * should not have aria-hidden either so focus can remain in the current overlay.
  5383. */
  5384. if (nextPresentedOverlay.hasAttribute('aria-hidden') || nextPresentedOverlay.tagName !== 'ION-TOAST') {
  5385. presentedOverlay.setAttribute('aria-hidden', 'true');
  5386. }
  5387. }
  5388. };
  5389. /**
  5390. * When dismissing an overlay we need to reveal the new top-most overlay to screen readers.
  5391. * If the top-most overlay is a Toast we potentially need to reveal more overlays since
  5392. * focus is never automatically moved to the Toast.
  5393. */
  5394. const revealOverlaysToScreenReaders = () => {
  5395. if (doc === undefined)
  5396. return;
  5397. const overlays = getPresentedOverlays(doc);
  5398. for (let i = overlays.length - 1; i >= 0; i--) {
  5399. const currentOverlay = overlays[i];
  5400. /**
  5401. * If the current we are looking at is a Toast then we can remove aria-hidden.
  5402. * However, we potentially need to keep looking at the overlay stack because there
  5403. * could be more Toasts underneath. Additionally, we need to unhide the closest non-Toast
  5404. * overlay too so focus can move there since focus is never automatically moved to the Toast.
  5405. */
  5406. currentOverlay.removeAttribute('aria-hidden');
  5407. /**
  5408. * If we found a non-Toast element then we can just remove aria-hidden and stop searching entirely
  5409. * since this overlay should always receive focus. As a result, all underlying overlays should still
  5410. * be hidden from screen readers.
  5411. */
  5412. if (currentOverlay.tagName !== 'ION-TOAST') {
  5413. break;
  5414. }
  5415. }
  5416. };
  5417. const FOCUS_TRAP_DISABLE_CLASS = 'ion-disable-focus-trap';
  5418. const hostContext = (selector, el) => {
  5419. return el.closest(selector) !== null;
  5420. };
  5421. /**
  5422. * Create the mode and color classes for the component based on the classes passed in
  5423. */
  5424. const createColorClasses$1 = (color, cssClassMap) => {
  5425. return typeof color === 'string' && color.length > 0
  5426. ? Object.assign({ 'ion-color': true, [`ion-color-${color}`]: true }, cssClassMap) : cssClassMap;
  5427. };
  5428. const getClassList = (classes) => {
  5429. if (classes !== undefined) {
  5430. const array = Array.isArray(classes) ? classes : classes.split(' ');
  5431. return array
  5432. .filter((c) => c != null)
  5433. .map((c) => c.trim())
  5434. .filter((c) => c !== '');
  5435. }
  5436. return [];
  5437. };
  5438. const getClassMap = (classes) => {
  5439. const map = {};
  5440. getClassList(classes).forEach((c) => (map[c] = true));
  5441. return map;
  5442. };
  5443. const SCHEME = /^[a-z][a-z0-9+\-.]*:/;
  5444. const openURL = async (url, ev, direction, animation) => {
  5445. if (url != null && url[0] !== '#' && !SCHEME.test(url)) {
  5446. const router = document.querySelector('ion-router');
  5447. if (router) {
  5448. if (ev != null) {
  5449. ev.preventDefault();
  5450. }
  5451. return router.push(url, direction, animation);
  5452. }
  5453. }
  5454. return false;
  5455. };
  5456. let animationPrefix;
  5457. const getAnimationPrefix = (el) => {
  5458. if (animationPrefix === undefined) {
  5459. const supportsUnprefixed = el.style.animationName !== undefined;
  5460. const supportsWebkitPrefix = el.style.webkitAnimationName !== undefined;
  5461. animationPrefix = !supportsUnprefixed && supportsWebkitPrefix ? '-webkit-' : '';
  5462. }
  5463. return animationPrefix;
  5464. };
  5465. const setStyleProperty = (element, propertyName, value) => {
  5466. const prefix = propertyName.startsWith('animation') ? getAnimationPrefix(element) : '';
  5467. element.style.setProperty(prefix + propertyName, value);
  5468. };
  5469. const addClassToArray = (classes = [], className) => {
  5470. if (className !== undefined) {
  5471. const classNameToAppend = Array.isArray(className) ? className : [className];
  5472. return [...classes, ...classNameToAppend];
  5473. }
  5474. return classes;
  5475. };
  5476. const createAnimation = (animationId) => {
  5477. let _delay;
  5478. let _duration;
  5479. let _easing;
  5480. let _iterations;
  5481. let _fill;
  5482. let _direction;
  5483. let _keyframes = [];
  5484. let beforeAddClasses = [];
  5485. let beforeRemoveClasses = [];
  5486. let initialized = false;
  5487. let parentAnimation;
  5488. let beforeStylesValue = {};
  5489. let afterAddClasses = [];
  5490. let afterRemoveClasses = [];
  5491. let afterStylesValue = {};
  5492. let numAnimationsRunning = 0;
  5493. let shouldForceLinearEasing = false;
  5494. let shouldForceSyncPlayback = false;
  5495. let forceDirectionValue;
  5496. let forceDurationValue;
  5497. let forceDelayValue;
  5498. let willComplete = true;
  5499. let finished = false;
  5500. let shouldCalculateNumAnimations = true;
  5501. let ani;
  5502. let paused = false;
  5503. const id = animationId;
  5504. const onFinishCallbacks = [];
  5505. const onFinishOneTimeCallbacks = [];
  5506. const onStopOneTimeCallbacks = [];
  5507. const elements = [];
  5508. const childAnimations = [];
  5509. const stylesheets = [];
  5510. const _beforeAddReadFunctions = [];
  5511. const _beforeAddWriteFunctions = [];
  5512. const _afterAddReadFunctions = [];
  5513. const _afterAddWriteFunctions = [];
  5514. const webAnimations = [];
  5515. const supportsAnimationEffect = typeof AnimationEffect === 'function' ||
  5516. (win$1 !== undefined && typeof win$1.AnimationEffect === 'function');
  5517. /**
  5518. * This is a feature detection for Web Animations.
  5519. *
  5520. * Certain environments such as emulated browser environments for testing,
  5521. * do not support Web Animations. As a result, we need to check for support
  5522. * and provide a fallback to test certain functionality related to Web Animations.
  5523. */
  5524. const supportsWebAnimations = typeof Element === 'function' &&
  5525. typeof Element.prototype.animate === 'function' &&
  5526. supportsAnimationEffect;
  5527. const getWebAnimations = () => {
  5528. return webAnimations;
  5529. };
  5530. const destroy = (clearStyleSheets) => {
  5531. childAnimations.forEach((childAnimation) => {
  5532. childAnimation.destroy(clearStyleSheets);
  5533. });
  5534. cleanUp(clearStyleSheets);
  5535. elements.length = 0;
  5536. childAnimations.length = 0;
  5537. _keyframes.length = 0;
  5538. clearOnFinish();
  5539. initialized = false;
  5540. shouldCalculateNumAnimations = true;
  5541. return ani;
  5542. };
  5543. /**
  5544. * Cancels any Web Animations, removes
  5545. * any animation properties from the
  5546. * animation's elements, and removes the
  5547. * animation's stylesheets from the DOM.
  5548. */
  5549. const cleanUp = (clearStyleSheets) => {
  5550. cleanUpElements();
  5551. if (clearStyleSheets) {
  5552. cleanUpStyleSheets();
  5553. }
  5554. };
  5555. const resetFlags = () => {
  5556. shouldForceLinearEasing = false;
  5557. shouldForceSyncPlayback = false;
  5558. shouldCalculateNumAnimations = true;
  5559. forceDirectionValue = undefined;
  5560. forceDurationValue = undefined;
  5561. forceDelayValue = undefined;
  5562. numAnimationsRunning = 0;
  5563. finished = false;
  5564. willComplete = true;
  5565. paused = false;
  5566. };
  5567. const isRunning = () => {
  5568. return numAnimationsRunning !== 0 && !paused;
  5569. };
  5570. /**
  5571. * @internal
  5572. * Remove a callback from a chosen callback array
  5573. * @param callbackToRemove: A reference to the callback that should be removed
  5574. * @param callbackObjects: An array of callbacks that callbackToRemove should be removed from.
  5575. */
  5576. const clearCallback = (callbackToRemove, callbackObjects) => {
  5577. const index = callbackObjects.findIndex((callbackObject) => callbackObject.c === callbackToRemove);
  5578. if (index > -1) {
  5579. callbackObjects.splice(index, 1);
  5580. }
  5581. };
  5582. /**
  5583. * @internal
  5584. * Add a callback to be fired when an animation is stopped/cancelled.
  5585. * @param callback: A reference to the callback that should be fired
  5586. * @param opts: Any options associated with this particular callback
  5587. */
  5588. const onStop = (callback, opts) => {
  5589. onStopOneTimeCallbacks.push({ c: callback, o: opts });
  5590. return ani;
  5591. };
  5592. const onFinish = (callback, opts) => {
  5593. const callbacks = (opts === null || opts === void 0 ? void 0 : opts.oneTimeCallback) ? onFinishOneTimeCallbacks : onFinishCallbacks;
  5594. callbacks.push({ c: callback, o: opts });
  5595. return ani;
  5596. };
  5597. const clearOnFinish = () => {
  5598. onFinishCallbacks.length = 0;
  5599. onFinishOneTimeCallbacks.length = 0;
  5600. return ani;
  5601. };
  5602. /**
  5603. * Cancels any Web Animations and removes
  5604. * any animation properties from the
  5605. * the animation's elements.
  5606. */
  5607. const cleanUpElements = () => {
  5608. if (supportsWebAnimations) {
  5609. webAnimations.forEach((animation) => {
  5610. animation.cancel();
  5611. });
  5612. webAnimations.length = 0;
  5613. }
  5614. };
  5615. /**
  5616. * Removes the animation's stylesheets
  5617. * from the DOM.
  5618. */
  5619. const cleanUpStyleSheets = () => {
  5620. stylesheets.forEach((stylesheet) => {
  5621. /**
  5622. * When sharing stylesheets, it's possible
  5623. * for another animation to have already
  5624. * cleaned up a particular stylesheet
  5625. */
  5626. if (stylesheet === null || stylesheet === void 0 ? void 0 : stylesheet.parentNode) {
  5627. stylesheet.parentNode.removeChild(stylesheet);
  5628. }
  5629. });
  5630. stylesheets.length = 0;
  5631. };
  5632. const beforeAddRead = (readFn) => {
  5633. _beforeAddReadFunctions.push(readFn);
  5634. return ani;
  5635. };
  5636. const beforeAddWrite = (writeFn) => {
  5637. _beforeAddWriteFunctions.push(writeFn);
  5638. return ani;
  5639. };
  5640. const afterAddRead = (readFn) => {
  5641. _afterAddReadFunctions.push(readFn);
  5642. return ani;
  5643. };
  5644. const afterAddWrite = (writeFn) => {
  5645. _afterAddWriteFunctions.push(writeFn);
  5646. return ani;
  5647. };
  5648. const beforeAddClass = (className) => {
  5649. beforeAddClasses = addClassToArray(beforeAddClasses, className);
  5650. return ani;
  5651. };
  5652. const beforeRemoveClass = (className) => {
  5653. beforeRemoveClasses = addClassToArray(beforeRemoveClasses, className);
  5654. return ani;
  5655. };
  5656. /**
  5657. * Set CSS inline styles to the animation's
  5658. * elements before the animation begins.
  5659. */
  5660. const beforeStyles = (styles = {}) => {
  5661. beforeStylesValue = styles;
  5662. return ani;
  5663. };
  5664. /**
  5665. * Clear CSS inline styles from the animation's
  5666. * elements before the animation begins.
  5667. */
  5668. const beforeClearStyles = (propertyNames = []) => {
  5669. for (const property of propertyNames) {
  5670. beforeStylesValue[property] = '';
  5671. }
  5672. return ani;
  5673. };
  5674. const afterAddClass = (className) => {
  5675. afterAddClasses = addClassToArray(afterAddClasses, className);
  5676. return ani;
  5677. };
  5678. const afterRemoveClass = (className) => {
  5679. afterRemoveClasses = addClassToArray(afterRemoveClasses, className);
  5680. return ani;
  5681. };
  5682. const afterStyles = (styles = {}) => {
  5683. afterStylesValue = styles;
  5684. return ani;
  5685. };
  5686. const afterClearStyles = (propertyNames = []) => {
  5687. for (const property of propertyNames) {
  5688. afterStylesValue[property] = '';
  5689. }
  5690. return ani;
  5691. };
  5692. const getFill = () => {
  5693. if (_fill !== undefined) {
  5694. return _fill;
  5695. }
  5696. if (parentAnimation) {
  5697. return parentAnimation.getFill();
  5698. }
  5699. return 'both';
  5700. };
  5701. const getDirection = () => {
  5702. if (forceDirectionValue !== undefined) {
  5703. return forceDirectionValue;
  5704. }
  5705. if (_direction !== undefined) {
  5706. return _direction;
  5707. }
  5708. if (parentAnimation) {
  5709. return parentAnimation.getDirection();
  5710. }
  5711. return 'normal';
  5712. };
  5713. const getEasing = () => {
  5714. if (shouldForceLinearEasing) {
  5715. return 'linear';
  5716. }
  5717. if (_easing !== undefined) {
  5718. return _easing;
  5719. }
  5720. if (parentAnimation) {
  5721. return parentAnimation.getEasing();
  5722. }
  5723. return 'linear';
  5724. };
  5725. const getDuration = () => {
  5726. if (shouldForceSyncPlayback) {
  5727. return 0;
  5728. }
  5729. if (forceDurationValue !== undefined) {
  5730. return forceDurationValue;
  5731. }
  5732. if (_duration !== undefined) {
  5733. return _duration;
  5734. }
  5735. if (parentAnimation) {
  5736. return parentAnimation.getDuration();
  5737. }
  5738. return 0;
  5739. };
  5740. const getIterations = () => {
  5741. if (_iterations !== undefined) {
  5742. return _iterations;
  5743. }
  5744. if (parentAnimation) {
  5745. return parentAnimation.getIterations();
  5746. }
  5747. return 1;
  5748. };
  5749. const getDelay = () => {
  5750. if (forceDelayValue !== undefined) {
  5751. return forceDelayValue;
  5752. }
  5753. if (_delay !== undefined) {
  5754. return _delay;
  5755. }
  5756. if (parentAnimation) {
  5757. return parentAnimation.getDelay();
  5758. }
  5759. return 0;
  5760. };
  5761. const getKeyframes = () => {
  5762. return _keyframes;
  5763. };
  5764. const direction = (animationDirection) => {
  5765. _direction = animationDirection;
  5766. update(true);
  5767. return ani;
  5768. };
  5769. const fill = (animationFill) => {
  5770. _fill = animationFill;
  5771. update(true);
  5772. return ani;
  5773. };
  5774. const delay = (animationDelay) => {
  5775. _delay = animationDelay;
  5776. update(true);
  5777. return ani;
  5778. };
  5779. const easing = (animationEasing) => {
  5780. _easing = animationEasing;
  5781. update(true);
  5782. return ani;
  5783. };
  5784. const duration = (animationDuration) => {
  5785. /**
  5786. * CSS Animation Durations of 0ms work fine on Chrome
  5787. * but do not run on Safari, so force it to 1ms to
  5788. * get it to run on both platforms.
  5789. */
  5790. if (!supportsWebAnimations && animationDuration === 0) {
  5791. animationDuration = 1;
  5792. }
  5793. _duration = animationDuration;
  5794. update(true);
  5795. return ani;
  5796. };
  5797. const iterations = (animationIterations) => {
  5798. _iterations = animationIterations;
  5799. update(true);
  5800. return ani;
  5801. };
  5802. const parent = (animation) => {
  5803. parentAnimation = animation;
  5804. return ani;
  5805. };
  5806. const addElement = (el) => {
  5807. if (el != null) {
  5808. if (el.nodeType === 1) {
  5809. elements.push(el);
  5810. }
  5811. else if (el.length >= 0) {
  5812. for (let i = 0; i < el.length; i++) {
  5813. elements.push(el[i]);
  5814. }
  5815. }
  5816. else {
  5817. printIonError('createAnimation - Invalid addElement value.');
  5818. }
  5819. }
  5820. return ani;
  5821. };
  5822. const addAnimation = (animationToAdd) => {
  5823. if (animationToAdd != null) {
  5824. if (Array.isArray(animationToAdd)) {
  5825. for (const animation of animationToAdd) {
  5826. animation.parent(ani);
  5827. childAnimations.push(animation);
  5828. }
  5829. }
  5830. else {
  5831. animationToAdd.parent(ani);
  5832. childAnimations.push(animationToAdd);
  5833. }
  5834. }
  5835. return ani;
  5836. };
  5837. const keyframes = (keyframeValues) => {
  5838. const different = _keyframes !== keyframeValues;
  5839. _keyframes = keyframeValues;
  5840. if (different) {
  5841. updateKeyframes(_keyframes);
  5842. }
  5843. return ani;
  5844. };
  5845. const updateKeyframes = (keyframeValues) => {
  5846. if (supportsWebAnimations) {
  5847. getWebAnimations().forEach((animation) => {
  5848. /**
  5849. * animation.effect's type is AnimationEffect.
  5850. * However, in this case we have a more specific
  5851. * type of AnimationEffect called KeyframeEffect which
  5852. * inherits from AnimationEffect. As a result,
  5853. * we cast animation.effect to KeyframeEffect.
  5854. */
  5855. const keyframeEffect = animation.effect;
  5856. /**
  5857. * setKeyframes is not supported in all browser
  5858. * versions that Ionic supports, so we need to
  5859. * check for support before using it.
  5860. */
  5861. // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
  5862. if (keyframeEffect.setKeyframes) {
  5863. keyframeEffect.setKeyframes(keyframeValues);
  5864. }
  5865. else {
  5866. const newEffect = new KeyframeEffect(keyframeEffect.target, keyframeValues, keyframeEffect.getTiming());
  5867. animation.effect = newEffect;
  5868. }
  5869. });
  5870. }
  5871. };
  5872. /**
  5873. * Run all "before" animation hooks.
  5874. */
  5875. const beforeAnimation = () => {
  5876. // Runs all before read callbacks
  5877. _beforeAddReadFunctions.forEach((callback) => callback());
  5878. // Runs all before write callbacks
  5879. _beforeAddWriteFunctions.forEach((callback) => callback());
  5880. // Updates styles and classes before animation runs
  5881. const addClasses = beforeAddClasses;
  5882. const removeClasses = beforeRemoveClasses;
  5883. const styles = beforeStylesValue;
  5884. elements.forEach((el) => {
  5885. const elementClassList = el.classList;
  5886. addClasses.forEach((c) => elementClassList.add(c));
  5887. removeClasses.forEach((c) => elementClassList.remove(c));
  5888. for (const property in styles) {
  5889. // eslint-disable-next-line no-prototype-builtins
  5890. if (styles.hasOwnProperty(property)) {
  5891. setStyleProperty(el, property, styles[property]);
  5892. }
  5893. }
  5894. });
  5895. };
  5896. /**
  5897. * Run all "after" animation hooks.
  5898. */
  5899. const afterAnimation = () => {
  5900. // Runs all after read callbacks
  5901. _afterAddReadFunctions.forEach((callback) => callback());
  5902. // Runs all after write callbacks
  5903. _afterAddWriteFunctions.forEach((callback) => callback());
  5904. // Updates styles and classes before animation ends
  5905. const currentStep = willComplete ? 1 : 0;
  5906. const addClasses = afterAddClasses;
  5907. const removeClasses = afterRemoveClasses;
  5908. const styles = afterStylesValue;
  5909. elements.forEach((el) => {
  5910. const elementClassList = el.classList;
  5911. addClasses.forEach((c) => elementClassList.add(c));
  5912. removeClasses.forEach((c) => elementClassList.remove(c));
  5913. for (const property in styles) {
  5914. // eslint-disable-next-line no-prototype-builtins
  5915. if (styles.hasOwnProperty(property)) {
  5916. setStyleProperty(el, property, styles[property]);
  5917. }
  5918. }
  5919. });
  5920. /**
  5921. * Clean up any value coercion before
  5922. * the user callbacks fire otherwise
  5923. * they may get stale values. For example,
  5924. * if someone calls progressStart(0) the
  5925. * animation may still be reversed.
  5926. */
  5927. forceDurationValue = undefined;
  5928. forceDirectionValue = undefined;
  5929. forceDelayValue = undefined;
  5930. onFinishCallbacks.forEach((onFinishCallback) => {
  5931. return onFinishCallback.c(currentStep, ani);
  5932. });
  5933. onFinishOneTimeCallbacks.forEach((onFinishCallback) => {
  5934. return onFinishCallback.c(currentStep, ani);
  5935. });
  5936. onFinishOneTimeCallbacks.length = 0;
  5937. shouldCalculateNumAnimations = true;
  5938. if (willComplete) {
  5939. finished = true;
  5940. }
  5941. willComplete = true;
  5942. };
  5943. const animationFinish = () => {
  5944. if (numAnimationsRunning === 0) {
  5945. return;
  5946. }
  5947. numAnimationsRunning--;
  5948. if (numAnimationsRunning === 0) {
  5949. afterAnimation();
  5950. if (parentAnimation) {
  5951. parentAnimation.animationFinish();
  5952. }
  5953. }
  5954. };
  5955. const initializeWebAnimation = () => {
  5956. elements.forEach((element) => {
  5957. const animation = element.animate(_keyframes, {
  5958. id,
  5959. delay: getDelay(),
  5960. duration: getDuration(),
  5961. easing: getEasing(),
  5962. iterations: getIterations(),
  5963. fill: getFill(),
  5964. direction: getDirection(),
  5965. });
  5966. animation.pause();
  5967. webAnimations.push(animation);
  5968. });
  5969. if (webAnimations.length > 0) {
  5970. webAnimations[0].onfinish = () => {
  5971. animationFinish();
  5972. };
  5973. }
  5974. };
  5975. const initializeAnimation = () => {
  5976. beforeAnimation();
  5977. if (_keyframes.length > 0) {
  5978. if (supportsWebAnimations) {
  5979. initializeWebAnimation();
  5980. }
  5981. }
  5982. initialized = true;
  5983. };
  5984. const setAnimationStep = (step) => {
  5985. step = Math.min(Math.max(step, 0), 0.9999);
  5986. if (supportsWebAnimations) {
  5987. webAnimations.forEach((animation) => {
  5988. // When creating the animation the delay is guaranteed to be set to a number.
  5989. animation.currentTime = animation.effect.getComputedTiming().delay + getDuration() * step;
  5990. animation.pause();
  5991. });
  5992. }
  5993. };
  5994. const updateWebAnimation = (step) => {
  5995. webAnimations.forEach((animation) => {
  5996. animation.effect.updateTiming({
  5997. delay: getDelay(),
  5998. duration: getDuration(),
  5999. easing: getEasing(),
  6000. iterations: getIterations(),
  6001. fill: getFill(),
  6002. direction: getDirection(),
  6003. });
  6004. });
  6005. if (step !== undefined) {
  6006. setAnimationStep(step);
  6007. }
  6008. };
  6009. const update = (deep = false, toggleAnimationName = true, step) => {
  6010. if (deep) {
  6011. childAnimations.forEach((animation) => {
  6012. animation.update(deep, toggleAnimationName, step);
  6013. });
  6014. }
  6015. if (supportsWebAnimations) {
  6016. updateWebAnimation(step);
  6017. }
  6018. return ani;
  6019. };
  6020. const progressStart = (forceLinearEasing = false, step) => {
  6021. childAnimations.forEach((animation) => {
  6022. animation.progressStart(forceLinearEasing, step);
  6023. });
  6024. pauseAnimation();
  6025. shouldForceLinearEasing = forceLinearEasing;
  6026. if (!initialized) {
  6027. initializeAnimation();
  6028. }
  6029. update(false, true, step);
  6030. return ani;
  6031. };
  6032. const progressStep = (step) => {
  6033. childAnimations.forEach((animation) => {
  6034. animation.progressStep(step);
  6035. });
  6036. setAnimationStep(step);
  6037. return ani;
  6038. };
  6039. const progressEnd = (playTo, step, dur) => {
  6040. shouldForceLinearEasing = false;
  6041. childAnimations.forEach((animation) => {
  6042. animation.progressEnd(playTo, step, dur);
  6043. });
  6044. if (dur !== undefined) {
  6045. forceDurationValue = dur;
  6046. }
  6047. finished = false;
  6048. willComplete = true;
  6049. if (playTo === 0) {
  6050. forceDirectionValue = getDirection() === 'reverse' ? 'normal' : 'reverse';
  6051. if (forceDirectionValue === 'reverse') {
  6052. willComplete = false;
  6053. }
  6054. if (supportsWebAnimations) {
  6055. update();
  6056. setAnimationStep(1 - step);
  6057. }
  6058. else {
  6059. forceDelayValue = (1 - step) * getDuration() * -1;
  6060. update(false, false);
  6061. }
  6062. }
  6063. else if (playTo === 1) {
  6064. if (supportsWebAnimations) {
  6065. update();
  6066. setAnimationStep(step);
  6067. }
  6068. else {
  6069. forceDelayValue = step * getDuration() * -1;
  6070. update(false, false);
  6071. }
  6072. }
  6073. if (playTo !== undefined && !parentAnimation) {
  6074. play();
  6075. }
  6076. return ani;
  6077. };
  6078. const pauseAnimation = () => {
  6079. if (initialized) {
  6080. if (supportsWebAnimations) {
  6081. webAnimations.forEach((animation) => {
  6082. animation.pause();
  6083. });
  6084. }
  6085. else {
  6086. elements.forEach((element) => {
  6087. setStyleProperty(element, 'animation-play-state', 'paused');
  6088. });
  6089. }
  6090. paused = true;
  6091. }
  6092. };
  6093. const pause = () => {
  6094. childAnimations.forEach((animation) => {
  6095. animation.pause();
  6096. });
  6097. pauseAnimation();
  6098. return ani;
  6099. };
  6100. const playCSSAnimations = () => {
  6101. animationFinish();
  6102. };
  6103. const playWebAnimations = () => {
  6104. webAnimations.forEach((animation) => {
  6105. animation.play();
  6106. });
  6107. if (_keyframes.length === 0 || elements.length === 0) {
  6108. animationFinish();
  6109. }
  6110. };
  6111. const resetAnimation = () => {
  6112. if (supportsWebAnimations) {
  6113. setAnimationStep(0);
  6114. updateWebAnimation();
  6115. }
  6116. };
  6117. const play = (opts) => {
  6118. return new Promise((resolve) => {
  6119. if (opts === null || opts === void 0 ? void 0 : opts.sync) {
  6120. shouldForceSyncPlayback = true;
  6121. onFinish(() => (shouldForceSyncPlayback = false), { oneTimeCallback: true });
  6122. }
  6123. if (!initialized) {
  6124. initializeAnimation();
  6125. }
  6126. if (finished) {
  6127. resetAnimation();
  6128. finished = false;
  6129. }
  6130. if (shouldCalculateNumAnimations) {
  6131. numAnimationsRunning = childAnimations.length + 1;
  6132. shouldCalculateNumAnimations = false;
  6133. }
  6134. /**
  6135. * When one of these callbacks fires we
  6136. * need to clear the other's callback otherwise
  6137. * you can potentially get these callbacks
  6138. * firing multiple times if the play method
  6139. * is subsequently called.
  6140. * Example:
  6141. * animation.play() (onStop and onFinish callbacks are registered)
  6142. * animation.stop() (onStop callback is fired, onFinish is not)
  6143. * animation.play() (onStop and onFinish callbacks are registered)
  6144. * Total onStop callbacks: 1
  6145. * Total onFinish callbacks: 2
  6146. */
  6147. const onStopCallback = () => {
  6148. clearCallback(onFinishCallback, onFinishOneTimeCallbacks);
  6149. resolve();
  6150. };
  6151. const onFinishCallback = () => {
  6152. clearCallback(onStopCallback, onStopOneTimeCallbacks);
  6153. resolve();
  6154. };
  6155. /**
  6156. * The play method resolves when an animation
  6157. * run either finishes or is cancelled.
  6158. */
  6159. onFinish(onFinishCallback, { oneTimeCallback: true });
  6160. onStop(onStopCallback, { oneTimeCallback: true });
  6161. childAnimations.forEach((animation) => {
  6162. animation.play();
  6163. });
  6164. if (supportsWebAnimations) {
  6165. playWebAnimations();
  6166. }
  6167. else {
  6168. playCSSAnimations();
  6169. }
  6170. paused = false;
  6171. });
  6172. };
  6173. /**
  6174. * Stops an animation and resets it state to the
  6175. * beginning. This does not fire any onFinish
  6176. * callbacks because the animation did not finish.
  6177. * However, since the animation was not destroyed
  6178. * (i.e. the animation could run again) we do not
  6179. * clear the onFinish callbacks.
  6180. */
  6181. const stop = () => {
  6182. childAnimations.forEach((animation) => {
  6183. animation.stop();
  6184. });
  6185. if (initialized) {
  6186. cleanUpElements();
  6187. initialized = false;
  6188. }
  6189. resetFlags();
  6190. onStopOneTimeCallbacks.forEach((onStopCallback) => onStopCallback.c(0, ani));
  6191. onStopOneTimeCallbacks.length = 0;
  6192. };
  6193. const from = (property, value) => {
  6194. const firstFrame = _keyframes[0];
  6195. if (firstFrame !== undefined && (firstFrame.offset === undefined || firstFrame.offset === 0)) {
  6196. firstFrame[property] = value;
  6197. }
  6198. else {
  6199. _keyframes = [{ offset: 0, [property]: value }, ..._keyframes];
  6200. }
  6201. return ani;
  6202. };
  6203. const to = (property, value) => {
  6204. const lastFrame = _keyframes[_keyframes.length - 1];
  6205. if (lastFrame !== undefined && (lastFrame.offset === undefined || lastFrame.offset === 1)) {
  6206. lastFrame[property] = value;
  6207. }
  6208. else {
  6209. _keyframes = [..._keyframes, { offset: 1, [property]: value }];
  6210. }
  6211. return ani;
  6212. };
  6213. const fromTo = (property, fromValue, toValue) => {
  6214. return from(property, fromValue).to(property, toValue);
  6215. };
  6216. return (ani = {
  6217. parentAnimation,
  6218. elements,
  6219. childAnimations,
  6220. id,
  6221. animationFinish,
  6222. from,
  6223. to,
  6224. fromTo,
  6225. parent,
  6226. play,
  6227. pause,
  6228. stop,
  6229. destroy,
  6230. keyframes,
  6231. addAnimation,
  6232. addElement,
  6233. update,
  6234. fill,
  6235. direction,
  6236. iterations,
  6237. duration,
  6238. easing,
  6239. delay,
  6240. getWebAnimations,
  6241. getKeyframes,
  6242. getFill,
  6243. getDirection,
  6244. getDelay,
  6245. getIterations,
  6246. getEasing,
  6247. getDuration,
  6248. afterAddRead,
  6249. afterAddWrite,
  6250. afterClearStyles,
  6251. afterStyles,
  6252. afterRemoveClass,
  6253. afterAddClass,
  6254. beforeAddRead,
  6255. beforeAddWrite,
  6256. beforeClearStyles,
  6257. beforeStyles,
  6258. beforeRemoveClass,
  6259. beforeAddClass,
  6260. onFinish,
  6261. isRunning,
  6262. progressStart,
  6263. progressStep,
  6264. progressEnd,
  6265. });
  6266. };
  6267. /**
  6268. * iOS Action Sheet Enter Animation
  6269. */
  6270. const iosEnterAnimation$6 = (baseEl) => {
  6271. const baseAnimation = createAnimation();
  6272. const backdropAnimation = createAnimation();
  6273. const wrapperAnimation = createAnimation();
  6274. backdropAnimation
  6275. .addElement(baseEl.querySelector('ion-backdrop'))
  6276. .fromTo('opacity', 0.01, 'var(--backdrop-opacity)')
  6277. .beforeStyles({
  6278. 'pointer-events': 'none',
  6279. })
  6280. .afterClearStyles(['pointer-events']);
  6281. wrapperAnimation
  6282. .addElement(baseEl.querySelector('.action-sheet-wrapper'))
  6283. .fromTo('transform', 'translateY(100%)', 'translateY(0%)');
  6284. return baseAnimation
  6285. .addElement(baseEl)
  6286. .easing('cubic-bezier(.36,.66,.04,1)')
  6287. .duration(400)
  6288. .addAnimation([backdropAnimation, wrapperAnimation]);
  6289. };
  6290. /**
  6291. * iOS Action Sheet Leave Animation
  6292. */
  6293. const iosLeaveAnimation$6 = (baseEl) => {
  6294. const baseAnimation = createAnimation();
  6295. const backdropAnimation = createAnimation();
  6296. const wrapperAnimation = createAnimation();
  6297. backdropAnimation.addElement(baseEl.querySelector('ion-backdrop')).fromTo('opacity', 'var(--backdrop-opacity)', 0);
  6298. wrapperAnimation
  6299. .addElement(baseEl.querySelector('.action-sheet-wrapper'))
  6300. .fromTo('transform', 'translateY(0%)', 'translateY(100%)');
  6301. return baseAnimation
  6302. .addElement(baseEl)
  6303. .easing('cubic-bezier(.36,.66,.04,1)')
  6304. .duration(450)
  6305. .addAnimation([backdropAnimation, wrapperAnimation]);
  6306. };
  6307. /**
  6308. * MD Action Sheet Enter Animation
  6309. */
  6310. const mdEnterAnimation$5 = (baseEl) => {
  6311. const baseAnimation = createAnimation();
  6312. const backdropAnimation = createAnimation();
  6313. const wrapperAnimation = createAnimation();
  6314. backdropAnimation
  6315. .addElement(baseEl.querySelector('ion-backdrop'))
  6316. .fromTo('opacity', 0.01, 'var(--backdrop-opacity)')
  6317. .beforeStyles({
  6318. 'pointer-events': 'none',
  6319. })
  6320. .afterClearStyles(['pointer-events']);
  6321. wrapperAnimation
  6322. .addElement(baseEl.querySelector('.action-sheet-wrapper'))
  6323. .fromTo('transform', 'translateY(100%)', 'translateY(0%)');
  6324. return baseAnimation
  6325. .addElement(baseEl)
  6326. .easing('cubic-bezier(.36,.66,.04,1)')
  6327. .duration(400)
  6328. .addAnimation([backdropAnimation, wrapperAnimation]);
  6329. };
  6330. /**
  6331. * MD Action Sheet Leave Animation
  6332. */
  6333. const mdLeaveAnimation$5 = (baseEl) => {
  6334. const baseAnimation = createAnimation();
  6335. const backdropAnimation = createAnimation();
  6336. const wrapperAnimation = createAnimation();
  6337. backdropAnimation.addElement(baseEl.querySelector('ion-backdrop')).fromTo('opacity', 'var(--backdrop-opacity)', 0);
  6338. wrapperAnimation
  6339. .addElement(baseEl.querySelector('.action-sheet-wrapper'))
  6340. .fromTo('transform', 'translateY(0%)', 'translateY(100%)');
  6341. return baseAnimation
  6342. .addElement(baseEl)
  6343. .easing('cubic-bezier(.36,.66,.04,1)')
  6344. .duration(450)
  6345. .addAnimation([backdropAnimation, wrapperAnimation]);
  6346. };
  6347. const actionSheetIosCss = ".sc-ion-action-sheet-ios-h{--color:initial;--button-color-activated:var(--button-color);--button-color-focused:var(--button-color);--button-color-hover:var(--button-color);--button-color-selected:var(--button-color);--min-width:auto;--width:100%;--max-width:500px;--min-height:auto;--height:auto;--max-height:calc(100% - (var(--ion-safe-area-top) + var(--ion-safe-area-bottom)));-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;left:0;right:0;top:0;bottom:0;display:block;position:fixed;outline:none;font-family:var(--ion-font-family, inherit);-ms-touch-action:none;touch-action:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;z-index:1001}.overlay-hidden.sc-ion-action-sheet-ios-h{display:none}.action-sheet-wrapper.sc-ion-action-sheet-ios{left:0;right:0;bottom:0;-webkit-transform:translate3d(0, 100%, 0);transform:translate3d(0, 100%, 0);display:block;position:absolute;width:var(--width);min-width:var(--min-width);max-width:var(--max-width);height:var(--height);min-height:var(--min-height);max-height:var(--max-height);z-index:10;pointer-events:none}.action-sheet-button.sc-ion-action-sheet-ios{display:block;position:relative;width:100%;border:0;outline:none;background:var(--button-background);color:var(--button-color);font-family:inherit;overflow:hidden}.action-sheet-button.sc-ion-action-sheet-ios:disabled{color:var(--button-color-disabled);opacity:0.4}.action-sheet-button-inner.sc-ion-action-sheet-ios{display:-ms-flexbox;display:flex;position:relative;-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-negative:0;flex-shrink:0;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;pointer-events:none;width:100%;height:100%;z-index:1}.action-sheet-container.sc-ion-action-sheet-ios{display:-ms-flexbox;display:flex;-ms-flex-flow:column;flex-flow:column;-ms-flex-pack:end;justify-content:flex-end;height:100%;max-height:calc(100vh - (var(--ion-safe-area-top, 0) + var(--ion-safe-area-bottom, 0)));max-height:calc(100dvh - (var(--ion-safe-area-top, 0) + var(--ion-safe-area-bottom, 0)))}.action-sheet-group.sc-ion-action-sheet-ios{-ms-flex-negative:2;flex-shrink:2;overscroll-behavior-y:contain;overflow-y:auto;-webkit-overflow-scrolling:touch;pointer-events:all;background:var(--background)}@media (any-pointer: coarse){.action-sheet-group.sc-ion-action-sheet-ios::-webkit-scrollbar{display:none}}.action-sheet-group-cancel.sc-ion-action-sheet-ios{-ms-flex-negative:0;flex-shrink:0;overflow:hidden}.action-sheet-button.sc-ion-action-sheet-ios::after{left:0;right:0;top:0;bottom:0;position:absolute;content:\"\";opacity:0}.action-sheet-selected.sc-ion-action-sheet-ios{color:var(--button-color-selected)}.action-sheet-selected.sc-ion-action-sheet-ios::after{background:var(--button-background-selected);opacity:var(--button-background-selected-opacity)}.action-sheet-button.ion-activated.sc-ion-action-sheet-ios{color:var(--button-color-activated)}.action-sheet-button.ion-activated.sc-ion-action-sheet-ios::after{background:var(--button-background-activated);opacity:var(--button-background-activated-opacity)}.action-sheet-button.ion-focused.sc-ion-action-sheet-ios{color:var(--button-color-focused)}.action-sheet-button.ion-focused.sc-ion-action-sheet-ios::after{background:var(--button-background-focused);opacity:var(--button-background-focused-opacity)}@media (any-hover: hover){.action-sheet-button.sc-ion-action-sheet-ios:not(:disabled):hover{color:var(--button-color-hover)}.action-sheet-button.sc-ion-action-sheet-ios:not(:disabled):hover::after{background:var(--button-background-hover);opacity:var(--button-background-hover-opacity)}}.sc-ion-action-sheet-ios-h{--background:var(--ion-overlay-background-color, var(--ion-color-step-100, var(--ion-background-color-step-100, #f9f9f9)));--backdrop-opacity:var(--ion-backdrop-opacity, 0.4);--button-background:linear-gradient(0deg, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.08), rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.08) 50%, transparent 50%) bottom/100% 1px no-repeat transparent;--button-background-activated:var(--ion-text-color, #000);--button-background-activated-opacity:.08;--button-background-hover:currentColor;--button-background-hover-opacity:.04;--button-background-focused:currentColor;--button-background-focused-opacity:.12;--button-background-selected:var(--ion-color-step-150, var(--ion-background-color-step-150, var(--ion-background-color, #fff)));--button-background-selected-opacity:1;--button-color:var(--ion-color-primary, #0054e9);--button-color-disabled:var(--ion-color-step-850, var(--ion-text-color-step-150, #262626));--color:var(--ion-color-step-400, var(--ion-text-color-step-600, #999999));text-align:center}.action-sheet-wrapper.sc-ion-action-sheet-ios{-webkit-margin-start:auto;margin-inline-start:auto;-webkit-margin-end:auto;margin-inline-end:auto;margin-top:var(--ion-safe-area-top, 0);padding-bottom:var(--ion-safe-area-bottom, 0);-webkit-box-sizing:content-box;box-sizing:content-box}.action-sheet-container.sc-ion-action-sheet-ios{-webkit-padding-start:8px;padding-inline-start:8px;-webkit-padding-end:8px;padding-inline-end:8px;padding-top:0;padding-bottom:0}.action-sheet-group.sc-ion-action-sheet-ios{border-radius:13px;margin-bottom:8px}.action-sheet-group.sc-ion-action-sheet-ios:first-child{margin-top:10px}.action-sheet-group.sc-ion-action-sheet-ios:last-child{margin-bottom:10px}@supports ((-webkit-backdrop-filter: blur(0)) or (backdrop-filter: blur(0))){.action-sheet-translucent.sc-ion-action-sheet-ios-h .action-sheet-group.sc-ion-action-sheet-ios{background-color:transparent;-webkit-backdrop-filter:saturate(280%) blur(20px);backdrop-filter:saturate(280%) blur(20px)}.action-sheet-translucent.sc-ion-action-sheet-ios-h .action-sheet-title.sc-ion-action-sheet-ios,.action-sheet-translucent.sc-ion-action-sheet-ios-h .action-sheet-button.sc-ion-action-sheet-ios{background-color:transparent;background-image:-webkit-gradient(linear, left bottom, left top, from(rgba(var(--ion-background-color-rgb, 255, 255, 255), 0.8)), to(rgba(var(--ion-background-color-rgb, 255, 255, 255), 0.8))), -webkit-gradient(linear, left bottom, left top, from(rgba(var(--ion-background-color-rgb, 255, 255, 255), 0.4)), color-stop(50%, rgba(var(--ion-background-color-rgb, 255, 255, 255), 0.4)), color-stop(50%, rgba(var(--ion-background-color-rgb, 255, 255, 255), 0.8)));background-image:linear-gradient(0deg, rgba(var(--ion-background-color-rgb, 255, 255, 255), 0.8), rgba(var(--ion-background-color-rgb, 255, 255, 255), 0.8) 100%), linear-gradient(0deg, rgba(var(--ion-background-color-rgb, 255, 255, 255), 0.4), rgba(var(--ion-background-color-rgb, 255, 255, 255), 0.4) 50%, rgba(var(--ion-background-color-rgb, 255, 255, 255), 0.8) 50%);background-repeat:no-repeat;background-position:top, bottom;background-size:100% calc(100% - 1px), 100% 1px;-webkit-backdrop-filter:saturate(120%);backdrop-filter:saturate(120%)}.action-sheet-translucent.sc-ion-action-sheet-ios-h .action-sheet-button.ion-activated.sc-ion-action-sheet-ios{background-color:rgba(var(--ion-background-color-rgb, 255, 255, 255), 0.7);background-image:none}.action-sheet-translucent.sc-ion-action-sheet-ios-h .action-sheet-cancel.sc-ion-action-sheet-ios{background:var(--button-background-selected)}}.action-sheet-title.sc-ion-action-sheet-ios{background:-webkit-gradient(linear, left bottom, left top, from(rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.08)), color-stop(50%, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.08)), color-stop(50%, transparent)) bottom/100% 1px no-repeat transparent;background:linear-gradient(0deg, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.08), rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.08) 50%, transparent 50%) bottom/100% 1px no-repeat transparent}.action-sheet-title.sc-ion-action-sheet-ios{-webkit-padding-start:10px;padding-inline-start:10px;-webkit-padding-end:10px;padding-inline-end:10px;padding-top:14px;padding-bottom:13px;color:var(--color, var(--ion-color-step-400, var(--ion-text-color-step-600, #999999)));font-size:max(13px, 0.8125rem);font-weight:400;text-align:center}.action-sheet-title.action-sheet-has-sub-title.sc-ion-action-sheet-ios{font-weight:600}.action-sheet-sub-title.sc-ion-action-sheet-ios{padding-left:0;padding-right:0;padding-top:6px;padding-bottom:0;font-size:max(13px, 0.8125rem);font-weight:400}.action-sheet-button.sc-ion-action-sheet-ios{-webkit-padding-start:14px;padding-inline-start:14px;-webkit-padding-end:14px;padding-inline-end:14px;padding-top:14px;padding-bottom:14px;min-height:56px;font-size:max(20px, 1.25rem);contain:content}.action-sheet-button.sc-ion-action-sheet-ios .action-sheet-icon.sc-ion-action-sheet-ios{-webkit-margin-end:0.3em;margin-inline-end:0.3em;font-size:max(28px, 1.75rem);pointer-events:none}.action-sheet-button.sc-ion-action-sheet-ios:last-child{background-image:none}.action-sheet-selected.sc-ion-action-sheet-ios{font-weight:bold}.action-sheet-cancel.sc-ion-action-sheet-ios{font-weight:600}.action-sheet-cancel.sc-ion-action-sheet-ios::after{background:var(--button-background-selected);opacity:var(--button-background-selected-opacity)}.action-sheet-destructive.sc-ion-action-sheet-ios,.action-sheet-destructive.ion-activated.sc-ion-action-sheet-ios,.action-sheet-destructive.ion-focused.sc-ion-action-sheet-ios{color:var(--ion-color-danger, #c5000f)}@media (any-hover: hover){.action-sheet-destructive.sc-ion-action-sheet-ios:hover{color:var(--ion-color-danger, #c5000f)}}";
  6348. var IonActionSheetIosStyle0 = actionSheetIosCss;
  6349. const actionSheetMdCss = ".sc-ion-action-sheet-md-h{--color:initial;--button-color-activated:var(--button-color);--button-color-focused:var(--button-color);--button-color-hover:var(--button-color);--button-color-selected:var(--button-color);--min-width:auto;--width:100%;--max-width:500px;--min-height:auto;--height:auto;--max-height:calc(100% - (var(--ion-safe-area-top) + var(--ion-safe-area-bottom)));-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;left:0;right:0;top:0;bottom:0;display:block;position:fixed;outline:none;font-family:var(--ion-font-family, inherit);-ms-touch-action:none;touch-action:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;z-index:1001}.overlay-hidden.sc-ion-action-sheet-md-h{display:none}.action-sheet-wrapper.sc-ion-action-sheet-md{left:0;right:0;bottom:0;-webkit-transform:translate3d(0, 100%, 0);transform:translate3d(0, 100%, 0);display:block;position:absolute;width:var(--width);min-width:var(--min-width);max-width:var(--max-width);height:var(--height);min-height:var(--min-height);max-height:var(--max-height);z-index:10;pointer-events:none}.action-sheet-button.sc-ion-action-sheet-md{display:block;position:relative;width:100%;border:0;outline:none;background:var(--button-background);color:var(--button-color);font-family:inherit;overflow:hidden}.action-sheet-button.sc-ion-action-sheet-md:disabled{color:var(--button-color-disabled);opacity:0.4}.action-sheet-button-inner.sc-ion-action-sheet-md{display:-ms-flexbox;display:flex;position:relative;-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-negative:0;flex-shrink:0;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;pointer-events:none;width:100%;height:100%;z-index:1}.action-sheet-container.sc-ion-action-sheet-md{display:-ms-flexbox;display:flex;-ms-flex-flow:column;flex-flow:column;-ms-flex-pack:end;justify-content:flex-end;height:100%;max-height:calc(100vh - (var(--ion-safe-area-top, 0) + var(--ion-safe-area-bottom, 0)));max-height:calc(100dvh - (var(--ion-safe-area-top, 0) + var(--ion-safe-area-bottom, 0)))}.action-sheet-group.sc-ion-action-sheet-md{-ms-flex-negative:2;flex-shrink:2;overscroll-behavior-y:contain;overflow-y:auto;-webkit-overflow-scrolling:touch;pointer-events:all;background:var(--background)}@media (any-pointer: coarse){.action-sheet-group.sc-ion-action-sheet-md::-webkit-scrollbar{display:none}}.action-sheet-group-cancel.sc-ion-action-sheet-md{-ms-flex-negative:0;flex-shrink:0;overflow:hidden}.action-sheet-button.sc-ion-action-sheet-md::after{left:0;right:0;top:0;bottom:0;position:absolute;content:\"\";opacity:0}.action-sheet-selected.sc-ion-action-sheet-md{color:var(--button-color-selected)}.action-sheet-selected.sc-ion-action-sheet-md::after{background:var(--button-background-selected);opacity:var(--button-background-selected-opacity)}.action-sheet-button.ion-activated.sc-ion-action-sheet-md{color:var(--button-color-activated)}.action-sheet-button.ion-activated.sc-ion-action-sheet-md::after{background:var(--button-background-activated);opacity:var(--button-background-activated-opacity)}.action-sheet-button.ion-focused.sc-ion-action-sheet-md{color:var(--button-color-focused)}.action-sheet-button.ion-focused.sc-ion-action-sheet-md::after{background:var(--button-background-focused);opacity:var(--button-background-focused-opacity)}@media (any-hover: hover){.action-sheet-button.sc-ion-action-sheet-md:not(:disabled):hover{color:var(--button-color-hover)}.action-sheet-button.sc-ion-action-sheet-md:not(:disabled):hover::after{background:var(--button-background-hover);opacity:var(--button-background-hover-opacity)}}.sc-ion-action-sheet-md-h{--background:var(--ion-overlay-background-color, var(--ion-background-color, #fff));--backdrop-opacity:var(--ion-backdrop-opacity, 0.32);--button-background:transparent;--button-background-selected:currentColor;--button-background-selected-opacity:0;--button-background-activated:transparent;--button-background-activated-opacity:0;--button-background-hover:currentColor;--button-background-hover-opacity:.04;--button-background-focused:currentColor;--button-background-focused-opacity:.12;--button-color:var(--ion-color-step-850, var(--ion-text-color-step-150, #262626));--button-color-disabled:var(--button-color);--color:rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.54)}.action-sheet-wrapper.sc-ion-action-sheet-md{-webkit-margin-start:auto;margin-inline-start:auto;-webkit-margin-end:auto;margin-inline-end:auto;margin-top:var(--ion-safe-area-top, 0);margin-bottom:0}.action-sheet-title.sc-ion-action-sheet-md{-webkit-padding-start:16px;padding-inline-start:16px;-webkit-padding-end:16px;padding-inline-end:16px;padding-top:20px;padding-bottom:17px;min-height:60px;color:var(--color, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.54));font-size:1rem;text-align:start}.action-sheet-sub-title.sc-ion-action-sheet-md{padding-left:0;padding-right:0;padding-top:16px;padding-bottom:0;font-size:0.875rem}.action-sheet-group.sc-ion-action-sheet-md:first-child{padding-top:0}.action-sheet-group.sc-ion-action-sheet-md:last-child{padding-bottom:var(--ion-safe-area-bottom)}.action-sheet-button.sc-ion-action-sheet-md{-webkit-padding-start:16px;padding-inline-start:16px;-webkit-padding-end:16px;padding-inline-end:16px;padding-top:12px;padding-bottom:12px;position:relative;min-height:52px;font-size:1rem;text-align:start;contain:content;overflow:hidden}.action-sheet-icon.sc-ion-action-sheet-md{-webkit-margin-start:0;margin-inline-start:0;-webkit-margin-end:32px;margin-inline-end:32px;margin-top:0;margin-bottom:0;color:var(--color);font-size:1.5rem}.action-sheet-button-inner.sc-ion-action-sheet-md{-ms-flex-pack:start;justify-content:flex-start}.action-sheet-selected.sc-ion-action-sheet-md{font-weight:bold}";
  6350. var IonActionSheetMdStyle0 = actionSheetMdCss;
  6351. /**
  6352. * @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
  6353. */
  6354. class ActionSheet {
  6355. constructor(hostRef) {
  6356. registerInstance(this, hostRef);
  6357. this.didPresent = createEvent(this, "ionActionSheetDidPresent", 7);
  6358. this.willPresent = createEvent(this, "ionActionSheetWillPresent", 7);
  6359. this.willDismiss = createEvent(this, "ionActionSheetWillDismiss", 7);
  6360. this.didDismiss = createEvent(this, "ionActionSheetDidDismiss", 7);
  6361. this.didPresentShorthand = createEvent(this, "didPresent", 7);
  6362. this.willPresentShorthand = createEvent(this, "willPresent", 7);
  6363. this.willDismissShorthand = createEvent(this, "willDismiss", 7);
  6364. this.didDismissShorthand = createEvent(this, "didDismiss", 7);
  6365. this.delegateController = createDelegateController(this);
  6366. this.lockController = createLockController();
  6367. this.triggerController = createTriggerController();
  6368. this.presented = false;
  6369. this.onBackdropTap = () => {
  6370. this.dismiss(undefined, BACKDROP);
  6371. };
  6372. this.dispatchCancelHandler = (ev) => {
  6373. const role = ev.detail.role;
  6374. if (isCancel(role)) {
  6375. const cancelButton = this.getButtons().find((b) => b.role === 'cancel');
  6376. this.callButtonHandler(cancelButton);
  6377. }
  6378. };
  6379. this.overlayIndex = undefined;
  6380. this.delegate = undefined;
  6381. this.hasController = false;
  6382. this.keyboardClose = true;
  6383. this.enterAnimation = undefined;
  6384. this.leaveAnimation = undefined;
  6385. this.buttons = [];
  6386. this.cssClass = undefined;
  6387. this.backdropDismiss = true;
  6388. this.header = undefined;
  6389. this.subHeader = undefined;
  6390. this.translucent = false;
  6391. this.animated = true;
  6392. this.htmlAttributes = undefined;
  6393. this.isOpen = false;
  6394. this.trigger = undefined;
  6395. }
  6396. onIsOpenChange(newValue, oldValue) {
  6397. if (newValue === true && oldValue === false) {
  6398. this.present();
  6399. }
  6400. else if (newValue === false && oldValue === true) {
  6401. this.dismiss();
  6402. }
  6403. }
  6404. triggerChanged() {
  6405. const { trigger, el, triggerController } = this;
  6406. if (trigger) {
  6407. triggerController.addClickListener(el, trigger);
  6408. }
  6409. }
  6410. /**
  6411. * Present the action sheet overlay after it has been created.
  6412. */
  6413. async present() {
  6414. const unlock = await this.lockController.lock();
  6415. await this.delegateController.attachViewToDom();
  6416. await present(this, 'actionSheetEnter', iosEnterAnimation$6, mdEnterAnimation$5);
  6417. unlock();
  6418. }
  6419. /**
  6420. * Dismiss the action sheet overlay after it has been presented.
  6421. *
  6422. * @param data Any data to emit in the dismiss events.
  6423. * @param role The role of the element that is dismissing the action sheet.
  6424. * This can be useful in a button handler for determining which button was
  6425. * clicked to dismiss the action sheet.
  6426. * Some examples include: ``"cancel"`, `"destructive"`, "selected"`, and `"backdrop"`.
  6427. *
  6428. * This is a no-op if the overlay has not been presented yet. If you want
  6429. * to remove an overlay from the DOM that was never presented, use the
  6430. * [remove](https://developer.mozilla.org/en-US/docs/Web/API/Element/remove) method.
  6431. */
  6432. async dismiss(data, role) {
  6433. const unlock = await this.lockController.lock();
  6434. const dismissed = await dismiss(this, data, role, 'actionSheetLeave', iosLeaveAnimation$6, mdLeaveAnimation$5);
  6435. if (dismissed) {
  6436. this.delegateController.removeViewFromDom();
  6437. }
  6438. unlock();
  6439. return dismissed;
  6440. }
  6441. /**
  6442. * Returns a promise that resolves when the action sheet did dismiss.
  6443. */
  6444. onDidDismiss() {
  6445. return eventMethod(this.el, 'ionActionSheetDidDismiss');
  6446. }
  6447. /**
  6448. * Returns a promise that resolves when the action sheet will dismiss.
  6449. *
  6450. */
  6451. onWillDismiss() {
  6452. return eventMethod(this.el, 'ionActionSheetWillDismiss');
  6453. }
  6454. async buttonClick(button) {
  6455. const role = button.role;
  6456. if (isCancel(role)) {
  6457. return this.dismiss(button.data, role);
  6458. }
  6459. const shouldDismiss = await this.callButtonHandler(button);
  6460. if (shouldDismiss) {
  6461. return this.dismiss(button.data, button.role);
  6462. }
  6463. return Promise.resolve();
  6464. }
  6465. async callButtonHandler(button) {
  6466. if (button) {
  6467. // a handler has been provided, execute it
  6468. // pass the handler the values from the inputs
  6469. const rtn = await safeCall(button.handler);
  6470. if (rtn === false) {
  6471. // if the return value of the handler is false then do not dismiss
  6472. return false;
  6473. }
  6474. }
  6475. return true;
  6476. }
  6477. getButtons() {
  6478. return this.buttons.map((b) => {
  6479. return typeof b === 'string' ? { text: b } : b;
  6480. });
  6481. }
  6482. connectedCallback() {
  6483. prepareOverlay(this.el);
  6484. this.triggerChanged();
  6485. }
  6486. disconnectedCallback() {
  6487. if (this.gesture) {
  6488. this.gesture.destroy();
  6489. this.gesture = undefined;
  6490. }
  6491. this.triggerController.removeClickListener();
  6492. }
  6493. componentWillLoad() {
  6494. var _a;
  6495. if (!((_a = this.htmlAttributes) === null || _a === void 0 ? void 0 : _a.id)) {
  6496. setOverlayId(this.el);
  6497. }
  6498. }
  6499. componentDidLoad() {
  6500. /**
  6501. * Only create gesture if:
  6502. * 1. A gesture does not already exist
  6503. * 2. App is running in iOS mode
  6504. * 3. A wrapper ref exists
  6505. * 4. A group ref exists
  6506. */
  6507. const { groupEl, wrapperEl } = this;
  6508. if (!this.gesture && getIonMode$1(this) === 'ios' && wrapperEl && groupEl) {
  6509. readTask(() => {
  6510. const isScrollable = groupEl.scrollHeight > groupEl.clientHeight;
  6511. if (!isScrollable) {
  6512. this.gesture = createButtonActiveGesture(wrapperEl, (refEl) => refEl.classList.contains('action-sheet-button'));
  6513. this.gesture.enable(true);
  6514. }
  6515. });
  6516. }
  6517. /**
  6518. * If action sheet was rendered with isOpen="true"
  6519. * then we should open action sheet immediately.
  6520. */
  6521. if (this.isOpen === true) {
  6522. raf(() => this.present());
  6523. }
  6524. /**
  6525. * When binding values in frameworks such as Angular
  6526. * it is possible for the value to be set after the Web Component
  6527. * initializes but before the value watcher is set up in Stencil.
  6528. * As a result, the watcher callback may not be fired.
  6529. * We work around this by manually calling the watcher
  6530. * callback when the component has loaded and the watcher
  6531. * is configured.
  6532. */
  6533. this.triggerChanged();
  6534. }
  6535. render() {
  6536. const { header, htmlAttributes, overlayIndex } = this;
  6537. const mode = getIonMode$1(this);
  6538. const allButtons = this.getButtons();
  6539. const cancelButton = allButtons.find((b) => b.role === 'cancel');
  6540. const buttons = allButtons.filter((b) => b.role !== 'cancel');
  6541. const headerID = `action-sheet-${overlayIndex}-header`;
  6542. return (hAsync(Host, Object.assign({ key: '7bbd202ca9e19727e7514abbe073687d982f80c3', role: "dialog", "aria-modal": "true", "aria-labelledby": header !== undefined ? headerID : null, tabindex: "-1" }, htmlAttributes, { style: {
  6543. zIndex: `${20000 + this.overlayIndex}`,
  6544. }, class: Object.assign(Object.assign({ [mode]: true }, getClassMap(this.cssClass)), { 'overlay-hidden': true, 'action-sheet-translucent': this.translucent }), onIonActionSheetWillDismiss: this.dispatchCancelHandler, onIonBackdropTap: this.onBackdropTap }), hAsync("ion-backdrop", { key: '23344a9221a2e6720d7b9de5249dc37256cafa7b', tappable: this.backdropDismiss }), hAsync("div", { key: 'fbc2ba15549c2ab04e759e82df6e177fd80cc0a6', tabindex: "0", "aria-hidden": "true" }), hAsync("div", { key: '748ee5235d0b4cb26d6f1b7589f77af2e37ad28a', class: "action-sheet-wrapper ion-overlay-wrapper", ref: (el) => (this.wrapperEl = el) }, hAsync("div", { key: '7ce5fa236cf75e9b1e49c4725c9a811078706554', class: "action-sheet-container" }, hAsync("div", { key: 'dc2251f3bcee4a93e3449f09621cbd2b65d329e9', class: "action-sheet-group", ref: (el) => (this.groupEl = el) }, header !== undefined && (hAsync("div", { key: '48d325c8a852f56ed57a9ada1a6709d05ba32ee2', id: headerID, class: {
  6545. 'action-sheet-title': true,
  6546. 'action-sheet-has-sub-title': this.subHeader !== undefined,
  6547. } }, header, this.subHeader && hAsync("div", { key: '66093728052eb67f37a35f3232761ce4a08896f3', class: "action-sheet-sub-title" }, this.subHeader))), buttons.map((b) => (hAsync("button", Object.assign({}, b.htmlAttributes, { type: "button", id: b.id, class: buttonClass$3(b), onClick: () => this.buttonClick(b), disabled: b.disabled }), hAsync("span", { class: "action-sheet-button-inner" }, b.icon && hAsync("ion-icon", { icon: b.icon, "aria-hidden": "true", lazy: false, class: "action-sheet-icon" }), b.text), mode === 'md' && hAsync("ion-ripple-effect", null))))), cancelButton && (hAsync("div", { key: 'f4eb8e3e2885b85af5080df18d0de0bdd1d719de', class: "action-sheet-group action-sheet-group-cancel" }, hAsync("button", Object.assign({ key: '169f4eb09255aba85062baad49ceb151239fbfb7' }, cancelButton.htmlAttributes, { type: "button", class: buttonClass$3(cancelButton), onClick: () => this.buttonClick(cancelButton) }), hAsync("span", { key: '25fb8a466dd67ea94c79cfb4f9965527e1ce6d42', class: "action-sheet-button-inner" }, cancelButton.icon && (hAsync("ion-icon", { key: 'eb5b071e120a2c86afdf967af6a763a43044d1ca', icon: cancelButton.icon, "aria-hidden": "true", lazy: false, class: "action-sheet-icon" })), cancelButton.text), mode === 'md' && hAsync("ion-ripple-effect", { key: '452ad7e1052b2c681e2d98de8193949755ad4d54' })))))), hAsync("div", { key: 'e1cecf280c987c050d9445e2c458b903f153089b', tabindex: "0", "aria-hidden": "true" })));
  6548. }
  6549. get el() { return getElement(this); }
  6550. static get watchers() { return {
  6551. "isOpen": ["onIsOpenChange"],
  6552. "trigger": ["triggerChanged"]
  6553. }; }
  6554. static get style() { return {
  6555. ios: IonActionSheetIosStyle0,
  6556. md: IonActionSheetMdStyle0
  6557. }; }
  6558. static get cmpMeta() { return {
  6559. "$flags$": 34,
  6560. "$tagName$": "ion-action-sheet",
  6561. "$members$": {
  6562. "overlayIndex": [2, "overlay-index"],
  6563. "delegate": [16],
  6564. "hasController": [4, "has-controller"],
  6565. "keyboardClose": [4, "keyboard-close"],
  6566. "enterAnimation": [16],
  6567. "leaveAnimation": [16],
  6568. "buttons": [16],
  6569. "cssClass": [1, "css-class"],
  6570. "backdropDismiss": [4, "backdrop-dismiss"],
  6571. "header": [1],
  6572. "subHeader": [1, "sub-header"],
  6573. "translucent": [4],
  6574. "animated": [4],
  6575. "htmlAttributes": [16],
  6576. "isOpen": [4, "is-open"],
  6577. "trigger": [1],
  6578. "present": [64],
  6579. "dismiss": [64],
  6580. "onDidDismiss": [64],
  6581. "onWillDismiss": [64]
  6582. },
  6583. "$listeners$": undefined,
  6584. "$lazyBundleId$": "-",
  6585. "$attrsToReflect$": []
  6586. }; }
  6587. }
  6588. const buttonClass$3 = (button) => {
  6589. return Object.assign({ 'action-sheet-button': true, 'ion-activatable': !button.disabled, 'ion-focusable': !button.disabled, [`action-sheet-${button.role}`]: button.role !== undefined }, getClassMap(button.cssClass));
  6590. };
  6591. const ENABLE_HTML_CONTENT_DEFAULT = false;
  6592. /**
  6593. * Does a simple sanitization of all elements
  6594. * in an untrusted string
  6595. */
  6596. const sanitizeDOMString = (untrustedString) => {
  6597. try {
  6598. if (untrustedString instanceof IonicSafeString) {
  6599. return untrustedString.value;
  6600. }
  6601. if (!isSanitizerEnabled() || typeof untrustedString !== 'string' || untrustedString === '') {
  6602. return untrustedString;
  6603. }
  6604. /**
  6605. * onload is fired when appending to a document
  6606. * fragment in Chrome. If a string
  6607. * contains onload then we should not
  6608. * attempt to add this to the fragment.
  6609. */
  6610. if (untrustedString.includes('onload=')) {
  6611. return '';
  6612. }
  6613. /**
  6614. * Create a document fragment
  6615. * separate from the main DOM,
  6616. * create a div to do our work in
  6617. */
  6618. const documentFragment = document.createDocumentFragment();
  6619. const workingDiv = document.createElement('div');
  6620. documentFragment.appendChild(workingDiv);
  6621. workingDiv.innerHTML = untrustedString;
  6622. /**
  6623. * Remove any elements
  6624. * that are blocked
  6625. */
  6626. blockedTags.forEach((blockedTag) => {
  6627. const getElementsToRemove = documentFragment.querySelectorAll(blockedTag);
  6628. for (let elementIndex = getElementsToRemove.length - 1; elementIndex >= 0; elementIndex--) {
  6629. const element = getElementsToRemove[elementIndex];
  6630. if (element.parentNode) {
  6631. element.parentNode.removeChild(element);
  6632. }
  6633. else {
  6634. documentFragment.removeChild(element);
  6635. }
  6636. /**
  6637. * We still need to sanitize
  6638. * the children of this element
  6639. * as they are left behind
  6640. */
  6641. const childElements = getElementChildren(element);
  6642. /* eslint-disable-next-line */
  6643. for (let childIndex = 0; childIndex < childElements.length; childIndex++) {
  6644. sanitizeElement(childElements[childIndex]);
  6645. }
  6646. }
  6647. });
  6648. /**
  6649. * Go through remaining elements and remove
  6650. * non-allowed attribs
  6651. */
  6652. // IE does not support .children on document fragments, only .childNodes
  6653. const dfChildren = getElementChildren(documentFragment);
  6654. /* eslint-disable-next-line */
  6655. for (let childIndex = 0; childIndex < dfChildren.length; childIndex++) {
  6656. sanitizeElement(dfChildren[childIndex]);
  6657. }
  6658. // Append document fragment to div
  6659. const fragmentDiv = document.createElement('div');
  6660. fragmentDiv.appendChild(documentFragment);
  6661. // First child is always the div we did our work in
  6662. const getInnerDiv = fragmentDiv.querySelector('div');
  6663. return getInnerDiv !== null ? getInnerDiv.innerHTML : fragmentDiv.innerHTML;
  6664. }
  6665. catch (err) {
  6666. printIonError('sanitizeDOMString', err);
  6667. return '';
  6668. }
  6669. };
  6670. /**
  6671. * Clean up current element based on allowed attributes
  6672. * and then recursively dig down into any child elements to
  6673. * clean those up as well
  6674. */
  6675. // TODO(FW-2832): type (using Element triggers other type errors as well)
  6676. const sanitizeElement = (element) => {
  6677. // IE uses childNodes, so ignore nodes that are not elements
  6678. if (element.nodeType && element.nodeType !== 1) {
  6679. return;
  6680. }
  6681. /**
  6682. * If attributes is not a NamedNodeMap
  6683. * then we should remove the element entirely.
  6684. * This helps avoid DOM Clobbering attacks where
  6685. * attributes is overridden.
  6686. */
  6687. if (typeof NamedNodeMap !== 'undefined' && !(element.attributes instanceof NamedNodeMap)) {
  6688. element.remove();
  6689. return;
  6690. }
  6691. for (let i = element.attributes.length - 1; i >= 0; i--) {
  6692. const attribute = element.attributes.item(i);
  6693. const attributeName = attribute.name;
  6694. // remove non-allowed attribs
  6695. if (!allowedAttributes.includes(attributeName.toLowerCase())) {
  6696. element.removeAttribute(attributeName);
  6697. continue;
  6698. }
  6699. // clean up any allowed attribs
  6700. // that attempt to do any JS funny-business
  6701. const attributeValue = attribute.value;
  6702. /**
  6703. * We also need to check the property value
  6704. * as javascript: can allow special characters
  6705. * such as &Tab; and still be valid (i.e. java&Tab;script)
  6706. */
  6707. const propertyValue = element[attributeName];
  6708. /* eslint-disable */
  6709. if ((attributeValue != null && attributeValue.toLowerCase().includes('javascript:')) ||
  6710. (propertyValue != null && propertyValue.toLowerCase().includes('javascript:'))) {
  6711. element.removeAttribute(attributeName);
  6712. }
  6713. /* eslint-enable */
  6714. }
  6715. /**
  6716. * Sanitize any nested children
  6717. */
  6718. const childElements = getElementChildren(element);
  6719. /* eslint-disable-next-line */
  6720. for (let i = 0; i < childElements.length; i++) {
  6721. sanitizeElement(childElements[i]);
  6722. }
  6723. };
  6724. /**
  6725. * IE doesn't always support .children
  6726. * so we revert to .childNodes instead
  6727. */
  6728. // TODO(FW-2832): type
  6729. const getElementChildren = (el) => {
  6730. return el.children != null ? el.children : el.childNodes;
  6731. };
  6732. const isSanitizerEnabled = () => {
  6733. var _a;
  6734. const win = window;
  6735. const config = (_a = win === null || win === void 0 ? void 0 : win.Ionic) === null || _a === void 0 ? void 0 : _a.config;
  6736. if (config) {
  6737. if (config.get) {
  6738. return config.get('sanitizerEnabled', true);
  6739. }
  6740. else {
  6741. return config.sanitizerEnabled === true || config.sanitizerEnabled === undefined;
  6742. }
  6743. }
  6744. return true;
  6745. };
  6746. const allowedAttributes = ['class', 'id', 'href', 'src', 'name', 'slot'];
  6747. const blockedTags = ['script', 'style', 'iframe', 'meta', 'link', 'object', 'embed'];
  6748. class IonicSafeString {
  6749. constructor(value) {
  6750. this.value = value;
  6751. }
  6752. }
  6753. /**
  6754. * iOS Alert Enter Animation
  6755. */
  6756. const iosEnterAnimation$5 = (baseEl) => {
  6757. const baseAnimation = createAnimation();
  6758. const backdropAnimation = createAnimation();
  6759. const wrapperAnimation = createAnimation();
  6760. backdropAnimation
  6761. .addElement(baseEl.querySelector('ion-backdrop'))
  6762. .fromTo('opacity', 0.01, 'var(--backdrop-opacity)')
  6763. .beforeStyles({
  6764. 'pointer-events': 'none',
  6765. })
  6766. .afterClearStyles(['pointer-events']);
  6767. wrapperAnimation.addElement(baseEl.querySelector('.alert-wrapper')).keyframes([
  6768. { offset: 0, opacity: '0.01', transform: 'scale(1.1)' },
  6769. { offset: 1, opacity: '1', transform: 'scale(1)' },
  6770. ]);
  6771. return baseAnimation
  6772. .addElement(baseEl)
  6773. .easing('ease-in-out')
  6774. .duration(200)
  6775. .addAnimation([backdropAnimation, wrapperAnimation]);
  6776. };
  6777. /**
  6778. * iOS Alert Leave Animation
  6779. */
  6780. const iosLeaveAnimation$5 = (baseEl) => {
  6781. const baseAnimation = createAnimation();
  6782. const backdropAnimation = createAnimation();
  6783. const wrapperAnimation = createAnimation();
  6784. backdropAnimation.addElement(baseEl.querySelector('ion-backdrop')).fromTo('opacity', 'var(--backdrop-opacity)', 0);
  6785. wrapperAnimation.addElement(baseEl.querySelector('.alert-wrapper')).keyframes([
  6786. { offset: 0, opacity: 0.99, transform: 'scale(1)' },
  6787. { offset: 1, opacity: 0, transform: 'scale(0.9)' },
  6788. ]);
  6789. return baseAnimation
  6790. .addElement(baseEl)
  6791. .easing('ease-in-out')
  6792. .duration(200)
  6793. .addAnimation([backdropAnimation, wrapperAnimation]);
  6794. };
  6795. /**
  6796. * Md Alert Enter Animation
  6797. */
  6798. const mdEnterAnimation$4 = (baseEl) => {
  6799. const baseAnimation = createAnimation();
  6800. const backdropAnimation = createAnimation();
  6801. const wrapperAnimation = createAnimation();
  6802. backdropAnimation
  6803. .addElement(baseEl.querySelector('ion-backdrop'))
  6804. .fromTo('opacity', 0.01, 'var(--backdrop-opacity)')
  6805. .beforeStyles({
  6806. 'pointer-events': 'none',
  6807. })
  6808. .afterClearStyles(['pointer-events']);
  6809. wrapperAnimation.addElement(baseEl.querySelector('.alert-wrapper')).keyframes([
  6810. { offset: 0, opacity: '0.01', transform: 'scale(0.9)' },
  6811. { offset: 1, opacity: '1', transform: 'scale(1)' },
  6812. ]);
  6813. return baseAnimation
  6814. .addElement(baseEl)
  6815. .easing('ease-in-out')
  6816. .duration(150)
  6817. .addAnimation([backdropAnimation, wrapperAnimation]);
  6818. };
  6819. /**
  6820. * Md Alert Leave Animation
  6821. */
  6822. const mdLeaveAnimation$4 = (baseEl) => {
  6823. const baseAnimation = createAnimation();
  6824. const backdropAnimation = createAnimation();
  6825. const wrapperAnimation = createAnimation();
  6826. backdropAnimation.addElement(baseEl.querySelector('ion-backdrop')).fromTo('opacity', 'var(--backdrop-opacity)', 0);
  6827. wrapperAnimation.addElement(baseEl.querySelector('.alert-wrapper')).fromTo('opacity', 0.99, 0);
  6828. return baseAnimation
  6829. .addElement(baseEl)
  6830. .easing('ease-in-out')
  6831. .duration(150)
  6832. .addAnimation([backdropAnimation, wrapperAnimation]);
  6833. };
  6834. const alertIosCss = ".sc-ion-alert-ios-h{--min-width:250px;--width:auto;--min-height:auto;--height:auto;--max-height:90%;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;left:0;right:0;top:0;bottom:0;display:-ms-flexbox;display:flex;position:absolute;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;outline:none;font-family:var(--ion-font-family, inherit);contain:strict;-ms-touch-action:none;touch-action:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;z-index:1001}.overlay-hidden.sc-ion-alert-ios-h{display:none}.alert-top.sc-ion-alert-ios-h{padding-top:50px;-ms-flex-align:start;align-items:flex-start}.alert-wrapper.sc-ion-alert-ios{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;width:var(--width);min-width:var(--min-width);max-width:var(--max-width);height:var(--height);min-height:var(--min-height);max-height:var(--max-height);background:var(--background);contain:content;opacity:0;z-index:10}.alert-title.sc-ion-alert-ios{margin-left:0;margin-right:0;margin-top:0;margin-bottom:0;padding-left:0;padding-right:0;padding-top:0;padding-bottom:0}.alert-sub-title.sc-ion-alert-ios{margin-left:0;margin-right:0;margin-top:5px;margin-bottom:0;padding-left:0;padding-right:0;padding-top:0;padding-bottom:0;font-weight:normal}.alert-message.sc-ion-alert-ios,.alert-input-group.sc-ion-alert-ios{-webkit-box-sizing:border-box;box-sizing:border-box;-webkit-overflow-scrolling:touch;overflow-y:auto;overscroll-behavior-y:contain}.alert-checkbox-label.sc-ion-alert-ios,.alert-radio-label.sc-ion-alert-ios{overflow-wrap:anywhere}@media (any-pointer: coarse){.alert-checkbox-group.sc-ion-alert-ios::-webkit-scrollbar,.alert-radio-group.sc-ion-alert-ios::-webkit-scrollbar,.alert-message.sc-ion-alert-ios::-webkit-scrollbar{display:none}}.alert-input.sc-ion-alert-ios{padding-left:0;padding-right:0;padding-top:10px;padding-bottom:10px;width:100%;border:0;background:inherit;font:inherit;-webkit-box-sizing:border-box;box-sizing:border-box}.alert-button-group.sc-ion-alert-ios{display:-ms-flexbox;display:flex;-ms-flex-direction:row;flex-direction:row;width:100%}.alert-button-group-vertical.sc-ion-alert-ios{-ms-flex-direction:column;flex-direction:column;-ms-flex-wrap:nowrap;flex-wrap:nowrap}.alert-button.sc-ion-alert-ios{margin-left:0;margin-right:0;margin-top:0;margin-bottom:0;display:block;border:0;font-size:0.875rem;line-height:1.25rem;z-index:0}.alert-button.ion-focused.sc-ion-alert-ios,.alert-tappable.ion-focused.sc-ion-alert-ios{background:var(--ion-color-step-100, var(--ion-background-color-step-100, #e6e6e6))}.alert-button-inner.sc-ion-alert-ios{display:-ms-flexbox;display:flex;-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-negative:0;flex-shrink:0;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;width:100%;height:100%;min-height:inherit}.alert-input-disabled.sc-ion-alert-ios,.alert-checkbox-button-disabled.sc-ion-alert-ios .alert-button-inner.sc-ion-alert-ios,.alert-radio-button-disabled.sc-ion-alert-ios .alert-button-inner.sc-ion-alert-ios{cursor:default;opacity:0.5;pointer-events:none}.alert-tappable.sc-ion-alert-ios{margin-left:0;margin-right:0;margin-top:0;margin-bottom:0;padding-left:0;padding-right:0;padding-top:0;padding-bottom:0;display:-ms-flexbox;display:flex;width:100%;border:0;background:transparent;font-size:inherit;line-height:initial;text-align:start;-webkit-appearance:none;-moz-appearance:none;appearance:none;contain:content}.alert-button.sc-ion-alert-ios,.alert-checkbox.sc-ion-alert-ios,.alert-input.sc-ion-alert-ios,.alert-radio.sc-ion-alert-ios{outline:none}.alert-radio-icon.sc-ion-alert-ios,.alert-checkbox-icon.sc-ion-alert-ios,.alert-checkbox-inner.sc-ion-alert-ios{-webkit-box-sizing:border-box;box-sizing:border-box}textarea.alert-input.sc-ion-alert-ios{min-height:37px;resize:none}.sc-ion-alert-ios-h{--background:var(--ion-overlay-background-color, var(--ion-color-step-100, var(--ion-background-color-step-100, #f9f9f9)));--max-width:clamp(270px, 16.875rem, 324px);--backdrop-opacity:var(--ion-backdrop-opacity, 0.3);font-size:max(14px, 0.875rem)}.alert-wrapper.sc-ion-alert-ios{border-radius:13px;-webkit-box-shadow:none;box-shadow:none;overflow:hidden}.alert-button.sc-ion-alert-ios .alert-button-inner.sc-ion-alert-ios{pointer-events:none}@supports ((-webkit-backdrop-filter: blur(0)) or (backdrop-filter: blur(0))){.alert-translucent.sc-ion-alert-ios-h .alert-wrapper.sc-ion-alert-ios{background:rgba(var(--ion-background-color-rgb, 255, 255, 255), 0.9);-webkit-backdrop-filter:saturate(180%) blur(20px);backdrop-filter:saturate(180%) blur(20px)}}.alert-head.sc-ion-alert-ios{-webkit-padding-start:16px;padding-inline-start:16px;-webkit-padding-end:16px;padding-inline-end:16px;padding-top:12px;padding-bottom:7px;text-align:center}.alert-title.sc-ion-alert-ios{margin-top:8px;color:var(--ion-text-color, #000);font-size:max(17px, 1.0625rem);font-weight:600}.alert-sub-title.sc-ion-alert-ios{color:var(--ion-color-step-600, var(--ion-text-color-step-400, #666666));font-size:max(14px, 0.875rem)}.alert-message.sc-ion-alert-ios,.alert-input-group.sc-ion-alert-ios{-webkit-padding-start:16px;padding-inline-start:16px;-webkit-padding-end:16px;padding-inline-end:16px;padding-top:0;padding-bottom:21px;color:var(--ion-text-color, #000);font-size:max(13px, 0.8125rem);text-align:center}.alert-message.sc-ion-alert-ios{max-height:240px}.alert-message.sc-ion-alert-ios:empty{padding-left:0;padding-right:0;padding-top:0;padding-bottom:12px}.alert-input.sc-ion-alert-ios{border-radius:7px;margin-top:10px;-webkit-padding-start:7px;padding-inline-start:7px;-webkit-padding-end:7px;padding-inline-end:7px;padding-top:7px;padding-bottom:7px;border:0.55px solid var(--ion-color-step-250, var(--ion-background-color-step-250, #bfbfbf));background-color:var(--ion-background-color, #fff);-webkit-appearance:none;-moz-appearance:none;appearance:none;font-size:1rem}.alert-input.sc-ion-alert-ios::-webkit-input-placeholder{color:var(--ion-placeholder-color, var(--ion-color-step-400, var(--ion-text-color-step-600, #999999)));font-family:inherit;font-weight:inherit}.alert-input.sc-ion-alert-ios::-moz-placeholder{color:var(--ion-placeholder-color, var(--ion-color-step-400, var(--ion-text-color-step-600, #999999)));font-family:inherit;font-weight:inherit}.alert-input.sc-ion-alert-ios:-ms-input-placeholder{color:var(--ion-placeholder-color, var(--ion-color-step-400, var(--ion-text-color-step-600, #999999)));font-family:inherit;font-weight:inherit}.alert-input.sc-ion-alert-ios::-ms-input-placeholder{color:var(--ion-placeholder-color, var(--ion-color-step-400, var(--ion-text-color-step-600, #999999)));font-family:inherit;font-weight:inherit}.alert-input.sc-ion-alert-ios::placeholder{color:var(--ion-placeholder-color, var(--ion-color-step-400, var(--ion-text-color-step-600, #999999)));font-family:inherit;font-weight:inherit}.alert-input.sc-ion-alert-ios::-ms-clear{display:none}.alert-input.sc-ion-alert-ios::-webkit-date-and-time-value{height:18px}.alert-radio-group.sc-ion-alert-ios,.alert-checkbox-group.sc-ion-alert-ios{-ms-scroll-chaining:none;overscroll-behavior:contain;max-height:240px;border-top:0.55px solid rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.2);overflow-y:auto;-webkit-overflow-scrolling:touch}.alert-tappable.sc-ion-alert-ios{min-height:44px}.alert-radio-label.sc-ion-alert-ios{-webkit-padding-start:13px;padding-inline-start:13px;-webkit-padding-end:13px;padding-inline-end:13px;padding-top:13px;padding-bottom:13px;-ms-flex:1;flex:1;-ms-flex-order:0;order:0;color:var(--ion-text-color, #000)}[aria-checked=true].sc-ion-alert-ios .alert-radio-label.sc-ion-alert-ios{color:var(--ion-color-primary, #0054e9)}.alert-radio-icon.sc-ion-alert-ios{position:relative;-ms-flex-order:1;order:1;min-width:30px}[aria-checked=true].sc-ion-alert-ios .alert-radio-inner.sc-ion-alert-ios{top:-7px;position:absolute;width:6px;height:12px;-webkit-transform:rotate(45deg);transform:rotate(45deg);border-width:2px;border-top-width:0;border-left-width:0;border-style:solid;border-color:var(--ion-color-primary, #0054e9)}[aria-checked=true].sc-ion-alert-ios .alert-radio-inner.sc-ion-alert-ios{inset-inline-start:7px}.alert-checkbox-label.sc-ion-alert-ios{-webkit-padding-start:13px;padding-inline-start:13px;-webkit-padding-end:13px;padding-inline-end:13px;padding-top:13px;padding-bottom:13px;-ms-flex:1;flex:1;color:var(--ion-text-color, #000)}.alert-checkbox-icon.sc-ion-alert-ios{border-radius:50%;-webkit-margin-start:16px;margin-inline-start:16px;-webkit-margin-end:6px;margin-inline-end:6px;margin-top:10px;margin-bottom:10px;position:relative;width:min(1.375rem, 55.836px);height:min(1.375rem, 55.836px);border-width:0.125rem;border-style:solid;border-color:var(--ion-item-border-color, var(--ion-border-color, var(--ion-color-step-250, var(--ion-background-color-step-250, #c8c7cc))));background-color:var(--ion-item-background, var(--ion-background-color, #fff));contain:strict}[aria-checked=true].sc-ion-alert-ios .alert-checkbox-icon.sc-ion-alert-ios{border-color:var(--ion-color-primary, #0054e9);background-color:var(--ion-color-primary, #0054e9)}[aria-checked=true].sc-ion-alert-ios .alert-checkbox-inner.sc-ion-alert-ios{top:calc(min(1.375rem, 55.836px) / 8);position:absolute;width:calc(min(1.375rem, 55.836px) / 6 + 1px);height:calc(min(1.375rem, 55.836px) * 0.5);-webkit-transform:rotate(45deg);transform:rotate(45deg);border-width:0.125rem;border-top-width:0;border-left-width:0;border-style:solid;border-color:var(--ion-background-color, #fff)}[aria-checked=true].sc-ion-alert-ios .alert-checkbox-inner.sc-ion-alert-ios{inset-inline-start:calc(min(1.375rem, 55.836px) / 3)}.alert-button-group.sc-ion-alert-ios{-webkit-margin-end:-0.55px;margin-inline-end:-0.55px;-ms-flex-wrap:wrap;flex-wrap:wrap}.alert-button-group-vertical.sc-ion-alert-ios .alert-button.sc-ion-alert-ios{border-right:none}[dir=rtl].sc-ion-alert-ios-h .alert-button-group-vertical.sc-ion-alert-ios .alert-button.sc-ion-alert-ios:last-child,[dir=rtl] .sc-ion-alert-ios-h .alert-button-group-vertical.sc-ion-alert-ios .alert-button.sc-ion-alert-ios:last-child{border-right:none}[dir=rtl].sc-ion-alert-ios .alert-button-group-vertical.sc-ion-alert-ios .alert-button.sc-ion-alert-ios:last-child{border-right:none}@supports selector(:dir(rtl)){.alert-button-group-vertical.sc-ion-alert-ios .alert-button.sc-ion-alert-ios:last-child:dir(rtl){border-right:none}}.alert-button.sc-ion-alert-ios{-webkit-padding-start:8px;padding-inline-start:8px;-webkit-padding-end:8px;padding-inline-end:8px;margin-left:0;margin-right:0;margin-top:0;margin-bottom:0;border-radius:0;-ms-flex:1 1 auto;flex:1 1 auto;min-width:50%;height:max(44px, 2.75rem);border-top:0.55px solid rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.2);border-right:0.55px solid rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.2);background-color:transparent;color:var(--ion-color-primary, #0054e9);font-size:max(17px, 1.0625rem);overflow:hidden}[dir=rtl].sc-ion-alert-ios-h .alert-button.sc-ion-alert-ios:first-child,[dir=rtl] .sc-ion-alert-ios-h .alert-button.sc-ion-alert-ios:first-child{border-right:0}[dir=rtl].sc-ion-alert-ios .alert-button.sc-ion-alert-ios:first-child{border-right:0}@supports selector(:dir(rtl)){.alert-button.sc-ion-alert-ios:first-child:dir(rtl){border-right:0}}.alert-button.sc-ion-alert-ios:last-child{border-right:0;font-weight:bold}[dir=rtl].sc-ion-alert-ios-h .alert-button.sc-ion-alert-ios:last-child,[dir=rtl] .sc-ion-alert-ios-h .alert-button.sc-ion-alert-ios:last-child{border-right:0.55px solid rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.2)}[dir=rtl].sc-ion-alert-ios .alert-button.sc-ion-alert-ios:last-child{border-right:0.55px solid rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.2)}@supports selector(:dir(rtl)){.alert-button.sc-ion-alert-ios:last-child:dir(rtl){border-right:0.55px solid rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.2)}}.alert-button.ion-activated.sc-ion-alert-ios{background-color:rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.1)}.alert-button-role-destructive.sc-ion-alert-ios,.alert-button-role-destructive.ion-activated.sc-ion-alert-ios,.alert-button-role-destructive.ion-focused.sc-ion-alert-ios{color:var(--ion-color-danger, #c5000f)}";
  6835. var IonAlertIosStyle0 = alertIosCss;
  6836. const alertMdCss = ".sc-ion-alert-md-h{--min-width:250px;--width:auto;--min-height:auto;--height:auto;--max-height:90%;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;left:0;right:0;top:0;bottom:0;display:-ms-flexbox;display:flex;position:absolute;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;outline:none;font-family:var(--ion-font-family, inherit);contain:strict;-ms-touch-action:none;touch-action:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;z-index:1001}.overlay-hidden.sc-ion-alert-md-h{display:none}.alert-top.sc-ion-alert-md-h{padding-top:50px;-ms-flex-align:start;align-items:flex-start}.alert-wrapper.sc-ion-alert-md{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;width:var(--width);min-width:var(--min-width);max-width:var(--max-width);height:var(--height);min-height:var(--min-height);max-height:var(--max-height);background:var(--background);contain:content;opacity:0;z-index:10}.alert-title.sc-ion-alert-md{margin-left:0;margin-right:0;margin-top:0;margin-bottom:0;padding-left:0;padding-right:0;padding-top:0;padding-bottom:0}.alert-sub-title.sc-ion-alert-md{margin-left:0;margin-right:0;margin-top:5px;margin-bottom:0;padding-left:0;padding-right:0;padding-top:0;padding-bottom:0;font-weight:normal}.alert-message.sc-ion-alert-md,.alert-input-group.sc-ion-alert-md{-webkit-box-sizing:border-box;box-sizing:border-box;-webkit-overflow-scrolling:touch;overflow-y:auto;overscroll-behavior-y:contain}.alert-checkbox-label.sc-ion-alert-md,.alert-radio-label.sc-ion-alert-md{overflow-wrap:anywhere}@media (any-pointer: coarse){.alert-checkbox-group.sc-ion-alert-md::-webkit-scrollbar,.alert-radio-group.sc-ion-alert-md::-webkit-scrollbar,.alert-message.sc-ion-alert-md::-webkit-scrollbar{display:none}}.alert-input.sc-ion-alert-md{padding-left:0;padding-right:0;padding-top:10px;padding-bottom:10px;width:100%;border:0;background:inherit;font:inherit;-webkit-box-sizing:border-box;box-sizing:border-box}.alert-button-group.sc-ion-alert-md{display:-ms-flexbox;display:flex;-ms-flex-direction:row;flex-direction:row;width:100%}.alert-button-group-vertical.sc-ion-alert-md{-ms-flex-direction:column;flex-direction:column;-ms-flex-wrap:nowrap;flex-wrap:nowrap}.alert-button.sc-ion-alert-md{margin-left:0;margin-right:0;margin-top:0;margin-bottom:0;display:block;border:0;font-size:0.875rem;line-height:1.25rem;z-index:0}.alert-button.ion-focused.sc-ion-alert-md,.alert-tappable.ion-focused.sc-ion-alert-md{background:var(--ion-color-step-100, var(--ion-background-color-step-100, #e6e6e6))}.alert-button-inner.sc-ion-alert-md{display:-ms-flexbox;display:flex;-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-negative:0;flex-shrink:0;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;width:100%;height:100%;min-height:inherit}.alert-input-disabled.sc-ion-alert-md,.alert-checkbox-button-disabled.sc-ion-alert-md .alert-button-inner.sc-ion-alert-md,.alert-radio-button-disabled.sc-ion-alert-md .alert-button-inner.sc-ion-alert-md{cursor:default;opacity:0.5;pointer-events:none}.alert-tappable.sc-ion-alert-md{margin-left:0;margin-right:0;margin-top:0;margin-bottom:0;padding-left:0;padding-right:0;padding-top:0;padding-bottom:0;display:-ms-flexbox;display:flex;width:100%;border:0;background:transparent;font-size:inherit;line-height:initial;text-align:start;-webkit-appearance:none;-moz-appearance:none;appearance:none;contain:content}.alert-button.sc-ion-alert-md,.alert-checkbox.sc-ion-alert-md,.alert-input.sc-ion-alert-md,.alert-radio.sc-ion-alert-md{outline:none}.alert-radio-icon.sc-ion-alert-md,.alert-checkbox-icon.sc-ion-alert-md,.alert-checkbox-inner.sc-ion-alert-md{-webkit-box-sizing:border-box;box-sizing:border-box}textarea.alert-input.sc-ion-alert-md{min-height:37px;resize:none}.sc-ion-alert-md-h{--background:var(--ion-overlay-background-color, var(--ion-background-color, #fff));--max-width:280px;--backdrop-opacity:var(--ion-backdrop-opacity, 0.32);font-size:0.875rem}.alert-wrapper.sc-ion-alert-md{border-radius:4px;-webkit-box-shadow:0 11px 15px -7px rgba(0, 0, 0, 0.2), 0 24px 38px 3px rgba(0, 0, 0, 0.14), 0 9px 46px 8px rgba(0, 0, 0, 0.12);box-shadow:0 11px 15px -7px rgba(0, 0, 0, 0.2), 0 24px 38px 3px rgba(0, 0, 0, 0.14), 0 9px 46px 8px rgba(0, 0, 0, 0.12)}.alert-head.sc-ion-alert-md{-webkit-padding-start:23px;padding-inline-start:23px;-webkit-padding-end:23px;padding-inline-end:23px;padding-top:20px;padding-bottom:15px;text-align:start}.alert-title.sc-ion-alert-md{color:var(--ion-text-color, #000);font-size:1.25rem;font-weight:500}.alert-sub-title.sc-ion-alert-md{color:var(--ion-text-color, #000);font-size:1rem}.alert-message.sc-ion-alert-md,.alert-input-group.sc-ion-alert-md{-webkit-padding-start:24px;padding-inline-start:24px;-webkit-padding-end:24px;padding-inline-end:24px;padding-top:20px;padding-bottom:20px;color:var(--ion-color-step-550, var(--ion-text-color-step-450, #737373))}.alert-message.sc-ion-alert-md{font-size:1rem}@media screen and (max-width: 767px){.alert-message.sc-ion-alert-md{max-height:266px}}.alert-message.sc-ion-alert-md:empty{padding-left:0;padding-right:0;padding-top:0;padding-bottom:0}.alert-head.sc-ion-alert-md+.alert-message.sc-ion-alert-md{padding-top:0}.alert-input.sc-ion-alert-md{margin-left:0;margin-right:0;margin-top:5px;margin-bottom:5px;border-bottom:1px solid var(--ion-color-step-150, var(--ion-background-color-step-150, #d9d9d9));color:var(--ion-text-color, #000)}.alert-input.sc-ion-alert-md::-webkit-input-placeholder{color:var(--ion-placeholder-color, var(--ion-color-step-400, var(--ion-text-color-step-600, #999999)));font-family:inherit;font-weight:inherit}.alert-input.sc-ion-alert-md::-moz-placeholder{color:var(--ion-placeholder-color, var(--ion-color-step-400, var(--ion-text-color-step-600, #999999)));font-family:inherit;font-weight:inherit}.alert-input.sc-ion-alert-md:-ms-input-placeholder{color:var(--ion-placeholder-color, var(--ion-color-step-400, var(--ion-text-color-step-600, #999999)));font-family:inherit;font-weight:inherit}.alert-input.sc-ion-alert-md::-ms-input-placeholder{color:var(--ion-placeholder-color, var(--ion-color-step-400, var(--ion-text-color-step-600, #999999)));font-family:inherit;font-weight:inherit}.alert-input.sc-ion-alert-md::placeholder{color:var(--ion-placeholder-color, var(--ion-color-step-400, var(--ion-text-color-step-600, #999999)));font-family:inherit;font-weight:inherit}.alert-input.sc-ion-alert-md::-ms-clear{display:none}.alert-input.sc-ion-alert-md:focus{margin-bottom:4px;border-bottom:2px solid var(--ion-color-primary, #0054e9)}.alert-radio-group.sc-ion-alert-md,.alert-checkbox-group.sc-ion-alert-md{position:relative;border-top:1px solid var(--ion-color-step-150, var(--ion-background-color-step-150, #d9d9d9));border-bottom:1px solid var(--ion-color-step-150, var(--ion-background-color-step-150, #d9d9d9));overflow:auto}@media screen and (max-width: 767px){.alert-radio-group.sc-ion-alert-md,.alert-checkbox-group.sc-ion-alert-md{max-height:266px}}.alert-tappable.sc-ion-alert-md{position:relative;min-height:48px}.alert-radio-label.sc-ion-alert-md{-webkit-padding-start:52px;padding-inline-start:52px;-webkit-padding-end:26px;padding-inline-end:26px;padding-top:13px;padding-bottom:13px;-ms-flex:1;flex:1;color:var(--ion-color-step-850, var(--ion-text-color-step-150, #262626));font-size:1rem}.alert-radio-icon.sc-ion-alert-md{top:0;border-radius:50%;display:block;position:relative;width:20px;height:20px;border-width:2px;border-style:solid;border-color:var(--ion-color-step-550, var(--ion-background-color-step-550, #737373))}.alert-radio-icon.sc-ion-alert-md{inset-inline-start:26px}.alert-radio-inner.sc-ion-alert-md{top:3px;border-radius:50%;position:absolute;width:10px;height:10px;-webkit-transform:scale3d(0, 0, 0);transform:scale3d(0, 0, 0);-webkit-transition:-webkit-transform 280ms cubic-bezier(0.4, 0, 0.2, 1);transition:-webkit-transform 280ms cubic-bezier(0.4, 0, 0.2, 1);transition:transform 280ms cubic-bezier(0.4, 0, 0.2, 1);transition:transform 280ms cubic-bezier(0.4, 0, 0.2, 1), -webkit-transform 280ms cubic-bezier(0.4, 0, 0.2, 1);background-color:var(--ion-color-primary, #0054e9)}.alert-radio-inner.sc-ion-alert-md{inset-inline-start:3px}[aria-checked=true].sc-ion-alert-md .alert-radio-label.sc-ion-alert-md{color:var(--ion-color-step-850, var(--ion-text-color-step-150, #262626))}[aria-checked=true].sc-ion-alert-md .alert-radio-icon.sc-ion-alert-md{border-color:var(--ion-color-primary, #0054e9)}[aria-checked=true].sc-ion-alert-md .alert-radio-inner.sc-ion-alert-md{-webkit-transform:scale3d(1, 1, 1);transform:scale3d(1, 1, 1)}.alert-checkbox-label.sc-ion-alert-md{-webkit-padding-start:53px;padding-inline-start:53px;-webkit-padding-end:26px;padding-inline-end:26px;padding-top:13px;padding-bottom:13px;-ms-flex:1;flex:1;width:calc(100% - 53px);color:var(--ion-color-step-850, var(--ion-text-color-step-150, #262626));font-size:1rem}.alert-checkbox-icon.sc-ion-alert-md{top:0;border-radius:2px;position:relative;width:16px;height:16px;border-width:2px;border-style:solid;border-color:var(--ion-color-step-550, var(--ion-background-color-step-550, #737373));contain:strict}.alert-checkbox-icon.sc-ion-alert-md{inset-inline-start:26px}[aria-checked=true].sc-ion-alert-md .alert-checkbox-icon.sc-ion-alert-md{border-color:var(--ion-color-primary, #0054e9);background-color:var(--ion-color-primary, #0054e9)}[aria-checked=true].sc-ion-alert-md .alert-checkbox-inner.sc-ion-alert-md{top:0;position:absolute;width:6px;height:10px;-webkit-transform:rotate(45deg);transform:rotate(45deg);border-width:2px;border-top-width:0;border-left-width:0;border-style:solid;border-color:var(--ion-color-primary-contrast, #fff)}[aria-checked=true].sc-ion-alert-md .alert-checkbox-inner.sc-ion-alert-md{inset-inline-start:3px}.alert-button-group.sc-ion-alert-md{-webkit-padding-start:8px;padding-inline-start:8px;-webkit-padding-end:8px;padding-inline-end:8px;padding-top:8px;padding-bottom:8px;-webkit-box-sizing:border-box;box-sizing:border-box;-ms-flex-wrap:wrap-reverse;flex-wrap:wrap-reverse;-ms-flex-pack:end;justify-content:flex-end}.alert-button.sc-ion-alert-md{border-radius:2px;-webkit-margin-start:0;margin-inline-start:0;-webkit-margin-end:8px;margin-inline-end:8px;margin-top:0;margin-bottom:0;-webkit-padding-start:10px;padding-inline-start:10px;-webkit-padding-end:10px;padding-inline-end:10px;padding-top:10px;padding-bottom:10px;position:relative;background-color:transparent;color:var(--ion-color-primary, #0054e9);font-weight:500;text-align:end;text-transform:uppercase;overflow:hidden}.alert-button-inner.sc-ion-alert-md{-ms-flex-pack:end;justify-content:flex-end}@media screen and (min-width: 768px){.sc-ion-alert-md-h{--max-width:min(100vw - 96px, 560px);--max-height:min(100vh - 96px, 560px)}}";
  6837. var IonAlertMdStyle0 = alertMdCss;
  6838. // TODO(FW-2832): types
  6839. /**
  6840. * @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
  6841. */
  6842. class Alert {
  6843. constructor(hostRef) {
  6844. registerInstance(this, hostRef);
  6845. this.didPresent = createEvent(this, "ionAlertDidPresent", 7);
  6846. this.willPresent = createEvent(this, "ionAlertWillPresent", 7);
  6847. this.willDismiss = createEvent(this, "ionAlertWillDismiss", 7);
  6848. this.didDismiss = createEvent(this, "ionAlertDidDismiss", 7);
  6849. this.didPresentShorthand = createEvent(this, "didPresent", 7);
  6850. this.willPresentShorthand = createEvent(this, "willPresent", 7);
  6851. this.willDismissShorthand = createEvent(this, "willDismiss", 7);
  6852. this.didDismissShorthand = createEvent(this, "didDismiss", 7);
  6853. this.delegateController = createDelegateController(this);
  6854. this.lockController = createLockController();
  6855. this.triggerController = createTriggerController();
  6856. this.customHTMLEnabled = config.get('innerHTMLTemplatesEnabled', ENABLE_HTML_CONTENT_DEFAULT);
  6857. this.processedInputs = [];
  6858. this.processedButtons = [];
  6859. this.presented = false;
  6860. this.onBackdropTap = () => {
  6861. this.dismiss(undefined, BACKDROP);
  6862. };
  6863. this.dispatchCancelHandler = (ev) => {
  6864. const role = ev.detail.role;
  6865. if (isCancel(role)) {
  6866. const cancelButton = this.processedButtons.find((b) => b.role === 'cancel');
  6867. this.callButtonHandler(cancelButton);
  6868. }
  6869. };
  6870. this.overlayIndex = undefined;
  6871. this.delegate = undefined;
  6872. this.hasController = false;
  6873. this.keyboardClose = true;
  6874. this.enterAnimation = undefined;
  6875. this.leaveAnimation = undefined;
  6876. this.cssClass = undefined;
  6877. this.header = undefined;
  6878. this.subHeader = undefined;
  6879. this.message = undefined;
  6880. this.buttons = [];
  6881. this.inputs = [];
  6882. this.backdropDismiss = true;
  6883. this.translucent = false;
  6884. this.animated = true;
  6885. this.htmlAttributes = undefined;
  6886. this.isOpen = false;
  6887. this.trigger = undefined;
  6888. }
  6889. onIsOpenChange(newValue, oldValue) {
  6890. if (newValue === true && oldValue === false) {
  6891. this.present();
  6892. }
  6893. else if (newValue === false && oldValue === true) {
  6894. this.dismiss();
  6895. }
  6896. }
  6897. triggerChanged() {
  6898. const { trigger, el, triggerController } = this;
  6899. if (trigger) {
  6900. triggerController.addClickListener(el, trigger);
  6901. }
  6902. }
  6903. onKeydown(ev) {
  6904. var _a;
  6905. const inputTypes = new Set(this.processedInputs.map((i) => i.type));
  6906. /**
  6907. * Based on keyboard navigation requirements, the
  6908. * checkbox should not respond to the enter keydown event.
  6909. */
  6910. if (inputTypes.has('checkbox') && ev.key === 'Enter') {
  6911. ev.preventDefault();
  6912. return;
  6913. }
  6914. /**
  6915. * Ensure when alert container is being focused, and the user presses the tab + shift keys, the focus will be set to the last alert button.
  6916. */
  6917. if (ev.target.classList.contains('alert-wrapper')) {
  6918. if (ev.key === 'Tab' && ev.shiftKey) {
  6919. ev.preventDefault();
  6920. const lastChildBtn = (_a = this.wrapperEl) === null || _a === void 0 ? void 0 : _a.querySelector('.alert-button:last-child');
  6921. lastChildBtn.focus();
  6922. return;
  6923. }
  6924. }
  6925. // The only inputs we want to navigate between using arrow keys are the radios
  6926. // ignore the keydown event if it is not on a radio button
  6927. if (!inputTypes.has('radio') ||
  6928. (ev.target && !this.el.contains(ev.target)) ||
  6929. ev.target.classList.contains('alert-button')) {
  6930. return;
  6931. }
  6932. // Get all radios inside of the radio group and then
  6933. // filter out disabled radios since we need to skip those
  6934. const query = this.el.querySelectorAll('.alert-radio');
  6935. const radios = Array.from(query).filter((radio) => !radio.disabled);
  6936. // The focused radio is the one that shares the same id as
  6937. // the event target
  6938. const index = radios.findIndex((radio) => radio.id === ev.target.id);
  6939. // We need to know what the next radio element should
  6940. // be in order to change the focus
  6941. let nextEl;
  6942. // If hitting arrow down or arrow right, move to the next radio
  6943. // If we're on the last radio, move to the first radio
  6944. if (['ArrowDown', 'ArrowRight'].includes(ev.key)) {
  6945. nextEl = index === radios.length - 1 ? radios[0] : radios[index + 1];
  6946. }
  6947. // If hitting arrow up or arrow left, move to the previous radio
  6948. // If we're on the first radio, move to the last radio
  6949. if (['ArrowUp', 'ArrowLeft'].includes(ev.key)) {
  6950. nextEl = index === 0 ? radios[radios.length - 1] : radios[index - 1];
  6951. }
  6952. if (nextEl && radios.includes(nextEl)) {
  6953. const nextProcessed = this.processedInputs.find((input) => input.id === (nextEl === null || nextEl === void 0 ? void 0 : nextEl.id));
  6954. if (nextProcessed) {
  6955. this.rbClick(nextProcessed);
  6956. nextEl.focus();
  6957. }
  6958. }
  6959. }
  6960. buttonsChanged() {
  6961. const buttons = this.buttons;
  6962. this.processedButtons = buttons.map((btn) => {
  6963. return typeof btn === 'string' ? { text: btn, role: btn.toLowerCase() === 'cancel' ? 'cancel' : undefined } : btn;
  6964. });
  6965. }
  6966. inputsChanged() {
  6967. const inputs = this.inputs;
  6968. // Get the first input that is not disabled and the checked one
  6969. // If an enabled checked input exists, set it to be the focusable input
  6970. // otherwise we default to focus the first input
  6971. // This will only be used when the input is type radio
  6972. const first = inputs.find((input) => !input.disabled);
  6973. const checked = inputs.find((input) => input.checked && !input.disabled);
  6974. const focusable = checked || first;
  6975. // An alert can be created with several different inputs. Radios,
  6976. // checkboxes and inputs are all accepted, but they cannot be mixed.
  6977. const inputTypes = new Set(inputs.map((i) => i.type));
  6978. if (inputTypes.has('checkbox') && inputTypes.has('radio')) {
  6979. printIonWarning(`[ion-alert] - Alert cannot mix input types: ${Array.from(inputTypes.values()).join('/')}. Please see alert docs for more info.`);
  6980. }
  6981. this.inputType = inputTypes.values().next().value;
  6982. this.processedInputs = inputs.map((i, index) => {
  6983. var _a;
  6984. return ({
  6985. type: i.type || 'text',
  6986. name: i.name || `${index}`,
  6987. placeholder: i.placeholder || '',
  6988. value: i.value,
  6989. label: i.label,
  6990. checked: !!i.checked,
  6991. disabled: !!i.disabled,
  6992. id: i.id || `alert-input-${this.overlayIndex}-${index}`,
  6993. handler: i.handler,
  6994. min: i.min,
  6995. max: i.max,
  6996. cssClass: (_a = i.cssClass) !== null && _a !== void 0 ? _a : '',
  6997. attributes: i.attributes || {},
  6998. tabindex: i.type === 'radio' && i !== focusable ? -1 : 0,
  6999. });
  7000. });
  7001. }
  7002. connectedCallback() {
  7003. prepareOverlay(this.el);
  7004. this.triggerChanged();
  7005. }
  7006. componentWillLoad() {
  7007. var _a;
  7008. if (!((_a = this.htmlAttributes) === null || _a === void 0 ? void 0 : _a.id)) {
  7009. setOverlayId(this.el);
  7010. }
  7011. this.inputsChanged();
  7012. this.buttonsChanged();
  7013. }
  7014. disconnectedCallback() {
  7015. this.triggerController.removeClickListener();
  7016. if (this.gesture) {
  7017. this.gesture.destroy();
  7018. this.gesture = undefined;
  7019. }
  7020. }
  7021. componentDidLoad() {
  7022. /**
  7023. * Only create gesture if:
  7024. * 1. A gesture does not already exist
  7025. * 2. App is running in iOS mode
  7026. * 3. A wrapper ref exists
  7027. */
  7028. if (!this.gesture && getIonMode$1(this) === 'ios' && this.wrapperEl) {
  7029. this.gesture = createButtonActiveGesture(this.wrapperEl, (refEl) => refEl.classList.contains('alert-button'));
  7030. this.gesture.enable(true);
  7031. }
  7032. /**
  7033. * If alert was rendered with isOpen="true"
  7034. * then we should open alert immediately.
  7035. */
  7036. if (this.isOpen === true) {
  7037. raf(() => this.present());
  7038. }
  7039. /**
  7040. * When binding values in frameworks such as Angular
  7041. * it is possible for the value to be set after the Web Component
  7042. * initializes but before the value watcher is set up in Stencil.
  7043. * As a result, the watcher callback may not be fired.
  7044. * We work around this by manually calling the watcher
  7045. * callback when the component has loaded and the watcher
  7046. * is configured.
  7047. */
  7048. this.triggerChanged();
  7049. }
  7050. /**
  7051. * Present the alert overlay after it has been created.
  7052. */
  7053. async present() {
  7054. const unlock = await this.lockController.lock();
  7055. await this.delegateController.attachViewToDom();
  7056. await present(this, 'alertEnter', iosEnterAnimation$5, mdEnterAnimation$4).then(() => {
  7057. var _a, _b;
  7058. /**
  7059. * Check if alert has only one button and no inputs.
  7060. * If so, then focus on the button. Otherwise, focus the alert wrapper.
  7061. * This will map to the default native alert behavior.
  7062. */
  7063. if (this.buttons.length === 1 && this.inputs.length === 0) {
  7064. const queryBtn = (_a = this.wrapperEl) === null || _a === void 0 ? void 0 : _a.querySelector('.alert-button');
  7065. queryBtn.focus();
  7066. }
  7067. else {
  7068. (_b = this.wrapperEl) === null || _b === void 0 ? void 0 : _b.focus();
  7069. }
  7070. });
  7071. unlock();
  7072. }
  7073. /**
  7074. * Dismiss the alert overlay after it has been presented.
  7075. *
  7076. * @param data Any data to emit in the dismiss events.
  7077. * @param role The role of the element that is dismissing the alert.
  7078. * This can be useful in a button handler for determining which button was
  7079. * clicked to dismiss the alert.
  7080. * Some examples include: ``"cancel"`, `"destructive"`, "selected"`, and `"backdrop"`.
  7081. *
  7082. * This is a no-op if the overlay has not been presented yet. If you want
  7083. * to remove an overlay from the DOM that was never presented, use the
  7084. * [remove](https://developer.mozilla.org/en-US/docs/Web/API/Element/remove) method.
  7085. */
  7086. async dismiss(data, role) {
  7087. const unlock = await this.lockController.lock();
  7088. const dismissed = await dismiss(this, data, role, 'alertLeave', iosLeaveAnimation$5, mdLeaveAnimation$4);
  7089. if (dismissed) {
  7090. this.delegateController.removeViewFromDom();
  7091. }
  7092. unlock();
  7093. return dismissed;
  7094. }
  7095. /**
  7096. * Returns a promise that resolves when the alert did dismiss.
  7097. */
  7098. onDidDismiss() {
  7099. return eventMethod(this.el, 'ionAlertDidDismiss');
  7100. }
  7101. /**
  7102. * Returns a promise that resolves when the alert will dismiss.
  7103. */
  7104. onWillDismiss() {
  7105. return eventMethod(this.el, 'ionAlertWillDismiss');
  7106. }
  7107. rbClick(selectedInput) {
  7108. for (const input of this.processedInputs) {
  7109. input.checked = input === selectedInput;
  7110. input.tabindex = input === selectedInput ? 0 : -1;
  7111. }
  7112. this.activeId = selectedInput.id;
  7113. safeCall(selectedInput.handler, selectedInput);
  7114. }
  7115. cbClick(selectedInput) {
  7116. selectedInput.checked = !selectedInput.checked;
  7117. safeCall(selectedInput.handler, selectedInput);
  7118. }
  7119. async buttonClick(button) {
  7120. const role = button.role;
  7121. const values = this.getValues();
  7122. if (isCancel(role)) {
  7123. return this.dismiss({ values }, role);
  7124. }
  7125. const returnData = await this.callButtonHandler(button, values);
  7126. if (returnData !== false) {
  7127. return this.dismiss(Object.assign({ values }, returnData), button.role);
  7128. }
  7129. return false;
  7130. }
  7131. async callButtonHandler(button, data) {
  7132. if (button === null || button === void 0 ? void 0 : button.handler) {
  7133. // a handler has been provided, execute it
  7134. // pass the handler the values from the inputs
  7135. const returnData = await safeCall(button.handler, data);
  7136. if (returnData === false) {
  7137. // if the return value of the handler is false then do not dismiss
  7138. return false;
  7139. }
  7140. if (typeof returnData === 'object') {
  7141. return returnData;
  7142. }
  7143. }
  7144. return {};
  7145. }
  7146. getValues() {
  7147. if (this.processedInputs.length === 0) {
  7148. // this is an alert without any options/inputs at all
  7149. return undefined;
  7150. }
  7151. if (this.inputType === 'radio') {
  7152. // this is an alert with radio buttons (single value select)
  7153. // return the one value which is checked, otherwise undefined
  7154. const checkedInput = this.processedInputs.find((i) => !!i.checked);
  7155. return checkedInput ? checkedInput.value : undefined;
  7156. }
  7157. if (this.inputType === 'checkbox') {
  7158. // this is an alert with checkboxes (multiple value select)
  7159. // return an array of all the checked values
  7160. return this.processedInputs.filter((i) => i.checked).map((i) => i.value);
  7161. }
  7162. // this is an alert with text inputs
  7163. // return an object of all the values with the input name as the key
  7164. const values = {};
  7165. this.processedInputs.forEach((i) => {
  7166. values[i.name] = i.value || '';
  7167. });
  7168. return values;
  7169. }
  7170. renderAlertInputs() {
  7171. switch (this.inputType) {
  7172. case 'checkbox':
  7173. return this.renderCheckbox();
  7174. case 'radio':
  7175. return this.renderRadio();
  7176. default:
  7177. return this.renderInput();
  7178. }
  7179. }
  7180. renderCheckbox() {
  7181. const inputs = this.processedInputs;
  7182. const mode = getIonMode$1(this);
  7183. if (inputs.length === 0) {
  7184. return null;
  7185. }
  7186. return (hAsync("div", { class: "alert-checkbox-group" }, inputs.map((i) => (hAsync("button", { type: "button", onClick: () => this.cbClick(i), "aria-checked": `${i.checked}`, id: i.id, disabled: i.disabled, tabIndex: i.tabindex, role: "checkbox", class: Object.assign(Object.assign({}, getClassMap(i.cssClass)), { 'alert-tappable': true, 'alert-checkbox': true, 'alert-checkbox-button': true, 'ion-focusable': true, 'alert-checkbox-button-disabled': i.disabled || false }) }, hAsync("div", { class: "alert-button-inner" }, hAsync("div", { class: "alert-checkbox-icon" }, hAsync("div", { class: "alert-checkbox-inner" })), hAsync("div", { class: "alert-checkbox-label" }, i.label)), mode === 'md' && hAsync("ion-ripple-effect", null))))));
  7187. }
  7188. renderRadio() {
  7189. const inputs = this.processedInputs;
  7190. if (inputs.length === 0) {
  7191. return null;
  7192. }
  7193. return (hAsync("div", { class: "alert-radio-group", role: "radiogroup", "aria-activedescendant": this.activeId }, inputs.map((i) => (hAsync("button", { type: "button", onClick: () => this.rbClick(i), "aria-checked": `${i.checked}`, disabled: i.disabled, id: i.id, tabIndex: i.tabindex, class: Object.assign(Object.assign({}, getClassMap(i.cssClass)), { 'alert-radio-button': true, 'alert-tappable': true, 'alert-radio': true, 'ion-focusable': true, 'alert-radio-button-disabled': i.disabled || false }), role: "radio" }, hAsync("div", { class: "alert-button-inner" }, hAsync("div", { class: "alert-radio-icon" }, hAsync("div", { class: "alert-radio-inner" })), hAsync("div", { class: "alert-radio-label" }, i.label)))))));
  7194. }
  7195. renderInput() {
  7196. const inputs = this.processedInputs;
  7197. if (inputs.length === 0) {
  7198. return null;
  7199. }
  7200. return (hAsync("div", { class: "alert-input-group" }, inputs.map((i) => {
  7201. var _a, _b, _c, _d;
  7202. if (i.type === 'textarea') {
  7203. return (hAsync("div", { class: "alert-input-wrapper" }, hAsync("textarea", Object.assign({ placeholder: i.placeholder, value: i.value, id: i.id, tabIndex: i.tabindex }, i.attributes, { disabled: (_b = (_a = i.attributes) === null || _a === void 0 ? void 0 : _a.disabled) !== null && _b !== void 0 ? _b : i.disabled, class: inputClass(i), onInput: (e) => {
  7204. var _a;
  7205. i.value = e.target.value;
  7206. if ((_a = i.attributes) === null || _a === void 0 ? void 0 : _a.onInput) {
  7207. i.attributes.onInput(e);
  7208. }
  7209. } }))));
  7210. }
  7211. else {
  7212. return (hAsync("div", { class: "alert-input-wrapper" }, hAsync("input", Object.assign({ placeholder: i.placeholder, type: i.type, min: i.min, max: i.max, value: i.value, id: i.id, tabIndex: i.tabindex }, i.attributes, { disabled: (_d = (_c = i.attributes) === null || _c === void 0 ? void 0 : _c.disabled) !== null && _d !== void 0 ? _d : i.disabled, class: inputClass(i), onInput: (e) => {
  7213. var _a;
  7214. i.value = e.target.value;
  7215. if ((_a = i.attributes) === null || _a === void 0 ? void 0 : _a.onInput) {
  7216. i.attributes.onInput(e);
  7217. }
  7218. } }))));
  7219. }
  7220. })));
  7221. }
  7222. renderAlertButtons() {
  7223. const buttons = this.processedButtons;
  7224. const mode = getIonMode$1(this);
  7225. const alertButtonGroupClass = {
  7226. 'alert-button-group': true,
  7227. 'alert-button-group-vertical': buttons.length > 2,
  7228. };
  7229. return (hAsync("div", { class: alertButtonGroupClass }, buttons.map((button) => (hAsync("button", Object.assign({}, button.htmlAttributes, { type: "button", id: button.id, class: buttonClass$2(button), tabIndex: 0, onClick: () => this.buttonClick(button) }), hAsync("span", { class: "alert-button-inner" }, button.text), mode === 'md' && hAsync("ion-ripple-effect", null))))));
  7230. }
  7231. renderAlertMessage(msgId) {
  7232. const { customHTMLEnabled, message } = this;
  7233. if (customHTMLEnabled) {
  7234. return hAsync("div", { id: msgId, class: "alert-message", innerHTML: sanitizeDOMString(message) });
  7235. }
  7236. return (hAsync("div", { id: msgId, class: "alert-message" }, message));
  7237. }
  7238. render() {
  7239. const { overlayIndex, header, subHeader, message, htmlAttributes } = this;
  7240. const mode = getIonMode$1(this);
  7241. const hdrId = `alert-${overlayIndex}-hdr`;
  7242. const msgId = `alert-${overlayIndex}-msg`;
  7243. const subHdrId = `alert-${overlayIndex}-sub-hdr`;
  7244. const role = this.inputs.length > 0 || this.buttons.length > 0 ? 'alertdialog' : 'alert';
  7245. /**
  7246. * Use both the header and subHeader ids if they are defined.
  7247. * If only the header is defined, use the header id.
  7248. * If only the subHeader is defined, use the subHeader id.
  7249. * If neither are defined, do not set aria-labelledby.
  7250. */
  7251. const ariaLabelledBy = header && subHeader ? `${hdrId} ${subHdrId}` : header ? hdrId : subHeader ? subHdrId : null;
  7252. return (hAsync(Host, { key: 'f8ee04fe6a97a2585b302c8e1a9eea3b122e3479', tabindex: "-1", style: {
  7253. zIndex: `${20000 + overlayIndex}`,
  7254. }, class: Object.assign(Object.assign({}, getClassMap(this.cssClass)), { [mode]: true, 'overlay-hidden': true, 'alert-translucent': this.translucent }), onIonAlertWillDismiss: this.dispatchCancelHandler, onIonBackdropTap: this.onBackdropTap }, hAsync("ion-backdrop", { key: 'e9592e879f51c27ef20016beec12c986be632cf3', tappable: this.backdropDismiss }), hAsync("div", { key: '5e9425c3c8acdea6f8006389689c73220e2ce423', tabindex: "0", "aria-hidden": "true" }), hAsync("div", Object.assign({ key: '615465703e357619681fc36ed7276591a6fe3787', class: "alert-wrapper ion-overlay-wrapper", role: role, "aria-modal": "true", "aria-labelledby": ariaLabelledBy, "aria-describedby": message !== undefined ? msgId : null, tabindex: "0", ref: (el) => (this.wrapperEl = el) }, htmlAttributes), hAsync("div", { key: '934eba3759456cd4660e10f274edc7859f908461', class: "alert-head" }, header && (hAsync("h2", { key: '7d5d98d71f81f59a2cba227121b6fa01e6cc53b6', id: hdrId, class: "alert-title" }, header)), subHeader && !header && (hAsync("h2", { key: 'e5f5d35748c58a98ee933eb15cb1dcaf8113e9a7', id: subHdrId, class: "alert-sub-title" }, subHeader)), subHeader && header && (hAsync("h3", { key: 'a5cb89ca02bfa9c4828e694cb0835493a9088b05', id: subHdrId, class: "alert-sub-title" }, subHeader))), this.renderAlertMessage(msgId), this.renderAlertInputs(), this.renderAlertButtons()), hAsync("div", { key: 'cacffc31c911882df73e6845d15c8bb2d4acab56', tabindex: "0", "aria-hidden": "true" })));
  7255. }
  7256. get el() { return getElement(this); }
  7257. static get watchers() { return {
  7258. "isOpen": ["onIsOpenChange"],
  7259. "trigger": ["triggerChanged"],
  7260. "buttons": ["buttonsChanged"],
  7261. "inputs": ["inputsChanged"]
  7262. }; }
  7263. static get style() { return {
  7264. ios: IonAlertIosStyle0,
  7265. md: IonAlertMdStyle0
  7266. }; }
  7267. static get cmpMeta() { return {
  7268. "$flags$": 34,
  7269. "$tagName$": "ion-alert",
  7270. "$members$": {
  7271. "overlayIndex": [2, "overlay-index"],
  7272. "delegate": [16],
  7273. "hasController": [4, "has-controller"],
  7274. "keyboardClose": [4, "keyboard-close"],
  7275. "enterAnimation": [16],
  7276. "leaveAnimation": [16],
  7277. "cssClass": [1, "css-class"],
  7278. "header": [1],
  7279. "subHeader": [1, "sub-header"],
  7280. "message": [1],
  7281. "buttons": [16],
  7282. "inputs": [1040],
  7283. "backdropDismiss": [4, "backdrop-dismiss"],
  7284. "translucent": [4],
  7285. "animated": [4],
  7286. "htmlAttributes": [16],
  7287. "isOpen": [4, "is-open"],
  7288. "trigger": [1],
  7289. "present": [64],
  7290. "dismiss": [64],
  7291. "onDidDismiss": [64],
  7292. "onWillDismiss": [64]
  7293. },
  7294. "$listeners$": [[4, "keydown", "onKeydown"]],
  7295. "$lazyBundleId$": "-",
  7296. "$attrsToReflect$": []
  7297. }; }
  7298. }
  7299. const inputClass = (input) => {
  7300. var _a, _b, _c;
  7301. return Object.assign(Object.assign({ 'alert-input': true, 'alert-input-disabled': ((_b = (_a = input.attributes) === null || _a === void 0 ? void 0 : _a.disabled) !== null && _b !== void 0 ? _b : input.disabled) || false }, getClassMap(input.cssClass)), getClassMap(input.attributes ? (_c = input.attributes.class) === null || _c === void 0 ? void 0 : _c.toString() : ''));
  7302. };
  7303. const buttonClass$2 = (button) => {
  7304. return Object.assign({ 'alert-button': true, 'ion-focusable': true, 'ion-activatable': true, [`alert-button-role-${button.role}`]: button.role !== undefined }, getClassMap(button.cssClass));
  7305. };
  7306. const appCss = "html.plt-mobile ion-app{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}html.plt-mobile ion-app [contenteditable]{-webkit-user-select:text;-moz-user-select:text;-ms-user-select:text;user-select:text}ion-app.force-statusbar-padding{--ion-safe-area-top:20px}";
  7307. var IonAppStyle0 = appCss;
  7308. class App {
  7309. constructor(hostRef) {
  7310. registerInstance(this, hostRef);
  7311. }
  7312. componentDidLoad() {
  7313. }
  7314. /**
  7315. * Used to set focus on an element that uses `ion-focusable`.
  7316. * Do not use this if focusing the element as a result of a keyboard
  7317. * event as the focus utility should handle this for us. This method
  7318. * should be used when we want to programmatically focus an element as
  7319. * a result of another user action. (Ex: We focus the first element
  7320. * inside of a popover when the user presents it, but the popover is not always
  7321. * presented as a result of keyboard action.)
  7322. */
  7323. async setFocus(elements) {
  7324. if (this.focusVisible) {
  7325. this.focusVisible.setFocus(elements);
  7326. }
  7327. }
  7328. render() {
  7329. const mode = getIonMode$1(this);
  7330. return (hAsync(Host, { key: '03aa892f986330078d112b1e8b010df98fa7e39e', class: {
  7331. [mode]: true,
  7332. 'ion-page': true,
  7333. 'force-statusbar-padding': config.getBoolean('_forceStatusbarPadding'),
  7334. } }));
  7335. }
  7336. get el() { return getElement(this); }
  7337. static get style() { return IonAppStyle0; }
  7338. static get cmpMeta() { return {
  7339. "$flags$": 0,
  7340. "$tagName$": "ion-app",
  7341. "$members$": {
  7342. "setFocus": [64]
  7343. },
  7344. "$listeners$": undefined,
  7345. "$lazyBundleId$": "-",
  7346. "$attrsToReflect$": []
  7347. }; }
  7348. }
  7349. const avatarIosCss = ":host{border-radius:var(--border-radius);display:block}::slotted(ion-img),::slotted(img){border-radius:var(--border-radius);width:100%;height:100%;-o-object-fit:cover;object-fit:cover;overflow:hidden}:host{--border-radius:50%;width:48px;height:48px}";
  7350. var IonAvatarIosStyle0 = avatarIosCss;
  7351. const avatarMdCss = ":host{border-radius:var(--border-radius);display:block}::slotted(ion-img),::slotted(img){border-radius:var(--border-radius);width:100%;height:100%;-o-object-fit:cover;object-fit:cover;overflow:hidden}:host{--border-radius:50%;width:64px;height:64px}";
  7352. var IonAvatarMdStyle0 = avatarMdCss;
  7353. class Avatar {
  7354. constructor(hostRef) {
  7355. registerInstance(this, hostRef);
  7356. }
  7357. render() {
  7358. return (hAsync(Host, { key: '998217066084f966bf5d356fed85bcbd451f675a', class: getIonMode$1(this) }, hAsync("slot", { key: '1a6f7c9d4dc6a875f86b5b3cda6d59cb39587f22' })));
  7359. }
  7360. static get style() { return {
  7361. ios: IonAvatarIosStyle0,
  7362. md: IonAvatarMdStyle0
  7363. }; }
  7364. static get cmpMeta() { return {
  7365. "$flags$": 41,
  7366. "$tagName$": "ion-avatar",
  7367. "$members$": undefined,
  7368. "$listeners$": undefined,
  7369. "$lazyBundleId$": "-",
  7370. "$attrsToReflect$": []
  7371. }; }
  7372. }
  7373. const backButtonIosCss = ":host{--background:transparent;--color-focused:currentColor;--color-hover:currentColor;--icon-margin-top:0;--icon-margin-bottom:0;--icon-padding-top:0;--icon-padding-end:0;--icon-padding-bottom:0;--icon-padding-start:0;--margin-top:0;--margin-end:0;--margin-bottom:0;--margin-start:0;--min-width:auto;--min-height:auto;--padding-top:0;--padding-end:0;--padding-bottom:0;--padding-start:0;--opacity:1;--ripple-color:currentColor;--transition:background-color, opacity 100ms linear;display:none;min-width:var(--min-width);min-height:var(--min-height);color:var(--color);font-family:var(--ion-font-family, inherit);text-align:center;text-decoration:none;text-overflow:ellipsis;text-transform:none;white-space:nowrap;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-font-kerning:none;font-kerning:none}ion-ripple-effect{color:var(--ripple-color)}:host(.ion-color) .button-native{color:var(--ion-color-base)}:host(.show-back-button){display:block}:host(.back-button-disabled){cursor:default;opacity:0.5;pointer-events:none}.button-native{border-radius:var(--border-radius);-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;-webkit-margin-start:var(--margin-start);margin-inline-start:var(--margin-start);-webkit-margin-end:var(--margin-end);margin-inline-end:var(--margin-end);margin-top:var(--margin-top);margin-bottom:var(--margin-bottom);-webkit-padding-start:var(--padding-start);padding-inline-start:var(--padding-start);-webkit-padding-end:var(--padding-end);padding-inline-end:var(--padding-end);padding-top:var(--padding-top);padding-bottom:var(--padding-bottom);font-family:inherit;font-size:inherit;font-style:inherit;font-weight:inherit;letter-spacing:inherit;text-decoration:inherit;text-indent:inherit;text-overflow:inherit;text-transform:inherit;text-align:inherit;white-space:inherit;color:inherit;display:block;position:relative;width:100%;height:100%;min-height:inherit;-webkit-transition:var(--transition);transition:var(--transition);border:0;outline:none;background:var(--background);line-height:1;cursor:pointer;opacity:var(--opacity);overflow:hidden;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;z-index:0;-webkit-appearance:none;-moz-appearance:none;appearance:none}.button-inner{display:-ms-flexbox;display:flex;position:relative;-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-negative:0;flex-shrink:0;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;width:100%;height:100%;z-index:1}ion-icon{-webkit-padding-start:var(--icon-padding-start);padding-inline-start:var(--icon-padding-start);-webkit-padding-end:var(--icon-padding-end);padding-inline-end:var(--icon-padding-end);padding-top:var(--icon-padding-top);padding-bottom:var(--icon-padding-bottom);-webkit-margin-start:var(--icon-margin-start);margin-inline-start:var(--icon-margin-start);-webkit-margin-end:var(--icon-margin-end);margin-inline-end:var(--icon-margin-end);margin-top:var(--icon-margin-top);margin-bottom:var(--icon-margin-bottom);display:inherit;font-size:var(--icon-font-size);font-weight:var(--icon-font-weight);pointer-events:none}:host(.ion-focused) .button-native{color:var(--color-focused)}:host(.ion-focused) .button-native::after{background:var(--background-focused);opacity:var(--background-focused-opacity)}.button-native::after{left:0;right:0;top:0;bottom:0;position:absolute;content:\"\";opacity:0}@media (any-hover: hover){:host(:hover) .button-native{color:var(--color-hover)}:host(:hover) .button-native::after{background:var(--background-hover);opacity:var(--background-hover-opacity)}}:host(.ion-color.ion-focused) .button-native{color:var(--ion-color-base)}@media (any-hover: hover){:host(.ion-color:hover) .button-native{color:var(--ion-color-base)}}:host(.in-toolbar:not(.in-toolbar-color)){color:var(--ion-toolbar-color, var(--color))}:host{--background-hover:transparent;--background-hover-opacity:1;--background-focused:currentColor;--background-focused-opacity:.1;--border-radius:4px;--color:var(--ion-color-primary, #0054e9);--icon-margin-end:1px;--icon-margin-start:-4px;--icon-font-size:1.6em;--min-height:32px;font-size:clamp(17px, 1.0625rem, 21.998px)}.button-native{-webkit-transform:translateZ(0);transform:translateZ(0);overflow:visible;z-index:99}:host(.ion-activated) .button-native{opacity:0.4}@media (any-hover: hover){:host(:hover){opacity:0.6}}";
  7374. var IonBackButtonIosStyle0 = backButtonIosCss;
  7375. const backButtonMdCss = ":host{--background:transparent;--color-focused:currentColor;--color-hover:currentColor;--icon-margin-top:0;--icon-margin-bottom:0;--icon-padding-top:0;--icon-padding-end:0;--icon-padding-bottom:0;--icon-padding-start:0;--margin-top:0;--margin-end:0;--margin-bottom:0;--margin-start:0;--min-width:auto;--min-height:auto;--padding-top:0;--padding-end:0;--padding-bottom:0;--padding-start:0;--opacity:1;--ripple-color:currentColor;--transition:background-color, opacity 100ms linear;display:none;min-width:var(--min-width);min-height:var(--min-height);color:var(--color);font-family:var(--ion-font-family, inherit);text-align:center;text-decoration:none;text-overflow:ellipsis;text-transform:none;white-space:nowrap;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-font-kerning:none;font-kerning:none}ion-ripple-effect{color:var(--ripple-color)}:host(.ion-color) .button-native{color:var(--ion-color-base)}:host(.show-back-button){display:block}:host(.back-button-disabled){cursor:default;opacity:0.5;pointer-events:none}.button-native{border-radius:var(--border-radius);-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;-webkit-margin-start:var(--margin-start);margin-inline-start:var(--margin-start);-webkit-margin-end:var(--margin-end);margin-inline-end:var(--margin-end);margin-top:var(--margin-top);margin-bottom:var(--margin-bottom);-webkit-padding-start:var(--padding-start);padding-inline-start:var(--padding-start);-webkit-padding-end:var(--padding-end);padding-inline-end:var(--padding-end);padding-top:var(--padding-top);padding-bottom:var(--padding-bottom);font-family:inherit;font-size:inherit;font-style:inherit;font-weight:inherit;letter-spacing:inherit;text-decoration:inherit;text-indent:inherit;text-overflow:inherit;text-transform:inherit;text-align:inherit;white-space:inherit;color:inherit;display:block;position:relative;width:100%;height:100%;min-height:inherit;-webkit-transition:var(--transition);transition:var(--transition);border:0;outline:none;background:var(--background);line-height:1;cursor:pointer;opacity:var(--opacity);overflow:hidden;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;z-index:0;-webkit-appearance:none;-moz-appearance:none;appearance:none}.button-inner{display:-ms-flexbox;display:flex;position:relative;-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-negative:0;flex-shrink:0;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;width:100%;height:100%;z-index:1}ion-icon{-webkit-padding-start:var(--icon-padding-start);padding-inline-start:var(--icon-padding-start);-webkit-padding-end:var(--icon-padding-end);padding-inline-end:var(--icon-padding-end);padding-top:var(--icon-padding-top);padding-bottom:var(--icon-padding-bottom);-webkit-margin-start:var(--icon-margin-start);margin-inline-start:var(--icon-margin-start);-webkit-margin-end:var(--icon-margin-end);margin-inline-end:var(--icon-margin-end);margin-top:var(--icon-margin-top);margin-bottom:var(--icon-margin-bottom);display:inherit;font-size:var(--icon-font-size);font-weight:var(--icon-font-weight);pointer-events:none}:host(.ion-focused) .button-native{color:var(--color-focused)}:host(.ion-focused) .button-native::after{background:var(--background-focused);opacity:var(--background-focused-opacity)}.button-native::after{left:0;right:0;top:0;bottom:0;position:absolute;content:\"\";opacity:0}@media (any-hover: hover){:host(:hover) .button-native{color:var(--color-hover)}:host(:hover) .button-native::after{background:var(--background-hover);opacity:var(--background-hover-opacity)}}:host(.ion-color.ion-focused) .button-native{color:var(--ion-color-base)}@media (any-hover: hover){:host(.ion-color:hover) .button-native{color:var(--ion-color-base)}}:host(.in-toolbar:not(.in-toolbar-color)){color:var(--ion-toolbar-color, var(--color))}:host{--border-radius:4px;--background-focused:currentColor;--background-focused-opacity:.12;--background-hover:currentColor;--background-hover-opacity:0.04;--color:currentColor;--icon-margin-end:0;--icon-margin-start:0;--icon-font-size:1.5rem;--icon-font-weight:normal;--min-height:32px;--min-width:44px;--padding-start:12px;--padding-end:12px;font-size:0.875rem;font-weight:500;text-transform:uppercase}:host(.back-button-has-icon-only){--border-radius:50%;min-width:48px;min-height:48px;aspect-ratio:1/1}.button-native{-webkit-box-shadow:none;box-shadow:none}.button-text{-webkit-padding-start:4px;padding-inline-start:4px;-webkit-padding-end:4px;padding-inline-end:4px;padding-top:0;padding-bottom:0}ion-icon{line-height:0.67;text-align:start}@media (any-hover: hover){:host(.ion-color:hover) .button-native::after{background:var(--ion-color-base)}}:host(.ion-color.ion-focused) .button-native::after{background:var(--ion-color-base)}";
  7376. var IonBackButtonMdStyle0 = backButtonMdCss;
  7377. /**
  7378. * @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
  7379. *
  7380. * @part native - The native HTML button element that wraps all child elements.
  7381. * @part icon - The back button icon (uses ion-icon).
  7382. * @part text - The back button text.
  7383. */
  7384. class BackButton {
  7385. constructor(hostRef) {
  7386. registerInstance(this, hostRef);
  7387. this.inheritedAttributes = {};
  7388. this.onClick = async (ev) => {
  7389. const nav = this.el.closest('ion-nav');
  7390. ev.preventDefault();
  7391. if (nav && (await nav.canGoBack())) {
  7392. return nav.pop({ animationBuilder: this.routerAnimation, skipIfBusy: true });
  7393. }
  7394. return openURL(this.defaultHref, ev, 'back', this.routerAnimation);
  7395. };
  7396. this.color = undefined;
  7397. this.defaultHref = undefined;
  7398. this.disabled = false;
  7399. this.icon = undefined;
  7400. this.text = undefined;
  7401. this.type = 'button';
  7402. this.routerAnimation = undefined;
  7403. }
  7404. componentWillLoad() {
  7405. this.inheritedAttributes = inheritAriaAttributes(this.el);
  7406. if (this.defaultHref === undefined) {
  7407. this.defaultHref = config.get('backButtonDefaultHref');
  7408. }
  7409. }
  7410. get backButtonIcon() {
  7411. const icon = this.icon;
  7412. if (icon != null) {
  7413. // icon is set on the component or by the config
  7414. return icon;
  7415. }
  7416. if (getIonMode$1(this) === 'ios') {
  7417. // default ios back button icon
  7418. return config.get('backButtonIcon', chevronBack);
  7419. }
  7420. // default md back button icon
  7421. return config.get('backButtonIcon', arrowBackSharp);
  7422. }
  7423. get backButtonText() {
  7424. const defaultBackButtonText = getIonMode$1(this) === 'ios' ? 'Back' : null;
  7425. return this.text != null ? this.text : config.get('backButtonText', defaultBackButtonText);
  7426. }
  7427. get hasIconOnly() {
  7428. return this.backButtonIcon && !this.backButtonText;
  7429. }
  7430. get rippleType() {
  7431. // If the button only has an icon we use the unbounded
  7432. // "circular" ripple effect
  7433. if (this.hasIconOnly) {
  7434. return 'unbounded';
  7435. }
  7436. return 'bounded';
  7437. }
  7438. render() {
  7439. const { color, defaultHref, disabled, type, hasIconOnly, backButtonIcon, backButtonText, icon, inheritedAttributes, } = this;
  7440. const showBackButton = defaultHref !== undefined;
  7441. const mode = getIonMode$1(this);
  7442. const ariaLabel = inheritedAttributes['aria-label'] || backButtonText || 'back';
  7443. return (hAsync(Host, { key: '5466624a10f1ab56f5469e6dc07080303880f2fe', onClick: this.onClick, class: createColorClasses$1(color, {
  7444. [mode]: true,
  7445. button: true, // ion-buttons target .button
  7446. 'back-button-disabled': disabled,
  7447. 'back-button-has-icon-only': hasIconOnly,
  7448. 'in-toolbar': hostContext('ion-toolbar', this.el),
  7449. 'in-toolbar-color': hostContext('ion-toolbar[color]', this.el),
  7450. 'ion-activatable': true,
  7451. 'ion-focusable': true,
  7452. 'show-back-button': showBackButton,
  7453. }) }, hAsync("button", { key: '63bc75ef0ad7cc9fb79e58217a3314b20acd73e3', type: type, disabled: disabled, class: "button-native", part: "native", "aria-label": ariaLabel }, hAsync("span", { key: '5d3eacbd11af2245c6e1151cab446a0d96559ad8', class: "button-inner" }, backButtonIcon && (hAsync("ion-icon", { key: '6439af0ae463764174e7d3207f02267811df666d', part: "icon", icon: backButtonIcon, "aria-hidden": "true", lazy: false, "flip-rtl": icon === undefined })), backButtonText && (hAsync("span", { key: '8ee89fb18dfdb5b75948a8b197ff4cdbc008742f', part: "text", "aria-hidden": "true", class: "button-text" }, backButtonText))), mode === 'md' && hAsync("ion-ripple-effect", { key: '63803a884998bc73bea5afe0b2a0a14e3fa4d6bf', type: this.rippleType }))));
  7454. }
  7455. get el() { return getElement(this); }
  7456. static get style() { return {
  7457. ios: IonBackButtonIosStyle0,
  7458. md: IonBackButtonMdStyle0
  7459. }; }
  7460. static get cmpMeta() { return {
  7461. "$flags$": 41,
  7462. "$tagName$": "ion-back-button",
  7463. "$members$": {
  7464. "color": [513],
  7465. "defaultHref": [1025, "default-href"],
  7466. "disabled": [516],
  7467. "icon": [1],
  7468. "text": [1],
  7469. "type": [1],
  7470. "routerAnimation": [16]
  7471. },
  7472. "$listeners$": undefined,
  7473. "$lazyBundleId$": "-",
  7474. "$attrsToReflect$": [["color", "color"], ["disabled", "disabled"]]
  7475. }; }
  7476. }
  7477. const backdropIosCss = ":host{left:0;right:0;top:0;bottom:0;display:block;position:absolute;-webkit-transform:translateZ(0);transform:translateZ(0);contain:strict;cursor:pointer;opacity:0.01;-ms-touch-action:none;touch-action:none;z-index:2}:host(.backdrop-hide){background:transparent}:host(.backdrop-no-tappable){cursor:auto}:host{background-color:var(--ion-backdrop-color, #000)}";
  7478. var IonBackdropIosStyle0 = backdropIosCss;
  7479. const backdropMdCss = ":host{left:0;right:0;top:0;bottom:0;display:block;position:absolute;-webkit-transform:translateZ(0);transform:translateZ(0);contain:strict;cursor:pointer;opacity:0.01;-ms-touch-action:none;touch-action:none;z-index:2}:host(.backdrop-hide){background:transparent}:host(.backdrop-no-tappable){cursor:auto}:host{background-color:var(--ion-backdrop-color, #000)}";
  7480. var IonBackdropMdStyle0 = backdropMdCss;
  7481. class Backdrop {
  7482. constructor(hostRef) {
  7483. registerInstance(this, hostRef);
  7484. this.ionBackdropTap = createEvent(this, "ionBackdropTap", 7);
  7485. this.visible = true;
  7486. this.tappable = true;
  7487. this.stopPropagation = true;
  7488. }
  7489. onMouseDown(ev) {
  7490. this.emitTap(ev);
  7491. }
  7492. emitTap(ev) {
  7493. if (this.stopPropagation) {
  7494. ev.preventDefault();
  7495. ev.stopPropagation();
  7496. }
  7497. if (this.tappable) {
  7498. this.ionBackdropTap.emit();
  7499. }
  7500. }
  7501. render() {
  7502. const mode = getIonMode$1(this);
  7503. return (hAsync(Host, { key: '7abaf2c310aa399607451b14063265e8a5846938', "aria-hidden": "true", class: {
  7504. [mode]: true,
  7505. 'backdrop-hide': !this.visible,
  7506. 'backdrop-no-tappable': !this.tappable,
  7507. } }));
  7508. }
  7509. static get style() { return {
  7510. ios: IonBackdropIosStyle0,
  7511. md: IonBackdropMdStyle0
  7512. }; }
  7513. static get cmpMeta() { return {
  7514. "$flags$": 41,
  7515. "$tagName$": "ion-backdrop",
  7516. "$members$": {
  7517. "visible": [4],
  7518. "tappable": [4],
  7519. "stopPropagation": [4, "stop-propagation"]
  7520. },
  7521. "$listeners$": [[2, "click", "onMouseDown"]],
  7522. "$lazyBundleId$": "-",
  7523. "$attrsToReflect$": []
  7524. }; }
  7525. }
  7526. const badgeIosCss = ":host{--background:var(--ion-color-primary, #0054e9);--color:var(--ion-color-primary-contrast, #fff);--padding-top:3px;--padding-end:8px;--padding-bottom:3px;--padding-start:8px;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;-webkit-padding-start:var(--padding-start);padding-inline-start:var(--padding-start);-webkit-padding-end:var(--padding-end);padding-inline-end:var(--padding-end);padding-top:var(--padding-top);padding-bottom:var(--padding-bottom);display:inline-block;min-width:10px;background:var(--background);color:var(--color);font-family:var(--ion-font-family, inherit);font-size:0.8125rem;font-weight:bold;line-height:1;text-align:center;white-space:nowrap;contain:content;vertical-align:baseline}:host(.ion-color){background:var(--ion-color-base);color:var(--ion-color-contrast)}:host(:empty){display:none}:host{border-radius:10px;font-size:max(13px, 0.8125rem)}";
  7527. var IonBadgeIosStyle0 = badgeIosCss;
  7528. const badgeMdCss = ":host{--background:var(--ion-color-primary, #0054e9);--color:var(--ion-color-primary-contrast, #fff);--padding-top:3px;--padding-end:8px;--padding-bottom:3px;--padding-start:8px;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;-webkit-padding-start:var(--padding-start);padding-inline-start:var(--padding-start);-webkit-padding-end:var(--padding-end);padding-inline-end:var(--padding-end);padding-top:var(--padding-top);padding-bottom:var(--padding-bottom);display:inline-block;min-width:10px;background:var(--background);color:var(--color);font-family:var(--ion-font-family, inherit);font-size:0.8125rem;font-weight:bold;line-height:1;text-align:center;white-space:nowrap;contain:content;vertical-align:baseline}:host(.ion-color){background:var(--ion-color-base);color:var(--ion-color-contrast)}:host(:empty){display:none}:host{--padding-top:3px;--padding-end:4px;--padding-bottom:4px;--padding-start:4px;border-radius:4px}";
  7529. var IonBadgeMdStyle0 = badgeMdCss;
  7530. /**
  7531. * @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
  7532. */
  7533. class Badge {
  7534. constructor(hostRef) {
  7535. registerInstance(this, hostRef);
  7536. this.color = undefined;
  7537. }
  7538. render() {
  7539. const mode = getIonMode$1(this);
  7540. return (hAsync(Host, { key: '1a2d39c5deec771a2f2196447627b62a7d4c8389', class: createColorClasses$1(this.color, {
  7541. [mode]: true,
  7542. }) }, hAsync("slot", { key: 'fc1b6587f1ed24715748eb6785e7fb7a57cdd5cd' })));
  7543. }
  7544. static get style() { return {
  7545. ios: IonBadgeIosStyle0,
  7546. md: IonBadgeMdStyle0
  7547. }; }
  7548. static get cmpMeta() { return {
  7549. "$flags$": 41,
  7550. "$tagName$": "ion-badge",
  7551. "$members$": {
  7552. "color": [513]
  7553. },
  7554. "$listeners$": undefined,
  7555. "$lazyBundleId$": "-",
  7556. "$attrsToReflect$": [["color", "color"]]
  7557. }; }
  7558. }
  7559. const breadcrumbIosCss = ":host{display:-ms-flexbox;display:flex;-ms-flex:0 0 auto;flex:0 0 auto;-ms-flex-align:center;align-items:center;color:var(--color);font-size:1rem;font-weight:400;line-height:1.5}.breadcrumb-native{font-family:inherit;font-size:inherit;font-style:inherit;font-weight:inherit;letter-spacing:inherit;text-decoration:inherit;text-indent:inherit;text-overflow:inherit;text-transform:inherit;text-align:inherit;white-space:inherit;color:inherit;padding-left:0;padding-right:0;padding-top:0;padding-bottom:0;margin-left:0;margin-right:0;margin-top:0;margin-bottom:0;display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;width:100%;outline:none;background:inherit}:host(.breadcrumb-disabled){cursor:default;opacity:0.5;pointer-events:none}:host(.breadcrumb-active){color:var(--color-active)}:host(.ion-focused){color:var(--color-focused)}:host(.ion-focused) .breadcrumb-native{background:var(--background-focused)}@media (any-hover: hover){:host(.ion-activatable:hover){color:var(--color-hover)}:host(.ion-activatable.in-breadcrumbs-color:hover),:host(.ion-activatable.ion-color:hover){color:var(--ion-color-shade)}}.breadcrumb-separator{display:-ms-inline-flexbox;display:inline-flex}:host(.breadcrumb-collapsed) .breadcrumb-native{display:none}:host(.in-breadcrumbs-color),:host(.in-breadcrumbs-color.breadcrumb-active){color:var(--ion-color-base)}:host(.in-breadcrumbs-color) .breadcrumb-separator{color:var(--ion-color-base)}:host(.ion-color){color:var(--ion-color-base)}:host(.in-toolbar-color),:host(.in-toolbar-color) .breadcrumb-separator{color:rgba(var(--ion-color-contrast-rgb), 0.8)}:host(.in-toolbar-color.breadcrumb-active){color:var(--ion-color-contrast)}.breadcrumbs-collapsed-indicator{padding-left:0;padding-right:0;padding-top:0;padding-bottom:0;-webkit-margin-start:14px;margin-inline-start:14px;-webkit-margin-end:14px;margin-inline-end:14px;margin-top:0;margin-bottom:0;display:-ms-flexbox;display:flex;-ms-flex:1 1 100%;flex:1 1 100%;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;width:32px;height:18px;border:0;outline:none;cursor:pointer;-webkit-appearance:none;-moz-appearance:none;appearance:none}.breadcrumbs-collapsed-indicator ion-icon{margin-top:1px;font-size:1.375rem}:host{--color:var(--ion-color-step-850, var(--ion-text-color-step-150, #2d4665));--color-active:var(--ion-text-color, #03060b);--color-hover:var(--ion-text-color, #03060b);--color-focused:var(--color-active);--background-focused:var(--ion-color-step-50, var(--ion-background-color-step-50, rgba(233, 237, 243, 0.7)));font-size:clamp(16px, 1rem, 22px)}:host(.breadcrumb-active){font-weight:600}.breadcrumb-native{border-radius:4px;-webkit-padding-start:12px;padding-inline-start:12px;-webkit-padding-end:12px;padding-inline-end:12px;padding-top:5px;padding-bottom:5px;border:1px solid transparent}:host(.ion-focused) .breadcrumb-native{border-radius:8px}:host(.in-breadcrumbs-color.ion-focused) .breadcrumb-native,:host(.ion-color.ion-focused) .breadcrumb-native{background:rgba(var(--ion-color-base-rgb), 0.1);color:var(--ion-color-base)}:host(.ion-focused) ::slotted(ion-icon),:host(.in-breadcrumbs-color.ion-focused) ::slotted(ion-icon),:host(.ion-color.ion-focused) ::slotted(ion-icon){color:var(--ion-color-step-750, var(--ion-text-color-step-250, #445b78))}.breadcrumb-separator{color:var(--ion-color-step-550, var(--ion-text-color-step-450, #73849a))}::slotted(ion-icon){color:var(--ion-color-step-400, var(--ion-text-color-step-600, #92a0b3));font-size:min(1.125rem, 21.6px)}::slotted(ion-icon[slot=start]){-webkit-margin-end:8px;margin-inline-end:8px}::slotted(ion-icon[slot=end]){-webkit-margin-start:8px;margin-inline-start:8px}:host(.breadcrumb-active) ::slotted(ion-icon){color:var(--ion-color-step-850, var(--ion-text-color-step-150, #242d39))}.breadcrumbs-collapsed-indicator{border-radius:4px;background:var(--ion-color-step-100, var(--ion-background-color-step-100, #e9edf3));color:var(--ion-color-step-550, var(--ion-text-color-step-450, #73849a))}.breadcrumbs-collapsed-indicator:hover{opacity:0.45}.breadcrumbs-collapsed-indicator:focus{background:var(--ion-color-step-150, var(--ion-background-color-step-150, #d9e0ea))}.breadcrumbs-collapsed-indicator ion-icon{font-size:min(1.375rem, 22px)}";
  7560. var IonBreadcrumbIosStyle0 = breadcrumbIosCss;
  7561. const breadcrumbMdCss = ":host{display:-ms-flexbox;display:flex;-ms-flex:0 0 auto;flex:0 0 auto;-ms-flex-align:center;align-items:center;color:var(--color);font-size:1rem;font-weight:400;line-height:1.5}.breadcrumb-native{font-family:inherit;font-size:inherit;font-style:inherit;font-weight:inherit;letter-spacing:inherit;text-decoration:inherit;text-indent:inherit;text-overflow:inherit;text-transform:inherit;text-align:inherit;white-space:inherit;color:inherit;padding-left:0;padding-right:0;padding-top:0;padding-bottom:0;margin-left:0;margin-right:0;margin-top:0;margin-bottom:0;display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;width:100%;outline:none;background:inherit}:host(.breadcrumb-disabled){cursor:default;opacity:0.5;pointer-events:none}:host(.breadcrumb-active){color:var(--color-active)}:host(.ion-focused){color:var(--color-focused)}:host(.ion-focused) .breadcrumb-native{background:var(--background-focused)}@media (any-hover: hover){:host(.ion-activatable:hover){color:var(--color-hover)}:host(.ion-activatable.in-breadcrumbs-color:hover),:host(.ion-activatable.ion-color:hover){color:var(--ion-color-shade)}}.breadcrumb-separator{display:-ms-inline-flexbox;display:inline-flex}:host(.breadcrumb-collapsed) .breadcrumb-native{display:none}:host(.in-breadcrumbs-color),:host(.in-breadcrumbs-color.breadcrumb-active){color:var(--ion-color-base)}:host(.in-breadcrumbs-color) .breadcrumb-separator{color:var(--ion-color-base)}:host(.ion-color){color:var(--ion-color-base)}:host(.in-toolbar-color),:host(.in-toolbar-color) .breadcrumb-separator{color:rgba(var(--ion-color-contrast-rgb), 0.8)}:host(.in-toolbar-color.breadcrumb-active){color:var(--ion-color-contrast)}.breadcrumbs-collapsed-indicator{padding-left:0;padding-right:0;padding-top:0;padding-bottom:0;-webkit-margin-start:14px;margin-inline-start:14px;-webkit-margin-end:14px;margin-inline-end:14px;margin-top:0;margin-bottom:0;display:-ms-flexbox;display:flex;-ms-flex:1 1 100%;flex:1 1 100%;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;width:32px;height:18px;border:0;outline:none;cursor:pointer;-webkit-appearance:none;-moz-appearance:none;appearance:none}.breadcrumbs-collapsed-indicator ion-icon{margin-top:1px;font-size:1.375rem}:host{--color:var(--ion-color-step-600, var(--ion-text-color-step-400, #677483));--color-active:var(--ion-text-color, #03060b);--color-hover:var(--ion-text-color, #03060b);--color-focused:var(--ion-color-step-800, var(--ion-text-color-step-200, #35404e));--background-focused:var(--ion-color-step-50, var(--ion-background-color-step-50, #fff))}:host(.breadcrumb-active){font-weight:500}.breadcrumb-native{-webkit-padding-start:12px;padding-inline-start:12px;-webkit-padding-end:12px;padding-inline-end:12px;padding-top:6px;padding-bottom:6px}.breadcrumb-separator{-webkit-margin-start:10px;margin-inline-start:10px;-webkit-margin-end:10px;margin-inline-end:10px;margin-top:-1px}:host(.ion-focused) .breadcrumb-native{border-radius:4px;-webkit-box-shadow:0px 1px 2px rgba(0, 0, 0, 0.2), 0px 2px 8px rgba(0, 0, 0, 0.12);box-shadow:0px 1px 2px rgba(0, 0, 0, 0.2), 0px 2px 8px rgba(0, 0, 0, 0.12)}.breadcrumb-separator{color:var(--ion-color-step-550, var(--ion-text-color-step-450, #73849a))}::slotted(ion-icon){color:var(--ion-color-step-550, var(--ion-text-color-step-450, #7d8894));font-size:1.125rem}::slotted(ion-icon[slot=start]){-webkit-margin-end:8px;margin-inline-end:8px}::slotted(ion-icon[slot=end]){-webkit-margin-start:8px;margin-inline-start:8px}:host(.breadcrumb-active) ::slotted(ion-icon){color:var(--ion-color-step-850, var(--ion-text-color-step-150, #222d3a))}.breadcrumbs-collapsed-indicator{border-radius:2px;background:var(--ion-color-step-100, var(--ion-background-color-step-100, #eef1f3));color:var(--ion-color-step-550, var(--ion-text-color-step-450, #73849a))}.breadcrumbs-collapsed-indicator:hover{opacity:0.7}.breadcrumbs-collapsed-indicator:focus{background:var(--ion-color-step-150, var(--ion-background-color-step-150, #dfe5e8))}";
  7562. var IonBreadcrumbMdStyle0 = breadcrumbMdCss;
  7563. /**
  7564. * @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
  7565. *
  7566. * @part native - The native HTML anchor or div element that wraps all child elements.
  7567. * @part separator - The separator element between each breadcrumb.
  7568. * @part collapsed-indicator - The indicator element that shows the breadcrumbs are collapsed.
  7569. */
  7570. class Breadcrumb {
  7571. constructor(hostRef) {
  7572. registerInstance(this, hostRef);
  7573. this.ionFocus = createEvent(this, "ionFocus", 7);
  7574. this.ionBlur = createEvent(this, "ionBlur", 7);
  7575. this.collapsedClick = createEvent(this, "collapsedClick", 7);
  7576. this.inheritedAttributes = {};
  7577. this.onFocus = () => {
  7578. this.ionFocus.emit();
  7579. };
  7580. this.onBlur = () => {
  7581. this.ionBlur.emit();
  7582. };
  7583. this.collapsedIndicatorClick = () => {
  7584. this.collapsedClick.emit({ ionShadowTarget: this.collapsedRef });
  7585. };
  7586. this.collapsed = false;
  7587. this.last = undefined;
  7588. this.showCollapsedIndicator = undefined;
  7589. this.color = undefined;
  7590. this.active = false;
  7591. this.disabled = false;
  7592. this.download = undefined;
  7593. this.href = undefined;
  7594. this.rel = undefined;
  7595. this.separator = undefined;
  7596. this.target = undefined;
  7597. this.routerDirection = 'forward';
  7598. this.routerAnimation = undefined;
  7599. }
  7600. componentWillLoad() {
  7601. this.inheritedAttributes = inheritAriaAttributes(this.el);
  7602. }
  7603. isClickable() {
  7604. return this.href !== undefined;
  7605. }
  7606. render() {
  7607. const { color, active, collapsed, disabled, download, el, inheritedAttributes, last, routerAnimation, routerDirection, separator, showCollapsedIndicator, target, } = this;
  7608. const clickable = this.isClickable();
  7609. const TagType = this.href === undefined ? 'span' : 'a';
  7610. // Links can still be tabbed to when set to disabled if they have an href
  7611. // in order to truly disable them we can keep it as an anchor but remove the href
  7612. const href = disabled ? undefined : this.href;
  7613. const mode = getIonMode$1(this);
  7614. const attrs = TagType === 'span'
  7615. ? {}
  7616. : {
  7617. download,
  7618. href,
  7619. target,
  7620. };
  7621. // If the breadcrumb is collapsed, check if it contains the collapsed indicator
  7622. // to show the separator as long as it isn't also the last breadcrumb
  7623. // otherwise if not collapsed use the value in separator
  7624. const showSeparator = last ? false : collapsed ? (showCollapsedIndicator && !last ? true : false) : separator;
  7625. return (hAsync(Host, { key: '32ca61c83721dff52b5e97171ed449dce3584a55', onClick: (ev) => openURL(href, ev, routerDirection, routerAnimation), "aria-disabled": disabled ? 'true' : null, class: createColorClasses$1(color, {
  7626. [mode]: true,
  7627. 'breadcrumb-active': active,
  7628. 'breadcrumb-collapsed': collapsed,
  7629. 'breadcrumb-disabled': disabled,
  7630. 'in-breadcrumbs-color': hostContext('ion-breadcrumbs[color]', el),
  7631. 'in-toolbar': hostContext('ion-toolbar', this.el),
  7632. 'in-toolbar-color': hostContext('ion-toolbar[color]', this.el),
  7633. 'ion-activatable': clickable,
  7634. 'ion-focusable': clickable,
  7635. }) }, hAsync(TagType, Object.assign({ key: '479feb845f4a6d8009d5422b33eb423730b9722b' }, attrs, { class: "breadcrumb-native", part: "native", disabled: disabled, onFocus: this.onFocus, onBlur: this.onBlur }, inheritedAttributes), hAsync("slot", { key: '3c5dcaeb0d258235d1b7707868026ff1d1404099', name: "start" }), hAsync("slot", { key: 'f1cfb934443cd97dc220882c5e3596ea879d66cf' }), hAsync("slot", { key: '539710121b5b1f3ee8d4c24a9651b67c2ae08add', name: "end" })), showCollapsedIndicator && (hAsync("button", { key: 'ed53a95ccd89022c8b7bee0658a221ec62a5c73b', part: "collapsed-indicator", "aria-label": "Show more breadcrumbs", onClick: () => this.collapsedIndicatorClick(), ref: (collapsedEl) => (this.collapsedRef = collapsedEl), class: {
  7636. 'breadcrumbs-collapsed-indicator': true,
  7637. } }, hAsync("ion-icon", { key: 'a849e1142a86f06f207cf11662fa2a560ab7fc6a', "aria-hidden": "true", icon: ellipsisHorizontal, lazy: false }))), showSeparator && (
  7638. /**
  7639. * Separators should not be announced by narrators.
  7640. * We add aria-hidden on the span so that this applies
  7641. * to any custom separators too.
  7642. */
  7643. hAsync("span", { key: 'fc3c741cb01fafef8b26046c7ee5b190efc69a7c', class: "breadcrumb-separator", part: "separator", "aria-hidden": "true" }, hAsync("slot", { key: '4871932ae1dae520767e0713e7cee2d11b0bba6d', name: "separator" }, mode === 'ios' ? (hAsync("ion-icon", { icon: chevronForwardOutline, lazy: false, "flip-rtl": true })) : (hAsync("span", null, "/")))))));
  7644. }
  7645. get el() { return getElement(this); }
  7646. static get style() { return {
  7647. ios: IonBreadcrumbIosStyle0,
  7648. md: IonBreadcrumbMdStyle0
  7649. }; }
  7650. static get cmpMeta() { return {
  7651. "$flags$": 41,
  7652. "$tagName$": "ion-breadcrumb",
  7653. "$members$": {
  7654. "collapsed": [4],
  7655. "last": [4],
  7656. "showCollapsedIndicator": [4, "show-collapsed-indicator"],
  7657. "color": [1],
  7658. "active": [4],
  7659. "disabled": [4],
  7660. "download": [1],
  7661. "href": [1],
  7662. "rel": [1],
  7663. "separator": [4],
  7664. "target": [1],
  7665. "routerDirection": [1, "router-direction"],
  7666. "routerAnimation": [16]
  7667. },
  7668. "$listeners$": undefined,
  7669. "$lazyBundleId$": "-",
  7670. "$attrsToReflect$": []
  7671. }; }
  7672. }
  7673. const breadcrumbsIosCss = ":host{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-align:center;align-items:center}:host(.in-toolbar-color),:host(.in-toolbar-color) .breadcrumbs-collapsed-indicator ion-icon{color:var(--ion-color-contrast)}:host(.in-toolbar-color) .breadcrumbs-collapsed-indicator{background:rgba(var(--ion-color-contrast-rgb), 0.11)}:host(.in-toolbar){-webkit-padding-start:20px;padding-inline-start:20px;-webkit-padding-end:20px;padding-inline-end:20px;padding-top:0;padding-bottom:0;-ms-flex-pack:center;justify-content:center}";
  7674. var IonBreadcrumbsIosStyle0 = breadcrumbsIosCss;
  7675. const breadcrumbsMdCss = ":host{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-align:center;align-items:center}:host(.in-toolbar-color),:host(.in-toolbar-color) .breadcrumbs-collapsed-indicator ion-icon{color:var(--ion-color-contrast)}:host(.in-toolbar-color) .breadcrumbs-collapsed-indicator{background:rgba(var(--ion-color-contrast-rgb), 0.11)}:host(.in-toolbar){-webkit-padding-start:8px;padding-inline-start:8px;-webkit-padding-end:8px;padding-inline-end:8px;padding-top:0;padding-bottom:0}";
  7676. var IonBreadcrumbsMdStyle0 = breadcrumbsMdCss;
  7677. /**
  7678. * @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
  7679. *
  7680. */
  7681. class Breadcrumbs {
  7682. constructor(hostRef) {
  7683. registerInstance(this, hostRef);
  7684. this.ionCollapsedClick = createEvent(this, "ionCollapsedClick", 7);
  7685. this.breadcrumbsInit = () => {
  7686. this.setBreadcrumbSeparator();
  7687. this.setMaxItems();
  7688. };
  7689. this.resetActiveBreadcrumb = () => {
  7690. const breadcrumbs = this.getBreadcrumbs();
  7691. // Only reset the active breadcrumb if we were the ones to change it
  7692. // otherwise use the one set on the component
  7693. const activeBreadcrumb = breadcrumbs.find((breadcrumb) => breadcrumb.active);
  7694. if (activeBreadcrumb && this.activeChanged) {
  7695. activeBreadcrumb.active = false;
  7696. }
  7697. };
  7698. this.setMaxItems = () => {
  7699. const { itemsAfterCollapse, itemsBeforeCollapse, maxItems } = this;
  7700. const breadcrumbs = this.getBreadcrumbs();
  7701. for (const breadcrumb of breadcrumbs) {
  7702. breadcrumb.showCollapsedIndicator = false;
  7703. breadcrumb.collapsed = false;
  7704. }
  7705. // If the number of breadcrumbs exceeds the maximum number of items
  7706. // that should show and the items before / after collapse do not
  7707. // exceed the maximum items then we need to collapse the breadcrumbs
  7708. const shouldCollapse = maxItems !== undefined && breadcrumbs.length > maxItems && itemsBeforeCollapse + itemsAfterCollapse <= maxItems;
  7709. if (shouldCollapse) {
  7710. // Show the collapsed indicator in the first breadcrumb that collapses
  7711. breadcrumbs.forEach((breadcrumb, index) => {
  7712. if (index === itemsBeforeCollapse) {
  7713. breadcrumb.showCollapsedIndicator = true;
  7714. }
  7715. // Collapse all breadcrumbs that have an index greater than or equal to
  7716. // the number before collapse and an index less than the total number
  7717. // of breadcrumbs minus the items that should show after the collapse
  7718. if (index >= itemsBeforeCollapse && index < breadcrumbs.length - itemsAfterCollapse) {
  7719. breadcrumb.collapsed = true;
  7720. }
  7721. });
  7722. }
  7723. };
  7724. this.setBreadcrumbSeparator = () => {
  7725. const { itemsAfterCollapse, itemsBeforeCollapse, maxItems } = this;
  7726. const breadcrumbs = this.getBreadcrumbs();
  7727. // Check if an active breadcrumb exists already
  7728. const active = breadcrumbs.find((breadcrumb) => breadcrumb.active);
  7729. // Set the separator on all but the last breadcrumb
  7730. for (const breadcrumb of breadcrumbs) {
  7731. // The only time the last breadcrumb changes is when
  7732. // itemsAfterCollapse is set to 0, in this case the
  7733. // last breadcrumb will be the collapsed indicator
  7734. const last = maxItems !== undefined && itemsAfterCollapse === 0
  7735. ? breadcrumb === breadcrumbs[itemsBeforeCollapse]
  7736. : breadcrumb === breadcrumbs[breadcrumbs.length - 1];
  7737. breadcrumb.last = last;
  7738. // If the breadcrumb has defined whether or not to show the
  7739. // separator then use that value, otherwise check if it's the
  7740. // last breadcrumb
  7741. const separator = breadcrumb.separator !== undefined ? breadcrumb.separator : last ? undefined : true;
  7742. breadcrumb.separator = separator;
  7743. // If there is not an active breadcrumb already
  7744. // set the last one to active
  7745. if (!active && last) {
  7746. breadcrumb.active = true;
  7747. this.activeChanged = true;
  7748. }
  7749. }
  7750. };
  7751. this.getBreadcrumbs = () => {
  7752. return Array.from(this.el.querySelectorAll('ion-breadcrumb'));
  7753. };
  7754. this.slotChanged = () => {
  7755. this.resetActiveBreadcrumb();
  7756. this.breadcrumbsInit();
  7757. };
  7758. this.collapsed = undefined;
  7759. this.activeChanged = undefined;
  7760. this.color = undefined;
  7761. this.maxItems = undefined;
  7762. this.itemsBeforeCollapse = 1;
  7763. this.itemsAfterCollapse = 1;
  7764. }
  7765. onCollapsedClick(ev) {
  7766. const breadcrumbs = this.getBreadcrumbs();
  7767. const collapsedBreadcrumbs = breadcrumbs.filter((breadcrumb) => breadcrumb.collapsed);
  7768. this.ionCollapsedClick.emit(Object.assign(Object.assign({}, ev.detail), { collapsedBreadcrumbs }));
  7769. }
  7770. maxItemsChanged() {
  7771. this.resetActiveBreadcrumb();
  7772. this.breadcrumbsInit();
  7773. }
  7774. componentWillLoad() {
  7775. this.breadcrumbsInit();
  7776. }
  7777. render() {
  7778. const { color, collapsed } = this;
  7779. const mode = getIonMode$1(this);
  7780. return (hAsync(Host, { key: 'fe64e9cdf597ede2db140bf5fa05a0359d82db57', class: createColorClasses$1(color, {
  7781. [mode]: true,
  7782. 'in-toolbar': hostContext('ion-toolbar', this.el),
  7783. 'in-toolbar-color': hostContext('ion-toolbar[color]', this.el),
  7784. 'breadcrumbs-collapsed': collapsed,
  7785. }) }, hAsync("slot", { key: 'a2c99b579e339055c50a613d5c6b61032f5ddffe', onSlotchange: this.slotChanged })));
  7786. }
  7787. get el() { return getElement(this); }
  7788. static get watchers() { return {
  7789. "maxItems": ["maxItemsChanged"],
  7790. "itemsBeforeCollapse": ["maxItemsChanged"],
  7791. "itemsAfterCollapse": ["maxItemsChanged"]
  7792. }; }
  7793. static get style() { return {
  7794. ios: IonBreadcrumbsIosStyle0,
  7795. md: IonBreadcrumbsMdStyle0
  7796. }; }
  7797. static get cmpMeta() { return {
  7798. "$flags$": 41,
  7799. "$tagName$": "ion-breadcrumbs",
  7800. "$members$": {
  7801. "color": [513],
  7802. "maxItems": [2, "max-items"],
  7803. "itemsBeforeCollapse": [2, "items-before-collapse"],
  7804. "itemsAfterCollapse": [2, "items-after-collapse"],
  7805. "collapsed": [32],
  7806. "activeChanged": [32]
  7807. },
  7808. "$listeners$": [[0, "collapsedClick", "onCollapsedClick"]],
  7809. "$lazyBundleId$": "-",
  7810. "$attrsToReflect$": [["color", "color"]]
  7811. }; }
  7812. }
  7813. const buttonIosCss = ":host{--overflow:hidden;--ripple-color:currentColor;--border-width:initial;--border-color:initial;--border-style:initial;--color-activated:var(--color);--color-focused:var(--color);--color-hover:var(--color);--box-shadow:none;display:inline-block;width:auto;color:var(--color);font-family:var(--ion-font-family, inherit);text-align:center;text-decoration:none;white-space:normal;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;vertical-align:top;vertical-align:-webkit-baseline-middle;-webkit-font-kerning:none;font-kerning:none}:host(.button-disabled){cursor:default;opacity:0.5;pointer-events:none}:host(.button-solid){--background:var(--ion-color-primary, #0054e9);--color:var(--ion-color-primary-contrast, #fff)}:host(.button-outline){--border-color:var(--ion-color-primary, #0054e9);--background:transparent;--color:var(--ion-color-primary, #0054e9)}:host(.button-clear){--border-width:0;--background:transparent;--color:var(--ion-color-primary, #0054e9)}:host(.button-block){display:block}:host(.button-block) .button-native{margin-left:0;margin-right:0;width:100%;clear:both;contain:content}:host(.button-block) .button-native::after{clear:both}:host(.button-full){display:block}:host(.button-full) .button-native{margin-left:0;margin-right:0;width:100%;contain:content}:host(.button-full:not(.button-round)) .button-native{border-radius:0;border-right-width:0;border-left-width:0}.button-native{border-radius:var(--border-radius);-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;margin-left:0;margin-right:0;margin-top:0;margin-bottom:0;-webkit-padding-start:var(--padding-start);padding-inline-start:var(--padding-start);-webkit-padding-end:var(--padding-end);padding-inline-end:var(--padding-end);padding-top:var(--padding-top);padding-bottom:var(--padding-bottom);font-family:inherit;font-size:inherit;font-style:inherit;font-weight:inherit;letter-spacing:inherit;text-decoration:inherit;text-indent:inherit;text-overflow:inherit;text-transform:inherit;text-align:inherit;white-space:inherit;color:inherit;display:-ms-flexbox;display:flex;position:relative;-ms-flex-align:center;align-items:center;width:100%;height:100%;min-height:inherit;-webkit-transition:var(--transition);transition:var(--transition);border-width:var(--border-width);border-style:var(--border-style);border-color:var(--border-color);outline:none;background:var(--background);line-height:1;-webkit-box-shadow:var(--box-shadow);box-shadow:var(--box-shadow);contain:layout style;cursor:pointer;opacity:var(--opacity);overflow:var(--overflow);z-index:0;-webkit-box-sizing:border-box;box-sizing:border-box;-webkit-appearance:none;-moz-appearance:none;appearance:none}.button-native::-moz-focus-inner{border:0}.button-inner{display:-ms-flexbox;display:flex;position:relative;-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-negative:0;flex-shrink:0;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;width:100%;height:100%;z-index:1}::slotted([slot=start]),::slotted([slot=end]){-ms-flex-negative:0;flex-shrink:0}::slotted(ion-icon){font-size:1.35em;pointer-events:none}::slotted(ion-icon[slot=start]){-webkit-margin-start:-0.3em;margin-inline-start:-0.3em;-webkit-margin-end:0.3em;margin-inline-end:0.3em;margin-top:0;margin-bottom:0}::slotted(ion-icon[slot=end]){-webkit-margin-start:0.3em;margin-inline-start:0.3em;-webkit-margin-end:-0.2em;margin-inline-end:-0.2em;margin-top:0;margin-bottom:0}ion-ripple-effect{color:var(--ripple-color)}.button-native::after{left:0;right:0;top:0;bottom:0;position:absolute;content:\"\";opacity:0}:host(.ion-focused){color:var(--color-focused)}:host(.ion-focused) .button-native::after{background:var(--background-focused);opacity:var(--background-focused-opacity)}@media (any-hover: hover){:host(:hover){color:var(--color-hover)}:host(:hover) .button-native::after{background:var(--background-hover);opacity:var(--background-hover-opacity)}}:host(.ion-activated){color:var(--color-activated)}:host(.ion-activated) .button-native::after{background:var(--background-activated);opacity:var(--background-activated-opacity)}:host(.button-solid.ion-color) .button-native{background:var(--ion-color-base);color:var(--ion-color-contrast)}:host(.button-outline.ion-color) .button-native{border-color:var(--ion-color-base);background:transparent;color:var(--ion-color-base)}:host(.button-clear.ion-color) .button-native{background:transparent;color:var(--ion-color-base)}:host(.in-toolbar:not(.ion-color):not(.in-toolbar-color)) .button-native{color:var(--ion-toolbar-color, var(--color))}:host(.button-outline.in-toolbar:not(.ion-color):not(.in-toolbar-color)) .button-native{border-color:var(--ion-toolbar-color, var(--color, var(--border-color)))}:host(.button-solid.in-toolbar:not(.ion-color):not(.in-toolbar-color)) .button-native{background:var(--ion-toolbar-color, var(--background));color:var(--ion-toolbar-background, var(--color))}:host{--border-radius:14px;--padding-top:13px;--padding-bottom:13px;--padding-start:1em;--padding-end:1em;--transition:background-color, opacity 100ms linear;-webkit-margin-start:2px;margin-inline-start:2px;-webkit-margin-end:2px;margin-inline-end:2px;margin-top:4px;margin-bottom:4px;min-height:3.1em;font-size:min(1rem, 48px);font-weight:500;letter-spacing:0}:host(.button-solid){--background-activated:var(--ion-color-primary-shade, #004acd);--background-focused:var(--ion-color-primary-shade, #004acd);--background-hover:var(--ion-color-primary-tint, #1a65eb);--background-activated-opacity:1;--background-focused-opacity:1;--background-hover-opacity:1}:host(.button-outline){--border-radius:14px;--border-width:1px;--border-style:solid;--background-activated:var(--ion-color-primary, #0054e9);--background-focused:var(--ion-color-primary, #0054e9);--background-hover:transparent;--background-focused-opacity:.1;--color-activated:var(--ion-color-primary-contrast, #fff)}:host(.button-clear){--background-activated:transparent;--background-activated-opacity:0;--background-focused:var(--ion-color-primary, #0054e9);--background-hover:transparent;--background-focused-opacity:.1;font-size:min(1.0625rem, 51px);font-weight:normal}:host(.in-buttons){font-size:clamp(17px, 1.0625rem, 21.08px);font-weight:400}:host(.button-large){--border-radius:16px;--padding-top:17px;--padding-start:1em;--padding-end:1em;--padding-bottom:17px;min-height:3.1em;font-size:min(1.25rem, 60px)}:host(.button-small){--border-radius:6px;--padding-top:4px;--padding-start:0.9em;--padding-end:0.9em;--padding-bottom:4px;min-height:2.1em;font-size:min(0.8125rem, 39px)}:host(.button-round){--border-radius:999px;--padding-top:0;--padding-start:26px;--padding-end:26px;--padding-bottom:0}:host(.button-strong){font-weight:600}:host(.button-has-icon-only){--padding-top:0;--padding-bottom:var(--padding-top);--padding-end:var(--padding-top);--padding-start:var(--padding-end);min-width:clamp(30px, 2.125em, 60px);min-height:clamp(30px, 2.125em, 60px)}::slotted(ion-icon[slot=icon-only]){font-size:clamp(15.12px, 1.125em, 43.02px)}:host(.button-small.button-has-icon-only){min-width:clamp(23px, 2.16em, 54px);min-height:clamp(23px, 2.16em, 54px)}:host(.button-small) ::slotted(ion-icon[slot=icon-only]){font-size:clamp(12.1394px, 1.308125em, 40.1856px)}:host(.button-large.button-has-icon-only){min-width:clamp(46px, 2.5em, 78px);min-height:clamp(46px, 2.5em, 78px)}:host(.button-large) ::slotted(ion-icon[slot=icon-only]){font-size:clamp(15.12px, 0.9em, 43.056px)}:host(.button-outline.ion-focused.ion-color) .button-native,:host(.button-clear.ion-focused.ion-color) .button-native{color:var(--ion-color-base)}:host(.button-outline.ion-focused.ion-color) .button-native::after,:host(.button-clear.ion-focused.ion-color) .button-native::after{background:var(--ion-color-base)}:host(.button-solid.ion-color.ion-focused) .button-native::after{background:var(--ion-color-shade)}@media (any-hover: hover){:host(.button-clear:not(.ion-activated):hover),:host(.button-outline:not(.ion-activated):hover){opacity:0.6}:host(.button-clear.ion-color:hover) .button-native,:host(.button-outline.ion-color:hover) .button-native{color:var(--ion-color-base)}:host(.button-clear.ion-color:hover) .button-native::after,:host(.button-outline.ion-color:hover) .button-native::after{background:transparent}:host(.button-solid.ion-color:hover) .button-native::after{background:var(--ion-color-tint)}:host(:hover.button-solid.in-toolbar:not(.ion-color):not(.in-toolbar-color):not(.ion-activated)) .button-native::after{background:#fff;opacity:0.1}}:host(.button-clear.ion-activated){opacity:0.4}:host(.button-outline.ion-activated.ion-color) .button-native{color:var(--ion-color-contrast)}:host(.button-outline.ion-activated.ion-color) .button-native::after{background:var(--ion-color-base)}:host(.button-solid.ion-color.ion-activated) .button-native::after{background:var(--ion-color-shade)}:host(.button-outline.ion-activated.in-toolbar:not(.ion-color):not(.in-toolbar-color)) .button-native{background:var(--ion-toolbar-color, var(--color));color:var(--ion-toolbar-background, var(--background), var(--ion-color-primary-contrast, #fff))}";
  7814. var IonButtonIosStyle0 = buttonIosCss;
  7815. const buttonMdCss = ":host{--overflow:hidden;--ripple-color:currentColor;--border-width:initial;--border-color:initial;--border-style:initial;--color-activated:var(--color);--color-focused:var(--color);--color-hover:var(--color);--box-shadow:none;display:inline-block;width:auto;color:var(--color);font-family:var(--ion-font-family, inherit);text-align:center;text-decoration:none;white-space:normal;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;vertical-align:top;vertical-align:-webkit-baseline-middle;-webkit-font-kerning:none;font-kerning:none}:host(.button-disabled){cursor:default;opacity:0.5;pointer-events:none}:host(.button-solid){--background:var(--ion-color-primary, #0054e9);--color:var(--ion-color-primary-contrast, #fff)}:host(.button-outline){--border-color:var(--ion-color-primary, #0054e9);--background:transparent;--color:var(--ion-color-primary, #0054e9)}:host(.button-clear){--border-width:0;--background:transparent;--color:var(--ion-color-primary, #0054e9)}:host(.button-block){display:block}:host(.button-block) .button-native{margin-left:0;margin-right:0;width:100%;clear:both;contain:content}:host(.button-block) .button-native::after{clear:both}:host(.button-full){display:block}:host(.button-full) .button-native{margin-left:0;margin-right:0;width:100%;contain:content}:host(.button-full:not(.button-round)) .button-native{border-radius:0;border-right-width:0;border-left-width:0}.button-native{border-radius:var(--border-radius);-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;margin-left:0;margin-right:0;margin-top:0;margin-bottom:0;-webkit-padding-start:var(--padding-start);padding-inline-start:var(--padding-start);-webkit-padding-end:var(--padding-end);padding-inline-end:var(--padding-end);padding-top:var(--padding-top);padding-bottom:var(--padding-bottom);font-family:inherit;font-size:inherit;font-style:inherit;font-weight:inherit;letter-spacing:inherit;text-decoration:inherit;text-indent:inherit;text-overflow:inherit;text-transform:inherit;text-align:inherit;white-space:inherit;color:inherit;display:-ms-flexbox;display:flex;position:relative;-ms-flex-align:center;align-items:center;width:100%;height:100%;min-height:inherit;-webkit-transition:var(--transition);transition:var(--transition);border-width:var(--border-width);border-style:var(--border-style);border-color:var(--border-color);outline:none;background:var(--background);line-height:1;-webkit-box-shadow:var(--box-shadow);box-shadow:var(--box-shadow);contain:layout style;cursor:pointer;opacity:var(--opacity);overflow:var(--overflow);z-index:0;-webkit-box-sizing:border-box;box-sizing:border-box;-webkit-appearance:none;-moz-appearance:none;appearance:none}.button-native::-moz-focus-inner{border:0}.button-inner{display:-ms-flexbox;display:flex;position:relative;-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-negative:0;flex-shrink:0;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;width:100%;height:100%;z-index:1}::slotted([slot=start]),::slotted([slot=end]){-ms-flex-negative:0;flex-shrink:0}::slotted(ion-icon){font-size:1.35em;pointer-events:none}::slotted(ion-icon[slot=start]){-webkit-margin-start:-0.3em;margin-inline-start:-0.3em;-webkit-margin-end:0.3em;margin-inline-end:0.3em;margin-top:0;margin-bottom:0}::slotted(ion-icon[slot=end]){-webkit-margin-start:0.3em;margin-inline-start:0.3em;-webkit-margin-end:-0.2em;margin-inline-end:-0.2em;margin-top:0;margin-bottom:0}ion-ripple-effect{color:var(--ripple-color)}.button-native::after{left:0;right:0;top:0;bottom:0;position:absolute;content:\"\";opacity:0}:host(.ion-focused){color:var(--color-focused)}:host(.ion-focused) .button-native::after{background:var(--background-focused);opacity:var(--background-focused-opacity)}@media (any-hover: hover){:host(:hover){color:var(--color-hover)}:host(:hover) .button-native::after{background:var(--background-hover);opacity:var(--background-hover-opacity)}}:host(.ion-activated){color:var(--color-activated)}:host(.ion-activated) .button-native::after{background:var(--background-activated);opacity:var(--background-activated-opacity)}:host(.button-solid.ion-color) .button-native{background:var(--ion-color-base);color:var(--ion-color-contrast)}:host(.button-outline.ion-color) .button-native{border-color:var(--ion-color-base);background:transparent;color:var(--ion-color-base)}:host(.button-clear.ion-color) .button-native{background:transparent;color:var(--ion-color-base)}:host(.in-toolbar:not(.ion-color):not(.in-toolbar-color)) .button-native{color:var(--ion-toolbar-color, var(--color))}:host(.button-outline.in-toolbar:not(.ion-color):not(.in-toolbar-color)) .button-native{border-color:var(--ion-toolbar-color, var(--color, var(--border-color)))}:host(.button-solid.in-toolbar:not(.ion-color):not(.in-toolbar-color)) .button-native{background:var(--ion-toolbar-color, var(--background));color:var(--ion-toolbar-background, var(--color))}:host{--border-radius:4px;--padding-top:8px;--padding-bottom:8px;--padding-start:1.1em;--padding-end:1.1em;--transition:box-shadow 280ms cubic-bezier(.4, 0, .2, 1),\n background-color 15ms linear,\n color 15ms linear;-webkit-margin-start:2px;margin-inline-start:2px;-webkit-margin-end:2px;margin-inline-end:2px;margin-top:4px;margin-bottom:4px;min-height:36px;font-size:0.875rem;font-weight:500;letter-spacing:0.06em;text-transform:uppercase}:host(.button-solid){--background-activated:transparent;--background-hover:var(--ion-color-primary-contrast, #fff);--background-focused:var(--ion-color-primary-contrast, #fff);--background-activated-opacity:0;--background-focused-opacity:.24;--background-hover-opacity:.08;--box-shadow:0 3px 1px -2px rgba(0, 0, 0, 0.2), 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 1px 5px 0 rgba(0, 0, 0, 0.12)}:host(.button-solid.ion-activated){--box-shadow:0 5px 5px -3px rgba(0, 0, 0, 0.2), 0 8px 10px 1px rgba(0, 0, 0, 0.14), 0 3px 14px 2px rgba(0, 0, 0, 0.12)}:host(.button-outline){--border-width:2px;--border-style:solid;--box-shadow:none;--background-activated:transparent;--background-focused:var(--ion-color-primary, #0054e9);--background-hover:var(--ion-color-primary, #0054e9);--background-activated-opacity:0;--background-focused-opacity:.12;--background-hover-opacity:.04}:host(.button-outline.ion-activated.ion-color) .button-native{background:transparent}:host(.button-clear){--background-activated:transparent;--background-focused:var(--ion-color-primary, #0054e9);--background-hover:var(--ion-color-primary, #0054e9);--background-activated-opacity:0;--background-focused-opacity:.12;--background-hover-opacity:.04}:host(.button-round){--border-radius:999px;--padding-top:0;--padding-start:26px;--padding-end:26px;--padding-bottom:0}:host(.button-large){--padding-top:14px;--padding-start:1em;--padding-end:1em;--padding-bottom:14px;min-height:2.8em;font-size:1.25rem}:host(.button-small){--padding-top:4px;--padding-start:0.9em;--padding-end:0.9em;--padding-bottom:4px;min-height:2.1em;font-size:0.8125rem}:host(.button-strong){font-weight:bold}:host(.button-has-icon-only){--padding-top:0;--padding-bottom:var(--padding-top);--padding-end:var(--padding-top);--padding-start:var(--padding-end);min-width:clamp(30px, 2.86em, 60px);min-height:clamp(30px, 2.86em, 60px)}::slotted(ion-icon[slot=icon-only]){font-size:clamp(15.104px, 1.6em, 43.008px)}:host(.button-small.button-has-icon-only){min-width:clamp(23px, 2.16em, 54px);min-height:clamp(23px, 2.16em, 54px)}:host(.button-small) ::slotted(ion-icon[slot=icon-only]){font-size:clamp(13.002px, 1.23125em, 40.385px)}:host(.button-large.button-has-icon-only){min-width:clamp(46px, 2.5em, 78px);min-height:clamp(46px, 2.5em, 78px)}:host(.button-large) ::slotted(ion-icon[slot=icon-only]){font-size:clamp(15.008px, 1.4em, 43.008px)}:host(.button-solid.ion-color.ion-focused) .button-native::after{background:var(--ion-color-contrast)}:host(.button-clear.ion-color.ion-focused) .button-native::after,:host(.button-outline.ion-color.ion-focused) .button-native::after{background:var(--ion-color-base)}@media (any-hover: hover){:host(.button-solid.ion-color:hover) .button-native::after{background:var(--ion-color-contrast)}:host(.button-clear.ion-color:hover) .button-native::after,:host(.button-outline.ion-color:hover) .button-native::after{background:var(--ion-color-base)}}:host(.button-outline.ion-activated.in-toolbar:not(.ion-color):not(.in-toolbar-color)) .button-native{background:var(--ion-toolbar-background, var(--color));color:var(--ion-toolbar-color, var(--background), var(--ion-color-primary-contrast, #fff))}";
  7816. var IonButtonMdStyle0 = buttonMdCss;
  7817. /**
  7818. * @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
  7819. *
  7820. * @slot - Content is placed between the named slots if provided without a slot.
  7821. * @slot icon-only - Should be used on an icon in a button that has no text.
  7822. * @slot start - Content is placed to the left of the button text in LTR, and to the right in RTL.
  7823. * @slot end - Content is placed to the right of the button text in LTR, and to the left in RTL.
  7824. *
  7825. * @part native - The native HTML button or anchor element that wraps all child elements.
  7826. */
  7827. class Button {
  7828. constructor(hostRef) {
  7829. registerInstance(this, hostRef);
  7830. this.ionFocus = createEvent(this, "ionFocus", 7);
  7831. this.ionBlur = createEvent(this, "ionBlur", 7);
  7832. this.inItem = false;
  7833. this.inListHeader = false;
  7834. this.inToolbar = false;
  7835. this.formButtonEl = null;
  7836. this.formEl = null;
  7837. this.inheritedAttributes = {};
  7838. this.handleClick = (ev) => {
  7839. const { el } = this;
  7840. if (this.type === 'button') {
  7841. openURL(this.href, ev, this.routerDirection, this.routerAnimation);
  7842. }
  7843. else if (hasShadowDom(el)) {
  7844. this.submitForm(ev);
  7845. }
  7846. };
  7847. this.onFocus = () => {
  7848. this.ionFocus.emit();
  7849. };
  7850. this.onBlur = () => {
  7851. this.ionBlur.emit();
  7852. };
  7853. this.slotChanged = () => {
  7854. /**
  7855. * Ensures that the 'has-icon-only' class is properly added
  7856. * or removed from `ion-button` when manipulating the
  7857. * `icon-only` slot.
  7858. *
  7859. * Without this, the 'has-icon-only' class is only checked
  7860. * or added when `ion-button` component first renders.
  7861. */
  7862. this.isCircle = this.hasIconOnly;
  7863. };
  7864. this.isCircle = false;
  7865. this.color = undefined;
  7866. this.buttonType = 'button';
  7867. this.disabled = false;
  7868. this.expand = undefined;
  7869. this.fill = undefined;
  7870. this.routerDirection = 'forward';
  7871. this.routerAnimation = undefined;
  7872. this.download = undefined;
  7873. this.href = undefined;
  7874. this.rel = undefined;
  7875. this.shape = undefined;
  7876. this.size = undefined;
  7877. this.strong = false;
  7878. this.target = undefined;
  7879. this.type = 'button';
  7880. this.form = undefined;
  7881. }
  7882. disabledChanged() {
  7883. const { disabled } = this;
  7884. if (this.formButtonEl) {
  7885. this.formButtonEl.disabled = disabled;
  7886. }
  7887. }
  7888. /**
  7889. * This is responsible for rendering a hidden native
  7890. * button element inside the associated form. This allows
  7891. * users to submit a form by pressing "Enter" when a text
  7892. * field inside of the form is focused. The native button
  7893. * rendered inside of `ion-button` is in the Shadow DOM
  7894. * and therefore does not participate in form submission
  7895. * which is why the following code is necessary.
  7896. */
  7897. renderHiddenButton() {
  7898. const formEl = (this.formEl = this.findForm());
  7899. if (formEl) {
  7900. const { formButtonEl } = this;
  7901. /**
  7902. * If the form already has a rendered form button
  7903. * then do not append a new one again.
  7904. */
  7905. if (formButtonEl !== null && formEl.contains(formButtonEl)) {
  7906. return;
  7907. }
  7908. // Create a hidden native button inside of the form
  7909. const newFormButtonEl = (this.formButtonEl = document.createElement('button'));
  7910. newFormButtonEl.type = this.type;
  7911. newFormButtonEl.style.display = 'none';
  7912. // Only submit if the button is not disabled.
  7913. newFormButtonEl.disabled = this.disabled;
  7914. formEl.appendChild(newFormButtonEl);
  7915. }
  7916. }
  7917. componentWillLoad() {
  7918. this.inToolbar = !!this.el.closest('ion-buttons');
  7919. this.inListHeader = !!this.el.closest('ion-list-header');
  7920. this.inItem = !!this.el.closest('ion-item') || !!this.el.closest('ion-item-divider');
  7921. this.inheritedAttributes = inheritAriaAttributes(this.el);
  7922. }
  7923. get hasIconOnly() {
  7924. return !!this.el.querySelector('[slot="icon-only"]');
  7925. }
  7926. get rippleType() {
  7927. const hasClearFill = this.fill === undefined || this.fill === 'clear';
  7928. // If the button is in a toolbar, has a clear fill (which is the default)
  7929. // and only has an icon we use the unbounded "circular" ripple effect
  7930. if (hasClearFill && this.hasIconOnly && this.inToolbar) {
  7931. return 'unbounded';
  7932. }
  7933. return 'bounded';
  7934. }
  7935. /**
  7936. * Finds the form element based on the provided `form` selector
  7937. * or element reference provided.
  7938. */
  7939. findForm() {
  7940. const { form } = this;
  7941. if (form instanceof HTMLFormElement) {
  7942. return form;
  7943. }
  7944. if (typeof form === 'string') {
  7945. // Check if the string provided is a form id.
  7946. const el = document.getElementById(form);
  7947. if (el) {
  7948. if (el instanceof HTMLFormElement) {
  7949. return el;
  7950. }
  7951. else {
  7952. /**
  7953. * The developer specified a string for the form attribute, but the
  7954. * element with that id is not a form element.
  7955. */
  7956. printIonWarning(`[ion-button] - Form with selector: "#${form}" could not be found. Verify that the id is attached to a <form> element.`, this.el);
  7957. return null;
  7958. }
  7959. }
  7960. else {
  7961. /**
  7962. * The developer specified a string for the form attribute, but the
  7963. * element with that id could not be found in the DOM.
  7964. */
  7965. printIonWarning(`[ion-button] - Form with selector: "#${form}" could not be found. Verify that the id is correct and the form is rendered in the DOM.`, this.el);
  7966. return null;
  7967. }
  7968. }
  7969. if (form !== undefined) {
  7970. /**
  7971. * The developer specified a HTMLElement for the form attribute,
  7972. * but the element is not a HTMLFormElement.
  7973. * This will also catch if the developer tries to pass in null
  7974. * as the form attribute.
  7975. */
  7976. printIonWarning(`[ion-button] - The provided "form" element is invalid. Verify that the form is a HTMLFormElement and rendered in the DOM.`, this.el);
  7977. return null;
  7978. }
  7979. /**
  7980. * If the form element is not set, the button may be inside
  7981. * of a form element. Query the closest form element to the button.
  7982. */
  7983. return this.el.closest('form');
  7984. }
  7985. submitForm(ev) {
  7986. // this button wants to specifically submit a form
  7987. // climb up the dom to see if we're in a <form>
  7988. // and if so, then use JS to submit it
  7989. if (this.formEl && this.formButtonEl) {
  7990. ev.preventDefault();
  7991. this.formButtonEl.click();
  7992. }
  7993. }
  7994. render() {
  7995. const mode = getIonMode$1(this);
  7996. const { buttonType, type, disabled, rel, target, size, href, color, expand, hasIconOnly, shape, strong, inheritedAttributes, } = this;
  7997. const finalSize = size === undefined && this.inItem ? 'small' : size;
  7998. const TagType = href === undefined ? 'button' : 'a';
  7999. const attrs = TagType === 'button'
  8000. ? { type }
  8001. : {
  8002. download: this.download,
  8003. href,
  8004. rel,
  8005. target,
  8006. };
  8007. let fill = this.fill;
  8008. /**
  8009. * We check both undefined and null to
  8010. * work around https://github.com/ionic-team/stencil/issues/3586.
  8011. */
  8012. if (fill == null) {
  8013. fill = this.inToolbar || this.inListHeader ? 'clear' : 'solid';
  8014. }
  8015. /**
  8016. * We call renderHiddenButton in the render function to account
  8017. * for any properties being set async. For example, changing the
  8018. * "type" prop from "button" to "submit" after the component has
  8019. * loaded would warrant the hidden button being added to the
  8020. * associated form.
  8021. */
  8022. {
  8023. type !== 'button' && this.renderHiddenButton();
  8024. }
  8025. return (hAsync(Host, { key: 'e213b0bb76b3f90f883b1a0ea463bb86c2df69c3', onClick: this.handleClick, "aria-disabled": disabled ? 'true' : null, class: createColorClasses$1(color, {
  8026. [mode]: true,
  8027. [buttonType]: true,
  8028. [`${buttonType}-${expand}`]: expand !== undefined,
  8029. [`${buttonType}-${finalSize}`]: finalSize !== undefined,
  8030. [`${buttonType}-${shape}`]: shape !== undefined,
  8031. [`${buttonType}-${fill}`]: true,
  8032. [`${buttonType}-strong`]: strong,
  8033. 'in-toolbar': hostContext('ion-toolbar', this.el),
  8034. 'in-toolbar-color': hostContext('ion-toolbar[color]', this.el),
  8035. 'in-buttons': hostContext('ion-buttons', this.el),
  8036. 'button-has-icon-only': hasIconOnly,
  8037. 'button-disabled': disabled,
  8038. 'ion-activatable': true,
  8039. 'ion-focusable': true,
  8040. }) }, hAsync(TagType, Object.assign({ key: 'b7c2a46fb994024841219316f4089335fa463d84' }, attrs, { class: "button-native", part: "native", disabled: disabled, onFocus: this.onFocus, onBlur: this.onBlur }, inheritedAttributes), hAsync("span", { key: '3e07a5c9f86836f9fbaefc6c617bdde6eb6f70cd', class: "button-inner" }, hAsync("slot", { key: '41c08ae09aed16faaa57707d229ff75d97f0731c', name: "icon-only", onSlotchange: this.slotChanged }), hAsync("slot", { key: 'ab8b749e4572884cc04970a7594466b4a24c886e', name: "start" }), hAsync("slot", { key: '397f7ff48ea45e82029414be95d29ae86e12c3a9' }), hAsync("slot", { key: '9a5627713002e8be3738d392b616f6e951b70e12', name: "end" })), mode === 'md' && hAsync("ion-ripple-effect", { key: '105566543ceda102474edab7ca8a44c7e71af589', type: this.rippleType }))));
  8041. }
  8042. get el() { return getElement(this); }
  8043. static get watchers() { return {
  8044. "disabled": ["disabledChanged"]
  8045. }; }
  8046. static get style() { return {
  8047. ios: IonButtonIosStyle0,
  8048. md: IonButtonMdStyle0
  8049. }; }
  8050. static get cmpMeta() { return {
  8051. "$flags$": 41,
  8052. "$tagName$": "ion-button",
  8053. "$members$": {
  8054. "color": [513],
  8055. "buttonType": [1025, "button-type"],
  8056. "disabled": [516],
  8057. "expand": [513],
  8058. "fill": [1537],
  8059. "routerDirection": [1, "router-direction"],
  8060. "routerAnimation": [16],
  8061. "download": [1],
  8062. "href": [1],
  8063. "rel": [1],
  8064. "shape": [513],
  8065. "size": [513],
  8066. "strong": [4],
  8067. "target": [1],
  8068. "type": [1],
  8069. "form": [1],
  8070. "isCircle": [32]
  8071. },
  8072. "$listeners$": undefined,
  8073. "$lazyBundleId$": "-",
  8074. "$attrsToReflect$": [["color", "color"], ["disabled", "disabled"], ["expand", "expand"], ["fill", "fill"], ["shape", "shape"], ["size", "size"]]
  8075. }; }
  8076. }
  8077. const buttonsIosCss = ".sc-ion-buttons-ios-h{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-webkit-transform:translateZ(0);transform:translateZ(0);z-index:99}.sc-ion-buttons-ios-s ion-button{--padding-top:0;--padding-bottom:0;margin-left:0;margin-right:0;margin-top:0;margin-bottom:0}.sc-ion-buttons-ios-s ion-button{--padding-top:3px;--padding-bottom:3px;--padding-start:5px;--padding-end:5px;-webkit-margin-start:2px;margin-inline-start:2px;-webkit-margin-end:2px;margin-inline-end:2px;min-height:32px}.sc-ion-buttons-ios-s .button-has-icon-only{--padding-top:0;--padding-bottom:0}.sc-ion-buttons-ios-s ion-button:not(.button-round){--border-radius:4px}.sc-ion-buttons-ios-h.ion-color.sc-ion-buttons-ios-s .button,.ion-color .sc-ion-buttons-ios-h.sc-ion-buttons-ios-s .button{--color:initial;--border-color:initial;--background-focused:var(--ion-color-contrast)}.sc-ion-buttons-ios-h.ion-color.sc-ion-buttons-ios-s .button-solid,.ion-color .sc-ion-buttons-ios-h.sc-ion-buttons-ios-s .button-solid{--background:var(--ion-color-contrast);--background-focused:#000;--background-focused-opacity:.12;--background-activated:#000;--background-activated-opacity:.12;--background-hover:var(--ion-color-base);--background-hover-opacity:0.45;--color:var(--ion-color-base);--color-focused:var(--ion-color-base)}.sc-ion-buttons-ios-h.ion-color.sc-ion-buttons-ios-s .button-clear,.ion-color .sc-ion-buttons-ios-h.sc-ion-buttons-ios-s .button-clear{--color-activated:var(--ion-color-contrast);--color-focused:var(--ion-color-contrast)}.sc-ion-buttons-ios-h.ion-color.sc-ion-buttons-ios-s .button-outline,.ion-color .sc-ion-buttons-ios-h.sc-ion-buttons-ios-s .button-outline{--color-activated:var(--ion-color-base);--color-focused:var(--ion-color-contrast);--background-activated:var(--ion-color-contrast)}.sc-ion-buttons-ios-s .button-clear,.sc-ion-buttons-ios-s .button-outline{--background-activated:transparent;--background-focused:currentColor;--background-hover:transparent}.sc-ion-buttons-ios-s .button-solid:not(.ion-color){--background-focused:#000;--background-focused-opacity:.12;--background-activated:#000;--background-activated-opacity:.12}.sc-ion-buttons-ios-s ion-icon[slot=start]{margin-left:0;margin-right:0;margin-top:0;margin-bottom:0;-webkit-margin-end:0.3em;margin-inline-end:0.3em;font-size:1.41em;line-height:0.67}.sc-ion-buttons-ios-s ion-icon[slot=end]{margin-left:0;margin-right:0;margin-top:0;margin-bottom:0;-webkit-margin-start:0.4em;margin-inline-start:0.4em;font-size:1.41em;line-height:0.67}.sc-ion-buttons-ios-s ion-icon[slot=icon-only]{padding-left:0;padding-right:0;padding-top:0;padding-bottom:0;margin-left:0;margin-right:0;margin-top:0;margin-bottom:0;font-size:1.65em;line-height:0.67}";
  8078. var IonButtonsIosStyle0 = buttonsIosCss;
  8079. const buttonsMdCss = ".sc-ion-buttons-md-h{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-webkit-transform:translateZ(0);transform:translateZ(0);z-index:99}.sc-ion-buttons-md-s ion-button{--padding-top:0;--padding-bottom:0;margin-left:0;margin-right:0;margin-top:0;margin-bottom:0}.sc-ion-buttons-md-s ion-button{--padding-top:3px;--padding-bottom:3px;--padding-start:8px;--padding-end:8px;--box-shadow:none;-webkit-margin-start:2px;margin-inline-start:2px;-webkit-margin-end:2px;margin-inline-end:2px;min-height:32px}.sc-ion-buttons-md-s .button-has-icon-only{--padding-top:0;--padding-bottom:0}.sc-ion-buttons-md-s ion-button:not(.button-round){--border-radius:2px}.sc-ion-buttons-md-h.ion-color.sc-ion-buttons-md-s .button,.ion-color .sc-ion-buttons-md-h.sc-ion-buttons-md-s .button{--color:initial;--color-focused:var(--ion-color-contrast);--color-hover:var(--ion-color-contrast);--background-activated:transparent;--background-focused:var(--ion-color-contrast);--background-hover:var(--ion-color-contrast)}.sc-ion-buttons-md-h.ion-color.sc-ion-buttons-md-s .button-solid,.ion-color .sc-ion-buttons-md-h.sc-ion-buttons-md-s .button-solid{--background:var(--ion-color-contrast);--background-activated:transparent;--background-focused:var(--ion-color-shade);--background-hover:var(--ion-color-base);--color:var(--ion-color-base);--color-focused:var(--ion-color-base);--color-hover:var(--ion-color-base)}.sc-ion-buttons-md-h.ion-color.sc-ion-buttons-md-s .button-outline,.ion-color .sc-ion-buttons-md-h.sc-ion-buttons-md-s .button-outline{--border-color:var(--ion-color-contrast)}.sc-ion-buttons-md-s .button-has-icon-only.button-clear{--padding-top:12px;--padding-end:12px;--padding-bottom:12px;--padding-start:12px;--border-radius:50%;margin-left:0;margin-right:0;margin-top:0;margin-bottom:0;width:3rem;height:3rem}.sc-ion-buttons-md-s .button{--background-hover:currentColor}.sc-ion-buttons-md-s .button-solid{--color:var(--ion-toolbar-background, var(--ion-background-color, #fff));--background:var(--ion-toolbar-color, var(--ion-text-color, #424242));--background-activated:transparent;--background-focused:currentColor}.sc-ion-buttons-md-s .button-outline{--color:initial;--background:transparent;--background-activated:transparent;--background-focused:currentColor;--background-hover:currentColor;--border-color:currentColor}.sc-ion-buttons-md-s .button-clear{--color:initial;--background:transparent;--background-activated:transparent;--background-focused:currentColor;--background-hover:currentColor}.sc-ion-buttons-md-s ion-icon[slot=start]{margin-left:0;margin-right:0;margin-top:0;margin-bottom:0;-webkit-margin-end:0.3em;margin-inline-end:0.3em;font-size:1.4em}.sc-ion-buttons-md-s ion-icon[slot=end]{margin-left:0;margin-right:0;margin-top:0;margin-bottom:0;-webkit-margin-start:0.4em;margin-inline-start:0.4em;font-size:1.4em}.sc-ion-buttons-md-s ion-icon[slot=icon-only]{padding-left:0;padding-right:0;padding-top:0;padding-bottom:0;margin-left:0;margin-right:0;margin-top:0;margin-bottom:0;font-size:1.8em}";
  8080. var IonButtonsMdStyle0 = buttonsMdCss;
  8081. class Buttons {
  8082. constructor(hostRef) {
  8083. registerInstance(this, hostRef);
  8084. this.collapse = false;
  8085. }
  8086. render() {
  8087. const mode = getIonMode$1(this);
  8088. return (hAsync(Host, { key: '58c1fc5eb867d0731c63549b1ccb3ec3bbbe6e1b', class: {
  8089. [mode]: true,
  8090. ['buttons-collapse']: this.collapse,
  8091. } }, hAsync("slot", { key: '0c8f95b9840c8fa0c4e50be84c5159620a3eb5c8' })));
  8092. }
  8093. static get style() { return {
  8094. ios: IonButtonsIosStyle0,
  8095. md: IonButtonsMdStyle0
  8096. }; }
  8097. static get cmpMeta() { return {
  8098. "$flags$": 38,
  8099. "$tagName$": "ion-buttons",
  8100. "$members$": {
  8101. "collapse": [4]
  8102. },
  8103. "$listeners$": undefined,
  8104. "$lazyBundleId$": "-",
  8105. "$attrsToReflect$": []
  8106. }; }
  8107. }
  8108. const cardIosCss = ":host{--ion-safe-area-left:0px;--ion-safe-area-right:0px;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;display:block;position:relative;background:var(--background);color:var(--color);font-family:var(--ion-font-family, inherit);contain:content;overflow:hidden}:host(.ion-color){background:var(--ion-color-base);color:var(--ion-color-contrast)}:host(.card-disabled){cursor:default;opacity:0.3;pointer-events:none}.card-native{font-family:inherit;font-size:inherit;font-style:inherit;font-weight:inherit;letter-spacing:inherit;text-decoration:inherit;text-indent:inherit;text-overflow:inherit;text-transform:inherit;text-align:inherit;white-space:inherit;color:inherit;padding-left:0;padding-right:0;padding-top:0;padding-bottom:0;margin-left:0;margin-right:0;margin-top:0;margin-bottom:0;display:block;width:100%;min-height:var(--min-height);-webkit-transition:var(--transition);transition:var(--transition);border-width:var(--border-width);border-style:var(--border-style);border-color:var(--border-color);outline:none;background:inherit}.card-native::-moz-focus-inner{border:0}button,a{cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-user-drag:none}ion-ripple-effect{color:var(--ripple-color)}:host{--background:var(--ion-card-background, var(--ion-item-background, var(--ion-background-color, #fff)));--color:var(--ion-card-color, var(--ion-item-color, var(--ion-color-step-600, var(--ion-text-color-step-400, #666666))));-webkit-margin-start:16px;margin-inline-start:16px;-webkit-margin-end:16px;margin-inline-end:16px;margin-top:24px;margin-bottom:24px;border-radius:8px;-webkit-transition:-webkit-transform 500ms cubic-bezier(0.12, 0.72, 0.29, 1);transition:-webkit-transform 500ms cubic-bezier(0.12, 0.72, 0.29, 1);transition:transform 500ms cubic-bezier(0.12, 0.72, 0.29, 1);transition:transform 500ms cubic-bezier(0.12, 0.72, 0.29, 1), -webkit-transform 500ms cubic-bezier(0.12, 0.72, 0.29, 1);font-size:0.875rem;-webkit-box-shadow:0 4px 16px rgba(0, 0, 0, 0.12);box-shadow:0 4px 16px rgba(0, 0, 0, 0.12)}:host(.ion-activated){-webkit-transform:scale3d(0.97, 0.97, 1);transform:scale3d(0.97, 0.97, 1)}";
  8109. var IonCardIosStyle0 = cardIosCss;
  8110. const cardMdCss = ":host{--ion-safe-area-left:0px;--ion-safe-area-right:0px;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;display:block;position:relative;background:var(--background);color:var(--color);font-family:var(--ion-font-family, inherit);contain:content;overflow:hidden}:host(.ion-color){background:var(--ion-color-base);color:var(--ion-color-contrast)}:host(.card-disabled){cursor:default;opacity:0.3;pointer-events:none}.card-native{font-family:inherit;font-size:inherit;font-style:inherit;font-weight:inherit;letter-spacing:inherit;text-decoration:inherit;text-indent:inherit;text-overflow:inherit;text-transform:inherit;text-align:inherit;white-space:inherit;color:inherit;padding-left:0;padding-right:0;padding-top:0;padding-bottom:0;margin-left:0;margin-right:0;margin-top:0;margin-bottom:0;display:block;width:100%;min-height:var(--min-height);-webkit-transition:var(--transition);transition:var(--transition);border-width:var(--border-width);border-style:var(--border-style);border-color:var(--border-color);outline:none;background:inherit}.card-native::-moz-focus-inner{border:0}button,a{cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-user-drag:none}ion-ripple-effect{color:var(--ripple-color)}:host{--background:var(--ion-card-background, var(--ion-item-background, var(--ion-background-color, #fff)));--color:var(--ion-card-color, var(--ion-item-color, var(--ion-color-step-550, var(--ion-text-color-step-450, #737373))));-webkit-margin-start:10px;margin-inline-start:10px;-webkit-margin-end:10px;margin-inline-end:10px;margin-top:10px;margin-bottom:10px;border-radius:4px;font-size:0.875rem;-webkit-box-shadow:0 3px 1px -2px rgba(0, 0, 0, 0.2), 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 1px 5px 0 rgba(0, 0, 0, 0.12);box-shadow:0 3px 1px -2px rgba(0, 0, 0, 0.2), 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 1px 5px 0 rgba(0, 0, 0, 0.12)}";
  8111. var IonCardMdStyle0 = cardMdCss;
  8112. /**
  8113. * @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
  8114. *
  8115. * @part native - The native HTML button, anchor, or div element that wraps all child elements.
  8116. */
  8117. class Card {
  8118. constructor(hostRef) {
  8119. registerInstance(this, hostRef);
  8120. this.inheritedAriaAttributes = {};
  8121. this.color = undefined;
  8122. this.button = false;
  8123. this.type = 'button';
  8124. this.disabled = false;
  8125. this.download = undefined;
  8126. this.href = undefined;
  8127. this.rel = undefined;
  8128. this.routerDirection = 'forward';
  8129. this.routerAnimation = undefined;
  8130. this.target = undefined;
  8131. }
  8132. componentWillLoad() {
  8133. this.inheritedAriaAttributes = inheritAttributes$1(this.el, ['aria-label']);
  8134. }
  8135. isClickable() {
  8136. return this.href !== undefined || this.button;
  8137. }
  8138. renderCard(mode) {
  8139. const clickable = this.isClickable();
  8140. if (!clickable) {
  8141. return [hAsync("slot", null)];
  8142. }
  8143. const { href, routerAnimation, routerDirection, inheritedAriaAttributes } = this;
  8144. const TagType = clickable ? (href === undefined ? 'button' : 'a') : 'div';
  8145. const attrs = TagType === 'button'
  8146. ? { type: this.type }
  8147. : {
  8148. download: this.download,
  8149. href: this.href,
  8150. rel: this.rel,
  8151. target: this.target,
  8152. };
  8153. return (hAsync(TagType, Object.assign({}, attrs, inheritedAriaAttributes, { class: "card-native", part: "native", disabled: this.disabled, onClick: (ev) => openURL(href, ev, routerDirection, routerAnimation) }), hAsync("slot", null), clickable && mode === 'md' && hAsync("ion-ripple-effect", null)));
  8154. }
  8155. render() {
  8156. const mode = getIonMode$1(this);
  8157. return (hAsync(Host, { key: '85e9b30bd81e79a0c7ac75cb3664bdcf9e4afc4d', class: createColorClasses$1(this.color, {
  8158. [mode]: true,
  8159. 'card-disabled': this.disabled,
  8160. 'ion-activatable': this.isClickable(),
  8161. }) }, this.renderCard(mode)));
  8162. }
  8163. get el() { return getElement(this); }
  8164. static get style() { return {
  8165. ios: IonCardIosStyle0,
  8166. md: IonCardMdStyle0
  8167. }; }
  8168. static get cmpMeta() { return {
  8169. "$flags$": 41,
  8170. "$tagName$": "ion-card",
  8171. "$members$": {
  8172. "color": [513],
  8173. "button": [4],
  8174. "type": [1],
  8175. "disabled": [4],
  8176. "download": [1],
  8177. "href": [1],
  8178. "rel": [1],
  8179. "routerDirection": [1, "router-direction"],
  8180. "routerAnimation": [16],
  8181. "target": [1]
  8182. },
  8183. "$listeners$": undefined,
  8184. "$lazyBundleId$": "-",
  8185. "$attrsToReflect$": [["color", "color"]]
  8186. }; }
  8187. }
  8188. const cardContentIosCss = "ion-card-content{display:block;position:relative}.card-content-ios{-webkit-padding-start:20px;padding-inline-start:20px;-webkit-padding-end:20px;padding-inline-end:20px;padding-top:20px;padding-bottom:20px;font-size:1rem;line-height:1.4}.card-content-ios h1{margin-left:0;margin-right:0;margin-top:0;margin-bottom:2px;font-size:1.5rem;font-weight:normal}.card-content-ios h2{margin-left:0;margin-right:0;margin-top:2px;margin-bottom:2px;font-size:1rem;font-weight:normal}.card-content-ios h3,.card-content-ios h4,.card-content-ios h5,.card-content-ios h6{margin-left:0;margin-right:0;margin-top:2px;margin-bottom:2px;font-size:0.875rem;font-weight:normal}.card-content-ios p{margin-left:0;margin-right:0;margin-top:0;margin-bottom:2px;font-size:0.875rem}ion-card-header+.card-content-ios{padding-top:0}";
  8189. var IonCardContentIosStyle0 = cardContentIosCss;
  8190. const cardContentMdCss = "ion-card-content{display:block;position:relative}.card-content-md{-webkit-padding-start:16px;padding-inline-start:16px;-webkit-padding-end:16px;padding-inline-end:16px;padding-top:13px;padding-bottom:13px;font-size:0.875rem;line-height:1.5}.card-content-md h1{margin-left:0;margin-right:0;margin-top:0;margin-bottom:2px;font-size:1.5rem;font-weight:normal}.card-content-md h2{margin-left:0;margin-right:0;margin-top:2px;margin-bottom:2px;font-size:1rem;font-weight:normal}.card-content-md h3,.card-content-md h4,.card-content-md h5,.card-content-md h6{margin-left:0;margin-right:0;margin-top:2px;margin-bottom:2px;font-size:0.875rem;font-weight:normal}.card-content-md p{margin-left:0;margin-right:0;margin-top:0;margin-bottom:2px;font-size:0.875rem;font-weight:normal;line-height:1.5}ion-card-header+.card-content-md{padding-top:0}";
  8191. var IonCardContentMdStyle0 = cardContentMdCss;
  8192. /**
  8193. * @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
  8194. */
  8195. class CardContent {
  8196. constructor(hostRef) {
  8197. registerInstance(this, hostRef);
  8198. }
  8199. render() {
  8200. const mode = getIonMode$1(this);
  8201. return (hAsync(Host, { key: 'd98e4d1fc6ad3237549f9bc17e4c67ec5059b1b3', class: {
  8202. [mode]: true,
  8203. // Used internally for styling
  8204. [`card-content-${mode}`]: true,
  8205. } }));
  8206. }
  8207. static get style() { return {
  8208. ios: IonCardContentIosStyle0,
  8209. md: IonCardContentMdStyle0
  8210. }; }
  8211. static get cmpMeta() { return {
  8212. "$flags$": 32,
  8213. "$tagName$": "ion-card-content",
  8214. "$members$": undefined,
  8215. "$listeners$": undefined,
  8216. "$lazyBundleId$": "-",
  8217. "$attrsToReflect$": []
  8218. }; }
  8219. }
  8220. const cardHeaderIosCss = ":host{--background:transparent;--color:inherit;display:-ms-flexbox;display:flex;position:relative;-ms-flex-direction:column;flex-direction:column;background:var(--background);color:var(--color)}:host(.ion-color){background:var(--ion-color-base);color:var(--ion-color-contrast)}:host{-webkit-padding-start:20px;padding-inline-start:20px;-webkit-padding-end:20px;padding-inline-end:20px;padding-top:20px;padding-bottom:16px;-ms-flex-direction:column-reverse;flex-direction:column-reverse}@supports ((-webkit-backdrop-filter: blur(0)) or (backdrop-filter: blur(0))){:host(.card-header-translucent){background-color:rgba(var(--ion-background-color-rgb, 255, 255, 255), 0.9);-webkit-backdrop-filter:saturate(180%) blur(30px);backdrop-filter:saturate(180%) blur(30px)}}";
  8221. var IonCardHeaderIosStyle0 = cardHeaderIosCss;
  8222. const cardHeaderMdCss = ":host{--background:transparent;--color:inherit;display:-ms-flexbox;display:flex;position:relative;-ms-flex-direction:column;flex-direction:column;background:var(--background);color:var(--color)}:host(.ion-color){background:var(--ion-color-base);color:var(--ion-color-contrast)}:host{-webkit-padding-start:16px;padding-inline-start:16px;-webkit-padding-end:16px;padding-inline-end:16px;padding-top:16px;padding-bottom:16px}::slotted(ion-card-title:not(:first-child)),::slotted(ion-card-subtitle:not(:first-child)){margin-top:8px}";
  8223. var IonCardHeaderMdStyle0 = cardHeaderMdCss;
  8224. /**
  8225. * @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
  8226. */
  8227. class CardHeader {
  8228. constructor(hostRef) {
  8229. registerInstance(this, hostRef);
  8230. this.color = undefined;
  8231. this.translucent = false;
  8232. }
  8233. render() {
  8234. const mode = getIonMode$1(this);
  8235. return (hAsync(Host, { key: '64246b81931203a64d553c788cd736f41e23f37b', class: createColorClasses$1(this.color, {
  8236. 'card-header-translucent': this.translucent,
  8237. 'ion-inherit-color': true,
  8238. [mode]: true,
  8239. }) }, hAsync("slot", { key: 'af2da2dfe266889afeb57fac25c6a730558dbba4' })));
  8240. }
  8241. static get style() { return {
  8242. ios: IonCardHeaderIosStyle0,
  8243. md: IonCardHeaderMdStyle0
  8244. }; }
  8245. static get cmpMeta() { return {
  8246. "$flags$": 41,
  8247. "$tagName$": "ion-card-header",
  8248. "$members$": {
  8249. "color": [513],
  8250. "translucent": [4]
  8251. },
  8252. "$listeners$": undefined,
  8253. "$lazyBundleId$": "-",
  8254. "$attrsToReflect$": [["color", "color"]]
  8255. }; }
  8256. }
  8257. const cardSubtitleIosCss = ":host{display:block;position:relative;color:var(--color)}:host(.ion-color){color:var(--ion-color-base)}:host{--color:var(--ion-color-step-600, var(--ion-text-color-step-400, #666666));margin-left:0;margin-right:0;margin-top:0;margin-bottom:4px;padding-left:0;padding-right:0;padding-top:0;padding-bottom:0;font-size:0.75rem;font-weight:700;letter-spacing:0.4px;text-transform:uppercase}";
  8258. var IonCardSubtitleIosStyle0 = cardSubtitleIosCss;
  8259. const cardSubtitleMdCss = ":host{display:block;position:relative;color:var(--color)}:host(.ion-color){color:var(--ion-color-base)}:host{--color:var(--ion-color-step-550, var(--ion-text-color-step-450, #737373));margin-left:0;margin-right:0;margin-top:0;margin-bottom:0;padding-left:0;padding-right:0;padding-top:0;padding-bottom:0;font-size:0.875rem;font-weight:500}";
  8260. var IonCardSubtitleMdStyle0 = cardSubtitleMdCss;
  8261. /**
  8262. * @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
  8263. */
  8264. class CardSubtitle {
  8265. constructor(hostRef) {
  8266. registerInstance(this, hostRef);
  8267. this.color = undefined;
  8268. }
  8269. render() {
  8270. const mode = getIonMode$1(this);
  8271. return (hAsync(Host, { key: '84d820a19d9074f9c8bc61ccba1ca40062a60b73', role: "heading", "aria-level": "3", class: createColorClasses$1(this.color, {
  8272. 'ion-inherit-color': true,
  8273. [mode]: true,
  8274. }) }, hAsync("slot", { key: 'e4d07d395a1f4469a90847636083101b32b776a1' })));
  8275. }
  8276. static get style() { return {
  8277. ios: IonCardSubtitleIosStyle0,
  8278. md: IonCardSubtitleMdStyle0
  8279. }; }
  8280. static get cmpMeta() { return {
  8281. "$flags$": 41,
  8282. "$tagName$": "ion-card-subtitle",
  8283. "$members$": {
  8284. "color": [513]
  8285. },
  8286. "$listeners$": undefined,
  8287. "$lazyBundleId$": "-",
  8288. "$attrsToReflect$": [["color", "color"]]
  8289. }; }
  8290. }
  8291. const cardTitleIosCss = ":host{display:block;position:relative;color:var(--color)}:host(.ion-color){color:var(--ion-color-base)}:host{--color:var(--ion-text-color, #000);margin-left:0;margin-right:0;margin-top:0;margin-bottom:0;padding-left:0;padding-right:0;padding-top:0;padding-bottom:0;font-size:1.75rem;font-weight:700;line-height:1.2}";
  8292. var IonCardTitleIosStyle0 = cardTitleIosCss;
  8293. const cardTitleMdCss = ":host{display:block;position:relative;color:var(--color)}:host(.ion-color){color:var(--ion-color-base)}:host{--color:var(--ion-color-step-850, var(--ion-text-color-step-150, #262626));margin-left:0;margin-right:0;margin-top:0;margin-bottom:0;padding-left:0;padding-right:0;padding-top:0;padding-bottom:0;font-size:1.25rem;font-weight:500;line-height:1.2}";
  8294. var IonCardTitleMdStyle0 = cardTitleMdCss;
  8295. /**
  8296. * @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
  8297. */
  8298. class CardTitle {
  8299. constructor(hostRef) {
  8300. registerInstance(this, hostRef);
  8301. this.color = undefined;
  8302. }
  8303. render() {
  8304. const mode = getIonMode$1(this);
  8305. return (hAsync(Host, { key: 'fca001a86396e83718d5211cd71912fdf40dea2f', role: "heading", "aria-level": "2", class: createColorClasses$1(this.color, {
  8306. 'ion-inherit-color': true,
  8307. [mode]: true,
  8308. }) }, hAsync("slot", { key: '2ba416aed488b2ff462fa75fb3b70373a6dd7da6' })));
  8309. }
  8310. static get style() { return {
  8311. ios: IonCardTitleIosStyle0,
  8312. md: IonCardTitleMdStyle0
  8313. }; }
  8314. static get cmpMeta() { return {
  8315. "$flags$": 41,
  8316. "$tagName$": "ion-card-title",
  8317. "$members$": {
  8318. "color": [513]
  8319. },
  8320. "$listeners$": undefined,
  8321. "$lazyBundleId$": "-",
  8322. "$attrsToReflect$": [["color", "color"]]
  8323. }; }
  8324. }
  8325. const checkboxIosCss = ":host{--checkbox-background-checked:var(--ion-color-primary, #0054e9);--border-color-checked:var(--ion-color-primary, #0054e9);--checkmark-color:var(--ion-color-primary-contrast, #fff);--transition:none;display:inline-block;position:relative;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;z-index:2}:host(.in-item){-ms-flex:1 1 0px;flex:1 1 0;width:100%;height:100%}:host([slot=start]),:host([slot=end]){-ms-flex:initial;flex:initial;width:auto}:host(.ion-color){--checkbox-background-checked:var(--ion-color-base);--border-color-checked:var(--ion-color-base);--checkmark-color:var(--ion-color-contrast)}.checkbox-wrapper{display:-ms-flexbox;display:flex;-ms-flex-positive:1;flex-grow:1;-ms-flex-align:center;align-items:center;-ms-flex-pack:justify;justify-content:space-between;height:inherit;cursor:inherit}.label-text-wrapper{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}:host(.in-item) .label-text-wrapper,:host(.in-item:not(.checkbox-label-placement-stacked):not([slot])) .native-wrapper{margin-top:10px;margin-bottom:10px}:host(.in-item.checkbox-label-placement-stacked) .label-text-wrapper{margin-top:10px;margin-bottom:16px}:host(.in-item.checkbox-label-placement-stacked) .native-wrapper{margin-bottom:10px}.label-text-wrapper-hidden{display:none}input{display:none}.native-wrapper{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center}.checkbox-icon{border-radius:var(--border-radius);position:relative;width:var(--size);height:var(--size);-webkit-transition:var(--transition);transition:var(--transition);border-width:var(--border-width);border-style:var(--border-style);border-color:var(--border-color);background:var(--checkbox-background);-webkit-box-sizing:border-box;box-sizing:border-box}.checkbox-icon path{fill:none;stroke:var(--checkmark-color);stroke-width:var(--checkmark-width);opacity:0}.checkbox-bottom{padding-top:4px;display:-ms-flexbox;display:flex;-ms-flex-pack:justify;justify-content:space-between;font-size:0.75rem;white-space:normal}:host(.checkbox-label-placement-stacked) .checkbox-bottom{font-size:1rem}.checkbox-bottom .error-text{display:none;color:var(--ion-color-danger, #c5000f)}.checkbox-bottom .helper-text{display:block;color:var(--ion-color-step-700, var(--ion-text-color-step-300, #4d4d4d))}:host(.ion-touched.ion-invalid) .checkbox-bottom .error-text{display:block}:host(.ion-touched.ion-invalid) .checkbox-bottom .helper-text{display:none}:host(.checkbox-label-placement-start) .checkbox-wrapper{-ms-flex-direction:row;flex-direction:row}:host(.checkbox-label-placement-start) .label-text-wrapper{-webkit-margin-start:0;margin-inline-start:0;-webkit-margin-end:16px;margin-inline-end:16px}:host(.checkbox-label-placement-end) .checkbox-wrapper{-ms-flex-direction:row-reverse;flex-direction:row-reverse;-ms-flex-pack:start;justify-content:start}:host(.checkbox-label-placement-end) .label-text-wrapper{-webkit-margin-start:16px;margin-inline-start:16px;-webkit-margin-end:0;margin-inline-end:0}:host(.checkbox-label-placement-fixed) .label-text-wrapper{-webkit-margin-start:0;margin-inline-start:0;-webkit-margin-end:16px;margin-inline-end:16px}:host(.checkbox-label-placement-fixed) .label-text-wrapper{-ms-flex:0 0 100px;flex:0 0 100px;width:100px;min-width:100px;max-width:200px}:host(.checkbox-label-placement-stacked) .checkbox-wrapper{-ms-flex-direction:column;flex-direction:column;text-align:center}:host(.checkbox-label-placement-stacked) .label-text-wrapper{-webkit-transform:scale(0.75);transform:scale(0.75);margin-left:0;margin-right:0;margin-bottom:16px;max-width:calc(100% / 0.75)}:host(.checkbox-label-placement-stacked.checkbox-alignment-start) .label-text-wrapper{-webkit-transform-origin:left top;transform-origin:left top}:host-context([dir=rtl]):host(.checkbox-label-placement-stacked.checkbox-alignment-start) .label-text-wrapper,:host-context([dir=rtl]).checkbox-label-placement-stacked.checkbox-alignment-start .label-text-wrapper{-webkit-transform-origin:right top;transform-origin:right top}@supports selector(:dir(rtl)){:host(.checkbox-label-placement-stacked.checkbox-alignment-start:dir(rtl)) .label-text-wrapper{-webkit-transform-origin:right top;transform-origin:right top}}:host(.checkbox-label-placement-stacked.checkbox-alignment-center) .label-text-wrapper{-webkit-transform-origin:center top;transform-origin:center top}:host-context([dir=rtl]):host(.checkbox-label-placement-stacked.checkbox-alignment-center) .label-text-wrapper,:host-context([dir=rtl]).checkbox-label-placement-stacked.checkbox-alignment-center .label-text-wrapper{-webkit-transform-origin:calc(100% - center) top;transform-origin:calc(100% - center) top}@supports selector(:dir(rtl)){:host(.checkbox-label-placement-stacked.checkbox-alignment-center:dir(rtl)) .label-text-wrapper{-webkit-transform-origin:calc(100% - center) top;transform-origin:calc(100% - center) top}}:host(.checkbox-justify-space-between) .checkbox-wrapper{-ms-flex-pack:justify;justify-content:space-between}:host(.checkbox-justify-start) .checkbox-wrapper{-ms-flex-pack:start;justify-content:start}:host(.checkbox-justify-end) .checkbox-wrapper{-ms-flex-pack:end;justify-content:end}:host(.checkbox-alignment-start) .checkbox-wrapper{-ms-flex-align:start;align-items:start}:host(.checkbox-alignment-center) .checkbox-wrapper{-ms-flex-align:center;align-items:center}:host(.checkbox-justify-space-between),:host(.checkbox-justify-start),:host(.checkbox-justify-end),:host(.checkbox-alignment-start),:host(.checkbox-alignment-center){display:block}:host(.checkbox-checked) .checkbox-icon,:host(.checkbox-indeterminate) .checkbox-icon{border-color:var(--border-color-checked);background:var(--checkbox-background-checked)}:host(.checkbox-checked) .checkbox-icon path,:host(.checkbox-indeterminate) .checkbox-icon path{opacity:1}:host(.checkbox-disabled){pointer-events:none}:host{--border-radius:50%;--border-width:0.125rem;--border-style:solid;--border-color:rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.23);--checkbox-background:var(--ion-item-background, var(--ion-background-color, #fff));--size:min(1.375rem, 55.836px);--checkmark-width:1.5px}:host(.checkbox-disabled){opacity:0.3}";
  8326. var IonCheckboxIosStyle0 = checkboxIosCss;
  8327. const checkboxMdCss = ":host{--checkbox-background-checked:var(--ion-color-primary, #0054e9);--border-color-checked:var(--ion-color-primary, #0054e9);--checkmark-color:var(--ion-color-primary-contrast, #fff);--transition:none;display:inline-block;position:relative;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;z-index:2}:host(.in-item){-ms-flex:1 1 0px;flex:1 1 0;width:100%;height:100%}:host([slot=start]),:host([slot=end]){-ms-flex:initial;flex:initial;width:auto}:host(.ion-color){--checkbox-background-checked:var(--ion-color-base);--border-color-checked:var(--ion-color-base);--checkmark-color:var(--ion-color-contrast)}.checkbox-wrapper{display:-ms-flexbox;display:flex;-ms-flex-positive:1;flex-grow:1;-ms-flex-align:center;align-items:center;-ms-flex-pack:justify;justify-content:space-between;height:inherit;cursor:inherit}.label-text-wrapper{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}:host(.in-item) .label-text-wrapper,:host(.in-item:not(.checkbox-label-placement-stacked):not([slot])) .native-wrapper{margin-top:10px;margin-bottom:10px}:host(.in-item.checkbox-label-placement-stacked) .label-text-wrapper{margin-top:10px;margin-bottom:16px}:host(.in-item.checkbox-label-placement-stacked) .native-wrapper{margin-bottom:10px}.label-text-wrapper-hidden{display:none}input{display:none}.native-wrapper{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center}.checkbox-icon{border-radius:var(--border-radius);position:relative;width:var(--size);height:var(--size);-webkit-transition:var(--transition);transition:var(--transition);border-width:var(--border-width);border-style:var(--border-style);border-color:var(--border-color);background:var(--checkbox-background);-webkit-box-sizing:border-box;box-sizing:border-box}.checkbox-icon path{fill:none;stroke:var(--checkmark-color);stroke-width:var(--checkmark-width);opacity:0}.checkbox-bottom{padding-top:4px;display:-ms-flexbox;display:flex;-ms-flex-pack:justify;justify-content:space-between;font-size:0.75rem;white-space:normal}:host(.checkbox-label-placement-stacked) .checkbox-bottom{font-size:1rem}.checkbox-bottom .error-text{display:none;color:var(--ion-color-danger, #c5000f)}.checkbox-bottom .helper-text{display:block;color:var(--ion-color-step-700, var(--ion-text-color-step-300, #4d4d4d))}:host(.ion-touched.ion-invalid) .checkbox-bottom .error-text{display:block}:host(.ion-touched.ion-invalid) .checkbox-bottom .helper-text{display:none}:host(.checkbox-label-placement-start) .checkbox-wrapper{-ms-flex-direction:row;flex-direction:row}:host(.checkbox-label-placement-start) .label-text-wrapper{-webkit-margin-start:0;margin-inline-start:0;-webkit-margin-end:16px;margin-inline-end:16px}:host(.checkbox-label-placement-end) .checkbox-wrapper{-ms-flex-direction:row-reverse;flex-direction:row-reverse;-ms-flex-pack:start;justify-content:start}:host(.checkbox-label-placement-end) .label-text-wrapper{-webkit-margin-start:16px;margin-inline-start:16px;-webkit-margin-end:0;margin-inline-end:0}:host(.checkbox-label-placement-fixed) .label-text-wrapper{-webkit-margin-start:0;margin-inline-start:0;-webkit-margin-end:16px;margin-inline-end:16px}:host(.checkbox-label-placement-fixed) .label-text-wrapper{-ms-flex:0 0 100px;flex:0 0 100px;width:100px;min-width:100px;max-width:200px}:host(.checkbox-label-placement-stacked) .checkbox-wrapper{-ms-flex-direction:column;flex-direction:column;text-align:center}:host(.checkbox-label-placement-stacked) .label-text-wrapper{-webkit-transform:scale(0.75);transform:scale(0.75);margin-left:0;margin-right:0;margin-bottom:16px;max-width:calc(100% / 0.75)}:host(.checkbox-label-placement-stacked.checkbox-alignment-start) .label-text-wrapper{-webkit-transform-origin:left top;transform-origin:left top}:host-context([dir=rtl]):host(.checkbox-label-placement-stacked.checkbox-alignment-start) .label-text-wrapper,:host-context([dir=rtl]).checkbox-label-placement-stacked.checkbox-alignment-start .label-text-wrapper{-webkit-transform-origin:right top;transform-origin:right top}@supports selector(:dir(rtl)){:host(.checkbox-label-placement-stacked.checkbox-alignment-start:dir(rtl)) .label-text-wrapper{-webkit-transform-origin:right top;transform-origin:right top}}:host(.checkbox-label-placement-stacked.checkbox-alignment-center) .label-text-wrapper{-webkit-transform-origin:center top;transform-origin:center top}:host-context([dir=rtl]):host(.checkbox-label-placement-stacked.checkbox-alignment-center) .label-text-wrapper,:host-context([dir=rtl]).checkbox-label-placement-stacked.checkbox-alignment-center .label-text-wrapper{-webkit-transform-origin:calc(100% - center) top;transform-origin:calc(100% - center) top}@supports selector(:dir(rtl)){:host(.checkbox-label-placement-stacked.checkbox-alignment-center:dir(rtl)) .label-text-wrapper{-webkit-transform-origin:calc(100% - center) top;transform-origin:calc(100% - center) top}}:host(.checkbox-justify-space-between) .checkbox-wrapper{-ms-flex-pack:justify;justify-content:space-between}:host(.checkbox-justify-start) .checkbox-wrapper{-ms-flex-pack:start;justify-content:start}:host(.checkbox-justify-end) .checkbox-wrapper{-ms-flex-pack:end;justify-content:end}:host(.checkbox-alignment-start) .checkbox-wrapper{-ms-flex-align:start;align-items:start}:host(.checkbox-alignment-center) .checkbox-wrapper{-ms-flex-align:center;align-items:center}:host(.checkbox-justify-space-between),:host(.checkbox-justify-start),:host(.checkbox-justify-end),:host(.checkbox-alignment-start),:host(.checkbox-alignment-center){display:block}:host(.checkbox-checked) .checkbox-icon,:host(.checkbox-indeterminate) .checkbox-icon{border-color:var(--border-color-checked);background:var(--checkbox-background-checked)}:host(.checkbox-checked) .checkbox-icon path,:host(.checkbox-indeterminate) .checkbox-icon path{opacity:1}:host(.checkbox-disabled){pointer-events:none}:host{--border-radius:calc(var(--size) * .125);--border-width:2px;--border-style:solid;--border-color:rgb(var(--ion-text-color-rgb, 0, 0, 0), 0.6);--checkmark-width:3;--checkbox-background:var(--ion-item-background, var(--ion-background-color, #fff));--transition:background 180ms cubic-bezier(0.4, 0, 0.2, 1);--size:18px}.checkbox-icon path{stroke-dasharray:30;stroke-dashoffset:30}:host(.checkbox-checked) .checkbox-icon path,:host(.checkbox-indeterminate) .checkbox-icon path{stroke-dashoffset:0;-webkit-transition:stroke-dashoffset 90ms linear 90ms;transition:stroke-dashoffset 90ms linear 90ms}:host(.checkbox-disabled) .label-text-wrapper{opacity:0.38}:host(.checkbox-disabled) .native-wrapper{opacity:0.63}";
  8328. var IonCheckboxMdStyle0 = checkboxMdCss;
  8329. /**
  8330. * @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
  8331. *
  8332. * @slot - The label text to associate with the checkbox. Use the "labelPlacement" property to control where the label is placed relative to the checkbox.
  8333. *
  8334. * @part container - The container for the checkbox mark.
  8335. * @part label - The label text describing the checkbox.
  8336. * @part mark - The checkmark used to indicate the checked state.
  8337. * @part supporting-text - Supporting text displayed beneath the checkbox label.
  8338. * @part helper-text - Supporting text displayed beneath the checkbox label when the checkbox is valid.
  8339. * @part error-text - Supporting text displayed beneath the checkbox label when the checkbox is invalid and touched.
  8340. */
  8341. class Checkbox {
  8342. constructor(hostRef) {
  8343. registerInstance(this, hostRef);
  8344. this.ionChange = createEvent(this, "ionChange", 7);
  8345. this.ionFocus = createEvent(this, "ionFocus", 7);
  8346. this.ionBlur = createEvent(this, "ionBlur", 7);
  8347. this.inputId = `ion-cb-${checkboxIds++}`;
  8348. this.inputLabelId = `${this.inputId}-lbl`;
  8349. this.helperTextId = `${this.inputId}-helper-text`;
  8350. this.errorTextId = `${this.inputId}-error-text`;
  8351. this.inheritedAttributes = {};
  8352. /**
  8353. * Sets the checked property and emits
  8354. * the ionChange event. Use this to update the
  8355. * checked state in response to user-generated
  8356. * actions such as a click.
  8357. */
  8358. this.setChecked = (state) => {
  8359. const isChecked = (this.checked = state);
  8360. this.ionChange.emit({
  8361. checked: isChecked,
  8362. value: this.value,
  8363. });
  8364. };
  8365. this.toggleChecked = (ev) => {
  8366. ev.preventDefault();
  8367. this.setFocus();
  8368. this.setChecked(!this.checked);
  8369. this.indeterminate = false;
  8370. };
  8371. this.onFocus = () => {
  8372. this.ionFocus.emit();
  8373. };
  8374. this.onBlur = () => {
  8375. this.ionBlur.emit();
  8376. };
  8377. this.onKeyDown = (ev) => {
  8378. if (ev.key === ' ') {
  8379. ev.preventDefault();
  8380. if (!this.disabled) {
  8381. this.toggleChecked(ev);
  8382. }
  8383. }
  8384. };
  8385. this.onClick = (ev) => {
  8386. if (this.disabled) {
  8387. return;
  8388. }
  8389. this.toggleChecked(ev);
  8390. };
  8391. /**
  8392. * Stops propagation when the display label is clicked,
  8393. * otherwise, two clicks will be triggered.
  8394. */
  8395. this.onDivLabelClick = (ev) => {
  8396. ev.stopPropagation();
  8397. };
  8398. this.color = undefined;
  8399. this.name = this.inputId;
  8400. this.checked = false;
  8401. this.indeterminate = false;
  8402. this.disabled = false;
  8403. this.errorText = undefined;
  8404. this.helperText = undefined;
  8405. this.value = 'on';
  8406. this.labelPlacement = 'start';
  8407. this.justify = undefined;
  8408. this.alignment = undefined;
  8409. this.required = false;
  8410. }
  8411. componentWillLoad() {
  8412. this.inheritedAttributes = Object.assign({}, inheritAriaAttributes(this.el));
  8413. }
  8414. /** @internal */
  8415. async setFocus() {
  8416. if (this.focusEl) {
  8417. this.focusEl.focus();
  8418. }
  8419. }
  8420. getHintTextID() {
  8421. const { el, helperText, errorText, helperTextId, errorTextId } = this;
  8422. if (el.classList.contains('ion-touched') && el.classList.contains('ion-invalid') && errorText) {
  8423. return errorTextId;
  8424. }
  8425. if (helperText) {
  8426. return helperTextId;
  8427. }
  8428. return undefined;
  8429. }
  8430. /**
  8431. * Responsible for rendering helper text and error text.
  8432. * This element should only be rendered if hint text is set.
  8433. */
  8434. renderHintText() {
  8435. const { helperText, errorText, helperTextId, errorTextId } = this;
  8436. /**
  8437. * undefined and empty string values should
  8438. * be treated as not having helper/error text.
  8439. */
  8440. const hasHintText = !!helperText || !!errorText;
  8441. if (!hasHintText) {
  8442. return;
  8443. }
  8444. return (hAsync("div", { class: "checkbox-bottom" }, hAsync("div", { id: helperTextId, class: "helper-text", part: "supporting-text helper-text" }, helperText), hAsync("div", { id: errorTextId, class: "error-text", part: "supporting-text error-text" }, errorText)));
  8445. }
  8446. render() {
  8447. const { color, checked, disabled, el, getSVGPath, indeterminate, inheritedAttributes, inputId, justify, labelPlacement, name, value, alignment, required, } = this;
  8448. const mode = getIonMode$1(this);
  8449. const path = getSVGPath(mode, indeterminate);
  8450. const hasLabelContent = el.textContent !== '';
  8451. renderHiddenInput(true, el, name, checked ? value : '', disabled);
  8452. // The host element must have a checkbox role to ensure proper VoiceOver
  8453. // support in Safari for accessibility.
  8454. return (hAsync(Host, { key: '26cbe7220e555107200e9b5deeae754aa534a80b', role: "checkbox", "aria-checked": indeterminate ? 'mixed' : `${checked}`, "aria-describedby": this.getHintTextID(), "aria-invalid": this.getHintTextID() === this.errorTextId, "aria-labelledby": hasLabelContent ? this.inputLabelId : null, "aria-label": inheritedAttributes['aria-label'] || null, "aria-disabled": disabled ? 'true' : null, tabindex: disabled ? undefined : 0, onKeyDown: this.onKeyDown, class: createColorClasses$1(color, {
  8455. [mode]: true,
  8456. 'in-item': hostContext('ion-item', el),
  8457. 'checkbox-checked': checked,
  8458. 'checkbox-disabled': disabled,
  8459. 'checkbox-indeterminate': indeterminate,
  8460. interactive: true,
  8461. [`checkbox-justify-${justify}`]: justify !== undefined,
  8462. [`checkbox-alignment-${alignment}`]: alignment !== undefined,
  8463. [`checkbox-label-placement-${labelPlacement}`]: true,
  8464. }), onClick: this.onClick }, hAsync("label", { key: 'f025cec5ff08e8be4487b9cc0324616ca5dfae2a', class: "checkbox-wrapper", htmlFor: inputId }, hAsync("input", Object.assign({ key: 'dc53f7e4e240dc2e18556e6350df2b5c3169f553', type: "checkbox", checked: checked ? true : undefined, disabled: disabled, id: inputId, onChange: this.toggleChecked, onFocus: () => this.onFocus(), onBlur: () => this.onBlur(), ref: (focusEl) => (this.focusEl = focusEl), required: required }, inheritedAttributes)), hAsync("div", { key: 'a625e9b50c3b617de8bbbfd624d772454fecaf2d', class: {
  8465. 'label-text-wrapper': true,
  8466. 'label-text-wrapper-hidden': !hasLabelContent,
  8467. }, part: "label", id: this.inputLabelId, onClick: this.onDivLabelClick }, hAsync("slot", { key: '87d1a90691327945f4343406706e4ab27f453844' }), this.renderHintText()), hAsync("div", { key: 'b57fed8cdecee4df1ef0d57f157267ee77fac653', class: "native-wrapper" }, hAsync("svg", { key: 'd472a06ec6c8b74dfb651415d2236db8080f6805', class: "checkbox-icon", viewBox: "0 0 24 24", part: "container" }, path)))));
  8468. }
  8469. getSVGPath(mode, indeterminate) {
  8470. let path = indeterminate ? (hAsync("path", { d: "M6 12L18 12", part: "mark" })) : (hAsync("path", { d: "M5.9,12.5l3.8,3.8l8.8-8.8", part: "mark" }));
  8471. if (mode === 'md') {
  8472. path = indeterminate ? (hAsync("path", { d: "M2 12H22", part: "mark" })) : (hAsync("path", { d: "M1.73,12.91 8.1,19.28 22.79,4.59", part: "mark" }));
  8473. }
  8474. return path;
  8475. }
  8476. get el() { return getElement(this); }
  8477. static get style() { return {
  8478. ios: IonCheckboxIosStyle0,
  8479. md: IonCheckboxMdStyle0
  8480. }; }
  8481. static get cmpMeta() { return {
  8482. "$flags$": 41,
  8483. "$tagName$": "ion-checkbox",
  8484. "$members$": {
  8485. "color": [513],
  8486. "name": [1],
  8487. "checked": [1028],
  8488. "indeterminate": [1028],
  8489. "disabled": [4],
  8490. "errorText": [1, "error-text"],
  8491. "helperText": [1, "helper-text"],
  8492. "value": [8],
  8493. "labelPlacement": [1, "label-placement"],
  8494. "justify": [1],
  8495. "alignment": [1],
  8496. "required": [4],
  8497. "setFocus": [64]
  8498. },
  8499. "$listeners$": undefined,
  8500. "$lazyBundleId$": "-",
  8501. "$attrsToReflect$": [["color", "color"]]
  8502. }; }
  8503. }
  8504. let checkboxIds = 0;
  8505. const chipIosCss = ":host{--background:rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.12);--color:rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.87);border-radius:16px;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;-webkit-margin-start:4px;margin-inline-start:4px;-webkit-margin-end:4px;margin-inline-end:4px;margin-top:4px;margin-bottom:4px;-webkit-padding-start:12px;padding-inline-start:12px;-webkit-padding-end:12px;padding-inline-end:12px;padding-top:6px;padding-bottom:6px;display:-ms-inline-flexbox;display:inline-flex;position:relative;-ms-flex-align:center;align-items:center;min-height:32px;background:var(--background);color:var(--color);font-family:var(--ion-font-family, inherit);cursor:pointer;overflow:hidden;vertical-align:middle;-webkit-box-sizing:border-box;box-sizing:border-box}:host(.chip-disabled){cursor:default;opacity:0.4;pointer-events:none}:host(.ion-color){background:rgba(var(--ion-color-base-rgb), 0.08);color:var(--ion-color-shade)}:host(.ion-color:focus){background:rgba(var(--ion-color-base-rgb), 0.12)}:host(.ion-color.ion-activated){background:rgba(var(--ion-color-base-rgb), 0.16)}:host(.chip-outline){border-width:1px;border-style:solid}:host(.chip-outline){border-color:rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.32);background:transparent}:host(.chip-outline.ion-color){border-color:rgba(var(--ion-color-base-rgb), 0.32)}:host(.chip-outline:not(.ion-color):focus){background:rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.04)}:host(.chip-outline.ion-activated:not(.ion-color)){background:rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.08)}::slotted(ion-icon){font-size:1.4285714286em}:host(:not(.ion-color)) ::slotted(ion-icon){color:rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.54)}::slotted(ion-icon:first-child){-webkit-margin-start:-4px;margin-inline-start:-4px;-webkit-margin-end:8px;margin-inline-end:8px;margin-top:-4px;margin-bottom:-4px}::slotted(ion-icon:last-child){-webkit-margin-start:8px;margin-inline-start:8px;-webkit-margin-end:-4px;margin-inline-end:-4px;margin-top:-4px;margin-bottom:-4px}::slotted(ion-avatar){-ms-flex-negative:0;flex-shrink:0;width:1.7142857143em;height:1.7142857143em}::slotted(ion-avatar:first-child){-webkit-margin-start:-8px;margin-inline-start:-8px;-webkit-margin-end:8px;margin-inline-end:8px;margin-top:-4px;margin-bottom:-4px}::slotted(ion-avatar:last-child){-webkit-margin-start:8px;margin-inline-start:8px;-webkit-margin-end:-8px;margin-inline-end:-8px;margin-top:-4px;margin-bottom:-4px}:host(:focus){outline:none}:host(:focus){--background:rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.16)}:host(.ion-activated){--background:rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.2)}@media (any-hover: hover){:host(:hover){--background:rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.16)}:host(.ion-color:hover){background:rgba(var(--ion-color-base-rgb), 0.12)}:host(.chip-outline:not(.ion-color):hover){background:rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.04)}}:host{font-size:clamp(13px, 0.875rem, 22px)}";
  8506. var IonChipIosStyle0 = chipIosCss;
  8507. const chipMdCss = ":host{--background:rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.12);--color:rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.87);border-radius:16px;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;-webkit-margin-start:4px;margin-inline-start:4px;-webkit-margin-end:4px;margin-inline-end:4px;margin-top:4px;margin-bottom:4px;-webkit-padding-start:12px;padding-inline-start:12px;-webkit-padding-end:12px;padding-inline-end:12px;padding-top:6px;padding-bottom:6px;display:-ms-inline-flexbox;display:inline-flex;position:relative;-ms-flex-align:center;align-items:center;min-height:32px;background:var(--background);color:var(--color);font-family:var(--ion-font-family, inherit);cursor:pointer;overflow:hidden;vertical-align:middle;-webkit-box-sizing:border-box;box-sizing:border-box}:host(.chip-disabled){cursor:default;opacity:0.4;pointer-events:none}:host(.ion-color){background:rgba(var(--ion-color-base-rgb), 0.08);color:var(--ion-color-shade)}:host(.ion-color:focus){background:rgba(var(--ion-color-base-rgb), 0.12)}:host(.ion-color.ion-activated){background:rgba(var(--ion-color-base-rgb), 0.16)}:host(.chip-outline){border-width:1px;border-style:solid}:host(.chip-outline){border-color:rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.32);background:transparent}:host(.chip-outline.ion-color){border-color:rgba(var(--ion-color-base-rgb), 0.32)}:host(.chip-outline:not(.ion-color):focus){background:rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.04)}:host(.chip-outline.ion-activated:not(.ion-color)){background:rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.08)}::slotted(ion-icon){font-size:1.4285714286em}:host(:not(.ion-color)) ::slotted(ion-icon){color:rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.54)}::slotted(ion-icon:first-child){-webkit-margin-start:-4px;margin-inline-start:-4px;-webkit-margin-end:8px;margin-inline-end:8px;margin-top:-4px;margin-bottom:-4px}::slotted(ion-icon:last-child){-webkit-margin-start:8px;margin-inline-start:8px;-webkit-margin-end:-4px;margin-inline-end:-4px;margin-top:-4px;margin-bottom:-4px}::slotted(ion-avatar){-ms-flex-negative:0;flex-shrink:0;width:1.7142857143em;height:1.7142857143em}::slotted(ion-avatar:first-child){-webkit-margin-start:-8px;margin-inline-start:-8px;-webkit-margin-end:8px;margin-inline-end:8px;margin-top:-4px;margin-bottom:-4px}::slotted(ion-avatar:last-child){-webkit-margin-start:8px;margin-inline-start:8px;-webkit-margin-end:-8px;margin-inline-end:-8px;margin-top:-4px;margin-bottom:-4px}:host(:focus){outline:none}:host(:focus){--background:rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.16)}:host(.ion-activated){--background:rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.2)}@media (any-hover: hover){:host(:hover){--background:rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.16)}:host(.ion-color:hover){background:rgba(var(--ion-color-base-rgb), 0.12)}:host(.chip-outline:not(.ion-color):hover){background:rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.04)}}:host{font-size:0.875rem}";
  8508. var IonChipMdStyle0 = chipMdCss;
  8509. /**
  8510. * @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
  8511. */
  8512. class Chip {
  8513. constructor(hostRef) {
  8514. registerInstance(this, hostRef);
  8515. this.color = undefined;
  8516. this.outline = false;
  8517. this.disabled = false;
  8518. }
  8519. render() {
  8520. const mode = getIonMode$1(this);
  8521. return (hAsync(Host, { key: 'fa2e9a4837ef87a17ef10f388e8caa7f604d9145', "aria-disabled": this.disabled ? 'true' : null, class: createColorClasses$1(this.color, {
  8522. [mode]: true,
  8523. 'chip-outline': this.outline,
  8524. 'chip-disabled': this.disabled,
  8525. 'ion-activatable': true,
  8526. }) }, hAsync("slot", { key: '3793fbd9d915cef7241fb101e2bc64c08b9ba482' }), mode === 'md' && hAsync("ion-ripple-effect", { key: 'd3b95b53918611dec095a50f2aaaab65617947a4' })));
  8527. }
  8528. static get style() { return {
  8529. ios: IonChipIosStyle0,
  8530. md: IonChipMdStyle0
  8531. }; }
  8532. static get cmpMeta() { return {
  8533. "$flags$": 41,
  8534. "$tagName$": "ion-chip",
  8535. "$members$": {
  8536. "color": [513],
  8537. "outline": [4],
  8538. "disabled": [4]
  8539. },
  8540. "$listeners$": undefined,
  8541. "$lazyBundleId$": "-",
  8542. "$attrsToReflect$": [["color", "color"]]
  8543. }; }
  8544. }
  8545. const SIZE_TO_MEDIA = {
  8546. xs: '(min-width: 0px)',
  8547. sm: '(min-width: 576px)',
  8548. md: '(min-width: 768px)',
  8549. lg: '(min-width: 992px)',
  8550. xl: '(min-width: 1200px)',
  8551. };
  8552. // Check if the window matches the media query
  8553. // at the breakpoint passed
  8554. // e.g. matchBreakpoint('sm') => true if screen width exceeds 576px
  8555. const matchBreakpoint = (breakpoint) => {
  8556. if (breakpoint === undefined || breakpoint === '') {
  8557. return true;
  8558. }
  8559. if (window.matchMedia) {
  8560. const mediaQuery = SIZE_TO_MEDIA[breakpoint];
  8561. return window.matchMedia(mediaQuery).matches;
  8562. }
  8563. return false;
  8564. };
  8565. const colCss = ":host{-webkit-padding-start:var(--ion-grid-column-padding-xs, var(--ion-grid-column-padding, 5px));padding-inline-start:var(--ion-grid-column-padding-xs, var(--ion-grid-column-padding, 5px));-webkit-padding-end:var(--ion-grid-column-padding-xs, var(--ion-grid-column-padding, 5px));padding-inline-end:var(--ion-grid-column-padding-xs, var(--ion-grid-column-padding, 5px));padding-top:var(--ion-grid-column-padding-xs, var(--ion-grid-column-padding, 5px));padding-bottom:var(--ion-grid-column-padding-xs, var(--ion-grid-column-padding, 5px));margin-left:0;margin-right:0;margin-top:0;margin-bottom:0;-webkit-box-sizing:border-box;box-sizing:border-box;position:relative;-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;width:100%;max-width:100%;min-height:1px}@media (min-width: 576px){:host{-webkit-padding-start:var(--ion-grid-column-padding-sm, var(--ion-grid-column-padding, 5px));padding-inline-start:var(--ion-grid-column-padding-sm, var(--ion-grid-column-padding, 5px));-webkit-padding-end:var(--ion-grid-column-padding-sm, var(--ion-grid-column-padding, 5px));padding-inline-end:var(--ion-grid-column-padding-sm, var(--ion-grid-column-padding, 5px));padding-top:var(--ion-grid-column-padding-sm, var(--ion-grid-column-padding, 5px));padding-bottom:var(--ion-grid-column-padding-sm, var(--ion-grid-column-padding, 5px))}}@media (min-width: 768px){:host{-webkit-padding-start:var(--ion-grid-column-padding-md, var(--ion-grid-column-padding, 5px));padding-inline-start:var(--ion-grid-column-padding-md, var(--ion-grid-column-padding, 5px));-webkit-padding-end:var(--ion-grid-column-padding-md, var(--ion-grid-column-padding, 5px));padding-inline-end:var(--ion-grid-column-padding-md, var(--ion-grid-column-padding, 5px));padding-top:var(--ion-grid-column-padding-md, var(--ion-grid-column-padding, 5px));padding-bottom:var(--ion-grid-column-padding-md, var(--ion-grid-column-padding, 5px))}}@media (min-width: 992px){:host{-webkit-padding-start:var(--ion-grid-column-padding-lg, var(--ion-grid-column-padding, 5px));padding-inline-start:var(--ion-grid-column-padding-lg, var(--ion-grid-column-padding, 5px));-webkit-padding-end:var(--ion-grid-column-padding-lg, var(--ion-grid-column-padding, 5px));padding-inline-end:var(--ion-grid-column-padding-lg, var(--ion-grid-column-padding, 5px));padding-top:var(--ion-grid-column-padding-lg, var(--ion-grid-column-padding, 5px));padding-bottom:var(--ion-grid-column-padding-lg, var(--ion-grid-column-padding, 5px))}}@media (min-width: 1200px){:host{-webkit-padding-start:var(--ion-grid-column-padding-xl, var(--ion-grid-column-padding, 5px));padding-inline-start:var(--ion-grid-column-padding-xl, var(--ion-grid-column-padding, 5px));-webkit-padding-end:var(--ion-grid-column-padding-xl, var(--ion-grid-column-padding, 5px));padding-inline-end:var(--ion-grid-column-padding-xl, var(--ion-grid-column-padding, 5px));padding-top:var(--ion-grid-column-padding-xl, var(--ion-grid-column-padding, 5px));padding-bottom:var(--ion-grid-column-padding-xl, var(--ion-grid-column-padding, 5px))}}";
  8566. var IonColStyle0 = colCss;
  8567. const win = typeof window !== 'undefined' ? window : undefined;
  8568. // eslint-disable-next-line @typescript-eslint/prefer-optional-chain
  8569. const SUPPORTS_VARS = win && !!(win.CSS && win.CSS.supports && win.CSS.supports('--a: 0'));
  8570. const BREAKPOINTS = ['', 'xs', 'sm', 'md', 'lg', 'xl'];
  8571. class Col {
  8572. constructor(hostRef) {
  8573. registerInstance(this, hostRef);
  8574. this.offset = undefined;
  8575. this.offsetXs = undefined;
  8576. this.offsetSm = undefined;
  8577. this.offsetMd = undefined;
  8578. this.offsetLg = undefined;
  8579. this.offsetXl = undefined;
  8580. this.pull = undefined;
  8581. this.pullXs = undefined;
  8582. this.pullSm = undefined;
  8583. this.pullMd = undefined;
  8584. this.pullLg = undefined;
  8585. this.pullXl = undefined;
  8586. this.push = undefined;
  8587. this.pushXs = undefined;
  8588. this.pushSm = undefined;
  8589. this.pushMd = undefined;
  8590. this.pushLg = undefined;
  8591. this.pushXl = undefined;
  8592. this.size = undefined;
  8593. this.sizeXs = undefined;
  8594. this.sizeSm = undefined;
  8595. this.sizeMd = undefined;
  8596. this.sizeLg = undefined;
  8597. this.sizeXl = undefined;
  8598. }
  8599. onResize() {
  8600. }
  8601. // Loop through all of the breakpoints to see if the media query
  8602. // matches and grab the column value from the relevant prop if so
  8603. getColumns(property) {
  8604. let matched;
  8605. for (const breakpoint of BREAKPOINTS) {
  8606. const matches = matchBreakpoint(breakpoint);
  8607. // Grab the value of the property, if it exists and our
  8608. // media query matches we return the value
  8609. const columns = this[property + breakpoint.charAt(0).toUpperCase() + breakpoint.slice(1)];
  8610. if (matches && columns !== undefined) {
  8611. matched = columns;
  8612. }
  8613. }
  8614. // Return the last matched columns since the breakpoints
  8615. // increase in size and we want to return the largest match
  8616. return matched;
  8617. }
  8618. calculateSize() {
  8619. const columns = this.getColumns('size');
  8620. // If size wasn't set for any breakpoint
  8621. // or if the user set the size without a value
  8622. // it means we need to stick with the default and return
  8623. // e.g. <ion-col size-md>
  8624. if (!columns || columns === '') {
  8625. return;
  8626. }
  8627. // If the size is set to auto then don't calculate a size
  8628. const colSize = columns === 'auto'
  8629. ? 'auto'
  8630. : // If CSS supports variables we should use the grid columns var
  8631. SUPPORTS_VARS
  8632. ? `calc(calc(${columns} / var(--ion-grid-columns, 12)) * 100%)`
  8633. : // Convert the columns to a percentage by dividing by the total number
  8634. // of columns (12) and then multiplying by 100
  8635. (columns / 12) * 100 + '%';
  8636. return {
  8637. flex: `0 0 ${colSize}`,
  8638. width: `${colSize}`,
  8639. 'max-width': `${colSize}`,
  8640. };
  8641. }
  8642. // Called by push, pull, and offset since they use the same calculations
  8643. calculatePosition(property, modifier) {
  8644. const columns = this.getColumns(property);
  8645. if (!columns) {
  8646. return;
  8647. }
  8648. // If the number of columns passed are greater than 0 and less than
  8649. // 12 we can position the column, else default to auto
  8650. const amount = SUPPORTS_VARS
  8651. ? // If CSS supports variables we should use the grid columns var
  8652. `calc(calc(${columns} / var(--ion-grid-columns, 12)) * 100%)`
  8653. : // Convert the columns to a percentage by dividing by the total number
  8654. // of columns (12) and then multiplying by 100
  8655. columns > 0 && columns < 12
  8656. ? (columns / 12) * 100 + '%'
  8657. : 'auto';
  8658. return {
  8659. [modifier]: amount,
  8660. };
  8661. }
  8662. calculateOffset(isRTL) {
  8663. return this.calculatePosition('offset', isRTL ? 'margin-right' : 'margin-left');
  8664. }
  8665. calculatePull(isRTL) {
  8666. return this.calculatePosition('pull', isRTL ? 'left' : 'right');
  8667. }
  8668. calculatePush(isRTL) {
  8669. return this.calculatePosition('push', isRTL ? 'right' : 'left');
  8670. }
  8671. render() {
  8672. const isRTL = document.dir === 'rtl';
  8673. const mode = getIonMode$1(this);
  8674. return (hAsync(Host, { key: '32ed75d81dd09d9bc8999f6d42e5b3cb99c84d91', class: {
  8675. [mode]: true,
  8676. }, style: Object.assign(Object.assign(Object.assign(Object.assign({}, this.calculateOffset(isRTL)), this.calculatePull(isRTL)), this.calculatePush(isRTL)), this.calculateSize()) }, hAsync("slot", { key: '38f8d0440c20cc6d1b1d6a654d07f16de61d8134' })));
  8677. }
  8678. static get style() { return IonColStyle0; }
  8679. static get cmpMeta() { return {
  8680. "$flags$": 9,
  8681. "$tagName$": "ion-col",
  8682. "$members$": {
  8683. "offset": [1],
  8684. "offsetXs": [1, "offset-xs"],
  8685. "offsetSm": [1, "offset-sm"],
  8686. "offsetMd": [1, "offset-md"],
  8687. "offsetLg": [1, "offset-lg"],
  8688. "offsetXl": [1, "offset-xl"],
  8689. "pull": [1],
  8690. "pullXs": [1, "pull-xs"],
  8691. "pullSm": [1, "pull-sm"],
  8692. "pullMd": [1, "pull-md"],
  8693. "pullLg": [1, "pull-lg"],
  8694. "pullXl": [1, "pull-xl"],
  8695. "push": [1],
  8696. "pushXs": [1, "push-xs"],
  8697. "pushSm": [1, "push-sm"],
  8698. "pushMd": [1, "push-md"],
  8699. "pushLg": [1, "push-lg"],
  8700. "pushXl": [1, "push-xl"],
  8701. "size": [1],
  8702. "sizeXs": [1, "size-xs"],
  8703. "sizeSm": [1, "size-sm"],
  8704. "sizeMd": [1, "size-md"],
  8705. "sizeLg": [1, "size-lg"],
  8706. "sizeXl": [1, "size-xl"]
  8707. },
  8708. "$listeners$": [[9, "resize", "onResize"]],
  8709. "$lazyBundleId$": "-",
  8710. "$attrsToReflect$": []
  8711. }; }
  8712. }
  8713. /**
  8714. * Returns `true` if the document or host element
  8715. * has a `dir` set to `rtl`. The host value will always
  8716. * take priority over the root document value.
  8717. */
  8718. const isRTL$1 = (hostEl) => {
  8719. if (hostEl) {
  8720. if (hostEl.dir !== '') {
  8721. return hostEl.dir.toLowerCase() === 'rtl';
  8722. }
  8723. }
  8724. return (document === null || document === void 0 ? void 0 : document.dir.toLowerCase()) === 'rtl';
  8725. };
  8726. const contentCss = ":host{--background:var(--ion-background-color, #fff);--color:var(--ion-text-color, #000);--padding-top:0px;--padding-bottom:0px;--padding-start:0px;--padding-end:0px;--keyboard-offset:0px;--offset-top:0px;--offset-bottom:0px;--overflow:auto;display:block;position:relative;-ms-flex:1;flex:1;width:100%;height:100%;margin:0 !important;padding:0 !important;font-family:var(--ion-font-family, inherit);contain:size style}:host(.ion-color) .inner-scroll{background:var(--ion-color-base);color:var(--ion-color-contrast)}#background-content{left:0px;right:0px;top:calc(var(--offset-top) * -1);bottom:calc(var(--offset-bottom) * -1);position:absolute;background:var(--background)}.inner-scroll{left:0px;right:0px;top:calc(var(--offset-top) * -1);bottom:calc(var(--offset-bottom) * -1);-webkit-padding-start:var(--padding-start);padding-inline-start:var(--padding-start);-webkit-padding-end:var(--padding-end);padding-inline-end:var(--padding-end);padding-top:calc(var(--padding-top) + var(--offset-top));padding-bottom:calc(var(--padding-bottom) + var(--keyboard-offset) + var(--offset-bottom));position:absolute;color:var(--color);-webkit-box-sizing:border-box;box-sizing:border-box;overflow:hidden;-ms-touch-action:pan-x pan-y pinch-zoom;touch-action:pan-x pan-y pinch-zoom}.scroll-y,.scroll-x{-webkit-overflow-scrolling:touch;z-index:0;will-change:scroll-position}.scroll-y{overflow-y:var(--overflow);overscroll-behavior-y:contain}.scroll-x{overflow-x:var(--overflow);overscroll-behavior-x:contain}.overscroll::before,.overscroll::after{position:absolute;width:1px;height:1px;content:\"\"}.overscroll::before{bottom:-1px}.overscroll::after{top:-1px}:host(.content-sizing){display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;min-height:0;contain:none}:host(.content-sizing) .inner-scroll{position:relative;top:0;bottom:0;margin-top:calc(var(--offset-top) * -1);margin-bottom:calc(var(--offset-bottom) * -1)}.transition-effect{display:none;position:absolute;width:100%;height:100vh;opacity:0;pointer-events:none}:host(.content-ltr) .transition-effect{left:-100%;}:host(.content-rtl) .transition-effect{right:-100%;}.transition-cover{position:absolute;right:0;width:100%;height:100%;background:black;opacity:0.1}.transition-shadow{display:block;position:absolute;width:100%;height:100%;-webkit-box-shadow:inset -9px 0 9px 0 rgba(0, 0, 100, 0.03);box-shadow:inset -9px 0 9px 0 rgba(0, 0, 100, 0.03)}:host(.content-ltr) .transition-shadow{right:0;}:host(.content-rtl) .transition-shadow{left:0;-webkit-transform:scaleX(-1);transform:scaleX(-1)}::slotted([slot=fixed]){position:absolute;-webkit-transform:translateZ(0);transform:translateZ(0)}";
  8727. var IonContentStyle0 = contentCss;
  8728. /**
  8729. * @slot - Content is placed in the scrollable area if provided without a slot.
  8730. * @slot fixed - Should be used for fixed content that should not scroll.
  8731. *
  8732. * @part background - The background of the content.
  8733. * @part scroll - The scrollable container of the content.
  8734. */
  8735. class Content {
  8736. constructor(hostRef) {
  8737. registerInstance(this, hostRef);
  8738. this.ionScrollStart = createEvent(this, "ionScrollStart", 7);
  8739. this.ionScroll = createEvent(this, "ionScroll", 7);
  8740. this.ionScrollEnd = createEvent(this, "ionScrollEnd", 7);
  8741. this.watchDog = null;
  8742. this.isScrolling = false;
  8743. this.lastScroll = 0;
  8744. this.queued = false;
  8745. this.cTop = -1;
  8746. this.cBottom = -1;
  8747. this.isMainContent = true;
  8748. this.resizeTimeout = null;
  8749. this.inheritedAttributes = {};
  8750. this.tabsElement = null;
  8751. // Detail is used in a hot loop in the scroll event, by allocating it here
  8752. // V8 will be able to inline any read/write to it since it's a monomorphic class.
  8753. // https://mrale.ph/blog/2015/01/11/whats-up-with-monomorphism.html
  8754. this.detail = {
  8755. scrollTop: 0,
  8756. scrollLeft: 0,
  8757. type: 'scroll',
  8758. event: undefined,
  8759. startX: 0,
  8760. startY: 0,
  8761. startTime: 0,
  8762. currentX: 0,
  8763. currentY: 0,
  8764. velocityX: 0,
  8765. velocityY: 0,
  8766. deltaX: 0,
  8767. deltaY: 0,
  8768. currentTime: 0,
  8769. data: undefined,
  8770. isScrolling: true,
  8771. };
  8772. this.color = undefined;
  8773. this.fullscreen = false;
  8774. this.fixedSlotPlacement = 'after';
  8775. this.forceOverscroll = undefined;
  8776. this.scrollX = false;
  8777. this.scrollY = true;
  8778. this.scrollEvents = false;
  8779. }
  8780. componentWillLoad() {
  8781. this.inheritedAttributes = inheritAriaAttributes(this.el);
  8782. }
  8783. connectedCallback() {
  8784. this.isMainContent = this.el.closest('ion-menu, ion-popover, ion-modal') === null;
  8785. /**
  8786. * The fullscreen content offsets need to be
  8787. * computed after the tab bar has loaded. Since
  8788. * lazy evaluation means components are not hydrated
  8789. * at the same time, we need to wait for the ionTabBarLoaded
  8790. * event to fire. This does not impact dist-custom-elements
  8791. * because there is no hydration there.
  8792. */
  8793. if (hasLazyBuild(this.el)) {
  8794. /**
  8795. * We need to cache the reference to the tabs.
  8796. * If just the content is unmounted then we won't
  8797. * be able to query for the closest tabs on disconnectedCallback
  8798. * since the content has been removed from the DOM tree.
  8799. */
  8800. const closestTabs = (this.tabsElement = this.el.closest('ion-tabs'));
  8801. if (closestTabs !== null) {
  8802. /**
  8803. * When adding and removing the event listener
  8804. * we need to make sure we pass the same function reference
  8805. * otherwise the event listener will not be removed properly.
  8806. * We can't only pass `this.resize` because "this" in the function
  8807. * context becomes a reference to IonTabs instead of IonContent.
  8808. *
  8809. * Additionally, we listen for ionTabBarLoaded on the IonTabs
  8810. * instance rather than the IonTabBar instance. It's possible for
  8811. * a tab bar to be conditionally rendered/mounted. Since ionTabBarLoaded
  8812. * bubbles, we can catch any instances of child tab bars loading by listening
  8813. * on IonTabs.
  8814. */
  8815. this.tabsLoadCallback = () => this.resize();
  8816. closestTabs.addEventListener('ionTabBarLoaded', this.tabsLoadCallback);
  8817. }
  8818. }
  8819. }
  8820. disconnectedCallback() {
  8821. this.onScrollEnd();
  8822. if (hasLazyBuild(this.el)) {
  8823. /**
  8824. * The event listener and tabs caches need to
  8825. * be cleared otherwise this will create a memory
  8826. * leak where the IonTabs instance can never be
  8827. * garbage collected.
  8828. */
  8829. const { tabsElement, tabsLoadCallback } = this;
  8830. if (tabsElement !== null && tabsLoadCallback !== undefined) {
  8831. tabsElement.removeEventListener('ionTabBarLoaded', tabsLoadCallback);
  8832. }
  8833. this.tabsElement = null;
  8834. this.tabsLoadCallback = undefined;
  8835. }
  8836. }
  8837. /**
  8838. * Rotating certain devices can update
  8839. * the safe area insets. As a result,
  8840. * the fullscreen feature on ion-content
  8841. * needs to be recalculated.
  8842. *
  8843. * We listen for "resize" because we
  8844. * do not care what the orientation of
  8845. * the device is. Other APIs
  8846. * such as ScreenOrientation or
  8847. * the deviceorientation event must have
  8848. * permission from the user first whereas
  8849. * the "resize" event does not.
  8850. *
  8851. * We also throttle the callback to minimize
  8852. * thrashing when quickly resizing a window.
  8853. */
  8854. onResize() {
  8855. if (this.resizeTimeout) {
  8856. clearTimeout(this.resizeTimeout);
  8857. this.resizeTimeout = null;
  8858. }
  8859. this.resizeTimeout = setTimeout(() => {
  8860. /**
  8861. * Resize should only happen
  8862. * if the content is visible.
  8863. * When the content is hidden
  8864. * then offsetParent will be null.
  8865. */
  8866. if (this.el.offsetParent === null) {
  8867. return;
  8868. }
  8869. this.resize();
  8870. }, 100);
  8871. }
  8872. shouldForceOverscroll() {
  8873. const { forceOverscroll } = this;
  8874. const mode = getIonMode$1(this);
  8875. return forceOverscroll === undefined ? mode === 'ios' && isPlatform('ios') : forceOverscroll;
  8876. }
  8877. resize() {
  8878. }
  8879. readDimensions() {
  8880. const page = getPageElement(this.el);
  8881. const top = Math.max(this.el.offsetTop, 0);
  8882. const bottom = Math.max(page.offsetHeight - top - this.el.offsetHeight, 0);
  8883. const dirty = top !== this.cTop || bottom !== this.cBottom;
  8884. if (dirty) {
  8885. this.cTop = top;
  8886. this.cBottom = bottom;
  8887. }
  8888. }
  8889. onScroll(ev) {
  8890. const timeStamp = Date.now();
  8891. const shouldStart = !this.isScrolling;
  8892. this.lastScroll = timeStamp;
  8893. if (shouldStart) {
  8894. this.onScrollStart();
  8895. }
  8896. if (!this.queued && this.scrollEvents) {
  8897. this.queued = true;
  8898. readTask((ts) => {
  8899. this.queued = false;
  8900. this.detail.event = ev;
  8901. updateScrollDetail(this.detail, this.scrollEl, ts, shouldStart);
  8902. this.ionScroll.emit(this.detail);
  8903. });
  8904. }
  8905. }
  8906. /**
  8907. * Get the element where the actual scrolling takes place.
  8908. * This element can be used to subscribe to `scroll` events or manually modify
  8909. * `scrollTop`. However, it's recommended to use the API provided by `ion-content`:
  8910. *
  8911. * i.e. Using `ionScroll`, `ionScrollStart`, `ionScrollEnd` for scrolling events
  8912. * and `scrollToPoint()` to scroll the content into a certain point.
  8913. */
  8914. async getScrollElement() {
  8915. /**
  8916. * If this gets called in certain early lifecycle hooks (ex: Vue onMounted),
  8917. * scrollEl won't be defined yet with the custom elements build, so wait for it to load in.
  8918. */
  8919. if (!this.scrollEl) {
  8920. await new Promise((resolve) => componentOnReady(this.el, resolve));
  8921. }
  8922. return Promise.resolve(this.scrollEl);
  8923. }
  8924. /**
  8925. * Returns the background content element.
  8926. * @internal
  8927. */
  8928. async getBackgroundElement() {
  8929. if (!this.backgroundContentEl) {
  8930. await new Promise((resolve) => componentOnReady(this.el, resolve));
  8931. }
  8932. return Promise.resolve(this.backgroundContentEl);
  8933. }
  8934. /**
  8935. * Scroll to the top of the component.
  8936. *
  8937. * @param duration The amount of time to take scrolling to the top. Defaults to `0`.
  8938. */
  8939. scrollToTop(duration = 0) {
  8940. return this.scrollToPoint(undefined, 0, duration);
  8941. }
  8942. /**
  8943. * Scroll to the bottom of the component.
  8944. *
  8945. * @param duration The amount of time to take scrolling to the bottom. Defaults to `0`.
  8946. */
  8947. async scrollToBottom(duration = 0) {
  8948. const scrollEl = await this.getScrollElement();
  8949. const y = scrollEl.scrollHeight - scrollEl.clientHeight;
  8950. return this.scrollToPoint(undefined, y, duration);
  8951. }
  8952. /**
  8953. * Scroll by a specified X/Y distance in the component.
  8954. *
  8955. * @param x The amount to scroll by on the horizontal axis.
  8956. * @param y The amount to scroll by on the vertical axis.
  8957. * @param duration The amount of time to take scrolling by that amount.
  8958. */
  8959. async scrollByPoint(x, y, duration) {
  8960. const scrollEl = await this.getScrollElement();
  8961. return this.scrollToPoint(x + scrollEl.scrollLeft, y + scrollEl.scrollTop, duration);
  8962. }
  8963. /**
  8964. * Scroll to a specified X/Y location in the component.
  8965. *
  8966. * @param x The point to scroll to on the horizontal axis.
  8967. * @param y The point to scroll to on the vertical axis.
  8968. * @param duration The amount of time to take scrolling to that point. Defaults to `0`.
  8969. */
  8970. async scrollToPoint(x, y, duration = 0) {
  8971. const el = await this.getScrollElement();
  8972. if (duration < 32) {
  8973. if (y != null) {
  8974. el.scrollTop = y;
  8975. }
  8976. if (x != null) {
  8977. el.scrollLeft = x;
  8978. }
  8979. return;
  8980. }
  8981. let resolve;
  8982. let startTime = 0;
  8983. const promise = new Promise((r) => (resolve = r));
  8984. const fromY = el.scrollTop;
  8985. const fromX = el.scrollLeft;
  8986. const deltaY = y != null ? y - fromY : 0;
  8987. const deltaX = x != null ? x - fromX : 0;
  8988. // scroll loop
  8989. const step = (timeStamp) => {
  8990. const linearTime = Math.min(1, (timeStamp - startTime) / duration) - 1;
  8991. const easedT = Math.pow(linearTime, 3) + 1;
  8992. if (deltaY !== 0) {
  8993. el.scrollTop = Math.floor(easedT * deltaY + fromY);
  8994. }
  8995. if (deltaX !== 0) {
  8996. el.scrollLeft = Math.floor(easedT * deltaX + fromX);
  8997. }
  8998. if (easedT < 1) {
  8999. // do not use DomController here
  9000. // must use nativeRaf in order to fire in the next frame
  9001. requestAnimationFrame(step);
  9002. }
  9003. else {
  9004. resolve();
  9005. }
  9006. };
  9007. // chill out for a frame first
  9008. requestAnimationFrame((ts) => {
  9009. startTime = ts;
  9010. step(ts);
  9011. });
  9012. return promise;
  9013. }
  9014. onScrollStart() {
  9015. this.isScrolling = true;
  9016. this.ionScrollStart.emit({
  9017. isScrolling: true,
  9018. });
  9019. if (this.watchDog) {
  9020. clearInterval(this.watchDog);
  9021. }
  9022. // watchdog
  9023. this.watchDog = setInterval(() => {
  9024. if (this.lastScroll < Date.now() - 120) {
  9025. this.onScrollEnd();
  9026. }
  9027. }, 100);
  9028. }
  9029. onScrollEnd() {
  9030. if (this.watchDog)
  9031. clearInterval(this.watchDog);
  9032. this.watchDog = null;
  9033. if (this.isScrolling) {
  9034. this.isScrolling = false;
  9035. this.ionScrollEnd.emit({
  9036. isScrolling: false,
  9037. });
  9038. }
  9039. }
  9040. render() {
  9041. const { fixedSlotPlacement, inheritedAttributes, isMainContent, scrollX, scrollY, el } = this;
  9042. const rtl = isRTL$1(el) ? 'rtl' : 'ltr';
  9043. const mode = getIonMode$1(this);
  9044. const forceOverscroll = this.shouldForceOverscroll();
  9045. const transitionShadow = mode === 'ios';
  9046. this.resize();
  9047. return (hAsync(Host, Object.assign({ key: 'f2a24aa66dbf5c76f9d4b06f708eb73cadc239df', role: isMainContent ? 'main' : undefined, class: createColorClasses$1(this.color, {
  9048. [mode]: true,
  9049. 'content-sizing': hostContext('ion-popover', this.el),
  9050. overscroll: forceOverscroll,
  9051. [`content-${rtl}`]: true,
  9052. }), style: {
  9053. '--offset-top': `${this.cTop}px`,
  9054. '--offset-bottom': `${this.cBottom}px`,
  9055. } }, inheritedAttributes), hAsync("div", { key: '6480ca7648b278abb36477b3838bccbcd4995e2a', ref: (el) => (this.backgroundContentEl = el), id: "background-content", part: "background" }), fixedSlotPlacement === 'before' ? hAsync("slot", { name: "fixed" }) : null, hAsync("div", { key: '29a23b663f5f0215bb000820c01e1814c0d55985', class: {
  9056. 'inner-scroll': true,
  9057. 'scroll-x': scrollX,
  9058. 'scroll-y': scrollY,
  9059. overscroll: (scrollX || scrollY) && forceOverscroll,
  9060. }, ref: (scrollEl) => (this.scrollEl = scrollEl), onScroll: this.scrollEvents ? (ev) => this.onScroll(ev) : undefined, part: "scroll" }, hAsync("slot", { key: '0fe1bd05609a4b88ae2ce9addf5d5dc5dc1806f0' })), transitionShadow ? (hAsync("div", { class: "transition-effect" }, hAsync("div", { class: "transition-cover" }), hAsync("div", { class: "transition-shadow" }))) : null, fixedSlotPlacement === 'after' ? hAsync("slot", { name: "fixed" }) : null));
  9061. }
  9062. get el() { return getElement(this); }
  9063. static get style() { return IonContentStyle0; }
  9064. static get cmpMeta() { return {
  9065. "$flags$": 9,
  9066. "$tagName$": "ion-content",
  9067. "$members$": {
  9068. "color": [513],
  9069. "fullscreen": [4],
  9070. "fixedSlotPlacement": [1, "fixed-slot-placement"],
  9071. "forceOverscroll": [1028, "force-overscroll"],
  9072. "scrollX": [4, "scroll-x"],
  9073. "scrollY": [4, "scroll-y"],
  9074. "scrollEvents": [4, "scroll-events"],
  9075. "getScrollElement": [64],
  9076. "getBackgroundElement": [64],
  9077. "scrollToTop": [64],
  9078. "scrollToBottom": [64],
  9079. "scrollByPoint": [64],
  9080. "scrollToPoint": [64]
  9081. },
  9082. "$listeners$": [[9, "resize", "onResize"]],
  9083. "$lazyBundleId$": "-",
  9084. "$attrsToReflect$": [["color", "color"]]
  9085. }; }
  9086. }
  9087. const getParentElement = (el) => {
  9088. var _a;
  9089. if (el.parentElement) {
  9090. // normal element with a parent element
  9091. return el.parentElement;
  9092. }
  9093. if ((_a = el.parentNode) === null || _a === void 0 ? void 0 : _a.host) {
  9094. // shadow dom's document fragment
  9095. return el.parentNode.host;
  9096. }
  9097. return null;
  9098. };
  9099. const getPageElement = (el) => {
  9100. const tabs = el.closest('ion-tabs');
  9101. if (tabs) {
  9102. return tabs;
  9103. }
  9104. /**
  9105. * If we're in a popover, we need to use its wrapper so we can account for space
  9106. * between the popover and the edges of the screen. But if the popover contains
  9107. * its own page element, we should use that instead.
  9108. */
  9109. const page = el.closest('ion-app, ion-page, .ion-page, page-inner, .popover-content');
  9110. if (page) {
  9111. return page;
  9112. }
  9113. return getParentElement(el);
  9114. };
  9115. // ******** DOM READ ****************
  9116. const updateScrollDetail = (detail, el, timestamp, shouldStart) => {
  9117. const prevX = detail.currentX;
  9118. const prevY = detail.currentY;
  9119. const prevT = detail.currentTime;
  9120. const currentX = el.scrollLeft;
  9121. const currentY = el.scrollTop;
  9122. const timeDelta = timestamp - prevT;
  9123. if (shouldStart) {
  9124. // remember the start positions
  9125. detail.startTime = timestamp;
  9126. detail.startX = currentX;
  9127. detail.startY = currentY;
  9128. detail.velocityX = detail.velocityY = 0;
  9129. }
  9130. detail.currentTime = timestamp;
  9131. detail.currentX = detail.scrollLeft = currentX;
  9132. detail.currentY = detail.scrollTop = currentY;
  9133. detail.deltaX = currentX - detail.startX;
  9134. detail.deltaY = currentY - detail.startY;
  9135. if (timeDelta > 0 && timeDelta < 100) {
  9136. const velocityX = (currentX - prevX) / timeDelta;
  9137. const velocityY = (currentY - prevY) / timeDelta;
  9138. detail.velocityX = velocityX * 0.7 + detail.velocityX * 0.3;
  9139. detail.velocityY = velocityY * 0.7 + detail.velocityY * 0.3;
  9140. }
  9141. };
  9142. const ION_FOCUSED = 'ion-focused';
  9143. const ION_FOCUSABLE = 'ion-focusable';
  9144. const FOCUS_KEYS = [
  9145. 'Tab',
  9146. 'ArrowDown',
  9147. 'Space',
  9148. 'Escape',
  9149. ' ',
  9150. 'Shift',
  9151. 'Enter',
  9152. 'ArrowLeft',
  9153. 'ArrowRight',
  9154. 'ArrowUp',
  9155. 'Home',
  9156. 'End',
  9157. ];
  9158. const startFocusVisible = (rootEl) => {
  9159. let currentFocus = [];
  9160. let keyboardMode = true;
  9161. const ref = rootEl ? rootEl.shadowRoot : document;
  9162. const root = rootEl ? rootEl : document.body;
  9163. const setFocus = (elements) => {
  9164. currentFocus.forEach((el) => el.classList.remove(ION_FOCUSED));
  9165. elements.forEach((el) => el.classList.add(ION_FOCUSED));
  9166. currentFocus = elements;
  9167. };
  9168. const pointerDown = () => {
  9169. keyboardMode = false;
  9170. setFocus([]);
  9171. };
  9172. const onKeydown = (ev) => {
  9173. keyboardMode = FOCUS_KEYS.includes(ev.key);
  9174. if (!keyboardMode) {
  9175. setFocus([]);
  9176. }
  9177. };
  9178. const onFocusin = (ev) => {
  9179. if (keyboardMode && ev.composedPath !== undefined) {
  9180. const toFocus = ev.composedPath().filter((el) => {
  9181. // TODO(FW-2832): type
  9182. if (el.classList) {
  9183. return el.classList.contains(ION_FOCUSABLE);
  9184. }
  9185. return false;
  9186. });
  9187. setFocus(toFocus);
  9188. }
  9189. };
  9190. const onFocusout = () => {
  9191. if (ref.activeElement === root) {
  9192. setFocus([]);
  9193. }
  9194. };
  9195. ref.addEventListener('keydown', onKeydown);
  9196. ref.addEventListener('focusin', onFocusin);
  9197. ref.addEventListener('focusout', onFocusout);
  9198. ref.addEventListener('touchstart', pointerDown, { passive: true });
  9199. ref.addEventListener('mousedown', pointerDown);
  9200. const destroy = () => {
  9201. ref.removeEventListener('keydown', onKeydown);
  9202. ref.removeEventListener('focusin', onFocusin);
  9203. ref.removeEventListener('focusout', onFocusout);
  9204. ref.removeEventListener('touchstart', pointerDown);
  9205. ref.removeEventListener('mousedown', pointerDown);
  9206. };
  9207. return {
  9208. destroy,
  9209. setFocus,
  9210. };
  9211. };
  9212. /**
  9213. * Returns true if the selected day is equal to the reference day
  9214. */
  9215. const isSameDay = (baseParts, compareParts) => {
  9216. return (baseParts.month === compareParts.month && baseParts.day === compareParts.day && baseParts.year === compareParts.year);
  9217. };
  9218. /**
  9219. * Returns true is the selected day is before the reference day.
  9220. */
  9221. const isBefore = (baseParts, compareParts) => {
  9222. return !!(baseParts.year < compareParts.year ||
  9223. (baseParts.year === compareParts.year && baseParts.month < compareParts.month) ||
  9224. (baseParts.year === compareParts.year &&
  9225. baseParts.month === compareParts.month &&
  9226. baseParts.day !== null &&
  9227. baseParts.day < compareParts.day));
  9228. };
  9229. /**
  9230. * Returns true is the selected day is after the reference day.
  9231. */
  9232. const isAfter = (baseParts, compareParts) => {
  9233. return !!(baseParts.year > compareParts.year ||
  9234. (baseParts.year === compareParts.year && baseParts.month > compareParts.month) ||
  9235. (baseParts.year === compareParts.year &&
  9236. baseParts.month === compareParts.month &&
  9237. baseParts.day !== null &&
  9238. baseParts.day > compareParts.day));
  9239. };
  9240. const warnIfValueOutOfBounds = (value, min, max) => {
  9241. const valueArray = Array.isArray(value) ? value : [value];
  9242. for (const val of valueArray) {
  9243. if ((min !== undefined && isBefore(val, min)) || (max !== undefined && isAfter(val, max))) {
  9244. printIonWarning('[ion-datetime] - The value provided to ion-datetime is out of bounds.\n\n' +
  9245. `Min: ${JSON.stringify(min)}\n` +
  9246. `Max: ${JSON.stringify(max)}\n` +
  9247. `Value: ${JSON.stringify(value)}`);
  9248. break;
  9249. }
  9250. }
  9251. };
  9252. /**
  9253. * Determines if given year is a
  9254. * leap year. Returns `true` if year
  9255. * is a leap year. Returns `false`
  9256. * otherwise.
  9257. */
  9258. const isLeapYear = (year) => {
  9259. return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;
  9260. };
  9261. /**
  9262. * Determines the hour cycle for a user.
  9263. * If the hour cycle is explicitly defined, just use that.
  9264. * Otherwise, we try to derive it from either the specified
  9265. * locale extension tags or from Intl.DateTimeFormat directly.
  9266. */
  9267. const getHourCycle = (locale, hourCycle) => {
  9268. /**
  9269. * If developer has explicitly enabled 24-hour time
  9270. * then return early and do not look at the system default.
  9271. */
  9272. if (hourCycle !== undefined) {
  9273. return hourCycle;
  9274. }
  9275. /**
  9276. * If hourCycle was not specified, check the locale
  9277. * that is set on the user's device. We first check the
  9278. * Intl.DateTimeFormat hourCycle option as developers can encode this
  9279. * option into the locale string. Example: `en-US-u-hc-h23`
  9280. */
  9281. const formatted = new Intl.DateTimeFormat(locale, { hour: 'numeric' });
  9282. const options = formatted.resolvedOptions();
  9283. if (options.hourCycle !== undefined) {
  9284. return options.hourCycle;
  9285. }
  9286. /**
  9287. * If hourCycle is not specified (either through lack
  9288. * of browser support or locale information) then fall
  9289. * back to this slower hourCycle check.
  9290. */
  9291. const date = new Date('5/18/2021 00:00');
  9292. const parts = formatted.formatToParts(date);
  9293. const hour = parts.find((p) => p.type === 'hour');
  9294. if (!hour) {
  9295. throw new Error('Hour value not found from DateTimeFormat');
  9296. }
  9297. /**
  9298. * Midnight for h11 starts at 0:00am
  9299. * Midnight for h12 starts at 12:00am
  9300. * Midnight for h23 starts at 00:00
  9301. * Midnight for h24 starts at 24:00
  9302. */
  9303. switch (hour.value) {
  9304. case '0':
  9305. return 'h11';
  9306. case '12':
  9307. return 'h12';
  9308. case '00':
  9309. return 'h23';
  9310. case '24':
  9311. return 'h24';
  9312. default:
  9313. throw new Error(`Invalid hour cycle "${hourCycle}"`);
  9314. }
  9315. };
  9316. /**
  9317. * Determine if the hour cycle uses a 24-hour format.
  9318. * Returns true for h23 and h24. Returns false otherwise.
  9319. * If you don't know the hourCycle, use getHourCycle above
  9320. * and pass the result into this function.
  9321. */
  9322. const is24Hour = (hourCycle) => {
  9323. return hourCycle === 'h23' || hourCycle === 'h24';
  9324. };
  9325. /**
  9326. * Given a date object, returns the number
  9327. * of days in that month.
  9328. * Month value begin at 1, not 0.
  9329. * i.e. January = month 1.
  9330. */
  9331. const getNumDaysInMonth = (month, year) => {
  9332. return month === 4 || month === 6 || month === 9 || month === 11
  9333. ? 30
  9334. : month === 2
  9335. ? isLeapYear(year)
  9336. ? 29
  9337. : 28
  9338. : 31;
  9339. };
  9340. /**
  9341. * Certain locales display month then year while
  9342. * others display year then month.
  9343. * We can use Intl.DateTimeFormat to determine
  9344. * the ordering for each locale.
  9345. * The formatOptions param can be used to customize
  9346. * which pieces of a date to compare against the month
  9347. * with. For example, some locales render dd/mm/yyyy
  9348. * while others render mm/dd/yyyy. This function can be
  9349. * used for variations of the same "month first" check.
  9350. */
  9351. const isMonthFirstLocale = (locale, formatOptions = {
  9352. month: 'numeric',
  9353. year: 'numeric',
  9354. }) => {
  9355. /**
  9356. * By setting month and year we guarantee that only
  9357. * month, year, and literal (slashes '/', for example)
  9358. * values are included in the formatToParts results.
  9359. *
  9360. * The ordering of the parts will be determined by
  9361. * the locale. So if the month is the first value,
  9362. * then we know month should be shown first. If the
  9363. * year is the first value, then we know year should be shown first.
  9364. *
  9365. * This ordering can be controlled by customizing the locale property.
  9366. */
  9367. const parts = new Intl.DateTimeFormat(locale, formatOptions).formatToParts(new Date());
  9368. return parts[0].type === 'month';
  9369. };
  9370. /**
  9371. * Determines if the given locale formats the day period (am/pm) to the
  9372. * left or right of the hour.
  9373. * @param locale The locale to check.
  9374. * @returns `true` if the locale formats the day period to the left of the hour.
  9375. */
  9376. const isLocaleDayPeriodRTL = (locale) => {
  9377. const parts = new Intl.DateTimeFormat(locale, { hour: 'numeric' }).formatToParts(new Date());
  9378. return parts[0].type === 'dayPeriod';
  9379. };
  9380. const ISO_8601_REGEXP =
  9381. // eslint-disable-next-line no-useless-escape
  9382. /^(\d{4}|[+\-]\d{6})(?:-(\d{2})(?:-(\d{2}))?)?(?:T(\d{2}):(\d{2})(?::(\d{2})(?:\.(\d{3}))?)?(?:(Z)|([+\-])(\d{2})(?::(\d{2}))?)?)?$/;
  9383. // eslint-disable-next-line no-useless-escape
  9384. const TIME_REGEXP = /^((\d{2}):(\d{2})(?::(\d{2})(?:\.(\d{3}))?)?(?:(Z)|([+\-])(\d{2})(?::(\d{2}))?)?)?$/;
  9385. /**
  9386. * Use to convert a string of comma separated numbers or
  9387. * an array of numbers, and clean up any user input
  9388. */
  9389. const convertToArrayOfNumbers = (input) => {
  9390. if (input === undefined) {
  9391. return;
  9392. }
  9393. let processedInput = input;
  9394. if (typeof input === 'string') {
  9395. // convert the string to an array of strings
  9396. // auto remove any whitespace and [] characters
  9397. processedInput = input.replace(/\[|\]|\s/g, '').split(',');
  9398. }
  9399. let values;
  9400. if (Array.isArray(processedInput)) {
  9401. // ensure each value is an actual number in the returned array
  9402. values = processedInput.map((num) => parseInt(num, 10)).filter(isFinite);
  9403. }
  9404. else {
  9405. values = [processedInput];
  9406. }
  9407. return values;
  9408. };
  9409. /**
  9410. * Extracts date information
  9411. * from a .calendar-day element
  9412. * into DatetimeParts.
  9413. */
  9414. const getPartsFromCalendarDay = (el) => {
  9415. return {
  9416. month: parseInt(el.getAttribute('data-month'), 10),
  9417. day: parseInt(el.getAttribute('data-day'), 10),
  9418. year: parseInt(el.getAttribute('data-year'), 10),
  9419. dayOfWeek: parseInt(el.getAttribute('data-day-of-week'), 10),
  9420. };
  9421. };
  9422. function parseDate(val) {
  9423. if (Array.isArray(val)) {
  9424. const parsedArray = [];
  9425. for (const valStr of val) {
  9426. const parsedVal = parseDate(valStr);
  9427. /**
  9428. * If any of the values weren't parsed correctly, consider
  9429. * the entire batch incorrect. This simplifies the type
  9430. * signatures by having "undefined" be a general error case
  9431. * instead of returning (Datetime | undefined)[], which is
  9432. * harder for TS to perform type narrowing on.
  9433. */
  9434. if (!parsedVal) {
  9435. return undefined;
  9436. }
  9437. parsedArray.push(parsedVal);
  9438. }
  9439. return parsedArray;
  9440. }
  9441. // manually parse IS0 cuz Date.parse cannot be trusted
  9442. // ISO 8601 format: 1994-12-15T13:47:20Z
  9443. let parse = null;
  9444. if (val != null && val !== '') {
  9445. // try parsing for just time first, HH:MM
  9446. parse = TIME_REGEXP.exec(val);
  9447. if (parse) {
  9448. // adjust the array so it fits nicely with the datetime parse
  9449. parse.unshift(undefined, undefined);
  9450. parse[2] = parse[3] = undefined;
  9451. }
  9452. else {
  9453. // try parsing for full ISO datetime
  9454. parse = ISO_8601_REGEXP.exec(val);
  9455. }
  9456. }
  9457. if (parse === null) {
  9458. // wasn't able to parse the ISO datetime
  9459. printIonWarning(`[ion-datetime] - Unable to parse date string: ${val}. Please provide a valid ISO 8601 datetime string.`);
  9460. return undefined;
  9461. }
  9462. // ensure all the parse values exist with at least 0
  9463. for (let i = 1; i < 8; i++) {
  9464. parse[i] = parse[i] !== undefined ? parseInt(parse[i], 10) : undefined;
  9465. }
  9466. // can also get second and millisecond from parse[6] and parse[7] if needed
  9467. return {
  9468. year: parse[1],
  9469. month: parse[2],
  9470. day: parse[3],
  9471. hour: parse[4],
  9472. minute: parse[5],
  9473. ampm: parse[4] < 12 ? 'am' : 'pm',
  9474. };
  9475. }
  9476. const clampDate = (dateParts, minParts, maxParts) => {
  9477. if (minParts && isBefore(dateParts, minParts)) {
  9478. return minParts;
  9479. }
  9480. else if (maxParts && isAfter(dateParts, maxParts)) {
  9481. return maxParts;
  9482. }
  9483. return dateParts;
  9484. };
  9485. /**
  9486. * Parses an hour and returns if the value is in the morning (am) or afternoon (pm).
  9487. * @param hour The hour to format, should be 0-23
  9488. * @returns `pm` if the hour is greater than or equal to 12, `am` if less than 12.
  9489. */
  9490. const parseAmPm = (hour) => {
  9491. return hour >= 12 ? 'pm' : 'am';
  9492. };
  9493. /**
  9494. * Takes a max date string and creates a DatetimeParts
  9495. * object, filling in any missing information.
  9496. * For example, max="2012" would fill in the missing
  9497. * month, day, hour, and minute information.
  9498. */
  9499. const parseMaxParts = (max, todayParts) => {
  9500. const result = parseDate(max);
  9501. /**
  9502. * If min was not a valid date then return undefined.
  9503. */
  9504. if (result === undefined) {
  9505. return;
  9506. }
  9507. const { month, day, year, hour, minute } = result;
  9508. /**
  9509. * When passing in `max` or `min`, developers
  9510. * can pass in any ISO-8601 string. This means
  9511. * that not all of the date/time fields are defined.
  9512. * For example, passing max="2012" is valid even though
  9513. * there is no month, day, hour, or minute data.
  9514. * However, all of this data is required when clamping the date
  9515. * so that the correct initial value can be selected. As a result,
  9516. * we need to fill in any omitted data with the min or max values.
  9517. */
  9518. const yearValue = year !== null && year !== void 0 ? year : todayParts.year;
  9519. const monthValue = month !== null && month !== void 0 ? month : 12;
  9520. return {
  9521. month: monthValue,
  9522. day: day !== null && day !== void 0 ? day : getNumDaysInMonth(monthValue, yearValue),
  9523. /**
  9524. * Passing in "HH:mm" is a valid ISO-8601
  9525. * string, so we just default to the current year
  9526. * in this case.
  9527. */
  9528. year: yearValue,
  9529. hour: hour !== null && hour !== void 0 ? hour : 23,
  9530. minute: minute !== null && minute !== void 0 ? minute : 59,
  9531. };
  9532. };
  9533. /**
  9534. * Takes a min date string and creates a DatetimeParts
  9535. * object, filling in any missing information.
  9536. * For example, min="2012" would fill in the missing
  9537. * month, day, hour, and minute information.
  9538. */
  9539. const parseMinParts = (min, todayParts) => {
  9540. const result = parseDate(min);
  9541. /**
  9542. * If min was not a valid date then return undefined.
  9543. */
  9544. if (result === undefined) {
  9545. return;
  9546. }
  9547. const { month, day, year, hour, minute } = result;
  9548. /**
  9549. * When passing in `max` or `min`, developers
  9550. * can pass in any ISO-8601 string. This means
  9551. * that not all of the date/time fields are defined.
  9552. * For example, passing max="2012" is valid even though
  9553. * there is no month, day, hour, or minute data.
  9554. * However, all of this data is required when clamping the date
  9555. * so that the correct initial value can be selected. As a result,
  9556. * we need to fill in any omitted data with the min or max values.
  9557. */
  9558. return {
  9559. month: month !== null && month !== void 0 ? month : 1,
  9560. day: day !== null && day !== void 0 ? day : 1,
  9561. /**
  9562. * Passing in "HH:mm" is a valid ISO-8601
  9563. * string, so we just default to the current year
  9564. * in this case.
  9565. */
  9566. year: year !== null && year !== void 0 ? year : todayParts.year,
  9567. hour: hour !== null && hour !== void 0 ? hour : 0,
  9568. minute: minute !== null && minute !== void 0 ? minute : 0,
  9569. };
  9570. };
  9571. const twoDigit = (val) => {
  9572. return ('0' + (val !== undefined ? Math.abs(val) : '0')).slice(-2);
  9573. };
  9574. const fourDigit = (val) => {
  9575. return ('000' + (val !== undefined ? Math.abs(val) : '0')).slice(-4);
  9576. };
  9577. function convertDataToISO(data) {
  9578. if (Array.isArray(data)) {
  9579. return data.map((parts) => convertDataToISO(parts));
  9580. }
  9581. // https://www.w3.org/TR/NOTE-datetime
  9582. let rtn = '';
  9583. if (data.year !== undefined) {
  9584. // YYYY
  9585. rtn = fourDigit(data.year);
  9586. if (data.month !== undefined) {
  9587. // YYYY-MM
  9588. rtn += '-' + twoDigit(data.month);
  9589. if (data.day !== undefined) {
  9590. // YYYY-MM-DD
  9591. rtn += '-' + twoDigit(data.day);
  9592. if (data.hour !== undefined) {
  9593. // YYYY-MM-DDTHH:mm:SS
  9594. rtn += `T${twoDigit(data.hour)}:${twoDigit(data.minute)}:00`;
  9595. }
  9596. }
  9597. }
  9598. }
  9599. else if (data.hour !== undefined) {
  9600. // HH:mm
  9601. rtn = twoDigit(data.hour) + ':' + twoDigit(data.minute);
  9602. }
  9603. return rtn;
  9604. }
  9605. /**
  9606. * Converts an 12 hour value to 24 hours.
  9607. */
  9608. const convert12HourTo24Hour = (hour, ampm) => {
  9609. if (ampm === undefined) {
  9610. return hour;
  9611. }
  9612. /**
  9613. * If AM and 12am
  9614. * then return 00:00.
  9615. * Otherwise just return
  9616. * the hour since it is
  9617. * already in 24 hour format.
  9618. */
  9619. if (ampm === 'am') {
  9620. if (hour === 12) {
  9621. return 0;
  9622. }
  9623. return hour;
  9624. }
  9625. /**
  9626. * If PM and 12pm
  9627. * just return 12:00
  9628. * since it is already
  9629. * in 24 hour format.
  9630. * Otherwise add 12 hours
  9631. * to the time.
  9632. */
  9633. if (hour === 12) {
  9634. return 12;
  9635. }
  9636. return hour + 12;
  9637. };
  9638. const getStartOfWeek = (refParts) => {
  9639. const { dayOfWeek } = refParts;
  9640. if (dayOfWeek === null || dayOfWeek === undefined) {
  9641. throw new Error('No day of week provided');
  9642. }
  9643. return subtractDays(refParts, dayOfWeek);
  9644. };
  9645. const getEndOfWeek = (refParts) => {
  9646. const { dayOfWeek } = refParts;
  9647. if (dayOfWeek === null || dayOfWeek === undefined) {
  9648. throw new Error('No day of week provided');
  9649. }
  9650. return addDays(refParts, 6 - dayOfWeek);
  9651. };
  9652. const getNextDay = (refParts) => {
  9653. return addDays(refParts, 1);
  9654. };
  9655. const getPreviousDay = (refParts) => {
  9656. return subtractDays(refParts, 1);
  9657. };
  9658. const getPreviousWeek = (refParts) => {
  9659. return subtractDays(refParts, 7);
  9660. };
  9661. const getNextWeek = (refParts) => {
  9662. return addDays(refParts, 7);
  9663. };
  9664. /**
  9665. * Given datetime parts, subtract
  9666. * numDays from the date.
  9667. * Returns a new DatetimeParts object
  9668. * Currently can only go backward at most 1 month.
  9669. */
  9670. const subtractDays = (refParts, numDays) => {
  9671. const { month, day, year } = refParts;
  9672. if (day === null) {
  9673. throw new Error('No day provided');
  9674. }
  9675. const workingParts = {
  9676. month,
  9677. day,
  9678. year,
  9679. };
  9680. workingParts.day = day - numDays;
  9681. /**
  9682. * If wrapping to previous month
  9683. * update days and decrement month
  9684. */
  9685. if (workingParts.day < 1) {
  9686. workingParts.month -= 1;
  9687. }
  9688. /**
  9689. * If moving to previous year, reset
  9690. * month to December and decrement year
  9691. */
  9692. if (workingParts.month < 1) {
  9693. workingParts.month = 12;
  9694. workingParts.year -= 1;
  9695. }
  9696. /**
  9697. * Determine how many days are in the current
  9698. * month
  9699. */
  9700. if (workingParts.day < 1) {
  9701. const daysInMonth = getNumDaysInMonth(workingParts.month, workingParts.year);
  9702. /**
  9703. * Take num days in month and add the
  9704. * number of underflow days. This number will
  9705. * be negative.
  9706. * Example: 1 week before Jan 2, 2021 is
  9707. * December 26, 2021 so:
  9708. * 2 - 7 = -5
  9709. * 31 + (-5) = 26
  9710. */
  9711. workingParts.day = daysInMonth + workingParts.day;
  9712. }
  9713. return workingParts;
  9714. };
  9715. /**
  9716. * Given datetime parts, add
  9717. * numDays to the date.
  9718. * Returns a new DatetimeParts object
  9719. * Currently can only go forward at most 1 month.
  9720. */
  9721. const addDays = (refParts, numDays) => {
  9722. const { month, day, year } = refParts;
  9723. if (day === null) {
  9724. throw new Error('No day provided');
  9725. }
  9726. const workingParts = {
  9727. month,
  9728. day,
  9729. year,
  9730. };
  9731. const daysInMonth = getNumDaysInMonth(month, year);
  9732. workingParts.day = day + numDays;
  9733. /**
  9734. * If wrapping to next month
  9735. * update days and increment month
  9736. */
  9737. if (workingParts.day > daysInMonth) {
  9738. workingParts.day -= daysInMonth;
  9739. workingParts.month += 1;
  9740. }
  9741. /**
  9742. * If moving to next year, reset
  9743. * month to January and increment year
  9744. */
  9745. if (workingParts.month > 12) {
  9746. workingParts.month = 1;
  9747. workingParts.year += 1;
  9748. }
  9749. return workingParts;
  9750. };
  9751. /**
  9752. * Given DatetimeParts, generate the previous month.
  9753. */
  9754. const getPreviousMonth = (refParts) => {
  9755. /**
  9756. * If current month is January, wrap backwards
  9757. * to December of the previous year.
  9758. */
  9759. const month = refParts.month === 1 ? 12 : refParts.month - 1;
  9760. const year = refParts.month === 1 ? refParts.year - 1 : refParts.year;
  9761. const numDaysInMonth = getNumDaysInMonth(month, year);
  9762. const day = numDaysInMonth < refParts.day ? numDaysInMonth : refParts.day;
  9763. return { month, year, day };
  9764. };
  9765. /**
  9766. * Given DatetimeParts, generate the next month.
  9767. */
  9768. const getNextMonth = (refParts) => {
  9769. /**
  9770. * If current month is December, wrap forwards
  9771. * to January of the next year.
  9772. */
  9773. const month = refParts.month === 12 ? 1 : refParts.month + 1;
  9774. const year = refParts.month === 12 ? refParts.year + 1 : refParts.year;
  9775. const numDaysInMonth = getNumDaysInMonth(month, year);
  9776. const day = numDaysInMonth < refParts.day ? numDaysInMonth : refParts.day;
  9777. return { month, year, day };
  9778. };
  9779. const changeYear = (refParts, yearDelta) => {
  9780. const month = refParts.month;
  9781. const year = refParts.year + yearDelta;
  9782. const numDaysInMonth = getNumDaysInMonth(month, year);
  9783. const day = numDaysInMonth < refParts.day ? numDaysInMonth : refParts.day;
  9784. return { month, year, day };
  9785. };
  9786. /**
  9787. * Given DatetimeParts, generate the previous year.
  9788. */
  9789. const getPreviousYear = (refParts) => {
  9790. return changeYear(refParts, -1);
  9791. };
  9792. /**
  9793. * Given DatetimeParts, generate the next year.
  9794. */
  9795. const getNextYear = (refParts) => {
  9796. return changeYear(refParts, 1);
  9797. };
  9798. /**
  9799. * If PM, then internal value should
  9800. * be converted to 24-hr time.
  9801. * Does not apply when public
  9802. * values are already 24-hr time.
  9803. */
  9804. const getInternalHourValue = (hour, use24Hour, ampm) => {
  9805. if (use24Hour) {
  9806. return hour;
  9807. }
  9808. return convert12HourTo24Hour(hour, ampm);
  9809. };
  9810. /**
  9811. * Unless otherwise stated, all month values are
  9812. * 1 indexed instead of the typical 0 index in JS Date.
  9813. * Example:
  9814. * January = Month 0 when using JS Date
  9815. * January = Month 1 when using this datetime util
  9816. */
  9817. /**
  9818. * Given the current datetime parts and a new AM/PM value
  9819. * calculate what the hour should be in 24-hour time format.
  9820. * Used when toggling the AM/PM segment since we store our hours
  9821. * in 24-hour time format internally.
  9822. */
  9823. const calculateHourFromAMPM = (currentParts, newAMPM) => {
  9824. const { ampm: currentAMPM, hour } = currentParts;
  9825. let newHour = hour;
  9826. /**
  9827. * If going from AM --> PM, need to update the
  9828. *
  9829. */
  9830. if (currentAMPM === 'am' && newAMPM === 'pm') {
  9831. newHour = convert12HourTo24Hour(newHour, 'pm');
  9832. /**
  9833. * If going from PM --> AM
  9834. */
  9835. }
  9836. else if (currentAMPM === 'pm' && newAMPM === 'am') {
  9837. newHour = Math.abs(newHour - 12);
  9838. }
  9839. return newHour;
  9840. };
  9841. /**
  9842. * Updates parts to ensure that month and day
  9843. * values are valid. For days that do not exist,
  9844. * or are outside the min/max bounds, the closest
  9845. * valid day is used.
  9846. */
  9847. const validateParts = (parts, minParts, maxParts) => {
  9848. const { month, day, year } = parts;
  9849. const partsCopy = clampDate(Object.assign({}, parts), minParts, maxParts);
  9850. const numDays = getNumDaysInMonth(month, year);
  9851. /**
  9852. * If the max number of days
  9853. * is greater than the day we want
  9854. * to set, update the DatetimeParts
  9855. * day field to be the max days.
  9856. */
  9857. if (day !== null && numDays < day) {
  9858. partsCopy.day = numDays;
  9859. }
  9860. /**
  9861. * If value is same day as min day,
  9862. * make sure the time value is in bounds.
  9863. */
  9864. if (minParts !== undefined && isSameDay(partsCopy, minParts)) {
  9865. /**
  9866. * If the hour is out of bounds,
  9867. * update both the hour and minute.
  9868. * This is done so that the new time
  9869. * is closest to what the user selected.
  9870. */
  9871. if (partsCopy.hour !== undefined && minParts.hour !== undefined) {
  9872. if (partsCopy.hour < minParts.hour) {
  9873. partsCopy.hour = minParts.hour;
  9874. partsCopy.minute = minParts.minute;
  9875. /**
  9876. * If only the minute is out of bounds,
  9877. * set it to the min minute.
  9878. */
  9879. }
  9880. else if (partsCopy.hour === minParts.hour &&
  9881. partsCopy.minute !== undefined &&
  9882. minParts.minute !== undefined &&
  9883. partsCopy.minute < minParts.minute) {
  9884. partsCopy.minute = minParts.minute;
  9885. }
  9886. }
  9887. }
  9888. /**
  9889. * If value is same day as max day,
  9890. * make sure the time value is in bounds.
  9891. */
  9892. if (maxParts !== undefined && isSameDay(parts, maxParts)) {
  9893. /**
  9894. * If the hour is out of bounds,
  9895. * update both the hour and minute.
  9896. * This is done so that the new time
  9897. * is closest to what the user selected.
  9898. */
  9899. if (partsCopy.hour !== undefined && maxParts.hour !== undefined) {
  9900. if (partsCopy.hour > maxParts.hour) {
  9901. partsCopy.hour = maxParts.hour;
  9902. partsCopy.minute = maxParts.minute;
  9903. /**
  9904. * If only the minute is out of bounds,
  9905. * set it to the max minute.
  9906. */
  9907. }
  9908. else if (partsCopy.hour === maxParts.hour &&
  9909. partsCopy.minute !== undefined &&
  9910. maxParts.minute !== undefined &&
  9911. partsCopy.minute > maxParts.minute) {
  9912. partsCopy.minute = maxParts.minute;
  9913. }
  9914. }
  9915. }
  9916. return partsCopy;
  9917. };
  9918. /**
  9919. * Returns the closest date to refParts
  9920. * that also meets the constraints of
  9921. * the *Values params.
  9922. */
  9923. const getClosestValidDate = ({ refParts, monthValues, dayValues, yearValues, hourValues, minuteValues, minParts, maxParts, }) => {
  9924. const { hour, minute, day, month, year } = refParts;
  9925. const copyParts = Object.assign(Object.assign({}, refParts), { dayOfWeek: undefined });
  9926. if (yearValues !== undefined) {
  9927. // Filters out years that are out of the min/max bounds
  9928. const filteredYears = yearValues.filter((year) => {
  9929. if (minParts !== undefined && year < minParts.year) {
  9930. return false;
  9931. }
  9932. if (maxParts !== undefined && year > maxParts.year) {
  9933. return false;
  9934. }
  9935. return true;
  9936. });
  9937. copyParts.year = findClosestValue(year, filteredYears);
  9938. }
  9939. if (monthValues !== undefined) {
  9940. // Filters out months that are out of the min/max bounds
  9941. const filteredMonths = monthValues.filter((month) => {
  9942. if (minParts !== undefined && copyParts.year === minParts.year && month < minParts.month) {
  9943. return false;
  9944. }
  9945. if (maxParts !== undefined && copyParts.year === maxParts.year && month > maxParts.month) {
  9946. return false;
  9947. }
  9948. return true;
  9949. });
  9950. copyParts.month = findClosestValue(month, filteredMonths);
  9951. }
  9952. // Day is nullable but cannot be undefined
  9953. if (day !== null && dayValues !== undefined) {
  9954. // Filters out days that are out of the min/max bounds
  9955. const filteredDays = dayValues.filter((day) => {
  9956. if (minParts !== undefined && isBefore(Object.assign(Object.assign({}, copyParts), { day }), minParts)) {
  9957. return false;
  9958. }
  9959. if (maxParts !== undefined && isAfter(Object.assign(Object.assign({}, copyParts), { day }), maxParts)) {
  9960. return false;
  9961. }
  9962. return true;
  9963. });
  9964. copyParts.day = findClosestValue(day, filteredDays);
  9965. }
  9966. if (hour !== undefined && hourValues !== undefined) {
  9967. // Filters out hours that are out of the min/max bounds
  9968. const filteredHours = hourValues.filter((hour) => {
  9969. if ((minParts === null || minParts === void 0 ? void 0 : minParts.hour) !== undefined && isSameDay(copyParts, minParts) && hour < minParts.hour) {
  9970. return false;
  9971. }
  9972. if ((maxParts === null || maxParts === void 0 ? void 0 : maxParts.hour) !== undefined && isSameDay(copyParts, maxParts) && hour > maxParts.hour) {
  9973. return false;
  9974. }
  9975. return true;
  9976. });
  9977. copyParts.hour = findClosestValue(hour, filteredHours);
  9978. copyParts.ampm = parseAmPm(copyParts.hour);
  9979. }
  9980. if (minute !== undefined && minuteValues !== undefined) {
  9981. // Filters out minutes that are out of the min/max bounds
  9982. const filteredMinutes = minuteValues.filter((minute) => {
  9983. if ((minParts === null || minParts === void 0 ? void 0 : minParts.minute) !== undefined &&
  9984. isSameDay(copyParts, minParts) &&
  9985. copyParts.hour === minParts.hour &&
  9986. minute < minParts.minute) {
  9987. return false;
  9988. }
  9989. if ((maxParts === null || maxParts === void 0 ? void 0 : maxParts.minute) !== undefined &&
  9990. isSameDay(copyParts, maxParts) &&
  9991. copyParts.hour === maxParts.hour &&
  9992. minute > maxParts.minute) {
  9993. return false;
  9994. }
  9995. return true;
  9996. });
  9997. copyParts.minute = findClosestValue(minute, filteredMinutes);
  9998. }
  9999. return copyParts;
  10000. };
  10001. /**
  10002. * Finds the value in "values" that is
  10003. * numerically closest to "reference".
  10004. * This function assumes that "values" is
  10005. * already sorted in ascending order.
  10006. * @param reference The reference number to use
  10007. * when finding the closest value
  10008. * @param values The allowed values that will be
  10009. * searched to find the closest value to "reference"
  10010. */
  10011. const findClosestValue = (reference, values) => {
  10012. let closestValue = values[0];
  10013. let rank = Math.abs(closestValue - reference);
  10014. for (let i = 1; i < values.length; i++) {
  10015. const value = values[i];
  10016. /**
  10017. * This code prioritizes the first
  10018. * closest result. Given two values
  10019. * with the same distance from reference,
  10020. * this code will prioritize the smaller of
  10021. * the two values.
  10022. */
  10023. const valueRank = Math.abs(value - reference);
  10024. if (valueRank < rank) {
  10025. closestValue = value;
  10026. rank = valueRank;
  10027. }
  10028. }
  10029. return closestValue;
  10030. };
  10031. const getFormattedDayPeriod = (dayPeriod) => {
  10032. if (dayPeriod === undefined) {
  10033. return '';
  10034. }
  10035. return dayPeriod.toUpperCase();
  10036. };
  10037. /**
  10038. * Including time zone options may lead to the rendered text showing a
  10039. * different time from what was selected in the Datetime, which could cause
  10040. * confusion.
  10041. */
  10042. const stripTimeZone = (formatOptions) => {
  10043. return Object.assign(Object.assign({}, formatOptions), {
  10044. /**
  10045. * Setting the time zone to UTC ensures that the value shown is always the
  10046. * same as what was selected and safeguards against older Safari bugs with
  10047. * Intl.DateTimeFormat.
  10048. */
  10049. timeZone: 'UTC',
  10050. /**
  10051. * We do not want to display the time zone name
  10052. */
  10053. timeZoneName: undefined });
  10054. };
  10055. const getLocalizedTime = (locale, refParts, hourCycle, formatOptions = { hour: 'numeric', minute: 'numeric' }) => {
  10056. const timeParts = {
  10057. hour: refParts.hour,
  10058. minute: refParts.minute,
  10059. };
  10060. if (timeParts.hour === undefined || timeParts.minute === undefined) {
  10061. return 'Invalid Time';
  10062. }
  10063. return new Intl.DateTimeFormat(locale, Object.assign(Object.assign({}, stripTimeZone(formatOptions)), {
  10064. /**
  10065. * We use hourCycle here instead of hour12 due to:
  10066. * https://bugs.chromium.org/p/chromium/issues/detail?id=1347316&q=hour12&can=2
  10067. */
  10068. hourCycle })).format(new Date(convertDataToISO(Object.assign({
  10069. /**
  10070. * JS uses a simplified ISO 8601 format which allows for
  10071. * date-only formats and date-time formats, but not
  10072. * time-only formats: https://tc39.es/ecma262/#sec-date-time-string-format
  10073. * As a result, developers who only pass a time will get
  10074. * an "Invalid Date" error. To account for this, we make sure that
  10075. * year/day/month values are set when passing to new Date().
  10076. * The Intl.DateTimeFormat call above only uses the hour/minute
  10077. * values, so passing these date values should have no impact
  10078. * on the time output.
  10079. */
  10080. year: 2023, day: 1, month: 1 }, timeParts)) + 'Z'));
  10081. };
  10082. /**
  10083. * Adds padding to a time value so
  10084. * that it is always 2 digits.
  10085. */
  10086. const addTimePadding = (value) => {
  10087. const valueToString = value.toString();
  10088. if (valueToString.length > 1) {
  10089. return valueToString;
  10090. }
  10091. return `0${valueToString}`;
  10092. };
  10093. /**
  10094. * Formats 24 hour times so that
  10095. * it always has 2 digits. For
  10096. * 12 hour times it ensures that
  10097. * hour 0 is formatted as '12'.
  10098. */
  10099. const getFormattedHour = (hour, hourCycle) => {
  10100. /**
  10101. * Midnight for h11 starts at 0:00am
  10102. * Midnight for h12 starts at 12:00am
  10103. * Midnight for h23 starts at 00:00
  10104. * Midnight for h24 starts at 24:00
  10105. */
  10106. if (hour === 0) {
  10107. switch (hourCycle) {
  10108. case 'h11':
  10109. return '0';
  10110. case 'h12':
  10111. return '12';
  10112. case 'h23':
  10113. return '00';
  10114. case 'h24':
  10115. return '24';
  10116. default:
  10117. throw new Error(`Invalid hour cycle "${hourCycle}"`);
  10118. }
  10119. }
  10120. const use24Hour = is24Hour(hourCycle);
  10121. /**
  10122. * h23 and h24 use 24 hour times.
  10123. */
  10124. if (use24Hour) {
  10125. return addTimePadding(hour);
  10126. }
  10127. return hour.toString();
  10128. };
  10129. /**
  10130. * Generates an aria-label to be read by screen readers
  10131. * given a local, a date, and whether or not that date is
  10132. * today's date.
  10133. */
  10134. const generateDayAriaLabel = (locale, today, refParts) => {
  10135. if (refParts.day === null) {
  10136. return null;
  10137. }
  10138. /**
  10139. * MM/DD/YYYY will return midnight in the user's timezone.
  10140. */
  10141. const date = getNormalizedDate(refParts);
  10142. const labelString = new Intl.DateTimeFormat(locale, {
  10143. weekday: 'long',
  10144. month: 'long',
  10145. day: 'numeric',
  10146. timeZone: 'UTC',
  10147. }).format(date);
  10148. /**
  10149. * If date is today, prepend "Today" so screen readers indicate
  10150. * that the date is today.
  10151. */
  10152. return today ? `Today, ${labelString}` : labelString;
  10153. };
  10154. /**
  10155. * Given a locale and a date object,
  10156. * return a formatted string that includes
  10157. * the month name and full year.
  10158. * Example: May 2021
  10159. */
  10160. const getMonthAndYear = (locale, refParts) => {
  10161. const date = getNormalizedDate(refParts);
  10162. return new Intl.DateTimeFormat(locale, { month: 'long', year: 'numeric', timeZone: 'UTC' }).format(date);
  10163. };
  10164. /**
  10165. * Given a locale and a date object,
  10166. * return a formatted string that includes
  10167. * the numeric day.
  10168. * Note: Some languages will add literal characters
  10169. * to the end. This function removes those literals.
  10170. * Example: 29
  10171. */
  10172. const getDay = (locale, refParts) => {
  10173. return getLocalizedDateTimeParts(locale, refParts, { day: 'numeric' }).find((obj) => obj.type === 'day').value;
  10174. };
  10175. /**
  10176. * Given a locale and a date object,
  10177. * return a formatted string that includes
  10178. * the numeric year.
  10179. * Example: 2022
  10180. */
  10181. const getYear = (locale, refParts) => {
  10182. return getLocalizedDateTime(locale, refParts, { year: 'numeric' });
  10183. };
  10184. /**
  10185. * Given reference parts, return a JS Date object
  10186. * with a normalized time.
  10187. */
  10188. const getNormalizedDate = (refParts) => {
  10189. var _a, _b, _c;
  10190. const timeString = refParts.hour !== undefined && refParts.minute !== undefined ? ` ${refParts.hour}:${refParts.minute}` : '';
  10191. /**
  10192. * We use / notation here for the date
  10193. * so we do not need to do extra work and pad values with zeroes.
  10194. * Values such as YYYY-MM are still valid, so
  10195. * we add fallback values so we still get
  10196. * a valid date otherwise we will pass in a string
  10197. * like "//2023". Some browsers, such as Chrome, will
  10198. * account for this and still return a valid date. However,
  10199. * this is not a consistent behavior across all browsers.
  10200. */
  10201. return new Date(`${(_a = refParts.month) !== null && _a !== void 0 ? _a : 1}/${(_b = refParts.day) !== null && _b !== void 0 ? _b : 1}/${(_c = refParts.year) !== null && _c !== void 0 ? _c : 2023}${timeString} GMT+0000`);
  10202. };
  10203. /**
  10204. * Given a locale, DatetimeParts, and options
  10205. * format the DatetimeParts according to the options
  10206. * and locale combination. This returns a string. If
  10207. * you want an array of the individual pieces
  10208. * that make up the localized date string, use
  10209. * getLocalizedDateTimeParts.
  10210. */
  10211. const getLocalizedDateTime = (locale, refParts, options) => {
  10212. const date = getNormalizedDate(refParts);
  10213. return getDateTimeFormat(locale, stripTimeZone(options)).format(date);
  10214. };
  10215. /**
  10216. * Given a locale, DatetimeParts, and options
  10217. * format the DatetimeParts according to the options
  10218. * and locale combination. This returns an array of
  10219. * each piece of the date.
  10220. */
  10221. const getLocalizedDateTimeParts = (locale, refParts, options) => {
  10222. const date = getNormalizedDate(refParts);
  10223. return getDateTimeFormat(locale, options).formatToParts(date);
  10224. };
  10225. /**
  10226. * Wrapper function for Intl.DateTimeFormat.
  10227. * Allows developers to apply an allowed format to DatetimeParts.
  10228. * This function also has built in safeguards for older browser bugs
  10229. * with Intl.DateTimeFormat.
  10230. */
  10231. const getDateTimeFormat = (locale, options) => {
  10232. return new Intl.DateTimeFormat(locale, Object.assign(Object.assign({}, options), { timeZone: 'UTC' }));
  10233. };
  10234. /**
  10235. * Gets a localized version of "Today"
  10236. * Falls back to "Today" in English for
  10237. * browsers that do not support RelativeTimeFormat.
  10238. */
  10239. const getTodayLabel = (locale) => {
  10240. if ('RelativeTimeFormat' in Intl) {
  10241. const label = new Intl.RelativeTimeFormat(locale, { numeric: 'auto' }).format(0, 'day');
  10242. return label.charAt(0).toUpperCase() + label.slice(1);
  10243. }
  10244. else {
  10245. return 'Today';
  10246. }
  10247. };
  10248. /**
  10249. * When calling toISOString(), the browser
  10250. * will convert the date to UTC time by either adding
  10251. * or subtracting the time zone offset.
  10252. * To work around this, we need to either add
  10253. * or subtract the time zone offset to the Date
  10254. * object prior to calling toISOString().
  10255. * This allows us to get an ISO string
  10256. * that is in the user's time zone.
  10257. *
  10258. * Example:
  10259. * Time zone offset is 240
  10260. * Meaning: The browser needs to add 240 minutes
  10261. * to the Date object to get UTC time.
  10262. * What Ionic does: We subtract 240 minutes
  10263. * from the Date object. The browser then adds
  10264. * 240 minutes in toISOString(). The result
  10265. * is a time that is in the user's time zone
  10266. * and not UTC.
  10267. *
  10268. * Note: Some timezones include minute adjustments
  10269. * such as 30 or 45 minutes. This is why we use setMinutes
  10270. * instead of setHours.
  10271. * Example: India Standard Time
  10272. * Timezone offset: -330 = -5.5 hours.
  10273. *
  10274. * List of timezones with 30 and 45 minute timezones:
  10275. * https://www.timeanddate.com/time/time-zones-interesting.html
  10276. */
  10277. const removeDateTzOffset = (date) => {
  10278. const tzOffset = date.getTimezoneOffset();
  10279. date.setMinutes(date.getMinutes() - tzOffset);
  10280. return date;
  10281. };
  10282. const DATE_AM = removeDateTzOffset(new Date('2022T01:00'));
  10283. const DATE_PM = removeDateTzOffset(new Date('2022T13:00'));
  10284. /**
  10285. * Formats the locale's string representation of the day period (am/pm) for a given
  10286. * ref parts day period.
  10287. *
  10288. * @param locale The locale to format the day period in.
  10289. * @param value The date string, in ISO format.
  10290. * @returns The localized day period (am/pm) representation of the given value.
  10291. */
  10292. const getLocalizedDayPeriod = (locale, dayPeriod) => {
  10293. const date = dayPeriod === 'am' ? DATE_AM : DATE_PM;
  10294. const localizedDayPeriod = new Intl.DateTimeFormat(locale, {
  10295. hour: 'numeric',
  10296. timeZone: 'UTC',
  10297. })
  10298. .formatToParts(date)
  10299. .find((part) => part.type === 'dayPeriod');
  10300. if (localizedDayPeriod) {
  10301. return localizedDayPeriod.value;
  10302. }
  10303. return getFormattedDayPeriod(dayPeriod);
  10304. };
  10305. /**
  10306. * Formats the datetime's value to a string, for use in the native input.
  10307. *
  10308. * @param value The value to format, either an ISO string or an array thereof.
  10309. */
  10310. const formatValue = (value) => {
  10311. return Array.isArray(value) ? value.join(',') : value;
  10312. };
  10313. /**
  10314. * Returns the current date as
  10315. * an ISO string in the user's
  10316. * time zone.
  10317. */
  10318. const getToday = () => {
  10319. /**
  10320. * ion-datetime intentionally does not
  10321. * parse time zones/do automatic time zone
  10322. * conversion when accepting user input.
  10323. * However when we get today's date string,
  10324. * we want it formatted relative to the user's
  10325. * time zone.
  10326. *
  10327. * When calling toISOString(), the browser
  10328. * will convert the date to UTC time by either adding
  10329. * or subtracting the time zone offset.
  10330. * To work around this, we need to either add
  10331. * or subtract the time zone offset to the Date
  10332. * object prior to calling toISOString().
  10333. * This allows us to get an ISO string
  10334. * that is in the user's time zone.
  10335. */
  10336. return removeDateTzOffset(new Date()).toISOString();
  10337. };
  10338. const minutes = [
  10339. 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
  10340. 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59,
  10341. ];
  10342. // h11 hour system uses 0-11. Midnight starts at 0:00am.
  10343. const hour11 = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];
  10344. // h12 hour system uses 0-12. Midnight starts at 12:00am.
  10345. const hour12 = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];
  10346. // h23 hour system uses 0-23. Midnight starts at 0:00.
  10347. const hour23 = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23];
  10348. // h24 hour system uses 1-24. Midnight starts at 24:00.
  10349. const hour24 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 0];
  10350. /**
  10351. * Given a locale and a mode,
  10352. * return an array with formatted days
  10353. * of the week. iOS should display days
  10354. * such as "Mon" or "Tue".
  10355. * MD should display days such as "M"
  10356. * or "T".
  10357. */
  10358. const getDaysOfWeek = (locale, mode, firstDayOfWeek = 0) => {
  10359. /**
  10360. * Nov 1st, 2020 starts on a Sunday.
  10361. * ion-datetime assumes weeks start on Sunday,
  10362. * but is configurable via `firstDayOfWeek`.
  10363. */
  10364. const weekdayFormat = mode === 'ios' ? 'short' : 'narrow';
  10365. const intl = new Intl.DateTimeFormat(locale, { weekday: weekdayFormat });
  10366. const startDate = new Date('11/01/2020');
  10367. const daysOfWeek = [];
  10368. /**
  10369. * For each day of the week,
  10370. * get the day name.
  10371. */
  10372. for (let i = firstDayOfWeek; i < firstDayOfWeek + 7; i++) {
  10373. const currentDate = new Date(startDate);
  10374. currentDate.setDate(currentDate.getDate() + i);
  10375. daysOfWeek.push(intl.format(currentDate));
  10376. }
  10377. return daysOfWeek;
  10378. };
  10379. /**
  10380. * Returns an array containing all of the
  10381. * days in a month for a given year. Values are
  10382. * aligned with a week calendar starting on
  10383. * the firstDayOfWeek value (Sunday by default)
  10384. * using null values.
  10385. */
  10386. const getDaysOfMonth = (month, year, firstDayOfWeek) => {
  10387. const numDays = getNumDaysInMonth(month, year);
  10388. const firstOfMonth = new Date(`${month}/1/${year}`).getDay();
  10389. /**
  10390. * To get the first day of the month aligned on the correct
  10391. * day of the week, we need to determine how many "filler" days
  10392. * to generate. These filler days as empty/disabled buttons
  10393. * that fill the space of the days of the week before the first
  10394. * of the month.
  10395. *
  10396. * There are two cases here:
  10397. *
  10398. * 1. If firstOfMonth = 4, firstDayOfWeek = 0 then the offset
  10399. * is (4 - (0 + 1)) = 3. Since the offset loop goes from 0 to 3 inclusive,
  10400. * this will generate 4 filler days (0, 1, 2, 3), and then day of week 4 will have
  10401. * the first day of the month.
  10402. *
  10403. * 2. If firstOfMonth = 2, firstDayOfWeek = 4 then the offset
  10404. * is (6 - (4 - 2)) = 4. Since the offset loop goes from 0 to 4 inclusive,
  10405. * this will generate 5 filler days (0, 1, 2, 3, 4), and then day of week 5 will have
  10406. * the first day of the month.
  10407. */
  10408. const offset = firstOfMonth >= firstDayOfWeek ? firstOfMonth - (firstDayOfWeek + 1) : 6 - (firstDayOfWeek - firstOfMonth);
  10409. let days = [];
  10410. for (let i = 1; i <= numDays; i++) {
  10411. days.push({ day: i, dayOfWeek: (offset + i) % 7 });
  10412. }
  10413. for (let i = 0; i <= offset; i++) {
  10414. days = [{ day: null, dayOfWeek: null }, ...days];
  10415. }
  10416. return days;
  10417. };
  10418. /**
  10419. * Returns an array of pre-defined hour
  10420. * values based on the provided hourCycle.
  10421. */
  10422. const getHourData = (hourCycle) => {
  10423. switch (hourCycle) {
  10424. case 'h11':
  10425. return hour11;
  10426. case 'h12':
  10427. return hour12;
  10428. case 'h23':
  10429. return hour23;
  10430. case 'h24':
  10431. return hour24;
  10432. default:
  10433. throw new Error(`Invalid hour cycle "${hourCycle}"`);
  10434. }
  10435. };
  10436. /**
  10437. * Given a local, reference datetime parts and option
  10438. * max/min bound datetime parts, calculate the acceptable
  10439. * hour and minute values according to the bounds and locale.
  10440. */
  10441. const generateTime = (locale, refParts, hourCycle = 'h12', minParts, maxParts, hourValues, minuteValues) => {
  10442. const computedHourCycle = getHourCycle(locale, hourCycle);
  10443. const use24Hour = is24Hour(computedHourCycle);
  10444. let processedHours = getHourData(computedHourCycle);
  10445. let processedMinutes = minutes;
  10446. let isAMAllowed = true;
  10447. let isPMAllowed = true;
  10448. if (hourValues) {
  10449. processedHours = processedHours.filter((hour) => hourValues.includes(hour));
  10450. }
  10451. if (minuteValues) {
  10452. processedMinutes = processedMinutes.filter((minute) => minuteValues.includes(minute));
  10453. }
  10454. if (minParts) {
  10455. /**
  10456. * If ref day is the same as the
  10457. * minimum allowed day, filter hour/minute
  10458. * values according to min hour and minute.
  10459. */
  10460. if (isSameDay(refParts, minParts)) {
  10461. /**
  10462. * Users may not always set the hour/minute for
  10463. * min value (i.e. 2021-06-02) so we should allow
  10464. * all hours/minutes in that case.
  10465. */
  10466. if (minParts.hour !== undefined) {
  10467. processedHours = processedHours.filter((hour) => {
  10468. const convertedHour = refParts.ampm === 'pm' ? (hour + 12) % 24 : hour;
  10469. return (use24Hour ? hour : convertedHour) >= minParts.hour;
  10470. });
  10471. isAMAllowed = minParts.hour < 13;
  10472. }
  10473. if (minParts.minute !== undefined) {
  10474. /**
  10475. * The minimum minute range should not be enforced when
  10476. * the hour is greater than the min hour.
  10477. *
  10478. * For example with a minimum range of 09:30, users
  10479. * should be able to select 10:00-10:29 and beyond.
  10480. */
  10481. let isPastMinHour = false;
  10482. if (minParts.hour !== undefined && refParts.hour !== undefined) {
  10483. if (refParts.hour > minParts.hour) {
  10484. isPastMinHour = true;
  10485. }
  10486. }
  10487. processedMinutes = processedMinutes.filter((minute) => {
  10488. if (isPastMinHour) {
  10489. return true;
  10490. }
  10491. return minute >= minParts.minute;
  10492. });
  10493. }
  10494. /**
  10495. * If ref day is before minimum
  10496. * day do not render any hours/minute values
  10497. */
  10498. }
  10499. else if (isBefore(refParts, minParts)) {
  10500. processedHours = [];
  10501. processedMinutes = [];
  10502. isAMAllowed = isPMAllowed = false;
  10503. }
  10504. }
  10505. if (maxParts) {
  10506. /**
  10507. * If ref day is the same as the
  10508. * maximum allowed day, filter hour/minute
  10509. * values according to max hour and minute.
  10510. */
  10511. if (isSameDay(refParts, maxParts)) {
  10512. /**
  10513. * Users may not always set the hour/minute for
  10514. * max value (i.e. 2021-06-02) so we should allow
  10515. * all hours/minutes in that case.
  10516. */
  10517. if (maxParts.hour !== undefined) {
  10518. processedHours = processedHours.filter((hour) => {
  10519. const convertedHour = refParts.ampm === 'pm' ? (hour + 12) % 24 : hour;
  10520. return (use24Hour ? hour : convertedHour) <= maxParts.hour;
  10521. });
  10522. isPMAllowed = maxParts.hour >= 12;
  10523. }
  10524. if (maxParts.minute !== undefined && refParts.hour === maxParts.hour) {
  10525. // The available minutes should only be filtered when the hour is the same as the max hour.
  10526. // For example if the max hour is 10:30 and the current hour is 10:00,
  10527. // users should be able to select 00-30 minutes.
  10528. // If the current hour is 09:00, users should be able to select 00-60 minutes.
  10529. processedMinutes = processedMinutes.filter((minute) => minute <= maxParts.minute);
  10530. }
  10531. /**
  10532. * If ref day is after minimum
  10533. * day do not render any hours/minute values
  10534. */
  10535. }
  10536. else if (isAfter(refParts, maxParts)) {
  10537. processedHours = [];
  10538. processedMinutes = [];
  10539. isAMAllowed = isPMAllowed = false;
  10540. }
  10541. }
  10542. return {
  10543. hours: processedHours,
  10544. minutes: processedMinutes,
  10545. am: isAMAllowed,
  10546. pm: isPMAllowed,
  10547. };
  10548. };
  10549. /**
  10550. * Given DatetimeParts, generate the previous,
  10551. * current, and and next months.
  10552. */
  10553. const generateMonths = (refParts, forcedDate) => {
  10554. const current = { month: refParts.month, year: refParts.year, day: refParts.day };
  10555. /**
  10556. * If we're forcing a month to appear, and it's different from the current month,
  10557. * ensure it appears by replacing the next or previous month as appropriate.
  10558. */
  10559. if (forcedDate !== undefined && (refParts.month !== forcedDate.month || refParts.year !== forcedDate.year)) {
  10560. const forced = { month: forcedDate.month, year: forcedDate.year, day: forcedDate.day };
  10561. const forcedMonthIsBefore = isBefore(forced, current);
  10562. return forcedMonthIsBefore
  10563. ? [forced, current, getNextMonth(refParts)]
  10564. : [getPreviousMonth(refParts), current, forced];
  10565. }
  10566. return [getPreviousMonth(refParts), current, getNextMonth(refParts)];
  10567. };
  10568. const getMonthColumnData = (locale, refParts, minParts, maxParts, monthValues, formatOptions = {
  10569. month: 'long',
  10570. }) => {
  10571. const { year } = refParts;
  10572. const months = [];
  10573. if (monthValues !== undefined) {
  10574. let processedMonths = monthValues;
  10575. if ((maxParts === null || maxParts === void 0 ? void 0 : maxParts.month) !== undefined) {
  10576. processedMonths = processedMonths.filter((month) => month <= maxParts.month);
  10577. }
  10578. if ((minParts === null || minParts === void 0 ? void 0 : minParts.month) !== undefined) {
  10579. processedMonths = processedMonths.filter((month) => month >= minParts.month);
  10580. }
  10581. processedMonths.forEach((processedMonth) => {
  10582. const date = new Date(`${processedMonth}/1/${year} GMT+0000`);
  10583. const monthString = new Intl.DateTimeFormat(locale, Object.assign(Object.assign({}, formatOptions), { timeZone: 'UTC' })).format(date);
  10584. months.push({ text: monthString, value: processedMonth });
  10585. });
  10586. }
  10587. else {
  10588. const maxMonth = maxParts && maxParts.year === year ? maxParts.month : 12;
  10589. const minMonth = minParts && minParts.year === year ? minParts.month : 1;
  10590. for (let i = minMonth; i <= maxMonth; i++) {
  10591. /**
  10592. *
  10593. * There is a bug on iOS 14 where
  10594. * Intl.DateTimeFormat takes into account
  10595. * the local timezone offset when formatting dates.
  10596. *
  10597. * Forcing the timezone to 'UTC' fixes the issue. However,
  10598. * we should keep this workaround as it is safer. In the event
  10599. * this breaks in another browser, we will not be impacted
  10600. * because all dates will be interpreted in UTC.
  10601. *
  10602. * Example:
  10603. * new Intl.DateTimeFormat('en-US', { month: 'long' }).format(new Date('Sat Apr 01 2006 00:00:00 GMT-0400 (EDT)')) // "March"
  10604. * new Intl.DateTimeFormat('en-US', { month: 'long', timeZone: 'UTC' }).format(new Date('Sat Apr 01 2006 00:00:00 GMT-0400 (EDT)')) // "April"
  10605. *
  10606. * In certain timezones, iOS 14 shows the wrong
  10607. * date for .toUTCString(). To combat this, we
  10608. * force all of the timezones to GMT+0000 (UTC).
  10609. *
  10610. * Example:
  10611. * Time Zone: Central European Standard Time
  10612. * new Date('1/1/1992').toUTCString() // "Tue, 31 Dec 1991 23:00:00 GMT"
  10613. * new Date('1/1/1992 GMT+0000').toUTCString() // "Wed, 01 Jan 1992 00:00:00 GMT"
  10614. */
  10615. const date = new Date(`${i}/1/${year} GMT+0000`);
  10616. const monthString = new Intl.DateTimeFormat(locale, Object.assign(Object.assign({}, formatOptions), { timeZone: 'UTC' })).format(date);
  10617. months.push({ text: monthString, value: i });
  10618. }
  10619. }
  10620. return months;
  10621. };
  10622. /**
  10623. * Returns information regarding
  10624. * selectable dates (i.e 1st, 2nd, 3rd, etc)
  10625. * within a reference month.
  10626. * @param locale The locale to format the date with
  10627. * @param refParts The reference month/year to generate dates for
  10628. * @param minParts The minimum bound on the date that can be returned
  10629. * @param maxParts The maximum bound on the date that can be returned
  10630. * @param dayValues The allowed date values
  10631. * @returns Date data to be used in ion-picker-column
  10632. */
  10633. const getDayColumnData = (locale, refParts, minParts, maxParts, dayValues, formatOptions = {
  10634. day: 'numeric',
  10635. }) => {
  10636. const { month, year } = refParts;
  10637. const days = [];
  10638. /**
  10639. * If we have max/min bounds that in the same
  10640. * month/year as the refParts, we should
  10641. * use the define day as the max/min day.
  10642. * Otherwise, fallback to the max/min days in a month.
  10643. */
  10644. const numDaysInMonth = getNumDaysInMonth(month, year);
  10645. const maxDay = (maxParts === null || maxParts === void 0 ? void 0 : maxParts.day) !== null && (maxParts === null || maxParts === void 0 ? void 0 : maxParts.day) !== undefined && maxParts.year === year && maxParts.month === month
  10646. ? maxParts.day
  10647. : numDaysInMonth;
  10648. const minDay = (minParts === null || minParts === void 0 ? void 0 : minParts.day) !== null && (minParts === null || minParts === void 0 ? void 0 : minParts.day) !== undefined && minParts.year === year && minParts.month === month
  10649. ? minParts.day
  10650. : 1;
  10651. if (dayValues !== undefined) {
  10652. let processedDays = dayValues;
  10653. processedDays = processedDays.filter((day) => day >= minDay && day <= maxDay);
  10654. processedDays.forEach((processedDay) => {
  10655. const date = new Date(`${month}/${processedDay}/${year} GMT+0000`);
  10656. const dayString = new Intl.DateTimeFormat(locale, Object.assign(Object.assign({}, formatOptions), { timeZone: 'UTC' })).format(date);
  10657. days.push({ text: dayString, value: processedDay });
  10658. });
  10659. }
  10660. else {
  10661. for (let i = minDay; i <= maxDay; i++) {
  10662. const date = new Date(`${month}/${i}/${year} GMT+0000`);
  10663. const dayString = new Intl.DateTimeFormat(locale, Object.assign(Object.assign({}, formatOptions), { timeZone: 'UTC' })).format(date);
  10664. days.push({ text: dayString, value: i });
  10665. }
  10666. }
  10667. return days;
  10668. };
  10669. const getYearColumnData = (locale, refParts, minParts, maxParts, yearValues) => {
  10670. var _a, _b;
  10671. let processedYears = [];
  10672. if (yearValues !== undefined) {
  10673. processedYears = yearValues;
  10674. if ((maxParts === null || maxParts === void 0 ? void 0 : maxParts.year) !== undefined) {
  10675. processedYears = processedYears.filter((year) => year <= maxParts.year);
  10676. }
  10677. if ((minParts === null || minParts === void 0 ? void 0 : minParts.year) !== undefined) {
  10678. processedYears = processedYears.filter((year) => year >= minParts.year);
  10679. }
  10680. }
  10681. else {
  10682. const { year } = refParts;
  10683. const maxYear = (_a = maxParts === null || maxParts === void 0 ? void 0 : maxParts.year) !== null && _a !== void 0 ? _a : year;
  10684. const minYear = (_b = minParts === null || minParts === void 0 ? void 0 : minParts.year) !== null && _b !== void 0 ? _b : year - 100;
  10685. for (let i = minYear; i <= maxYear; i++) {
  10686. processedYears.push(i);
  10687. }
  10688. }
  10689. return processedYears.map((year) => ({
  10690. text: getYear(locale, { year, month: refParts.month, day: refParts.day }),
  10691. value: year,
  10692. }));
  10693. };
  10694. /**
  10695. * Given a starting date and an upper bound,
  10696. * this functions returns an array of all
  10697. * month objects in that range.
  10698. */
  10699. const getAllMonthsInRange = (currentParts, maxParts) => {
  10700. if (currentParts.month === maxParts.month && currentParts.year === maxParts.year) {
  10701. return [currentParts];
  10702. }
  10703. return [currentParts, ...getAllMonthsInRange(getNextMonth(currentParts), maxParts)];
  10704. };
  10705. /**
  10706. * Creates and returns picker items
  10707. * that represent the days in a month.
  10708. * Example: "Thu, Jun 2"
  10709. */
  10710. const getCombinedDateColumnData = (locale, todayParts, minParts, maxParts, dayValues, monthValues) => {
  10711. let items = [];
  10712. let parts = [];
  10713. /**
  10714. * Get all month objects from the min date
  10715. * to the max date. Note: Do not use getMonthColumnData
  10716. * as that function only generates dates within a
  10717. * single year.
  10718. */
  10719. let months = getAllMonthsInRange(minParts, maxParts);
  10720. /**
  10721. * Filter out any disallowed month values.
  10722. */
  10723. if (monthValues) {
  10724. months = months.filter(({ month }) => monthValues.includes(month));
  10725. }
  10726. /**
  10727. * Get all of the days in the month.
  10728. * From there, generate an array where
  10729. * each item has the month, date, and day
  10730. * of work as the text.
  10731. */
  10732. months.forEach((monthObject) => {
  10733. const referenceMonth = { month: monthObject.month, day: null, year: monthObject.year };
  10734. const monthDays = getDayColumnData(locale, referenceMonth, minParts, maxParts, dayValues, {
  10735. month: 'short',
  10736. day: 'numeric',
  10737. weekday: 'short',
  10738. });
  10739. const dateParts = [];
  10740. const dateColumnItems = [];
  10741. monthDays.forEach((dayObject) => {
  10742. const isToday = isSameDay(Object.assign(Object.assign({}, referenceMonth), { day: dayObject.value }), todayParts);
  10743. /**
  10744. * Today's date should read as "Today" (localized)
  10745. * not the actual date string
  10746. */
  10747. dateColumnItems.push({
  10748. text: isToday ? getTodayLabel(locale) : dayObject.text,
  10749. value: `${referenceMonth.year}-${referenceMonth.month}-${dayObject.value}`,
  10750. });
  10751. /**
  10752. * When selecting a date in the wheel picker
  10753. * we need access to the raw datetime parts data.
  10754. * The picker column only accepts values of
  10755. * type string or number, so we need to return
  10756. * two sets of data: A data set to be passed
  10757. * to the picker column, and a data set to
  10758. * be used to reference the raw data when
  10759. * updating the picker column value.
  10760. */
  10761. dateParts.push({
  10762. month: referenceMonth.month,
  10763. year: referenceMonth.year,
  10764. day: dayObject.value,
  10765. });
  10766. });
  10767. parts = [...parts, ...dateParts];
  10768. items = [...items, ...dateColumnItems];
  10769. });
  10770. return {
  10771. parts,
  10772. items,
  10773. };
  10774. };
  10775. const getTimeColumnsData = (locale, refParts, hourCycle, minParts, maxParts, allowedHourValues, allowedMinuteValues) => {
  10776. const computedHourCycle = getHourCycle(locale, hourCycle);
  10777. const use24Hour = is24Hour(computedHourCycle);
  10778. const { hours, minutes, am, pm } = generateTime(locale, refParts, computedHourCycle, minParts, maxParts, allowedHourValues, allowedMinuteValues);
  10779. const hoursItems = hours.map((hour) => {
  10780. return {
  10781. text: getFormattedHour(hour, computedHourCycle),
  10782. value: getInternalHourValue(hour, use24Hour, refParts.ampm),
  10783. };
  10784. });
  10785. const minutesItems = minutes.map((minute) => {
  10786. return {
  10787. text: addTimePadding(minute),
  10788. value: minute,
  10789. };
  10790. });
  10791. const dayPeriodItems = [];
  10792. if (am && !use24Hour) {
  10793. dayPeriodItems.push({
  10794. text: getLocalizedDayPeriod(locale, 'am'),
  10795. value: 'am',
  10796. });
  10797. }
  10798. if (pm && !use24Hour) {
  10799. dayPeriodItems.push({
  10800. text: getLocalizedDayPeriod(locale, 'pm'),
  10801. value: 'pm',
  10802. });
  10803. }
  10804. return {
  10805. minutesData: minutesItems,
  10806. hoursData: hoursItems,
  10807. dayPeriodData: dayPeriodItems,
  10808. };
  10809. };
  10810. const isYearDisabled = (refYear, minParts, maxParts) => {
  10811. if (minParts && minParts.year > refYear) {
  10812. return true;
  10813. }
  10814. if (maxParts && maxParts.year < refYear) {
  10815. return true;
  10816. }
  10817. return false;
  10818. };
  10819. /**
  10820. * Returns true if a given day should
  10821. * not be interactive according to its value,
  10822. * or the max/min dates.
  10823. */
  10824. const isDayDisabled = (refParts, minParts, maxParts, dayValues) => {
  10825. /**
  10826. * If this is a filler date (i.e. padding)
  10827. * then the date is disabled.
  10828. */
  10829. if (refParts.day === null) {
  10830. return true;
  10831. }
  10832. /**
  10833. * If user passed in a list of acceptable day values
  10834. * check to make sure that the date we are looking
  10835. * at is in this array.
  10836. */
  10837. if (dayValues !== undefined && !dayValues.includes(refParts.day)) {
  10838. return true;
  10839. }
  10840. /**
  10841. * Given a min date, perform the following
  10842. * checks. If any of them are true, then the
  10843. * day should be disabled:
  10844. * 1. Is the current year < the min allowed year?
  10845. * 2. Is the current year === min allowed year,
  10846. * but the current month < the min allowed month?
  10847. * 3. Is the current year === min allowed year, the
  10848. * current month === min allow month, but the current
  10849. * day < the min allowed day?
  10850. */
  10851. if (minParts && isBefore(refParts, minParts)) {
  10852. return true;
  10853. }
  10854. /**
  10855. * Given a max date, perform the following
  10856. * checks. If any of them are true, then the
  10857. * day should be disabled:
  10858. * 1. Is the current year > the max allowed year?
  10859. * 2. Is the current year === max allowed year,
  10860. * but the current month > the max allowed month?
  10861. * 3. Is the current year === max allowed year, the
  10862. * current month === max allow month, but the current
  10863. * day > the max allowed day?
  10864. */
  10865. if (maxParts && isAfter(refParts, maxParts)) {
  10866. return true;
  10867. }
  10868. /**
  10869. * If none of these checks
  10870. * passed then the date should
  10871. * be interactive.
  10872. */
  10873. return false;
  10874. };
  10875. /**
  10876. * Given a locale, a date, the selected date(s), and today's date,
  10877. * generate the state for a given calendar day button.
  10878. */
  10879. const getCalendarDayState = (locale, refParts, activeParts, todayParts, minParts, maxParts, dayValues) => {
  10880. /**
  10881. * activeParts signals what day(s) are currently selected in the datetime.
  10882. * If multiple="true", this will be an array, but the logic in this util
  10883. * is the same whether we have one selected day or many because we're only
  10884. * calculating the state for one button. So, we treat a single activeParts value
  10885. * the same as an array of length one.
  10886. */
  10887. const activePartsArray = Array.isArray(activeParts) ? activeParts : [activeParts];
  10888. /**
  10889. * The day button is active if it is selected, or in other words, if refParts
  10890. * matches at least one selected date.
  10891. */
  10892. const isActive = activePartsArray.find((parts) => isSameDay(refParts, parts)) !== undefined;
  10893. const isToday = isSameDay(refParts, todayParts);
  10894. const disabled = isDayDisabled(refParts, minParts, maxParts, dayValues);
  10895. /**
  10896. * Note that we always return one object regardless of whether activeParts
  10897. * was an array, since we pare down to one value for isActive.
  10898. */
  10899. return {
  10900. disabled,
  10901. isActive,
  10902. isToday,
  10903. ariaSelected: isActive ? 'true' : null,
  10904. ariaLabel: generateDayAriaLabel(locale, isToday, refParts),
  10905. text: refParts.day != null ? getDay(locale, refParts) : null,
  10906. };
  10907. };
  10908. /**
  10909. * Returns `true` if the month is disabled given the
  10910. * current date value and min/max date constraints.
  10911. */
  10912. const isMonthDisabled = (refParts, { minParts, maxParts, }) => {
  10913. // If the year is disabled then the month is disabled.
  10914. if (isYearDisabled(refParts.year, minParts, maxParts)) {
  10915. return true;
  10916. }
  10917. // If the date value is before the min date, then the month is disabled.
  10918. // If the date value is after the max date, then the month is disabled.
  10919. if ((minParts && isBefore(refParts, minParts)) || (maxParts && isAfter(refParts, maxParts))) {
  10920. return true;
  10921. }
  10922. return false;
  10923. };
  10924. /**
  10925. * Given a working date, an optional minimum date range,
  10926. * and an optional maximum date range; determine if the
  10927. * previous navigation button is disabled.
  10928. */
  10929. const isPrevMonthDisabled = (refParts, minParts, maxParts) => {
  10930. const prevMonth = Object.assign(Object.assign({}, getPreviousMonth(refParts)), { day: null });
  10931. return isMonthDisabled(prevMonth, {
  10932. minParts,
  10933. maxParts,
  10934. });
  10935. };
  10936. /**
  10937. * Given a working date and a maximum date range,
  10938. * determine if the next navigation button is disabled.
  10939. */
  10940. const isNextMonthDisabled = (refParts, maxParts) => {
  10941. const nextMonth = Object.assign(Object.assign({}, getNextMonth(refParts)), { day: null });
  10942. return isMonthDisabled(nextMonth, {
  10943. maxParts,
  10944. });
  10945. };
  10946. /**
  10947. * Given the value of the highlightedDates property
  10948. * and an ISO string, return the styles to use for
  10949. * that date, or undefined if none are found.
  10950. */
  10951. const getHighlightStyles = (highlightedDates, dateIsoString, el) => {
  10952. if (Array.isArray(highlightedDates)) {
  10953. const dateStringWithoutTime = dateIsoString.split('T')[0];
  10954. const matchingHighlight = highlightedDates.find((hd) => hd.date === dateStringWithoutTime);
  10955. if (matchingHighlight) {
  10956. return {
  10957. textColor: matchingHighlight.textColor,
  10958. backgroundColor: matchingHighlight.backgroundColor,
  10959. };
  10960. }
  10961. }
  10962. else {
  10963. /**
  10964. * Wrap in a try-catch to prevent exceptions in the user's function
  10965. * from interrupting the calendar's rendering.
  10966. */
  10967. try {
  10968. return highlightedDates(dateIsoString);
  10969. }
  10970. catch (e) {
  10971. printIonError('[ion-datetime] - Exception thrown from provided `highlightedDates` callback. Please check your function and try again.', el, e);
  10972. }
  10973. }
  10974. return undefined;
  10975. };
  10976. /**
  10977. * If a time zone is provided in the format options, the rendered text could
  10978. * differ from what was selected in the Datetime, which could cause
  10979. * confusion.
  10980. */
  10981. const warnIfTimeZoneProvided = (el, formatOptions) => {
  10982. var _a, _b, _c, _d;
  10983. if (((_a = formatOptions === null || formatOptions === void 0 ? void 0 : formatOptions.date) === null || _a === void 0 ? void 0 : _a.timeZone) ||
  10984. ((_b = formatOptions === null || formatOptions === void 0 ? void 0 : formatOptions.date) === null || _b === void 0 ? void 0 : _b.timeZoneName) ||
  10985. ((_c = formatOptions === null || formatOptions === void 0 ? void 0 : formatOptions.time) === null || _c === void 0 ? void 0 : _c.timeZone) ||
  10986. ((_d = formatOptions === null || formatOptions === void 0 ? void 0 : formatOptions.time) === null || _d === void 0 ? void 0 : _d.timeZoneName)) {
  10987. printIonWarning('[ion-datetime] - "timeZone" and "timeZoneName" are not supported in "formatOptions".', el);
  10988. }
  10989. };
  10990. const checkForPresentationFormatMismatch = (el, presentation, formatOptions) => {
  10991. // formatOptions is not required
  10992. if (!formatOptions)
  10993. return;
  10994. // If formatOptions is provided, the date and/or time objects are required, depending on the presentation
  10995. switch (presentation) {
  10996. case 'date':
  10997. case 'month-year':
  10998. case 'month':
  10999. case 'year':
  11000. if (formatOptions.date === undefined) {
  11001. printIonWarning(`[ion-datetime] - The '${presentation}' presentation requires a date object in formatOptions.`, el);
  11002. }
  11003. break;
  11004. case 'time':
  11005. if (formatOptions.time === undefined) {
  11006. printIonWarning(`[ion-datetime] - The 'time' presentation requires a time object in formatOptions.`, el);
  11007. }
  11008. break;
  11009. case 'date-time':
  11010. case 'time-date':
  11011. if (formatOptions.date === undefined && formatOptions.time === undefined) {
  11012. printIonWarning(`[ion-datetime] - The '${presentation}' presentation requires either a date or time object (or both) in formatOptions.`, el);
  11013. }
  11014. break;
  11015. }
  11016. };
  11017. const datetimeIosCss = ":host{display:-ms-flexbox;display:flex;-ms-flex-flow:column;flex-flow:column;background:var(--background);overflow:hidden}:host(.datetime-size-fixed){width:auto;height:auto}:host(.datetime-size-fixed:not(.datetime-prefer-wheel)){max-width:350px}:host(.datetime-size-fixed.datetime-prefer-wheel){min-width:350px;max-width:-webkit-max-content;max-width:-moz-max-content;max-width:max-content}:host(.datetime-size-cover){width:100%}:host .calendar-body,:host .datetime-year{opacity:0}:host(:not(.datetime-ready)) .datetime-year{position:absolute;pointer-events:none}:host(.datetime-ready) .calendar-body{opacity:1}:host(.datetime-ready) .datetime-year{display:none;opacity:1}:host .wheel-order-year-first .day-column{-ms-flex-order:3;order:3;text-align:end}:host .wheel-order-year-first .month-column{-ms-flex-order:2;order:2;text-align:end}:host .wheel-order-year-first .year-column{-ms-flex-order:1;order:1;text-align:start}:host .datetime-calendar,:host .datetime-year{display:-ms-flexbox;display:flex;-ms-flex:1 1 auto;flex:1 1 auto;-ms-flex-flow:column;flex-flow:column}:host(.show-month-and-year) .datetime-year{display:-ms-flexbox;display:flex}:host(.show-month-and-year) .calendar-next-prev,:host(.show-month-and-year) .calendar-days-of-week,:host(.show-month-and-year) .calendar-body,:host(.show-month-and-year) .datetime-time{display:none}:host(.month-year-picker-open) .datetime-footer{display:none}:host(.datetime-disabled){pointer-events:none}:host(.datetime-disabled) .calendar-days-of-week,:host(.datetime-disabled) .datetime-time{opacity:0.4}:host(.datetime-readonly){pointer-events:none;}:host(.datetime-readonly) .calendar-action-buttons,:host(.datetime-readonly) .calendar-body,:host(.datetime-readonly) .datetime-year{pointer-events:initial}:host(.datetime-readonly) .calendar-day[disabled]:not(.calendar-day-constrained),:host(.datetime-readonly) .datetime-action-buttons ion-button[disabled]{opacity:1}:host .datetime-header .datetime-title{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}:host .datetime-action-buttons.has-clear-button{width:100%}:host .datetime-action-buttons ion-buttons{display:-ms-flexbox;display:flex;-ms-flex-pack:justify;justify-content:space-between}.datetime-action-buttons .datetime-action-buttons-container{display:-ms-flexbox;display:flex}:host .calendar-action-buttons{display:-ms-flexbox;display:flex;-ms-flex-pack:justify;justify-content:space-between}:host .calendar-action-buttons ion-button{--background:transparent}:host .calendar-days-of-week{display:grid;grid-template-columns:repeat(7, 1fr);text-align:center}.calendar-days-of-week .day-of-week{-webkit-margin-start:auto;margin-inline-start:auto;-webkit-margin-end:auto;margin-inline-end:auto;margin-top:0;margin-bottom:0}:host .calendar-body{display:-ms-flexbox;display:flex;-ms-flex-positive:1;flex-grow:1;-webkit-scroll-snap-type:x mandatory;-ms-scroll-snap-type:x mandatory;scroll-snap-type:x mandatory;overflow-x:scroll;overflow-y:hidden;scrollbar-width:none;outline:none}:host .calendar-body .calendar-month{display:-ms-flexbox;display:flex;-ms-flex-flow:column;flex-flow:column;scroll-snap-align:start;scroll-snap-stop:always;-ms-flex-negative:0;flex-shrink:0;width:100%}:host .calendar-body .calendar-month-disabled{scroll-snap-align:none}:host .calendar-body::-webkit-scrollbar{display:none}:host .calendar-body .calendar-month-grid{display:grid;grid-template-columns:repeat(7, 1fr)}:host .calendar-day-wrapper{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;min-width:0;min-height:0;overflow:visible}.calendar-day{border-radius:50%;-webkit-padding-start:0px;padding-inline-start:0px;-webkit-padding-end:0px;padding-inline-end:0px;padding-top:0px;padding-bottom:0px;-webkit-margin-start:0px;margin-inline-start:0px;-webkit-margin-end:0px;margin-inline-end:0px;margin-top:0px;margin-bottom:0px;display:-ms-flexbox;display:flex;position:relative;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;border:none;outline:none;background:none;color:currentColor;font-family:var(--ion-font-family, inherit);cursor:pointer;-webkit-appearance:none;-moz-appearance:none;appearance:none;z-index:0}:host .calendar-day[disabled]{pointer-events:none;opacity:0.4}.calendar-day:focus{background:rgba(var(--ion-color-base-rgb), 0.2);-webkit-box-shadow:0px 0px 0px 4px rgba(var(--ion-color-base-rgb), 0.2);box-shadow:0px 0px 0px 4px rgba(var(--ion-color-base-rgb), 0.2)}:host .datetime-time{display:-ms-flexbox;display:flex;-ms-flex-pack:justify;justify-content:space-between}:host(.datetime-presentation-time) .datetime-time{padding-left:0;padding-right:0;padding-top:0;padding-bottom:0}:host ion-popover{--height:200px}:host .time-header{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center}:host .time-body{border-radius:8px;-webkit-padding-start:12px;padding-inline-start:12px;-webkit-padding-end:12px;padding-inline-end:12px;padding-top:6px;padding-bottom:6px;display:-ms-flexbox;display:flex;border:none;background:var(--ion-color-step-300, var(--ion-background-color-step-300, #edeef0));color:var(--ion-text-color, #000);font-family:inherit;font-size:inherit;cursor:pointer;-webkit-appearance:none;-moz-appearance:none;appearance:none}:host .time-body-active{color:var(--ion-color-base)}:host(.in-item){position:static}:host(.show-month-and-year) .calendar-action-buttons .calendar-month-year-toggle{color:var(--ion-color-base)}.calendar-month-year{min-width:0}.calendar-month-year-toggle{font-family:inherit;font-size:inherit;font-style:inherit;font-weight:inherit;letter-spacing:inherit;text-decoration:inherit;text-indent:inherit;text-overflow:inherit;text-transform:inherit;text-align:inherit;white-space:inherit;color:inherit;position:relative;border:0;outline:none;background:transparent;cursor:pointer;z-index:1}.calendar-month-year-toggle::after{left:0;right:0;top:0;bottom:0;position:absolute;content:\"\";opacity:0;-webkit-transition:opacity 15ms linear, background-color 15ms linear;transition:opacity 15ms linear, background-color 15ms linear;z-index:-1}.calendar-month-year-toggle.ion-focused::after{background:currentColor}.calendar-month-year-toggle:disabled{opacity:0.3;pointer-events:none}.calendar-month-year-toggle ion-icon{-webkit-padding-start:4px;padding-inline-start:4px;-webkit-padding-end:0;padding-inline-end:0;padding-top:0;padding-bottom:0;-ms-flex-negative:0;flex-shrink:0}.calendar-month-year-toggle #toggle-wrapper{display:-ms-inline-flexbox;display:inline-flex;-ms-flex-align:center;align-items:center}ion-picker{--highlight-background:var(--wheel-highlight-background);--highlight-border-radius:var(--wheel-highlight-border-radius);--fade-background-rgb:var(--wheel-fade-background-rgb)}:host{--background:var(--ion-color-light, #f4f5f8);--background-rgb:var(--ion-color-light-rgb, 244, 245, 248);--title-color:var(--ion-color-step-600, var(--ion-text-color-step-400, #666666))}:host(.datetime-presentation-date-time:not(.datetime-prefer-wheel)),:host(.datetime-presentation-time-date:not(.datetime-prefer-wheel)),:host(.datetime-presentation-date:not(.datetime-prefer-wheel)){min-height:350px}:host .datetime-header{-webkit-padding-start:16px;padding-inline-start:16px;-webkit-padding-end:16px;padding-inline-end:16px;padding-top:16px;padding-bottom:16px;border-bottom:0.55px solid var(--ion-color-step-200, var(--ion-background-color-step-200, #cccccc));font-size:min(0.875rem, 22.4px)}:host .datetime-header .datetime-title{color:var(--title-color)}:host .datetime-header .datetime-selected-date{margin-top:10px}.calendar-month-year-toggle{-webkit-padding-start:16px;padding-inline-start:16px;-webkit-padding-end:16px;padding-inline-end:16px;padding-top:0px;padding-bottom:0px;min-height:44px;font-size:min(1rem, 25.6px);font-weight:600}.calendar-month-year-toggle.ion-focused::after{opacity:0.15}.calendar-month-year-toggle #toggle-wrapper{-webkit-margin-start:0;margin-inline-start:0;-webkit-margin-end:8px;margin-inline-end:8px;margin-top:10px;margin-bottom:10px}:host .calendar-action-buttons .calendar-month-year-toggle ion-icon,:host .calendar-action-buttons ion-buttons ion-button{color:var(--ion-color-base)}:host .calendar-action-buttons ion-buttons{padding-left:0;padding-right:0;padding-top:8px;padding-bottom:0}:host .calendar-action-buttons ion-buttons ion-button{margin-left:0;margin-right:0;margin-top:0;margin-bottom:0}:host .calendar-days-of-week{-webkit-padding-start:8px;padding-inline-start:8px;-webkit-padding-end:8px;padding-inline-end:8px;padding-top:0;padding-bottom:0;color:var(--ion-color-step-300, var(--ion-text-color-step-700, #b3b3b3));font-size:min(0.75rem, 19.2px);font-weight:600;line-height:24px;text-transform:uppercase}@supports (border-radius: mod(1px, 1px)){.calendar-days-of-week .day-of-week{width:clamp(20px, calc(mod(min(1rem, 24px), 24px) * 10), 100%);height:24px;overflow:hidden}.calendar-day{border-radius:max(8px, mod(min(1rem, 24px), 24px) * 10)}}@supports ((border-radius: mod(1px, 1px)) and (background: -webkit-named-image(apple-pay-logo-black)) and (not (contain-intrinsic-size: none))) or (not (border-radius: mod(1px, 1px))){.calendar-days-of-week .day-of-week{width:auto;height:auto;overflow:initial}.calendar-day{border-radius:32px}}:host .calendar-body .calendar-month .calendar-month-grid{-webkit-padding-start:8px;padding-inline-start:8px;-webkit-padding-end:8px;padding-inline-end:8px;padding-top:8px;padding-bottom:8px;-ms-flex-align:center;align-items:center;height:calc(100% - 16px)}:host .calendar-day-wrapper{-webkit-padding-start:4px;padding-inline-start:4px;-webkit-padding-end:4px;padding-inline-end:4px;padding-top:4px;padding-bottom:4px;height:0;min-height:1rem}:host .calendar-day{width:40px;min-width:40px;height:40px;font-size:min(1.25rem, 32px)}.calendar-day.calendar-day-active{background:rgba(var(--ion-color-base-rgb), 0.2);font-size:min(1.375rem, 35.2px)}:host .calendar-day.calendar-day-today{color:var(--ion-color-base)}:host .calendar-day.calendar-day-active{color:var(--ion-color-base);font-weight:600}:host .calendar-day.calendar-day-today.calendar-day-active{background:var(--ion-color-base);color:var(--ion-color-contrast)}:host .datetime-time{-webkit-padding-start:16px;padding-inline-start:16px;-webkit-padding-end:16px;padding-inline-end:16px;padding-top:8px;padding-bottom:16px;font-size:min(1rem, 25.6px)}:host .datetime-time .time-header{font-weight:600}:host .datetime-buttons{-webkit-padding-start:8px;padding-inline-start:8px;-webkit-padding-end:8px;padding-inline-end:8px;padding-top:8px;padding-bottom:8px;border-top:0.55px solid var(--ion-color-step-200, var(--ion-background-color-step-200, #cccccc))}:host .datetime-buttons ::slotted(ion-buttons),:host .datetime-buttons ion-buttons{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:justify;justify-content:space-between}:host .datetime-action-buttons{width:100%}";
  11018. var IonDatetimeIosStyle0 = datetimeIosCss;
  11019. const datetimeMdCss = ":host{display:-ms-flexbox;display:flex;-ms-flex-flow:column;flex-flow:column;background:var(--background);overflow:hidden}:host(.datetime-size-fixed){width:auto;height:auto}:host(.datetime-size-fixed:not(.datetime-prefer-wheel)){max-width:350px}:host(.datetime-size-fixed.datetime-prefer-wheel){min-width:350px;max-width:-webkit-max-content;max-width:-moz-max-content;max-width:max-content}:host(.datetime-size-cover){width:100%}:host .calendar-body,:host .datetime-year{opacity:0}:host(:not(.datetime-ready)) .datetime-year{position:absolute;pointer-events:none}:host(.datetime-ready) .calendar-body{opacity:1}:host(.datetime-ready) .datetime-year{display:none;opacity:1}:host .wheel-order-year-first .day-column{-ms-flex-order:3;order:3;text-align:end}:host .wheel-order-year-first .month-column{-ms-flex-order:2;order:2;text-align:end}:host .wheel-order-year-first .year-column{-ms-flex-order:1;order:1;text-align:start}:host .datetime-calendar,:host .datetime-year{display:-ms-flexbox;display:flex;-ms-flex:1 1 auto;flex:1 1 auto;-ms-flex-flow:column;flex-flow:column}:host(.show-month-and-year) .datetime-year{display:-ms-flexbox;display:flex}:host(.show-month-and-year) .calendar-next-prev,:host(.show-month-and-year) .calendar-days-of-week,:host(.show-month-and-year) .calendar-body,:host(.show-month-and-year) .datetime-time{display:none}:host(.month-year-picker-open) .datetime-footer{display:none}:host(.datetime-disabled){pointer-events:none}:host(.datetime-disabled) .calendar-days-of-week,:host(.datetime-disabled) .datetime-time{opacity:0.4}:host(.datetime-readonly){pointer-events:none;}:host(.datetime-readonly) .calendar-action-buttons,:host(.datetime-readonly) .calendar-body,:host(.datetime-readonly) .datetime-year{pointer-events:initial}:host(.datetime-readonly) .calendar-day[disabled]:not(.calendar-day-constrained),:host(.datetime-readonly) .datetime-action-buttons ion-button[disabled]{opacity:1}:host .datetime-header .datetime-title{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}:host .datetime-action-buttons.has-clear-button{width:100%}:host .datetime-action-buttons ion-buttons{display:-ms-flexbox;display:flex;-ms-flex-pack:justify;justify-content:space-between}.datetime-action-buttons .datetime-action-buttons-container{display:-ms-flexbox;display:flex}:host .calendar-action-buttons{display:-ms-flexbox;display:flex;-ms-flex-pack:justify;justify-content:space-between}:host .calendar-action-buttons ion-button{--background:transparent}:host .calendar-days-of-week{display:grid;grid-template-columns:repeat(7, 1fr);text-align:center}.calendar-days-of-week .day-of-week{-webkit-margin-start:auto;margin-inline-start:auto;-webkit-margin-end:auto;margin-inline-end:auto;margin-top:0;margin-bottom:0}:host .calendar-body{display:-ms-flexbox;display:flex;-ms-flex-positive:1;flex-grow:1;-webkit-scroll-snap-type:x mandatory;-ms-scroll-snap-type:x mandatory;scroll-snap-type:x mandatory;overflow-x:scroll;overflow-y:hidden;scrollbar-width:none;outline:none}:host .calendar-body .calendar-month{display:-ms-flexbox;display:flex;-ms-flex-flow:column;flex-flow:column;scroll-snap-align:start;scroll-snap-stop:always;-ms-flex-negative:0;flex-shrink:0;width:100%}:host .calendar-body .calendar-month-disabled{scroll-snap-align:none}:host .calendar-body::-webkit-scrollbar{display:none}:host .calendar-body .calendar-month-grid{display:grid;grid-template-columns:repeat(7, 1fr)}:host .calendar-day-wrapper{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;min-width:0;min-height:0;overflow:visible}.calendar-day{border-radius:50%;-webkit-padding-start:0px;padding-inline-start:0px;-webkit-padding-end:0px;padding-inline-end:0px;padding-top:0px;padding-bottom:0px;-webkit-margin-start:0px;margin-inline-start:0px;-webkit-margin-end:0px;margin-inline-end:0px;margin-top:0px;margin-bottom:0px;display:-ms-flexbox;display:flex;position:relative;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;border:none;outline:none;background:none;color:currentColor;font-family:var(--ion-font-family, inherit);cursor:pointer;-webkit-appearance:none;-moz-appearance:none;appearance:none;z-index:0}:host .calendar-day[disabled]{pointer-events:none;opacity:0.4}.calendar-day:focus{background:rgba(var(--ion-color-base-rgb), 0.2);-webkit-box-shadow:0px 0px 0px 4px rgba(var(--ion-color-base-rgb), 0.2);box-shadow:0px 0px 0px 4px rgba(var(--ion-color-base-rgb), 0.2)}:host .datetime-time{display:-ms-flexbox;display:flex;-ms-flex-pack:justify;justify-content:space-between}:host(.datetime-presentation-time) .datetime-time{padding-left:0;padding-right:0;padding-top:0;padding-bottom:0}:host ion-popover{--height:200px}:host .time-header{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center}:host .time-body{border-radius:8px;-webkit-padding-start:12px;padding-inline-start:12px;-webkit-padding-end:12px;padding-inline-end:12px;padding-top:6px;padding-bottom:6px;display:-ms-flexbox;display:flex;border:none;background:var(--ion-color-step-300, var(--ion-background-color-step-300, #edeef0));color:var(--ion-text-color, #000);font-family:inherit;font-size:inherit;cursor:pointer;-webkit-appearance:none;-moz-appearance:none;appearance:none}:host .time-body-active{color:var(--ion-color-base)}:host(.in-item){position:static}:host(.show-month-and-year) .calendar-action-buttons .calendar-month-year-toggle{color:var(--ion-color-base)}.calendar-month-year{min-width:0}.calendar-month-year-toggle{font-family:inherit;font-size:inherit;font-style:inherit;font-weight:inherit;letter-spacing:inherit;text-decoration:inherit;text-indent:inherit;text-overflow:inherit;text-transform:inherit;text-align:inherit;white-space:inherit;color:inherit;position:relative;border:0;outline:none;background:transparent;cursor:pointer;z-index:1}.calendar-month-year-toggle::after{left:0;right:0;top:0;bottom:0;position:absolute;content:\"\";opacity:0;-webkit-transition:opacity 15ms linear, background-color 15ms linear;transition:opacity 15ms linear, background-color 15ms linear;z-index:-1}.calendar-month-year-toggle.ion-focused::after{background:currentColor}.calendar-month-year-toggle:disabled{opacity:0.3;pointer-events:none}.calendar-month-year-toggle ion-icon{-webkit-padding-start:4px;padding-inline-start:4px;-webkit-padding-end:0;padding-inline-end:0;padding-top:0;padding-bottom:0;-ms-flex-negative:0;flex-shrink:0}.calendar-month-year-toggle #toggle-wrapper{display:-ms-inline-flexbox;display:inline-flex;-ms-flex-align:center;align-items:center}ion-picker{--highlight-background:var(--wheel-highlight-background);--highlight-border-radius:var(--wheel-highlight-border-radius);--fade-background-rgb:var(--wheel-fade-background-rgb)}:host{--background:var(--ion-color-step-100, var(--ion-background-color-step-100, #ffffff));--title-color:var(--ion-color-contrast)}:host .datetime-header{-webkit-padding-start:20px;padding-inline-start:20px;-webkit-padding-end:20px;padding-inline-end:20px;padding-top:20px;padding-bottom:20px;background:var(--ion-color-base);color:var(--title-color)}:host .datetime-header .datetime-title{font-size:0.75rem;text-transform:uppercase}:host .datetime-header .datetime-selected-date{margin-top:30px;font-size:2.125rem}:host .calendar-action-buttons ion-button{--color:var(--ion-color-step-650, var(--ion-text-color-step-350, #595959))}.calendar-month-year-toggle{-webkit-padding-start:20px;padding-inline-start:20px;-webkit-padding-end:16px;padding-inline-end:16px;padding-top:12px;padding-bottom:12px;min-height:48px;background:transparent;color:var(--ion-color-step-650, var(--ion-text-color-step-350, #595959));z-index:1}.calendar-month-year-toggle.ion-focused::after{opacity:0.04}.calendar-month-year-toggle ion-ripple-effect{color:currentColor}@media (any-hover: hover){.calendar-month-year-toggle.ion-activatable:not(.ion-focused):hover::after{background:currentColor;opacity:0.04}}:host .calendar-days-of-week{-webkit-padding-start:10px;padding-inline-start:10px;-webkit-padding-end:10px;padding-inline-end:10px;padding-top:0px;padding-bottom:0px;color:var(--ion-color-step-500, var(--ion-text-color-step-500, gray));font-size:0.875rem;line-height:36px}:host .calendar-body .calendar-month .calendar-month-grid{-webkit-padding-start:10px;padding-inline-start:10px;-webkit-padding-end:10px;padding-inline-end:10px;padding-top:4px;padding-bottom:4px;grid-template-rows:repeat(6, 1fr)}:host .calendar-day{width:42px;min-width:42px;height:42px;font-size:0.875rem}:host .calendar-day.calendar-day-today{border:1px solid var(--ion-color-base);color:var(--ion-color-base)}:host .calendar-day.calendar-day-active{color:var(--ion-color-contrast)}.calendar-day.calendar-day-active{border:1px solid var(--ion-color-base);background:var(--ion-color-base)}:host .datetime-time{-webkit-padding-start:16px;padding-inline-start:16px;-webkit-padding-end:16px;padding-inline-end:16px;padding-top:8px;padding-bottom:8px}:host .time-header{color:var(--ion-color-step-650, var(--ion-text-color-step-350, #595959))}:host(.datetime-presentation-month) .datetime-year,:host(.datetime-presentation-year) .datetime-year,:host(.datetime-presentation-month-year) .datetime-year{margin-top:20px;margin-bottom:20px}:host .datetime-buttons{-webkit-padding-start:10px;padding-inline-start:10px;-webkit-padding-end:10px;padding-inline-end:10px;padding-top:10px;padding-bottom:10px;display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:end;justify-content:flex-end}";
  11020. var IonDatetimeMdStyle0 = datetimeMdCss;
  11021. /**
  11022. * @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
  11023. *
  11024. * @slot title - The title of the datetime.
  11025. * @slot buttons - The buttons in the datetime.
  11026. * @slot time-label - The label for the time selector in the datetime.
  11027. *
  11028. * @part wheel-item - The individual items when using a wheel style layout, or in the
  11029. * month/year picker when using a grid style layout.
  11030. * @part wheel-item active - The currently selected wheel-item.
  11031. *
  11032. * @part time-button - The button that opens the time picker when using a grid style
  11033. * layout with `presentation="date-time"` or `"time-date"`.
  11034. * @part time-button active - The time picker button when the picker is open.
  11035. *
  11036. * @part month-year-button - The button that opens the month/year picker when
  11037. * using a grid style layout.
  11038. *
  11039. * @part calendar-day - The individual buttons that display a day inside of the datetime
  11040. * calendar.
  11041. * @part calendar-day active - The currently selected calendar day.
  11042. * @part calendar-day today - The calendar day that contains the current day.
  11043. * @part calendar-day disabled - The calendar day that is disabled.
  11044. */
  11045. class Datetime {
  11046. constructor(hostRef) {
  11047. registerInstance(this, hostRef);
  11048. this.ionCancel = createEvent(this, "ionCancel", 7);
  11049. this.ionChange = createEvent(this, "ionChange", 7);
  11050. this.ionValueChange = createEvent(this, "ionValueChange", 7);
  11051. this.ionFocus = createEvent(this, "ionFocus", 7);
  11052. this.ionBlur = createEvent(this, "ionBlur", 7);
  11053. this.ionStyle = createEvent(this, "ionStyle", 7);
  11054. this.ionRender = createEvent(this, "ionRender", 7);
  11055. this.inputId = `ion-dt-${datetimeIds++}`;
  11056. this.prevPresentation = null;
  11057. this.warnIfIncorrectValueUsage = () => {
  11058. const { multiple, value } = this;
  11059. if (!multiple && Array.isArray(value)) {
  11060. /**
  11061. * We do some processing on the `value` array so
  11062. * that it looks more like an array when logged to
  11063. * the console.
  11064. * Example given ['a', 'b']
  11065. * Default toString() behavior: a,b
  11066. * Custom behavior: ['a', 'b']
  11067. */
  11068. printIonWarning(`[ion-datetime] - An array of values was passed, but multiple is "false". This is incorrect usage and may result in unexpected behaviors. To dismiss this warning, pass a string to the "value" property when multiple="false".
  11069. Value Passed: [${value.map((v) => `'${v}'`).join(', ')}]
  11070. `, this.el);
  11071. }
  11072. };
  11073. this.setValue = (value) => {
  11074. this.value = value;
  11075. this.ionChange.emit({ value });
  11076. };
  11077. /**
  11078. * Returns the DatetimePart interface
  11079. * to use when rendering an initial set of
  11080. * data. This should be used when rendering an
  11081. * interface in an environment where the `value`
  11082. * may not be set. This function works
  11083. * by returning the first selected date and then
  11084. * falling back to defaultParts if no active date
  11085. * is selected.
  11086. */
  11087. this.getActivePartsWithFallback = () => {
  11088. var _a;
  11089. const { defaultParts } = this;
  11090. return (_a = this.getActivePart()) !== null && _a !== void 0 ? _a : defaultParts;
  11091. };
  11092. this.getActivePart = () => {
  11093. const { activeParts } = this;
  11094. return Array.isArray(activeParts) ? activeParts[0] : activeParts;
  11095. };
  11096. this.closeParentOverlay = (role) => {
  11097. const popoverOrModal = this.el.closest('ion-modal, ion-popover');
  11098. if (popoverOrModal) {
  11099. popoverOrModal.dismiss(undefined, role);
  11100. }
  11101. };
  11102. this.setWorkingParts = (parts) => {
  11103. this.workingParts = Object.assign({}, parts);
  11104. };
  11105. this.setActiveParts = (parts, removeDate = false) => {
  11106. /** if the datetime component is in readonly mode,
  11107. * allow browsing of the calendar without changing
  11108. * the set value
  11109. */
  11110. if (this.readonly) {
  11111. return;
  11112. }
  11113. const { multiple, minParts, maxParts, activeParts } = this;
  11114. /**
  11115. * When setting the active parts, it is possible
  11116. * to set invalid data. For example,
  11117. * when updating January 31 to February,
  11118. * February 31 does not exist. As a result
  11119. * we need to validate the active parts and
  11120. * ensure that we are only setting valid dates.
  11121. * Additionally, we need to update the working parts
  11122. * too in the event that the validated parts are different.
  11123. */
  11124. const validatedParts = validateParts(parts, minParts, maxParts);
  11125. this.setWorkingParts(validatedParts);
  11126. if (multiple) {
  11127. const activePartsArray = Array.isArray(activeParts) ? activeParts : [activeParts];
  11128. if (removeDate) {
  11129. this.activeParts = activePartsArray.filter((p) => !isSameDay(p, validatedParts));
  11130. }
  11131. else {
  11132. this.activeParts = [...activePartsArray, validatedParts];
  11133. }
  11134. }
  11135. else {
  11136. this.activeParts = Object.assign({}, validatedParts);
  11137. }
  11138. const hasSlottedButtons = this.el.querySelector('[slot="buttons"]') !== null;
  11139. if (hasSlottedButtons || this.showDefaultButtons) {
  11140. return;
  11141. }
  11142. this.confirm();
  11143. };
  11144. this.initializeKeyboardListeners = () => {
  11145. const calendarBodyRef = this.calendarBodyRef;
  11146. if (!calendarBodyRef) {
  11147. return;
  11148. }
  11149. const root = this.el.shadowRoot;
  11150. /**
  11151. * Get a reference to the month
  11152. * element we are currently viewing.
  11153. */
  11154. const currentMonth = calendarBodyRef.querySelector('.calendar-month:nth-of-type(2)');
  11155. /**
  11156. * When focusing the calendar body, we want to pass focus
  11157. * to the working day, but other days should
  11158. * only be accessible using the arrow keys. Pressing
  11159. * Tab should jump between bodies of selectable content.
  11160. */
  11161. const checkCalendarBodyFocus = (ev) => {
  11162. var _a;
  11163. const record = ev[0];
  11164. /**
  11165. * If calendar body was already focused
  11166. * when this fired or if the calendar body
  11167. * if not currently focused, we should not re-focus
  11168. * the inner day.
  11169. */
  11170. if (((_a = record.oldValue) === null || _a === void 0 ? void 0 : _a.includes('ion-focused')) || !calendarBodyRef.classList.contains('ion-focused')) {
  11171. return;
  11172. }
  11173. this.focusWorkingDay(currentMonth);
  11174. };
  11175. const mo = new MutationObserver(checkCalendarBodyFocus);
  11176. mo.observe(calendarBodyRef, { attributeFilter: ['class'], attributeOldValue: true });
  11177. this.destroyKeyboardMO = () => {
  11178. mo === null || mo === void 0 ? void 0 : mo.disconnect();
  11179. };
  11180. /**
  11181. * We must use keydown not keyup as we want
  11182. * to prevent scrolling when using the arrow keys.
  11183. */
  11184. calendarBodyRef.addEventListener('keydown', (ev) => {
  11185. const activeElement = root.activeElement;
  11186. if (!activeElement || !activeElement.classList.contains('calendar-day')) {
  11187. return;
  11188. }
  11189. const parts = getPartsFromCalendarDay(activeElement);
  11190. let partsToFocus;
  11191. switch (ev.key) {
  11192. case 'ArrowDown':
  11193. ev.preventDefault();
  11194. partsToFocus = getNextWeek(parts);
  11195. break;
  11196. case 'ArrowUp':
  11197. ev.preventDefault();
  11198. partsToFocus = getPreviousWeek(parts);
  11199. break;
  11200. case 'ArrowRight':
  11201. ev.preventDefault();
  11202. partsToFocus = getNextDay(parts);
  11203. break;
  11204. case 'ArrowLeft':
  11205. ev.preventDefault();
  11206. partsToFocus = getPreviousDay(parts);
  11207. break;
  11208. case 'Home':
  11209. ev.preventDefault();
  11210. partsToFocus = getStartOfWeek(parts);
  11211. break;
  11212. case 'End':
  11213. ev.preventDefault();
  11214. partsToFocus = getEndOfWeek(parts);
  11215. break;
  11216. case 'PageUp':
  11217. ev.preventDefault();
  11218. partsToFocus = ev.shiftKey ? getPreviousYear(parts) : getPreviousMonth(parts);
  11219. break;
  11220. case 'PageDown':
  11221. ev.preventDefault();
  11222. partsToFocus = ev.shiftKey ? getNextYear(parts) : getNextMonth(parts);
  11223. break;
  11224. /**
  11225. * Do not preventDefault here
  11226. * as we do not want to override other
  11227. * browser defaults such as pressing Enter/Space
  11228. * to select a day.
  11229. */
  11230. default:
  11231. return;
  11232. }
  11233. /**
  11234. * If the day we want to move focus to is
  11235. * disabled, do not do anything.
  11236. */
  11237. if (isDayDisabled(partsToFocus, this.minParts, this.maxParts)) {
  11238. return;
  11239. }
  11240. this.setWorkingParts(Object.assign(Object.assign({}, this.workingParts), partsToFocus));
  11241. /**
  11242. * Give view a chance to re-render
  11243. * then move focus to the new working day
  11244. */
  11245. requestAnimationFrame(() => this.focusWorkingDay(currentMonth));
  11246. });
  11247. };
  11248. this.focusWorkingDay = (currentMonth) => {
  11249. /**
  11250. * Get the number of padding days so
  11251. * we know how much to offset our next selector by
  11252. * to grab the correct calendar-day element.
  11253. */
  11254. const padding = currentMonth.querySelectorAll('.calendar-day-padding');
  11255. const { day } = this.workingParts;
  11256. if (day === null) {
  11257. return;
  11258. }
  11259. /**
  11260. * Get the calendar day element
  11261. * and focus it.
  11262. */
  11263. const dayEl = currentMonth.querySelector(`.calendar-day-wrapper:nth-of-type(${padding.length + day}) .calendar-day`);
  11264. if (dayEl) {
  11265. dayEl.focus();
  11266. }
  11267. };
  11268. this.processMinParts = () => {
  11269. const { min, defaultParts } = this;
  11270. if (min === undefined) {
  11271. this.minParts = undefined;
  11272. return;
  11273. }
  11274. this.minParts = parseMinParts(min, defaultParts);
  11275. };
  11276. this.processMaxParts = () => {
  11277. const { max, defaultParts } = this;
  11278. if (max === undefined) {
  11279. this.maxParts = undefined;
  11280. return;
  11281. }
  11282. this.maxParts = parseMaxParts(max, defaultParts);
  11283. };
  11284. this.initializeCalendarListener = () => {
  11285. const calendarBodyRef = this.calendarBodyRef;
  11286. if (!calendarBodyRef) {
  11287. return;
  11288. }
  11289. /**
  11290. * For performance reasons, we only render 3
  11291. * months at a time: The current month, the previous
  11292. * month, and the next month. We have a scroll listener
  11293. * on the calendar body to append/prepend new months.
  11294. *
  11295. * We can do this because Stencil is smart enough to not
  11296. * re-create the .calendar-month containers, but rather
  11297. * update the content within those containers.
  11298. *
  11299. * As an added bonus, WebKit has some troubles with
  11300. * scroll-snap-stop: always, so not rendering all of
  11301. * the months in a row allows us to mostly sidestep
  11302. * that issue.
  11303. */
  11304. const months = calendarBodyRef.querySelectorAll('.calendar-month');
  11305. const startMonth = months[0];
  11306. const workingMonth = months[1];
  11307. const endMonth = months[2];
  11308. const mode = getIonMode$1(this);
  11309. const needsiOSRubberBandFix = mode === 'ios' && typeof navigator !== 'undefined' && navigator.maxTouchPoints > 1;
  11310. /**
  11311. * Before setting up the scroll listener,
  11312. * scroll the middle month into view.
  11313. * scrollIntoView() will scroll entire page
  11314. * if element is not in viewport. Use scrollLeft instead.
  11315. */
  11316. writeTask(() => {
  11317. calendarBodyRef.scrollLeft = startMonth.clientWidth * (isRTL$1(this.el) ? -1 : 1);
  11318. const getChangedMonth = (parts) => {
  11319. const box = calendarBodyRef.getBoundingClientRect();
  11320. /**
  11321. * If the current scroll position is all the way to the left
  11322. * then we have scrolled to the previous month.
  11323. * Otherwise, assume that we have scrolled to the next
  11324. * month. We have a tolerance of 2px to account for
  11325. * sub pixel rendering.
  11326. *
  11327. * Check below the next line ensures that we did not
  11328. * swipe and abort (i.e. we swiped but we are still on the current month).
  11329. */
  11330. const condition = isRTL$1(this.el) ? calendarBodyRef.scrollLeft >= -2 : calendarBodyRef.scrollLeft <= 2;
  11331. const month = condition ? startMonth : endMonth;
  11332. /**
  11333. * The edge of the month must be lined up with
  11334. * the edge of the calendar body in order for
  11335. * the component to update. Otherwise, it
  11336. * may be the case that the user has paused their
  11337. * swipe or the browser has not finished snapping yet.
  11338. * Rather than check if the x values are equal,
  11339. * we give it a tolerance of 2px to account for
  11340. * sub pixel rendering.
  11341. */
  11342. const monthBox = month.getBoundingClientRect();
  11343. if (Math.abs(monthBox.x - box.x) > 2)
  11344. return;
  11345. /**
  11346. * If we're force-rendering a month, assume we've
  11347. * scrolled to that and return it.
  11348. *
  11349. * If forceRenderDate is ever used in a context where the
  11350. * forced month is not immediately auto-scrolled to, this
  11351. * should be updated to also check whether `month` has the
  11352. * same month and year as the forced date.
  11353. */
  11354. const { forceRenderDate } = this;
  11355. if (forceRenderDate !== undefined) {
  11356. return { month: forceRenderDate.month, year: forceRenderDate.year, day: forceRenderDate.day };
  11357. }
  11358. /**
  11359. * From here, we can determine if the start
  11360. * month or the end month was scrolled into view.
  11361. * If no month was changed, then we can return from
  11362. * the scroll callback early.
  11363. */
  11364. if (month === startMonth) {
  11365. return getPreviousMonth(parts);
  11366. }
  11367. else if (month === endMonth) {
  11368. return getNextMonth(parts);
  11369. }
  11370. else {
  11371. return;
  11372. }
  11373. };
  11374. const updateActiveMonth = () => {
  11375. if (needsiOSRubberBandFix) {
  11376. calendarBodyRef.style.removeProperty('pointer-events');
  11377. appliediOSRubberBandFix = false;
  11378. }
  11379. /**
  11380. * If the month did not change
  11381. * then we can return early.
  11382. */
  11383. const newDate = getChangedMonth(this.workingParts);
  11384. if (!newDate)
  11385. return;
  11386. const { month, day, year } = newDate;
  11387. if (isMonthDisabled({ month, year, day: null }, {
  11388. minParts: Object.assign(Object.assign({}, this.minParts), { day: null }),
  11389. maxParts: Object.assign(Object.assign({}, this.maxParts), { day: null }),
  11390. })) {
  11391. return;
  11392. }
  11393. /**
  11394. * Prevent scrolling for other browsers
  11395. * to give the DOM time to update and the container
  11396. * time to properly snap.
  11397. */
  11398. calendarBodyRef.style.setProperty('overflow', 'hidden');
  11399. /**
  11400. * Use a writeTask here to ensure
  11401. * that the state is updated and the
  11402. * correct month is scrolled into view
  11403. * in the same frame. This is not
  11404. * typically a problem on newer devices
  11405. * but older/slower device may have a flicker
  11406. * if we did not do this.
  11407. */
  11408. writeTask(() => {
  11409. this.setWorkingParts(Object.assign(Object.assign({}, this.workingParts), { month, day: day, year }));
  11410. calendarBodyRef.scrollLeft = workingMonth.clientWidth * (isRTL$1(this.el) ? -1 : 1);
  11411. calendarBodyRef.style.removeProperty('overflow');
  11412. if (this.resolveForceDateScrolling) {
  11413. this.resolveForceDateScrolling();
  11414. }
  11415. });
  11416. };
  11417. /**
  11418. * When the container finishes scrolling we
  11419. * need to update the DOM with the selected month.
  11420. */
  11421. let scrollTimeout;
  11422. /**
  11423. * We do not want to attempt to set pointer-events
  11424. * multiple times within a single swipe gesture as
  11425. * that adds unnecessary work to the main thread.
  11426. */
  11427. let appliediOSRubberBandFix = false;
  11428. const scrollCallback = () => {
  11429. if (scrollTimeout) {
  11430. clearTimeout(scrollTimeout);
  11431. }
  11432. /**
  11433. * On iOS it is possible to quickly rubber band
  11434. * the scroll area before the scroll timeout has fired.
  11435. * This results in users reaching the end of the scrollable
  11436. * container before the DOM has updated.
  11437. * By setting `pointer-events: none` we can ensure that
  11438. * subsequent swipes do not happen while the container
  11439. * is snapping.
  11440. */
  11441. if (!appliediOSRubberBandFix && needsiOSRubberBandFix) {
  11442. calendarBodyRef.style.setProperty('pointer-events', 'none');
  11443. appliediOSRubberBandFix = true;
  11444. }
  11445. // Wait ~3 frames
  11446. scrollTimeout = setTimeout(updateActiveMonth, 50);
  11447. };
  11448. calendarBodyRef.addEventListener('scroll', scrollCallback);
  11449. this.destroyCalendarListener = () => {
  11450. calendarBodyRef.removeEventListener('scroll', scrollCallback);
  11451. };
  11452. });
  11453. };
  11454. /**
  11455. * Clean up all listeners except for the overlay
  11456. * listener. This is so that we can re-create the listeners
  11457. * if the datetime has been hidden/presented by a modal or popover.
  11458. */
  11459. this.destroyInteractionListeners = () => {
  11460. const { destroyCalendarListener, destroyKeyboardMO } = this;
  11461. if (destroyCalendarListener !== undefined) {
  11462. destroyCalendarListener();
  11463. }
  11464. if (destroyKeyboardMO !== undefined) {
  11465. destroyKeyboardMO();
  11466. }
  11467. };
  11468. this.processValue = (value) => {
  11469. const hasValue = value !== null && value !== undefined && value !== '' && (!Array.isArray(value) || value.length > 0);
  11470. const valueToProcess = hasValue ? parseDate(value) : this.defaultParts;
  11471. const { minParts, maxParts, workingParts, el } = this;
  11472. this.warnIfIncorrectValueUsage();
  11473. /**
  11474. * Return early if the value wasn't parsed correctly, such as
  11475. * if an improperly formatted date string was provided.
  11476. */
  11477. if (!valueToProcess) {
  11478. return;
  11479. }
  11480. /**
  11481. * Datetime should only warn of out of bounds values
  11482. * if set by the user. If the `value` is undefined,
  11483. * we will default to today's date which may be out
  11484. * of bounds. In this case, the warning makes it look
  11485. * like the developer did something wrong which is
  11486. * not true.
  11487. */
  11488. if (hasValue) {
  11489. warnIfValueOutOfBounds(valueToProcess, minParts, maxParts);
  11490. }
  11491. /**
  11492. * If there are multiple values, pick an arbitrary one to clamp to. This way,
  11493. * if the values are across months, we always show at least one of them. Note
  11494. * that the values don't necessarily have to be in order.
  11495. */
  11496. const singleValue = Array.isArray(valueToProcess) ? valueToProcess[0] : valueToProcess;
  11497. const targetValue = clampDate(singleValue, minParts, maxParts);
  11498. const { month, day, year, hour, minute } = targetValue;
  11499. const ampm = parseAmPm(hour);
  11500. /**
  11501. * Since `activeParts` indicates a value that
  11502. * been explicitly selected either by the
  11503. * user or the app, only update `activeParts`
  11504. * if the `value` property is set.
  11505. */
  11506. if (hasValue) {
  11507. if (Array.isArray(valueToProcess)) {
  11508. this.activeParts = [...valueToProcess];
  11509. }
  11510. else {
  11511. this.activeParts = {
  11512. month,
  11513. day,
  11514. year,
  11515. hour,
  11516. minute,
  11517. ampm,
  11518. };
  11519. }
  11520. }
  11521. else {
  11522. /**
  11523. * Reset the active parts if the value is not set.
  11524. * This will clear the selected calendar day when
  11525. * performing a clear action or using the reset() method.
  11526. */
  11527. this.activeParts = [];
  11528. }
  11529. /**
  11530. * Only animate if:
  11531. * 1. We're using grid style (wheel style pickers should just jump to new value)
  11532. * 2. The month and/or year actually changed, and both are defined (otherwise there's nothing to animate to)
  11533. * 3. The calendar body is visible (prevents animation when in collapsed datetime-button, for example)
  11534. * 4. The month/year picker is not open (since you wouldn't see the animation anyway)
  11535. */
  11536. const didChangeMonth = (month !== undefined && month !== workingParts.month) || (year !== undefined && year !== workingParts.year);
  11537. const bodyIsVisible = el.classList.contains('datetime-ready');
  11538. const { isGridStyle, showMonthAndYear } = this;
  11539. let areAllSelectedDatesInSameMonth = true;
  11540. if (Array.isArray(valueToProcess)) {
  11541. const firstMonth = valueToProcess[0].month;
  11542. for (const date of valueToProcess) {
  11543. if (date.month !== firstMonth) {
  11544. areAllSelectedDatesInSameMonth = false;
  11545. break;
  11546. }
  11547. }
  11548. }
  11549. /**
  11550. * If there is more than one date selected
  11551. * and the dates aren't all in the same month,
  11552. * then we should neither animate to the date
  11553. * nor update the working parts because we do
  11554. * not know which date the user wants to view.
  11555. */
  11556. if (areAllSelectedDatesInSameMonth) {
  11557. if (isGridStyle && didChangeMonth && bodyIsVisible && !showMonthAndYear) {
  11558. this.animateToDate(targetValue);
  11559. }
  11560. else {
  11561. /**
  11562. * We only need to do this if we didn't just animate to a new month,
  11563. * since that calls prevMonth/nextMonth which calls setWorkingParts for us.
  11564. */
  11565. this.setWorkingParts({
  11566. month,
  11567. day,
  11568. year,
  11569. hour,
  11570. minute,
  11571. ampm,
  11572. });
  11573. }
  11574. }
  11575. };
  11576. this.animateToDate = async (targetValue) => {
  11577. const { workingParts } = this;
  11578. /**
  11579. * Tell other render functions that we need to force the
  11580. * target month to appear in place of the actual next/prev month.
  11581. * Because this is a State variable, a rerender will be triggered
  11582. * automatically, updating the rendered months.
  11583. */
  11584. this.forceRenderDate = targetValue;
  11585. /**
  11586. * Flag that we've started scrolling to the forced date.
  11587. * The resolve function will be called by the datetime's
  11588. * scroll listener when it's done updating everything.
  11589. * This is a replacement for making prev/nextMonth async,
  11590. * since the logic we're waiting on is in a listener.
  11591. */
  11592. const forceDateScrollingPromise = new Promise((resolve) => {
  11593. this.resolveForceDateScrolling = resolve;
  11594. });
  11595. /**
  11596. * Animate smoothly to the forced month. This will also update
  11597. * workingParts and correct the surrounding months for us.
  11598. */
  11599. const targetMonthIsBefore = isBefore(targetValue, workingParts);
  11600. targetMonthIsBefore ? this.prevMonth() : this.nextMonth();
  11601. await forceDateScrollingPromise;
  11602. this.resolveForceDateScrolling = undefined;
  11603. this.forceRenderDate = undefined;
  11604. };
  11605. this.onFocus = () => {
  11606. this.ionFocus.emit();
  11607. };
  11608. this.onBlur = () => {
  11609. this.ionBlur.emit();
  11610. };
  11611. this.hasValue = () => {
  11612. return this.value != null;
  11613. };
  11614. this.nextMonth = () => {
  11615. const calendarBodyRef = this.calendarBodyRef;
  11616. if (!calendarBodyRef) {
  11617. return;
  11618. }
  11619. const nextMonth = calendarBodyRef.querySelector('.calendar-month:last-of-type');
  11620. if (!nextMonth) {
  11621. return;
  11622. }
  11623. const left = nextMonth.offsetWidth * 2;
  11624. calendarBodyRef.scrollTo({
  11625. top: 0,
  11626. left: left * (isRTL$1(this.el) ? -1 : 1),
  11627. behavior: 'smooth',
  11628. });
  11629. };
  11630. this.prevMonth = () => {
  11631. const calendarBodyRef = this.calendarBodyRef;
  11632. if (!calendarBodyRef) {
  11633. return;
  11634. }
  11635. const prevMonth = calendarBodyRef.querySelector('.calendar-month:first-of-type');
  11636. if (!prevMonth) {
  11637. return;
  11638. }
  11639. calendarBodyRef.scrollTo({
  11640. top: 0,
  11641. left: 0,
  11642. behavior: 'smooth',
  11643. });
  11644. };
  11645. this.toggleMonthAndYearView = () => {
  11646. this.showMonthAndYear = !this.showMonthAndYear;
  11647. };
  11648. this.showMonthAndYear = false;
  11649. this.activeParts = [];
  11650. this.workingParts = {
  11651. month: 5,
  11652. day: 28,
  11653. year: 2021,
  11654. hour: 13,
  11655. minute: 52,
  11656. ampm: 'pm',
  11657. };
  11658. this.isTimePopoverOpen = false;
  11659. this.forceRenderDate = undefined;
  11660. this.color = 'primary';
  11661. this.name = this.inputId;
  11662. this.disabled = false;
  11663. this.formatOptions = undefined;
  11664. this.readonly = false;
  11665. this.isDateEnabled = undefined;
  11666. this.min = undefined;
  11667. this.max = undefined;
  11668. this.presentation = 'date-time';
  11669. this.cancelText = 'Cancel';
  11670. this.doneText = 'Done';
  11671. this.clearText = 'Clear';
  11672. this.yearValues = undefined;
  11673. this.monthValues = undefined;
  11674. this.dayValues = undefined;
  11675. this.hourValues = undefined;
  11676. this.minuteValues = undefined;
  11677. this.locale = 'default';
  11678. this.firstDayOfWeek = 0;
  11679. this.titleSelectedDatesFormatter = undefined;
  11680. this.multiple = false;
  11681. this.highlightedDates = undefined;
  11682. this.value = undefined;
  11683. this.showDefaultTitle = false;
  11684. this.showDefaultButtons = false;
  11685. this.showClearButton = false;
  11686. this.showDefaultTimeLabel = true;
  11687. this.hourCycle = undefined;
  11688. this.size = 'fixed';
  11689. this.preferWheel = false;
  11690. }
  11691. formatOptionsChanged() {
  11692. const { el, formatOptions, presentation } = this;
  11693. checkForPresentationFormatMismatch(el, presentation, formatOptions);
  11694. warnIfTimeZoneProvided(el, formatOptions);
  11695. }
  11696. disabledChanged() {
  11697. this.emitStyle();
  11698. }
  11699. minChanged() {
  11700. this.processMinParts();
  11701. }
  11702. maxChanged() {
  11703. this.processMaxParts();
  11704. }
  11705. presentationChanged() {
  11706. const { el, formatOptions, presentation } = this;
  11707. checkForPresentationFormatMismatch(el, presentation, formatOptions);
  11708. }
  11709. get isGridStyle() {
  11710. const { presentation, preferWheel } = this;
  11711. const hasDatePresentation = presentation === 'date' || presentation === 'date-time' || presentation === 'time-date';
  11712. return hasDatePresentation && !preferWheel;
  11713. }
  11714. yearValuesChanged() {
  11715. this.parsedYearValues = convertToArrayOfNumbers(this.yearValues);
  11716. }
  11717. monthValuesChanged() {
  11718. this.parsedMonthValues = convertToArrayOfNumbers(this.monthValues);
  11719. }
  11720. dayValuesChanged() {
  11721. this.parsedDayValues = convertToArrayOfNumbers(this.dayValues);
  11722. }
  11723. hourValuesChanged() {
  11724. this.parsedHourValues = convertToArrayOfNumbers(this.hourValues);
  11725. }
  11726. minuteValuesChanged() {
  11727. this.parsedMinuteValues = convertToArrayOfNumbers(this.minuteValues);
  11728. }
  11729. /**
  11730. * Update the datetime value when the value changes
  11731. */
  11732. async valueChanged() {
  11733. const { value } = this;
  11734. if (this.hasValue()) {
  11735. this.processValue(value);
  11736. }
  11737. this.emitStyle();
  11738. this.ionValueChange.emit({ value });
  11739. }
  11740. /**
  11741. * Confirms the selected datetime value, updates the
  11742. * `value` property, and optionally closes the popover
  11743. * or modal that the datetime was presented in.
  11744. */
  11745. async confirm(closeOverlay = false) {
  11746. const { isCalendarPicker, activeParts, preferWheel, workingParts } = this;
  11747. /**
  11748. * We only update the value if the presentation is not a calendar picker.
  11749. */
  11750. if (activeParts !== undefined || !isCalendarPicker) {
  11751. const activePartsIsArray = Array.isArray(activeParts);
  11752. if (activePartsIsArray && activeParts.length === 0) {
  11753. if (preferWheel) {
  11754. /**
  11755. * If the datetime is using a wheel picker, but the
  11756. * active parts are empty, then the user has confirmed the
  11757. * initial value (working parts) presented to them.
  11758. */
  11759. this.setValue(convertDataToISO(workingParts));
  11760. }
  11761. else {
  11762. this.setValue(undefined);
  11763. }
  11764. }
  11765. else {
  11766. this.setValue(convertDataToISO(activeParts));
  11767. }
  11768. }
  11769. if (closeOverlay) {
  11770. this.closeParentOverlay(CONFIRM_ROLE);
  11771. }
  11772. }
  11773. /**
  11774. * Resets the internal state of the datetime but does not update the value.
  11775. * Passing a valid ISO-8601 string will reset the state of the component to the provided date.
  11776. * If no value is provided, the internal state will be reset to the clamped value of the min, max and today.
  11777. */
  11778. async reset(startDate) {
  11779. this.processValue(startDate);
  11780. }
  11781. /**
  11782. * Emits the ionCancel event and
  11783. * optionally closes the popover
  11784. * or modal that the datetime was
  11785. * presented in.
  11786. */
  11787. async cancel(closeOverlay = false) {
  11788. this.ionCancel.emit();
  11789. if (closeOverlay) {
  11790. this.closeParentOverlay(CANCEL_ROLE);
  11791. }
  11792. }
  11793. get isCalendarPicker() {
  11794. const { presentation } = this;
  11795. return presentation === 'date' || presentation === 'date-time' || presentation === 'time-date';
  11796. }
  11797. connectedCallback() {
  11798. this.clearFocusVisible = startFocusVisible(this.el).destroy;
  11799. }
  11800. disconnectedCallback() {
  11801. if (this.clearFocusVisible) {
  11802. this.clearFocusVisible();
  11803. this.clearFocusVisible = undefined;
  11804. }
  11805. }
  11806. initializeListeners() {
  11807. this.initializeCalendarListener();
  11808. this.initializeKeyboardListeners();
  11809. }
  11810. componentDidLoad() {
  11811. const { el, intersectionTrackerRef } = this;
  11812. /**
  11813. * If a scrollable element is hidden using `display: none`,
  11814. * it will not have a scroll height meaning we cannot scroll elements
  11815. * into view. As a result, we will need to wait for the datetime to become
  11816. * visible if used inside of a modal or a popover otherwise the scrollable
  11817. * areas will not have the correct values snapped into place.
  11818. */
  11819. const visibleCallback = (entries) => {
  11820. const ev = entries[0];
  11821. if (!ev.isIntersecting) {
  11822. return;
  11823. }
  11824. this.initializeListeners();
  11825. /**
  11826. * TODO FW-2793: Datetime needs a frame to ensure that it
  11827. * can properly scroll contents into view. As a result
  11828. * we hide the scrollable content until after that frame
  11829. * so users do not see the content quickly shifting. The downside
  11830. * is that the content will pop into view a frame after. Maybe there
  11831. * is a better way to handle this?
  11832. */
  11833. writeTask(() => {
  11834. this.el.classList.add('datetime-ready');
  11835. });
  11836. };
  11837. const visibleIO = new IntersectionObserver(visibleCallback, { threshold: 0.01, root: el });
  11838. /**
  11839. * Use raf to avoid a race condition between the component loading and
  11840. * its display animation starting (such as when shown in a modal). This
  11841. * could cause the datetime to start at a visibility of 0, erroneously
  11842. * triggering the `hiddenIO` observer below.
  11843. */
  11844. raf(() => visibleIO === null || visibleIO === void 0 ? void 0 : visibleIO.observe(intersectionTrackerRef));
  11845. /**
  11846. * We need to clean up listeners when the datetime is hidden
  11847. * in a popover/modal so that we can properly scroll containers
  11848. * back into view if they are re-presented. When the datetime is hidden
  11849. * the scroll areas have scroll widths/heights of 0px, so any snapping
  11850. * we did originally has been lost.
  11851. */
  11852. const hiddenCallback = (entries) => {
  11853. const ev = entries[0];
  11854. if (ev.isIntersecting) {
  11855. return;
  11856. }
  11857. this.destroyInteractionListeners();
  11858. /**
  11859. * When datetime is hidden, we need to make sure that
  11860. * the month/year picker is closed. Otherwise,
  11861. * it will be open when the datetime re-appears
  11862. * and the scroll area of the calendar grid will be 0.
  11863. * As a result, the wrong month will be shown.
  11864. */
  11865. this.showMonthAndYear = false;
  11866. writeTask(() => {
  11867. this.el.classList.remove('datetime-ready');
  11868. });
  11869. };
  11870. const hiddenIO = new IntersectionObserver(hiddenCallback, { threshold: 0, root: el });
  11871. raf(() => hiddenIO === null || hiddenIO === void 0 ? void 0 : hiddenIO.observe(intersectionTrackerRef));
  11872. /**
  11873. * Datetime uses Ionic components that emit
  11874. * ionFocus and ionBlur. These events are
  11875. * composed meaning they will cross
  11876. * the shadow dom boundary. We need to
  11877. * stop propagation on these events otherwise
  11878. * developers will see 2 ionFocus or 2 ionBlur
  11879. * events at a time.
  11880. */
  11881. const root = getElementRoot(this.el);
  11882. root.addEventListener('ionFocus', (ev) => ev.stopPropagation());
  11883. root.addEventListener('ionBlur', (ev) => ev.stopPropagation());
  11884. }
  11885. /**
  11886. * When the presentation is changed, all calendar content is recreated,
  11887. * so we need to re-init behavior with the new elements.
  11888. */
  11889. componentDidRender() {
  11890. const { presentation, prevPresentation, calendarBodyRef, minParts, preferWheel, forceRenderDate } = this;
  11891. /**
  11892. * TODO(FW-2165)
  11893. * Remove this when https://bugs.webkit.org/show_bug.cgi?id=235960 is fixed.
  11894. * When using `min`, we add `scroll-snap-align: none`
  11895. * to the disabled month so that users cannot scroll to it.
  11896. * This triggers a bug in WebKit where the scroll position is reset.
  11897. * Since the month change logic is handled by a scroll listener,
  11898. * this causes the month to change leading to `scroll-snap-align`
  11899. * changing again, thus changing the scroll position again and causing
  11900. * an infinite loop.
  11901. * This issue only applies to the calendar grid, so we can disable
  11902. * it if the calendar grid is not being used.
  11903. */
  11904. const hasCalendarGrid = !preferWheel && ['date-time', 'time-date', 'date'].includes(presentation);
  11905. if (minParts !== undefined && hasCalendarGrid && calendarBodyRef) {
  11906. const workingMonth = calendarBodyRef.querySelector('.calendar-month:nth-of-type(1)');
  11907. /**
  11908. * We need to make sure the datetime is not in the process
  11909. * of scrolling to a new datetime value if the value
  11910. * is updated programmatically.
  11911. * Otherwise, the datetime will appear to not scroll at all because
  11912. * we are resetting the scroll position to the center of the view.
  11913. * Prior to the datetime's value being updated programmatically,
  11914. * the calendarBodyRef is scrolled such that the middle month is centered
  11915. * in the view. The below code updates the scroll position so the middle
  11916. * month is also centered in the view. Since the scroll position did not change,
  11917. * the scroll callback in this file does not fire,
  11918. * and the resolveForceDateScrolling promise never resolves.
  11919. */
  11920. if (workingMonth && forceRenderDate === undefined) {
  11921. calendarBodyRef.scrollLeft = workingMonth.clientWidth * (isRTL$1(this.el) ? -1 : 1);
  11922. }
  11923. }
  11924. if (prevPresentation === null) {
  11925. this.prevPresentation = presentation;
  11926. return;
  11927. }
  11928. if (presentation === prevPresentation) {
  11929. return;
  11930. }
  11931. this.prevPresentation = presentation;
  11932. this.destroyInteractionListeners();
  11933. this.initializeListeners();
  11934. /**
  11935. * The month/year picker from the date interface
  11936. * should be closed as it is not available in non-date
  11937. * interfaces.
  11938. */
  11939. this.showMonthAndYear = false;
  11940. raf(() => {
  11941. this.ionRender.emit();
  11942. });
  11943. }
  11944. componentWillLoad() {
  11945. const { el, formatOptions, highlightedDates, multiple, presentation, preferWheel } = this;
  11946. if (multiple) {
  11947. if (presentation !== 'date') {
  11948. printIonWarning('[ion-datetime] - Multiple date selection is only supported for presentation="date".', el);
  11949. }
  11950. if (preferWheel) {
  11951. printIonWarning('[ion-datetime] - Multiple date selection is not supported with preferWheel="true".', el);
  11952. }
  11953. }
  11954. if (highlightedDates !== undefined) {
  11955. if (presentation !== 'date' && presentation !== 'date-time' && presentation !== 'time-date') {
  11956. printIonWarning('[ion-datetime] - The highlightedDates property is only supported with the date, date-time, and time-date presentations.', el);
  11957. }
  11958. if (preferWheel) {
  11959. printIonWarning('[ion-datetime] - The highlightedDates property is not supported with preferWheel="true".', el);
  11960. }
  11961. }
  11962. if (formatOptions) {
  11963. checkForPresentationFormatMismatch(el, presentation, formatOptions);
  11964. warnIfTimeZoneProvided(el, formatOptions);
  11965. }
  11966. const hourValues = (this.parsedHourValues = convertToArrayOfNumbers(this.hourValues));
  11967. const minuteValues = (this.parsedMinuteValues = convertToArrayOfNumbers(this.minuteValues));
  11968. const monthValues = (this.parsedMonthValues = convertToArrayOfNumbers(this.monthValues));
  11969. const yearValues = (this.parsedYearValues = convertToArrayOfNumbers(this.yearValues));
  11970. const dayValues = (this.parsedDayValues = convertToArrayOfNumbers(this.dayValues));
  11971. const todayParts = (this.todayParts = parseDate(getToday()));
  11972. this.processMinParts();
  11973. this.processMaxParts();
  11974. this.defaultParts = getClosestValidDate({
  11975. refParts: todayParts,
  11976. monthValues,
  11977. dayValues,
  11978. yearValues,
  11979. hourValues,
  11980. minuteValues,
  11981. minParts: this.minParts,
  11982. maxParts: this.maxParts,
  11983. });
  11984. this.processValue(this.value);
  11985. this.emitStyle();
  11986. }
  11987. emitStyle() {
  11988. this.ionStyle.emit({
  11989. interactive: true,
  11990. datetime: true,
  11991. 'interactive-disabled': this.disabled,
  11992. });
  11993. }
  11994. /**
  11995. * Universal render methods
  11996. * These are pieces of datetime that
  11997. * are rendered independently of presentation.
  11998. */
  11999. renderFooter() {
  12000. const { disabled, readonly, showDefaultButtons, showClearButton } = this;
  12001. /**
  12002. * The cancel, clear, and confirm buttons
  12003. * should not be interactive if the datetime
  12004. * is disabled or readonly.
  12005. */
  12006. const isButtonDisabled = disabled || readonly;
  12007. const hasSlottedButtons = this.el.querySelector('[slot="buttons"]') !== null;
  12008. if (!hasSlottedButtons && !showDefaultButtons && !showClearButton) {
  12009. return;
  12010. }
  12011. const clearButtonClick = () => {
  12012. this.reset();
  12013. this.setValue(undefined);
  12014. };
  12015. /**
  12016. * By default we render two buttons:
  12017. * Cancel - Dismisses the datetime and
  12018. * does not update the `value` prop.
  12019. * OK - Dismisses the datetime and
  12020. * updates the `value` prop.
  12021. */
  12022. return (hAsync("div", { class: "datetime-footer" }, hAsync("div", { class: "datetime-buttons" }, hAsync("div", { class: {
  12023. ['datetime-action-buttons']: true,
  12024. ['has-clear-button']: this.showClearButton,
  12025. } }, hAsync("slot", { name: "buttons" }, hAsync("ion-buttons", null, showDefaultButtons && (hAsync("ion-button", { id: "cancel-button", color: this.color, onClick: () => this.cancel(true), disabled: isButtonDisabled }, this.cancelText)), hAsync("div", { class: "datetime-action-buttons-container" }, showClearButton && (hAsync("ion-button", { id: "clear-button", color: this.color, onClick: () => clearButtonClick(), disabled: isButtonDisabled }, this.clearText)), showDefaultButtons && (hAsync("ion-button", { id: "confirm-button", color: this.color, onClick: () => this.confirm(true), disabled: isButtonDisabled }, this.doneText)))))))));
  12026. }
  12027. /**
  12028. * Wheel picker render methods
  12029. */
  12030. renderWheelPicker(forcePresentation = this.presentation) {
  12031. /**
  12032. * If presentation="time-date" we switch the
  12033. * order of the render array here instead of
  12034. * manually reordering each date/time picker
  12035. * column with CSS. This allows for additional
  12036. * flexibility if we need to render subsets
  12037. * of the date/time data or do additional ordering
  12038. * within the child render functions.
  12039. */
  12040. const renderArray = forcePresentation === 'time-date'
  12041. ? [this.renderTimePickerColumns(forcePresentation), this.renderDatePickerColumns(forcePresentation)]
  12042. : [this.renderDatePickerColumns(forcePresentation), this.renderTimePickerColumns(forcePresentation)];
  12043. return hAsync("ion-picker", null, renderArray);
  12044. }
  12045. renderDatePickerColumns(forcePresentation) {
  12046. return forcePresentation === 'date-time' || forcePresentation === 'time-date'
  12047. ? this.renderCombinedDatePickerColumn()
  12048. : this.renderIndividualDatePickerColumns(forcePresentation);
  12049. }
  12050. renderCombinedDatePickerColumn() {
  12051. const { defaultParts, disabled, workingParts, locale, minParts, maxParts, todayParts, isDateEnabled } = this;
  12052. const activePart = this.getActivePartsWithFallback();
  12053. /**
  12054. * By default, generate a range of 3 months:
  12055. * Previous month, current month, and next month
  12056. */
  12057. const monthsToRender = generateMonths(workingParts);
  12058. const lastMonth = monthsToRender[monthsToRender.length - 1];
  12059. /**
  12060. * Ensure that users can select the entire window of dates.
  12061. */
  12062. monthsToRender[0].day = 1;
  12063. lastMonth.day = getNumDaysInMonth(lastMonth.month, lastMonth.year);
  12064. /**
  12065. * Narrow the dates rendered based on min/max dates (if any).
  12066. * The `min` date is used if the min is after the generated min month.
  12067. * The `max` date is used if the max is before the generated max month.
  12068. * This ensures that the sliding window always stays at 3 months
  12069. * but still allows future dates to be lazily rendered based on any min/max
  12070. * constraints.
  12071. */
  12072. const min = minParts !== undefined && isAfter(minParts, monthsToRender[0]) ? minParts : monthsToRender[0];
  12073. const max = maxParts !== undefined && isBefore(maxParts, lastMonth) ? maxParts : lastMonth;
  12074. const result = getCombinedDateColumnData(locale, todayParts, min, max, this.parsedDayValues, this.parsedMonthValues);
  12075. let items = result.items;
  12076. const parts = result.parts;
  12077. if (isDateEnabled) {
  12078. items = items.map((itemObject, index) => {
  12079. const referenceParts = parts[index];
  12080. let disabled;
  12081. try {
  12082. /**
  12083. * The `isDateEnabled` implementation is try-catch wrapped
  12084. * to prevent exceptions in the user's function from
  12085. * interrupting the calendar rendering.
  12086. */
  12087. disabled = !isDateEnabled(convertDataToISO(referenceParts));
  12088. }
  12089. catch (e) {
  12090. printIonError('[ion-datetime] - Exception thrown from provided `isDateEnabled` function. Please check your function and try again.', e);
  12091. }
  12092. return Object.assign(Object.assign({}, itemObject), { disabled });
  12093. });
  12094. }
  12095. /**
  12096. * If we have selected a day already, then default the column
  12097. * to that value. Otherwise, set it to the default date.
  12098. */
  12099. const todayString = workingParts.day !== null
  12100. ? `${workingParts.year}-${workingParts.month}-${workingParts.day}`
  12101. : `${defaultParts.year}-${defaultParts.month}-${defaultParts.day}`;
  12102. return (hAsync("ion-picker-column", { "aria-label": "Select a date", class: "date-column", color: this.color, disabled: disabled, value: todayString, onIonChange: (ev) => {
  12103. const { value } = ev.detail;
  12104. const findPart = parts.find(({ month, day, year }) => value === `${year}-${month}-${day}`);
  12105. this.setWorkingParts(Object.assign(Object.assign({}, workingParts), findPart));
  12106. this.setActiveParts(Object.assign(Object.assign({}, activePart), findPart));
  12107. ev.stopPropagation();
  12108. } }, items.map((item) => (hAsync("ion-picker-column-option", { part: item.value === todayString ? `${WHEEL_ITEM_PART} ${WHEEL_ITEM_ACTIVE_PART}` : WHEEL_ITEM_PART, key: item.value, disabled: item.disabled, value: item.value }, item.text)))));
  12109. }
  12110. renderIndividualDatePickerColumns(forcePresentation) {
  12111. const { workingParts, isDateEnabled } = this;
  12112. const shouldRenderMonths = forcePresentation !== 'year' && forcePresentation !== 'time';
  12113. const months = shouldRenderMonths
  12114. ? getMonthColumnData(this.locale, workingParts, this.minParts, this.maxParts, this.parsedMonthValues)
  12115. : [];
  12116. const shouldRenderDays = forcePresentation === 'date';
  12117. let days = shouldRenderDays
  12118. ? getDayColumnData(this.locale, workingParts, this.minParts, this.maxParts, this.parsedDayValues)
  12119. : [];
  12120. if (isDateEnabled) {
  12121. days = days.map((dayObject) => {
  12122. const { value } = dayObject;
  12123. const valueNum = typeof value === 'string' ? parseInt(value) : value;
  12124. const referenceParts = {
  12125. month: workingParts.month,
  12126. day: valueNum,
  12127. year: workingParts.year,
  12128. };
  12129. let disabled;
  12130. try {
  12131. /**
  12132. * The `isDateEnabled` implementation is try-catch wrapped
  12133. * to prevent exceptions in the user's function from
  12134. * interrupting the calendar rendering.
  12135. */
  12136. disabled = !isDateEnabled(convertDataToISO(referenceParts));
  12137. }
  12138. catch (e) {
  12139. printIonError('[ion-datetime] - Exception thrown from provided `isDateEnabled` function. Please check your function and try again.', e);
  12140. }
  12141. return Object.assign(Object.assign({}, dayObject), { disabled });
  12142. });
  12143. }
  12144. const shouldRenderYears = forcePresentation !== 'month' && forcePresentation !== 'time';
  12145. const years = shouldRenderYears
  12146. ? getYearColumnData(this.locale, this.defaultParts, this.minParts, this.maxParts, this.parsedYearValues)
  12147. : [];
  12148. /**
  12149. * Certain locales show the day before the month.
  12150. */
  12151. const showMonthFirst = isMonthFirstLocale(this.locale, { month: 'numeric', day: 'numeric' });
  12152. let renderArray = [];
  12153. if (showMonthFirst) {
  12154. renderArray = [
  12155. this.renderMonthPickerColumn(months),
  12156. this.renderDayPickerColumn(days),
  12157. this.renderYearPickerColumn(years),
  12158. ];
  12159. }
  12160. else {
  12161. renderArray = [
  12162. this.renderDayPickerColumn(days),
  12163. this.renderMonthPickerColumn(months),
  12164. this.renderYearPickerColumn(years),
  12165. ];
  12166. }
  12167. return renderArray;
  12168. }
  12169. renderDayPickerColumn(days) {
  12170. var _a;
  12171. if (days.length === 0) {
  12172. return [];
  12173. }
  12174. const { disabled, workingParts } = this;
  12175. const activePart = this.getActivePartsWithFallback();
  12176. const pickerColumnValue = (_a = (workingParts.day !== null ? workingParts.day : this.defaultParts.day)) !== null && _a !== void 0 ? _a : undefined;
  12177. return (hAsync("ion-picker-column", { "aria-label": "Select a day", class: "day-column", color: this.color, disabled: disabled, value: pickerColumnValue, onIonChange: (ev) => {
  12178. this.setWorkingParts(Object.assign(Object.assign({}, workingParts), { day: ev.detail.value }));
  12179. this.setActiveParts(Object.assign(Object.assign({}, activePart), { day: ev.detail.value }));
  12180. ev.stopPropagation();
  12181. } }, days.map((day) => (hAsync("ion-picker-column-option", { part: day.value === pickerColumnValue ? `${WHEEL_ITEM_PART} ${WHEEL_ITEM_ACTIVE_PART}` : WHEEL_ITEM_PART, key: day.value, disabled: day.disabled, value: day.value }, day.text)))));
  12182. }
  12183. renderMonthPickerColumn(months) {
  12184. if (months.length === 0) {
  12185. return [];
  12186. }
  12187. const { disabled, workingParts } = this;
  12188. const activePart = this.getActivePartsWithFallback();
  12189. return (hAsync("ion-picker-column", { "aria-label": "Select a month", class: "month-column", color: this.color, disabled: disabled, value: workingParts.month, onIonChange: (ev) => {
  12190. this.setWorkingParts(Object.assign(Object.assign({}, workingParts), { month: ev.detail.value }));
  12191. this.setActiveParts(Object.assign(Object.assign({}, activePart), { month: ev.detail.value }));
  12192. ev.stopPropagation();
  12193. } }, months.map((month) => (hAsync("ion-picker-column-option", { part: month.value === workingParts.month ? `${WHEEL_ITEM_PART} ${WHEEL_ITEM_ACTIVE_PART}` : WHEEL_ITEM_PART, key: month.value, disabled: month.disabled, value: month.value }, month.text)))));
  12194. }
  12195. renderYearPickerColumn(years) {
  12196. if (years.length === 0) {
  12197. return [];
  12198. }
  12199. const { disabled, workingParts } = this;
  12200. const activePart = this.getActivePartsWithFallback();
  12201. return (hAsync("ion-picker-column", { "aria-label": "Select a year", class: "year-column", color: this.color, disabled: disabled, value: workingParts.year, onIonChange: (ev) => {
  12202. this.setWorkingParts(Object.assign(Object.assign({}, workingParts), { year: ev.detail.value }));
  12203. this.setActiveParts(Object.assign(Object.assign({}, activePart), { year: ev.detail.value }));
  12204. ev.stopPropagation();
  12205. } }, years.map((year) => (hAsync("ion-picker-column-option", { part: year.value === workingParts.year ? `${WHEEL_ITEM_PART} ${WHEEL_ITEM_ACTIVE_PART}` : WHEEL_ITEM_PART, key: year.value, disabled: year.disabled, value: year.value }, year.text)))));
  12206. }
  12207. renderTimePickerColumns(forcePresentation) {
  12208. if (['date', 'month', 'month-year', 'year'].includes(forcePresentation)) {
  12209. return [];
  12210. }
  12211. /**
  12212. * If a user has not selected a date,
  12213. * then we should show all times. If the
  12214. * user has selected a date (even if it has
  12215. * not been confirmed yet), we should apply
  12216. * the max and min restrictions so that the
  12217. * time picker shows values that are
  12218. * appropriate for the selected date.
  12219. */
  12220. const activePart = this.getActivePart();
  12221. const userHasSelectedDate = activePart !== undefined;
  12222. const { hoursData, minutesData, dayPeriodData } = getTimeColumnsData(this.locale, this.workingParts, this.hourCycle, userHasSelectedDate ? this.minParts : undefined, userHasSelectedDate ? this.maxParts : undefined, this.parsedHourValues, this.parsedMinuteValues);
  12223. return [
  12224. this.renderHourPickerColumn(hoursData),
  12225. this.renderMinutePickerColumn(minutesData),
  12226. this.renderDayPeriodPickerColumn(dayPeriodData),
  12227. ];
  12228. }
  12229. renderHourPickerColumn(hoursData) {
  12230. const { disabled, workingParts } = this;
  12231. if (hoursData.length === 0)
  12232. return [];
  12233. const activePart = this.getActivePartsWithFallback();
  12234. return (hAsync("ion-picker-column", { "aria-label": "Select an hour", color: this.color, disabled: disabled, value: activePart.hour, numericInput: true, onIonChange: (ev) => {
  12235. this.setWorkingParts(Object.assign(Object.assign({}, workingParts), { hour: ev.detail.value }));
  12236. this.setActiveParts(Object.assign(Object.assign({}, this.getActivePartsWithFallback()), { hour: ev.detail.value }));
  12237. ev.stopPropagation();
  12238. } }, hoursData.map((hour) => (hAsync("ion-picker-column-option", { part: hour.value === activePart.hour ? `${WHEEL_ITEM_PART} ${WHEEL_ITEM_ACTIVE_PART}` : WHEEL_ITEM_PART, key: hour.value, disabled: hour.disabled, value: hour.value }, hour.text)))));
  12239. }
  12240. renderMinutePickerColumn(minutesData) {
  12241. const { disabled, workingParts } = this;
  12242. if (minutesData.length === 0)
  12243. return [];
  12244. const activePart = this.getActivePartsWithFallback();
  12245. return (hAsync("ion-picker-column", { "aria-label": "Select a minute", color: this.color, disabled: disabled, value: activePart.minute, numericInput: true, onIonChange: (ev) => {
  12246. this.setWorkingParts(Object.assign(Object.assign({}, workingParts), { minute: ev.detail.value }));
  12247. this.setActiveParts(Object.assign(Object.assign({}, this.getActivePartsWithFallback()), { minute: ev.detail.value }));
  12248. ev.stopPropagation();
  12249. } }, minutesData.map((minute) => (hAsync("ion-picker-column-option", { part: minute.value === activePart.minute ? `${WHEEL_ITEM_PART} ${WHEEL_ITEM_ACTIVE_PART}` : WHEEL_ITEM_PART, key: minute.value, disabled: minute.disabled, value: minute.value }, minute.text)))));
  12250. }
  12251. renderDayPeriodPickerColumn(dayPeriodData) {
  12252. const { disabled, workingParts } = this;
  12253. if (dayPeriodData.length === 0) {
  12254. return [];
  12255. }
  12256. const activePart = this.getActivePartsWithFallback();
  12257. const isDayPeriodRTL = isLocaleDayPeriodRTL(this.locale);
  12258. return (hAsync("ion-picker-column", { "aria-label": "Select a day period", style: isDayPeriodRTL ? { order: '-1' } : {}, color: this.color, disabled: disabled, value: activePart.ampm, onIonChange: (ev) => {
  12259. const hour = calculateHourFromAMPM(workingParts, ev.detail.value);
  12260. this.setWorkingParts(Object.assign(Object.assign({}, workingParts), { ampm: ev.detail.value, hour }));
  12261. this.setActiveParts(Object.assign(Object.assign({}, this.getActivePartsWithFallback()), { ampm: ev.detail.value, hour }));
  12262. ev.stopPropagation();
  12263. } }, dayPeriodData.map((dayPeriod) => (hAsync("ion-picker-column-option", { part: dayPeriod.value === activePart.ampm ? `${WHEEL_ITEM_PART} ${WHEEL_ITEM_ACTIVE_PART}` : WHEEL_ITEM_PART, key: dayPeriod.value, disabled: dayPeriod.disabled, value: dayPeriod.value }, dayPeriod.text)))));
  12264. }
  12265. renderWheelView(forcePresentation) {
  12266. const { locale } = this;
  12267. const showMonthFirst = isMonthFirstLocale(locale);
  12268. const columnOrder = showMonthFirst ? 'month-first' : 'year-first';
  12269. return (hAsync("div", { class: {
  12270. [`wheel-order-${columnOrder}`]: true,
  12271. } }, this.renderWheelPicker(forcePresentation)));
  12272. }
  12273. /**
  12274. * Grid Render Methods
  12275. */
  12276. renderCalendarHeader(mode) {
  12277. const { disabled } = this;
  12278. const expandedIcon = mode === 'ios' ? chevronDown : caretUpSharp;
  12279. const collapsedIcon = mode === 'ios' ? chevronForward : caretDownSharp;
  12280. const prevMonthDisabled = disabled || isPrevMonthDisabled(this.workingParts, this.minParts, this.maxParts);
  12281. const nextMonthDisabled = disabled || isNextMonthDisabled(this.workingParts, this.maxParts);
  12282. // don't use the inheritAttributes util because it removes dir from the host, and we still need that
  12283. const hostDir = this.el.getAttribute('dir') || undefined;
  12284. return (hAsync("div", { class: "calendar-header" }, hAsync("div", { class: "calendar-action-buttons" }, hAsync("div", { class: "calendar-month-year" }, hAsync("button", { class: {
  12285. 'calendar-month-year-toggle': true,
  12286. 'ion-activatable': true,
  12287. 'ion-focusable': true,
  12288. }, part: "month-year-button", disabled: disabled, "aria-label": this.showMonthAndYear ? 'Hide year picker' : 'Show year picker', onClick: () => this.toggleMonthAndYearView() }, hAsync("span", { id: "toggle-wrapper" }, getMonthAndYear(this.locale, this.workingParts), hAsync("ion-icon", { "aria-hidden": "true", icon: this.showMonthAndYear ? expandedIcon : collapsedIcon, lazy: false, flipRtl: true })), mode === 'md' && hAsync("ion-ripple-effect", null))), hAsync("div", { class: "calendar-next-prev" }, hAsync("ion-buttons", null, hAsync("ion-button", { "aria-label": "Previous month", disabled: prevMonthDisabled, onClick: () => this.prevMonth() }, hAsync("ion-icon", { dir: hostDir, "aria-hidden": "true", slot: "icon-only", icon: chevronBack, lazy: false, flipRtl: true })), hAsync("ion-button", { "aria-label": "Next month", disabled: nextMonthDisabled, onClick: () => this.nextMonth() }, hAsync("ion-icon", { dir: hostDir, "aria-hidden": "true", slot: "icon-only", icon: chevronForward, lazy: false, flipRtl: true }))))), hAsync("div", { class: "calendar-days-of-week", "aria-hidden": "true" }, getDaysOfWeek(this.locale, mode, this.firstDayOfWeek % 7).map((d) => {
  12289. return hAsync("div", { class: "day-of-week" }, d);
  12290. }))));
  12291. }
  12292. renderMonth(month, year) {
  12293. const { disabled, readonly } = this;
  12294. const yearAllowed = this.parsedYearValues === undefined || this.parsedYearValues.includes(year);
  12295. const monthAllowed = this.parsedMonthValues === undefined || this.parsedMonthValues.includes(month);
  12296. const isCalMonthDisabled = !yearAllowed || !monthAllowed;
  12297. const isDatetimeDisabled = disabled || readonly;
  12298. const swipeDisabled = disabled ||
  12299. isMonthDisabled({
  12300. month,
  12301. year,
  12302. day: null,
  12303. }, {
  12304. // The day is not used when checking if a month is disabled.
  12305. // Users should be able to access the min or max month, even if the
  12306. // min/max date is out of bounds (e.g. min is set to Feb 15, Feb should not be disabled).
  12307. minParts: Object.assign(Object.assign({}, this.minParts), { day: null }),
  12308. maxParts: Object.assign(Object.assign({}, this.maxParts), { day: null }),
  12309. });
  12310. // The working month should never have swipe disabled.
  12311. // Otherwise the CSS scroll snap will not work and the user
  12312. // can free-scroll the calendar.
  12313. const isWorkingMonth = this.workingParts.month === month && this.workingParts.year === year;
  12314. const activePart = this.getActivePartsWithFallback();
  12315. return (hAsync("div", { "aria-hidden": !isWorkingMonth ? 'true' : null, class: {
  12316. 'calendar-month': true,
  12317. // Prevents scroll snap swipe gestures for months outside of the min/max bounds
  12318. 'calendar-month-disabled': !isWorkingMonth && swipeDisabled,
  12319. } }, hAsync("div", { class: "calendar-month-grid" }, getDaysOfMonth(month, year, this.firstDayOfWeek % 7).map((dateObject, index) => {
  12320. const { day, dayOfWeek } = dateObject;
  12321. const { el, highlightedDates, isDateEnabled, multiple } = this;
  12322. const referenceParts = { month, day, year };
  12323. const isCalendarPadding = day === null;
  12324. const { isActive, isToday, ariaLabel, ariaSelected, disabled: isDayDisabled, text, } = getCalendarDayState(this.locale, referenceParts, this.activeParts, this.todayParts, this.minParts, this.maxParts, this.parsedDayValues);
  12325. const dateIsoString = convertDataToISO(referenceParts);
  12326. let isCalDayDisabled = isCalMonthDisabled || isDayDisabled;
  12327. if (!isCalDayDisabled && isDateEnabled !== undefined) {
  12328. try {
  12329. /**
  12330. * The `isDateEnabled` implementation is try-catch wrapped
  12331. * to prevent exceptions in the user's function from
  12332. * interrupting the calendar rendering.
  12333. */
  12334. isCalDayDisabled = !isDateEnabled(dateIsoString);
  12335. }
  12336. catch (e) {
  12337. printIonError('[ion-datetime] - Exception thrown from provided `isDateEnabled` function. Please check your function and try again.', el, e);
  12338. }
  12339. }
  12340. /**
  12341. * Some days are constrained through max & min or allowed dates
  12342. * and also disabled because the component is readonly or disabled.
  12343. * These need to be displayed differently.
  12344. */
  12345. const isCalDayConstrained = isCalDayDisabled && isDatetimeDisabled;
  12346. const isButtonDisabled = isCalDayDisabled || isDatetimeDisabled;
  12347. let dateStyle = undefined;
  12348. /**
  12349. * Custom highlight styles should not override the style for selected dates,
  12350. * nor apply to "filler days" at the start of the grid.
  12351. */
  12352. if (highlightedDates !== undefined && !isActive && day !== null) {
  12353. dateStyle = getHighlightStyles(highlightedDates, dateIsoString, el);
  12354. }
  12355. let dateParts = undefined;
  12356. // "Filler days" at the beginning of the grid should not get the calendar day
  12357. // CSS parts added to them
  12358. if (!isCalendarPadding) {
  12359. dateParts = `calendar-day${isActive ? ' active' : ''}${isToday ? ' today' : ''}${isCalDayDisabled ? ' disabled' : ''}`;
  12360. }
  12361. return (hAsync("div", { class: "calendar-day-wrapper" }, hAsync("button", {
  12362. // We need to use !important for the inline styles here because
  12363. // otherwise the CSS shadow parts will override these styles.
  12364. // See https://github.com/WICG/webcomponents/issues/847
  12365. // Both the CSS shadow parts and highlightedDates styles are
  12366. // provided by the developer, but highlightedDates styles should
  12367. // always take priority.
  12368. ref: (el) => {
  12369. if (el) {
  12370. el.style.setProperty('color', `${dateStyle ? dateStyle.textColor : ''}`, 'important');
  12371. el.style.setProperty('background-color', `${dateStyle ? dateStyle.backgroundColor : ''}`, 'important');
  12372. }
  12373. }, tabindex: "-1", "data-day": day, "data-month": month, "data-year": year, "data-index": index, "data-day-of-week": dayOfWeek, disabled: isButtonDisabled, class: {
  12374. 'calendar-day-padding': isCalendarPadding,
  12375. 'calendar-day': true,
  12376. 'calendar-day-active': isActive,
  12377. 'calendar-day-constrained': isCalDayConstrained,
  12378. 'calendar-day-today': isToday,
  12379. }, part: dateParts, "aria-hidden": isCalendarPadding ? 'true' : null, "aria-selected": ariaSelected, "aria-label": ariaLabel, onClick: () => {
  12380. if (isCalendarPadding) {
  12381. return;
  12382. }
  12383. this.setWorkingParts(Object.assign(Object.assign({}, this.workingParts), { month,
  12384. day,
  12385. year }));
  12386. // multiple only needs date info, so we can wipe out other fields like time
  12387. if (multiple) {
  12388. this.setActiveParts({
  12389. month,
  12390. day,
  12391. year,
  12392. }, isActive);
  12393. }
  12394. else {
  12395. this.setActiveParts(Object.assign(Object.assign({}, activePart), { month,
  12396. day,
  12397. year }));
  12398. }
  12399. }
  12400. }, text)));
  12401. }))));
  12402. }
  12403. renderCalendarBody() {
  12404. return (hAsync("div", { class: "calendar-body ion-focusable", ref: (el) => (this.calendarBodyRef = el), tabindex: "0" }, generateMonths(this.workingParts, this.forceRenderDate).map(({ month, year }) => {
  12405. return this.renderMonth(month, year);
  12406. })));
  12407. }
  12408. renderCalendar(mode) {
  12409. return (hAsync("div", { class: "datetime-calendar", key: "datetime-calendar" }, this.renderCalendarHeader(mode), this.renderCalendarBody()));
  12410. }
  12411. renderTimeLabel() {
  12412. const hasSlottedTimeLabel = this.el.querySelector('[slot="time-label"]') !== null;
  12413. if (!hasSlottedTimeLabel && !this.showDefaultTimeLabel) {
  12414. return;
  12415. }
  12416. return hAsync("slot", { name: "time-label" }, "Time");
  12417. }
  12418. renderTimeOverlay() {
  12419. const { disabled, hourCycle, isTimePopoverOpen, locale, formatOptions } = this;
  12420. const computedHourCycle = getHourCycle(locale, hourCycle);
  12421. const activePart = this.getActivePartsWithFallback();
  12422. return [
  12423. hAsync("div", { class: "time-header" }, this.renderTimeLabel()),
  12424. hAsync("button", { class: {
  12425. 'time-body': true,
  12426. 'time-body-active': isTimePopoverOpen,
  12427. }, part: `time-button${isTimePopoverOpen ? ' active' : ''}`, "aria-expanded": "false", "aria-haspopup": "true", disabled: disabled, onClick: async (ev) => {
  12428. const { popoverRef } = this;
  12429. if (popoverRef) {
  12430. this.isTimePopoverOpen = true;
  12431. popoverRef.present(new CustomEvent('ionShadowTarget', {
  12432. detail: {
  12433. ionShadowTarget: ev.target,
  12434. },
  12435. }));
  12436. await popoverRef.onWillDismiss();
  12437. this.isTimePopoverOpen = false;
  12438. }
  12439. } }, getLocalizedTime(locale, activePart, computedHourCycle, formatOptions === null || formatOptions === void 0 ? void 0 : formatOptions.time)),
  12440. hAsync("ion-popover", { alignment: "center", translucent: true, overlayIndex: 1, arrow: false, onWillPresent: (ev) => {
  12441. /**
  12442. * Intersection Observers do not consistently fire between Blink and Webkit
  12443. * when toggling the visibility of the popover and trying to scroll the picker
  12444. * column to the correct time value.
  12445. *
  12446. * This will correctly scroll the element position to the correct time value,
  12447. * before the popover is fully presented.
  12448. */
  12449. const cols = ev.target.querySelectorAll('ion-picker-column');
  12450. // TODO (FW-615): Potentially remove this when intersection observers are fixed in picker column
  12451. cols.forEach((col) => col.scrollActiveItemIntoView());
  12452. }, style: {
  12453. '--offset-y': '-10px',
  12454. '--min-width': 'fit-content',
  12455. },
  12456. // Allow native browser keyboard events to support up/down/home/end key
  12457. // navigation within the time picker.
  12458. keyboardEvents: true, ref: (el) => (this.popoverRef = el) }, this.renderWheelPicker('time')),
  12459. ];
  12460. }
  12461. getHeaderSelectedDateText() {
  12462. var _a;
  12463. const { activeParts, formatOptions, multiple, titleSelectedDatesFormatter } = this;
  12464. const isArray = Array.isArray(activeParts);
  12465. let headerText;
  12466. if (multiple && isArray && activeParts.length !== 1) {
  12467. headerText = `${activeParts.length} days`; // default/fallback for multiple selection
  12468. if (titleSelectedDatesFormatter !== undefined) {
  12469. try {
  12470. headerText = titleSelectedDatesFormatter(convertDataToISO(activeParts));
  12471. }
  12472. catch (e) {
  12473. printIonError('[ion-datetime] - Exception in provided `titleSelectedDatesFormatter`:', e);
  12474. }
  12475. }
  12476. }
  12477. else {
  12478. // for exactly 1 day selected (multiple set or not), show a formatted version of that
  12479. headerText = getLocalizedDateTime(this.locale, this.getActivePartsWithFallback(), (_a = formatOptions === null || formatOptions === void 0 ? void 0 : formatOptions.date) !== null && _a !== void 0 ? _a : { weekday: 'short', month: 'short', day: 'numeric' });
  12480. }
  12481. return headerText;
  12482. }
  12483. renderHeader(showExpandedHeader = true) {
  12484. const hasSlottedTitle = this.el.querySelector('[slot="title"]') !== null;
  12485. if (!hasSlottedTitle && !this.showDefaultTitle) {
  12486. return;
  12487. }
  12488. return (hAsync("div", { class: "datetime-header" }, hAsync("div", { class: "datetime-title" }, hAsync("slot", { name: "title" }, "Select Date")), showExpandedHeader && hAsync("div", { class: "datetime-selected-date" }, this.getHeaderSelectedDateText())));
  12489. }
  12490. /**
  12491. * Render time picker inside of datetime.
  12492. * Do not pass color prop to segment on
  12493. * iOS mode. MD segment has been customized and
  12494. * should take on the color prop, but iOS
  12495. * should just be the default segment.
  12496. */
  12497. renderTime() {
  12498. const { presentation } = this;
  12499. const timeOnlyPresentation = presentation === 'time';
  12500. return (hAsync("div", { class: "datetime-time" }, timeOnlyPresentation ? this.renderWheelPicker() : this.renderTimeOverlay()));
  12501. }
  12502. /**
  12503. * Renders the month/year picker that is
  12504. * displayed on the calendar grid.
  12505. * The .datetime-year class has additional
  12506. * styles that let us show/hide the
  12507. * picker when the user clicks on the
  12508. * toggle in the calendar header.
  12509. */
  12510. renderCalendarViewMonthYearPicker() {
  12511. return hAsync("div", { class: "datetime-year" }, this.renderWheelView('month-year'));
  12512. }
  12513. /**
  12514. * Render entry point
  12515. * All presentation types are rendered from here.
  12516. */
  12517. renderDatetime(mode) {
  12518. const { presentation, preferWheel } = this;
  12519. /**
  12520. * Certain presentation types have separate grid and wheel displays.
  12521. * If preferWheel is true then we should show a wheel picker instead.
  12522. */
  12523. const hasWheelVariant = presentation === 'date' || presentation === 'date-time' || presentation === 'time-date';
  12524. if (preferWheel && hasWheelVariant) {
  12525. return [this.renderHeader(false), this.renderWheelView(), this.renderFooter()];
  12526. }
  12527. switch (presentation) {
  12528. case 'date-time':
  12529. return [
  12530. this.renderHeader(),
  12531. this.renderCalendar(mode),
  12532. this.renderCalendarViewMonthYearPicker(),
  12533. this.renderTime(),
  12534. this.renderFooter(),
  12535. ];
  12536. case 'time-date':
  12537. return [
  12538. this.renderHeader(),
  12539. this.renderTime(),
  12540. this.renderCalendar(mode),
  12541. this.renderCalendarViewMonthYearPicker(),
  12542. this.renderFooter(),
  12543. ];
  12544. case 'time':
  12545. return [this.renderHeader(false), this.renderTime(), this.renderFooter()];
  12546. case 'month':
  12547. case 'month-year':
  12548. case 'year':
  12549. return [this.renderHeader(false), this.renderWheelView(), this.renderFooter()];
  12550. default:
  12551. return [
  12552. this.renderHeader(),
  12553. this.renderCalendar(mode),
  12554. this.renderCalendarViewMonthYearPicker(),
  12555. this.renderFooter(),
  12556. ];
  12557. }
  12558. }
  12559. render() {
  12560. const { name, value, disabled, el, color, readonly, showMonthAndYear, preferWheel, presentation, size, isGridStyle, } = this;
  12561. const mode = getIonMode$1(this);
  12562. const isMonthAndYearPresentation = presentation === 'year' || presentation === 'month' || presentation === 'month-year';
  12563. const shouldShowMonthAndYear = showMonthAndYear || isMonthAndYearPresentation;
  12564. const monthYearPickerOpen = showMonthAndYear && !isMonthAndYearPresentation;
  12565. const hasDatePresentation = presentation === 'date' || presentation === 'date-time' || presentation === 'time-date';
  12566. const hasWheelVariant = hasDatePresentation && preferWheel;
  12567. renderHiddenInput(true, el, name, formatValue(value), disabled);
  12568. return (hAsync(Host, { key: 'c3dfea8f46fcbcef38eb9e8a69b1b46a4e4b82fd', "aria-disabled": disabled ? 'true' : null, onFocus: this.onFocus, onBlur: this.onBlur, class: Object.assign({}, createColorClasses$1(color, {
  12569. [mode]: true,
  12570. ['datetime-readonly']: readonly,
  12571. ['datetime-disabled']: disabled,
  12572. 'show-month-and-year': shouldShowMonthAndYear,
  12573. 'month-year-picker-open': monthYearPickerOpen,
  12574. [`datetime-presentation-${presentation}`]: true,
  12575. [`datetime-size-${size}`]: true,
  12576. [`datetime-prefer-wheel`]: hasWheelVariant,
  12577. [`datetime-grid`]: isGridStyle,
  12578. })) }, hAsync("div", { key: '75c91243cf6a51f44b83d7cf7d8c0c96bfd3c83f', class: "intersection-tracker", ref: (el) => (this.intersectionTrackerRef = el) }), this.renderDatetime(mode)));
  12579. }
  12580. get el() { return getElement(this); }
  12581. static get watchers() { return {
  12582. "formatOptions": ["formatOptionsChanged"],
  12583. "disabled": ["disabledChanged"],
  12584. "min": ["minChanged"],
  12585. "max": ["maxChanged"],
  12586. "presentation": ["presentationChanged"],
  12587. "yearValues": ["yearValuesChanged"],
  12588. "monthValues": ["monthValuesChanged"],
  12589. "dayValues": ["dayValuesChanged"],
  12590. "hourValues": ["hourValuesChanged"],
  12591. "minuteValues": ["minuteValuesChanged"],
  12592. "value": ["valueChanged"]
  12593. }; }
  12594. static get style() { return {
  12595. ios: IonDatetimeIosStyle0,
  12596. md: IonDatetimeMdStyle0
  12597. }; }
  12598. static get cmpMeta() { return {
  12599. "$flags$": 41,
  12600. "$tagName$": "ion-datetime",
  12601. "$members$": {
  12602. "color": [1],
  12603. "name": [1],
  12604. "disabled": [4],
  12605. "formatOptions": [16],
  12606. "readonly": [4],
  12607. "isDateEnabled": [16],
  12608. "min": [1025],
  12609. "max": [1025],
  12610. "presentation": [1],
  12611. "cancelText": [1, "cancel-text"],
  12612. "doneText": [1, "done-text"],
  12613. "clearText": [1, "clear-text"],
  12614. "yearValues": [8, "year-values"],
  12615. "monthValues": [8, "month-values"],
  12616. "dayValues": [8, "day-values"],
  12617. "hourValues": [8, "hour-values"],
  12618. "minuteValues": [8, "minute-values"],
  12619. "locale": [1],
  12620. "firstDayOfWeek": [2, "first-day-of-week"],
  12621. "titleSelectedDatesFormatter": [16],
  12622. "multiple": [4],
  12623. "highlightedDates": [16],
  12624. "value": [1025],
  12625. "showDefaultTitle": [4, "show-default-title"],
  12626. "showDefaultButtons": [4, "show-default-buttons"],
  12627. "showClearButton": [4, "show-clear-button"],
  12628. "showDefaultTimeLabel": [4, "show-default-time-label"],
  12629. "hourCycle": [1, "hour-cycle"],
  12630. "size": [1],
  12631. "preferWheel": [4, "prefer-wheel"],
  12632. "showMonthAndYear": [32],
  12633. "activeParts": [32],
  12634. "workingParts": [32],
  12635. "isTimePopoverOpen": [32],
  12636. "forceRenderDate": [32],
  12637. "confirm": [64],
  12638. "reset": [64],
  12639. "cancel": [64]
  12640. },
  12641. "$listeners$": undefined,
  12642. "$lazyBundleId$": "-",
  12643. "$attrsToReflect$": []
  12644. }; }
  12645. }
  12646. let datetimeIds = 0;
  12647. const CANCEL_ROLE = 'datetime-cancel';
  12648. const CONFIRM_ROLE = 'datetime-confirm';
  12649. const WHEEL_ITEM_PART = 'wheel-item';
  12650. const WHEEL_ITEM_ACTIVE_PART = `active`;
  12651. const datetimeButtonIosCss = ":host{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center}:host button{border-radius:8px;-webkit-margin-start:2px;margin-inline-start:2px;-webkit-margin-end:2px;margin-inline-end:2px;margin-top:0px;margin-bottom:0px;position:relative;-webkit-transition:150ms color ease-in-out;transition:150ms color ease-in-out;border:none;background:var(--ion-color-step-300, var(--ion-background-color-step-300, #edeef0));color:var(--ion-text-color, #000);font-family:inherit;font-size:1rem;cursor:pointer;overflow:hidden;-webkit-appearance:none;-moz-appearance:none;appearance:none}:host(.time-active) #time-button,:host(.date-active) #date-button{color:var(--ion-color-base)}:host(.datetime-button-disabled){pointer-events:none}:host(.datetime-button-disabled) button{opacity:0.4}:host button{-webkit-padding-start:13px;padding-inline-start:13px;-webkit-padding-end:13px;padding-inline-end:13px;padding-top:7px;padding-bottom:7px}:host button.ion-activated{color:var(--ion-color-step-600, var(--ion-text-color-step-400, #666666))}";
  12652. var IonDatetimeButtonIosStyle0 = datetimeButtonIosCss;
  12653. const datetimeButtonMdCss = ":host{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center}:host button{border-radius:8px;-webkit-margin-start:2px;margin-inline-start:2px;-webkit-margin-end:2px;margin-inline-end:2px;margin-top:0px;margin-bottom:0px;position:relative;-webkit-transition:150ms color ease-in-out;transition:150ms color ease-in-out;border:none;background:var(--ion-color-step-300, var(--ion-background-color-step-300, #edeef0));color:var(--ion-text-color, #000);font-family:inherit;font-size:1rem;cursor:pointer;overflow:hidden;-webkit-appearance:none;-moz-appearance:none;appearance:none}:host(.time-active) #time-button,:host(.date-active) #date-button{color:var(--ion-color-base)}:host(.datetime-button-disabled){pointer-events:none}:host(.datetime-button-disabled) button{opacity:0.4}:host button{-webkit-padding-start:12px;padding-inline-start:12px;-webkit-padding-end:12px;padding-inline-end:12px;padding-top:6px;padding-bottom:6px}";
  12654. var IonDatetimeButtonMdStyle0 = datetimeButtonMdCss;
  12655. /**
  12656. * @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
  12657. *
  12658. * @slot date-target - Content displayed inside of the date button.
  12659. * @slot time-target - Content displayed inside of the time button.
  12660. *
  12661. * @part native - The native HTML button that wraps the slotted text.
  12662. */
  12663. class DatetimeButton {
  12664. constructor(hostRef) {
  12665. registerInstance(this, hostRef);
  12666. this.datetimeEl = null;
  12667. this.overlayEl = null;
  12668. /**
  12669. * Accepts one or more string values and converts
  12670. * them to DatetimeParts. This is done so datetime-button
  12671. * can work with an array internally and not need
  12672. * to keep checking if the datetime value is `string` or `string[]`.
  12673. */
  12674. this.getParsedDateValues = (value) => {
  12675. if (value === undefined || value === null) {
  12676. return [];
  12677. }
  12678. if (Array.isArray(value)) {
  12679. return value;
  12680. }
  12681. return [value];
  12682. };
  12683. /**
  12684. * Check the value property on the linked
  12685. * ion-datetime and then format it according
  12686. * to the locale specified on ion-datetime.
  12687. */
  12688. this.setDateTimeText = () => {
  12689. var _a, _b, _c, _d, _e;
  12690. const { datetimeEl, datetimePresentation } = this;
  12691. if (!datetimeEl) {
  12692. return;
  12693. }
  12694. const { value, locale, formatOptions, hourCycle, preferWheel, multiple, titleSelectedDatesFormatter } = datetimeEl;
  12695. const parsedValues = this.getParsedDateValues(value);
  12696. /**
  12697. * Both ion-datetime and ion-datetime-button default
  12698. * to today's date and time if no value is set.
  12699. */
  12700. const parsedDatetimes = parseDate(parsedValues.length > 0 ? parsedValues : [getToday()]);
  12701. if (!parsedDatetimes) {
  12702. return;
  12703. }
  12704. /**
  12705. * If developers incorrectly use multiple="true"
  12706. * with non "date" datetimes, then just select
  12707. * the first value so the interface does
  12708. * not appear broken. Datetime will provide a
  12709. * warning in the console.
  12710. */
  12711. const firstParsedDatetime = parsedDatetimes[0];
  12712. const computedHourCycle = getHourCycle(locale, hourCycle);
  12713. this.dateText = this.timeText = undefined;
  12714. switch (datetimePresentation) {
  12715. case 'date-time':
  12716. case 'time-date':
  12717. const dateText = getLocalizedDateTime(locale, firstParsedDatetime, (_a = formatOptions === null || formatOptions === void 0 ? void 0 : formatOptions.date) !== null && _a !== void 0 ? _a : { month: 'short', day: 'numeric', year: 'numeric' });
  12718. const timeText = getLocalizedTime(locale, firstParsedDatetime, computedHourCycle, formatOptions === null || formatOptions === void 0 ? void 0 : formatOptions.time);
  12719. if (preferWheel) {
  12720. this.dateText = `${dateText} ${timeText}`;
  12721. }
  12722. else {
  12723. this.dateText = dateText;
  12724. this.timeText = timeText;
  12725. }
  12726. break;
  12727. case 'date':
  12728. if (multiple && parsedValues.length !== 1) {
  12729. let headerText = `${parsedValues.length} days`; // default/fallback for multiple selection
  12730. if (titleSelectedDatesFormatter !== undefined) {
  12731. try {
  12732. headerText = titleSelectedDatesFormatter(parsedValues);
  12733. }
  12734. catch (e) {
  12735. printIonError('[ion-datetime-button] - Exception in provided `titleSelectedDatesFormatter`:', e);
  12736. }
  12737. }
  12738. this.dateText = headerText;
  12739. }
  12740. else {
  12741. this.dateText = getLocalizedDateTime(locale, firstParsedDatetime, (_b = formatOptions === null || formatOptions === void 0 ? void 0 : formatOptions.date) !== null && _b !== void 0 ? _b : { month: 'short', day: 'numeric', year: 'numeric' });
  12742. }
  12743. break;
  12744. case 'time':
  12745. this.timeText = getLocalizedTime(locale, firstParsedDatetime, computedHourCycle, formatOptions === null || formatOptions === void 0 ? void 0 : formatOptions.time);
  12746. break;
  12747. case 'month-year':
  12748. this.dateText = getLocalizedDateTime(locale, firstParsedDatetime, (_c = formatOptions === null || formatOptions === void 0 ? void 0 : formatOptions.date) !== null && _c !== void 0 ? _c : { month: 'long', year: 'numeric' });
  12749. break;
  12750. case 'month':
  12751. this.dateText = getLocalizedDateTime(locale, firstParsedDatetime, (_d = formatOptions === null || formatOptions === void 0 ? void 0 : formatOptions.time) !== null && _d !== void 0 ? _d : { month: 'long' });
  12752. break;
  12753. case 'year':
  12754. this.dateText = getLocalizedDateTime(locale, firstParsedDatetime, (_e = formatOptions === null || formatOptions === void 0 ? void 0 : formatOptions.time) !== null && _e !== void 0 ? _e : { year: 'numeric' });
  12755. break;
  12756. }
  12757. };
  12758. /**
  12759. * Waits for the ion-datetime to re-render.
  12760. * This is needed in order to correctly position
  12761. * a popover relative to the trigger element.
  12762. */
  12763. this.waitForDatetimeChanges = async () => {
  12764. const { datetimeEl } = this;
  12765. if (!datetimeEl) {
  12766. return Promise.resolve();
  12767. }
  12768. return new Promise((resolve) => {
  12769. addEventListener$1(datetimeEl, 'ionRender', resolve, { once: true });
  12770. });
  12771. };
  12772. this.handleDateClick = async (ev) => {
  12773. const { datetimeEl, datetimePresentation } = this;
  12774. if (!datetimeEl) {
  12775. return;
  12776. }
  12777. let needsPresentationChange = false;
  12778. /**
  12779. * When clicking the date button,
  12780. * we need to make sure that only a date
  12781. * picker is displayed. For presentation styles
  12782. * that display content other than a date picker,
  12783. * we need to update the presentation style.
  12784. */
  12785. switch (datetimePresentation) {
  12786. case 'date-time':
  12787. case 'time-date':
  12788. const needsChange = datetimeEl.presentation !== 'date';
  12789. /**
  12790. * The date+time wheel picker
  12791. * shows date and time together,
  12792. * so do not adjust the presentation
  12793. * in that case.
  12794. */
  12795. if (!datetimeEl.preferWheel && needsChange) {
  12796. datetimeEl.presentation = 'date';
  12797. needsPresentationChange = true;
  12798. }
  12799. break;
  12800. }
  12801. /**
  12802. * Track which button was clicked
  12803. * so that it can have the correct
  12804. * activated styles applied when
  12805. * the modal/popover containing
  12806. * the datetime is opened.
  12807. */
  12808. this.selectedButton = 'date';
  12809. this.presentOverlay(ev, needsPresentationChange, this.dateTargetEl);
  12810. };
  12811. this.handleTimeClick = (ev) => {
  12812. const { datetimeEl, datetimePresentation } = this;
  12813. if (!datetimeEl) {
  12814. return;
  12815. }
  12816. let needsPresentationChange = false;
  12817. /**
  12818. * When clicking the time button,
  12819. * we need to make sure that only a time
  12820. * picker is displayed. For presentation styles
  12821. * that display content other than a time picker,
  12822. * we need to update the presentation style.
  12823. */
  12824. switch (datetimePresentation) {
  12825. case 'date-time':
  12826. case 'time-date':
  12827. const needsChange = datetimeEl.presentation !== 'time';
  12828. if (needsChange) {
  12829. datetimeEl.presentation = 'time';
  12830. needsPresentationChange = true;
  12831. }
  12832. break;
  12833. }
  12834. /**
  12835. * Track which button was clicked
  12836. * so that it can have the correct
  12837. * activated styles applied when
  12838. * the modal/popover containing
  12839. * the datetime is opened.
  12840. */
  12841. this.selectedButton = 'time';
  12842. this.presentOverlay(ev, needsPresentationChange, this.timeTargetEl);
  12843. };
  12844. /**
  12845. * If the datetime is presented in an
  12846. * overlay, the datetime and overlay
  12847. * should be appropriately sized.
  12848. * These classes provide default sizing values
  12849. * that developers can customize.
  12850. * The goal is to provide an overlay that is
  12851. * reasonably sized with a datetime that
  12852. * fills the entire container.
  12853. */
  12854. this.presentOverlay = async (ev, needsPresentationChange, triggerEl) => {
  12855. const { overlayEl } = this;
  12856. if (!overlayEl) {
  12857. return;
  12858. }
  12859. if (overlayEl.tagName === 'ION-POPOVER') {
  12860. /**
  12861. * When the presentation on datetime changes,
  12862. * we need to wait for the component to re-render
  12863. * otherwise the computed width/height of the
  12864. * popover content will be wrong, causing
  12865. * the popover to not align with the trigger element.
  12866. */
  12867. if (needsPresentationChange) {
  12868. await this.waitForDatetimeChanges();
  12869. }
  12870. /**
  12871. * We pass the trigger button element
  12872. * so that the popover aligns with the individual
  12873. * button that was clicked, not the component container.
  12874. */
  12875. overlayEl.present(Object.assign(Object.assign({}, ev), { detail: {
  12876. ionShadowTarget: triggerEl,
  12877. } }));
  12878. }
  12879. else {
  12880. overlayEl.present();
  12881. }
  12882. };
  12883. this.datetimePresentation = 'date-time';
  12884. this.dateText = undefined;
  12885. this.timeText = undefined;
  12886. this.datetimeActive = false;
  12887. this.selectedButton = undefined;
  12888. this.color = 'primary';
  12889. this.disabled = false;
  12890. this.datetime = undefined;
  12891. }
  12892. async componentWillLoad() {
  12893. const { datetime } = this;
  12894. if (!datetime) {
  12895. printIonError('[ion-datetime-button] - An ID associated with an ion-datetime instance is required to function properly.', this.el);
  12896. return;
  12897. }
  12898. const datetimeEl = (this.datetimeEl = document.getElementById(datetime));
  12899. if (!datetimeEl) {
  12900. printIonError(`[ion-datetime-button] - No ion-datetime instance found for ID '${datetime}'.`, this.el);
  12901. return;
  12902. }
  12903. /**
  12904. * The element reference must be an ion-datetime. Print an error
  12905. * if a non-datetime element was provided.
  12906. */
  12907. if (datetimeEl.tagName !== 'ION-DATETIME') {
  12908. printIonError(`[ion-datetime-button] - Expected an ion-datetime instance for ID '${datetime}' but received '${datetimeEl.tagName.toLowerCase()}' instead.`, datetimeEl);
  12909. return;
  12910. }
  12911. /**
  12912. * Since the datetime can be used in any context (overlays, accordion, etc)
  12913. * we track when it is visible to determine when it is active.
  12914. * This informs which button is highlighted as well as the
  12915. * aria-expanded state.
  12916. */
  12917. const io = new IntersectionObserver((entries) => {
  12918. const ev = entries[0];
  12919. this.datetimeActive = ev.isIntersecting;
  12920. }, {
  12921. threshold: 0.01,
  12922. });
  12923. io.observe(datetimeEl);
  12924. /**
  12925. * Get a reference to any modal/popover
  12926. * the datetime is being used in so we can
  12927. * correctly size it when it is presented.
  12928. */
  12929. const overlayEl = (this.overlayEl = datetimeEl.closest('ion-modal, ion-popover'));
  12930. /**
  12931. * The .ion-datetime-button-overlay class contains
  12932. * styles that allow any modal/popover to be
  12933. * sized according to the dimensions of the datetime.
  12934. * If developers want a smaller/larger overlay all they need
  12935. * to do is change the width/height of the datetime.
  12936. * Additionally, this lets us avoid having to set
  12937. * explicit widths on each variant of datetime.
  12938. */
  12939. if (overlayEl) {
  12940. overlayEl.classList.add('ion-datetime-button-overlay');
  12941. }
  12942. componentOnReady(datetimeEl, () => {
  12943. const datetimePresentation = (this.datetimePresentation = datetimeEl.presentation || 'date-time');
  12944. /**
  12945. * Set the initial display
  12946. * in the rendered buttons.
  12947. *
  12948. * From there, we need to listen
  12949. * for ionChange to be emitted
  12950. * from datetime so we know when
  12951. * to re-render the displayed
  12952. * text in the buttons.
  12953. */
  12954. this.setDateTimeText();
  12955. addEventListener$1(datetimeEl, 'ionValueChange', this.setDateTimeText);
  12956. /**
  12957. * Configure the initial selected button
  12958. * in the event that the datetime is displayed
  12959. * without clicking one of the datetime buttons.
  12960. * For example, a datetime could be expanded
  12961. * in an accordion. In this case users only
  12962. * need to click the accordion header to show
  12963. * the datetime.
  12964. */
  12965. switch (datetimePresentation) {
  12966. case 'date-time':
  12967. case 'date':
  12968. case 'month-year':
  12969. case 'month':
  12970. case 'year':
  12971. this.selectedButton = 'date';
  12972. break;
  12973. case 'time-date':
  12974. case 'time':
  12975. this.selectedButton = 'time';
  12976. break;
  12977. }
  12978. });
  12979. }
  12980. render() {
  12981. const { color, dateText, timeText, selectedButton, datetimeActive, disabled } = this;
  12982. const mode = getIonMode$1(this);
  12983. return (hAsync(Host, { key: '11d037e6ab061e5116842970760b04850b42f2c7', class: createColorClasses$1(color, {
  12984. [mode]: true,
  12985. [`${selectedButton}-active`]: datetimeActive,
  12986. ['datetime-button-disabled']: disabled,
  12987. }) }, dateText && (hAsync("button", { key: '08ecb62da0fcbf7466a1f2403276712a3ff17fbc', class: "ion-activatable", id: "date-button", "aria-expanded": datetimeActive ? 'true' : 'false', onClick: this.handleDateClick, disabled: disabled, part: "native", ref: (el) => (this.dateTargetEl = el) }, hAsync("slot", { key: '1c04853d4d23c0f1a594602bde44511c98355644', name: "date-target" }, dateText), mode === 'md' && hAsync("ion-ripple-effect", { key: '5fc566cd4bc885bcf983ce99e3dc65d7f485bf9b' }))), timeText && (hAsync("button", { key: 'c9c5c34ac338badf8659da22bea5829d62c51169', class: "ion-activatable", id: "time-button", "aria-expanded": datetimeActive ? 'true' : 'false', onClick: this.handleTimeClick, disabled: disabled, part: "native", ref: (el) => (this.timeTargetEl = el) }, hAsync("slot", { key: '147a9d2069dbf737f6fc64787823d6d5af5aa653', name: "time-target" }, timeText), mode === 'md' && hAsync("ion-ripple-effect", { key: '70a5e25b75ed90ac6bba003468435f67aa9d8f0a' })))));
  12988. }
  12989. get el() { return getElement(this); }
  12990. static get style() { return {
  12991. ios: IonDatetimeButtonIosStyle0,
  12992. md: IonDatetimeButtonMdStyle0
  12993. }; }
  12994. static get cmpMeta() { return {
  12995. "$flags$": 41,
  12996. "$tagName$": "ion-datetime-button",
  12997. "$members$": {
  12998. "color": [513],
  12999. "disabled": [516],
  13000. "datetime": [1],
  13001. "datetimePresentation": [32],
  13002. "dateText": [32],
  13003. "timeText": [32],
  13004. "datetimeActive": [32],
  13005. "selectedButton": [32]
  13006. },
  13007. "$listeners$": undefined,
  13008. "$lazyBundleId$": "-",
  13009. "$attrsToReflect$": [["color", "color"], ["disabled", "disabled"]]
  13010. }; }
  13011. }
  13012. const fabCss = ":host{position:absolute;width:-webkit-fit-content;width:-moz-fit-content;width:fit-content;height:-webkit-fit-content;height:-moz-fit-content;height:fit-content;z-index:999}:host(.fab-horizontal-center){left:0px;right:0px;-webkit-margin-start:auto;margin-inline-start:auto;-webkit-margin-end:auto;margin-inline-end:auto}:host(.fab-horizontal-start){left:calc(10px + var(--ion-safe-area-left, 0px));}:host-context([dir=rtl]):host(.fab-horizontal-start),:host-context([dir=rtl]).fab-horizontal-start{right:calc(10px + var(--ion-safe-area-right, 0px));left:unset}@supports selector(:dir(rtl)){:host(.fab-horizontal-start:dir(rtl)){right:calc(10px + var(--ion-safe-area-right, 0px));left:unset}}:host(.fab-horizontal-end){right:calc(10px + var(--ion-safe-area-right, 0px));}:host-context([dir=rtl]):host(.fab-horizontal-end),:host-context([dir=rtl]).fab-horizontal-end{left:calc(10px + var(--ion-safe-area-left, 0px));right:unset}@supports selector(:dir(rtl)){:host(.fab-horizontal-end:dir(rtl)){left:calc(10px + var(--ion-safe-area-left, 0px));right:unset}}:host(.fab-vertical-top){top:10px}:host(.fab-vertical-top.fab-edge){top:0}:host(.fab-vertical-top.fab-edge) ::slotted(ion-fab-button){margin-top:-50%}:host(.fab-vertical-top.fab-edge) ::slotted(ion-fab-button.fab-button-small){margin-top:calc((-100% + 16px) / 2)}:host(.fab-vertical-top.fab-edge) ::slotted(ion-fab-list.fab-list-side-start),:host(.fab-vertical-top.fab-edge) ::slotted(ion-fab-list.fab-list-side-end){margin-top:-50%}:host(.fab-vertical-top.fab-edge) ::slotted(ion-fab-list.fab-list-side-top),:host(.fab-vertical-top.fab-edge) ::slotted(ion-fab-list.fab-list-side-bottom){margin-top:calc(50% + 10px)}:host(.fab-vertical-bottom){bottom:10px}:host(.fab-vertical-bottom.fab-edge){bottom:0}:host(.fab-vertical-bottom.fab-edge) ::slotted(ion-fab-button){margin-bottom:-50%}:host(.fab-vertical-bottom.fab-edge) ::slotted(ion-fab-button.fab-button-small){margin-bottom:calc((-100% + 16px) / 2)}:host(.fab-vertical-bottom.fab-edge) ::slotted(ion-fab-list.fab-list-side-start),:host(.fab-vertical-bottom.fab-edge) ::slotted(ion-fab-list.fab-list-side-end){margin-bottom:-50%}:host(.fab-vertical-bottom.fab-edge) ::slotted(ion-fab-list.fab-list-side-top),:host(.fab-vertical-bottom.fab-edge) ::slotted(ion-fab-list.fab-list-side-bottom){margin-bottom:calc(50% + 10px)}:host(.fab-vertical-center){top:0px;bottom:0px;margin-top:auto;margin-bottom:auto}";
  13013. var IonFabStyle0 = fabCss;
  13014. class Fab {
  13015. constructor(hostRef) {
  13016. registerInstance(this, hostRef);
  13017. this.horizontal = undefined;
  13018. this.vertical = undefined;
  13019. this.edge = false;
  13020. this.activated = false;
  13021. }
  13022. activatedChanged() {
  13023. const activated = this.activated;
  13024. const fab = this.getFab();
  13025. if (fab) {
  13026. fab.activated = activated;
  13027. }
  13028. Array.from(this.el.querySelectorAll('ion-fab-list')).forEach((list) => {
  13029. list.activated = activated;
  13030. });
  13031. }
  13032. componentDidLoad() {
  13033. if (this.activated) {
  13034. this.activatedChanged();
  13035. }
  13036. }
  13037. /**
  13038. * Close an active FAB list container.
  13039. */
  13040. async close() {
  13041. this.activated = false;
  13042. }
  13043. getFab() {
  13044. return this.el.querySelector('ion-fab-button');
  13045. }
  13046. /**
  13047. * Opens/Closes the FAB list container.
  13048. * @internal
  13049. */
  13050. async toggle() {
  13051. const hasList = !!this.el.querySelector('ion-fab-list');
  13052. if (hasList) {
  13053. this.activated = !this.activated;
  13054. }
  13055. }
  13056. render() {
  13057. const { horizontal, vertical, edge } = this;
  13058. const mode = getIonMode$1(this);
  13059. return (hAsync(Host, { key: '8a310806d0e748d7ebb0ed3d9a2652038e0f2960', class: {
  13060. [mode]: true,
  13061. [`fab-horizontal-${horizontal}`]: horizontal !== undefined,
  13062. [`fab-vertical-${vertical}`]: vertical !== undefined,
  13063. 'fab-edge': edge,
  13064. } }, hAsync("slot", { key: '9394ef6d6e5b0410fa6ba212171f687fb178ce2d' })));
  13065. }
  13066. get el() { return getElement(this); }
  13067. static get watchers() { return {
  13068. "activated": ["activatedChanged"]
  13069. }; }
  13070. static get style() { return IonFabStyle0; }
  13071. static get cmpMeta() { return {
  13072. "$flags$": 9,
  13073. "$tagName$": "ion-fab",
  13074. "$members$": {
  13075. "horizontal": [1],
  13076. "vertical": [1],
  13077. "edge": [4],
  13078. "activated": [1028],
  13079. "close": [64],
  13080. "toggle": [64]
  13081. },
  13082. "$listeners$": undefined,
  13083. "$lazyBundleId$": "-",
  13084. "$attrsToReflect$": []
  13085. }; }
  13086. }
  13087. const fabButtonIosCss = ":host{--color-activated:var(--color);--color-focused:var(--color);--color-hover:var(--color);--background-hover:var(--ion-color-primary-contrast, #fff);--background-hover-opacity:.08;--transition:background-color, opacity 100ms linear;--ripple-color:currentColor;--border-radius:50%;--border-width:0;--border-style:none;--border-color:initial;--padding-top:0;--padding-end:0;--padding-bottom:0;--padding-start:0;margin-left:0;margin-right:0;margin-top:0;margin-bottom:0;display:block;width:56px;height:56px;font-size:14px;text-align:center;text-overflow:ellipsis;text-transform:none;white-space:nowrap;-webkit-font-kerning:none;font-kerning:none}.button-native{border-radius:var(--border-radius);-webkit-padding-start:var(--padding-start);padding-inline-start:var(--padding-start);-webkit-padding-end:var(--padding-end);padding-inline-end:var(--padding-end);padding-top:var(--padding-top);padding-bottom:var(--padding-bottom);font-family:inherit;font-size:inherit;font-style:inherit;font-weight:inherit;letter-spacing:inherit;text-decoration:inherit;text-indent:inherit;text-overflow:inherit;text-transform:inherit;text-align:inherit;white-space:inherit;color:inherit;display:block;position:relative;width:100%;height:100%;-webkit-transform:var(--transform);transform:var(--transform);-webkit-transition:var(--transition);transition:var(--transition);border-width:var(--border-width);border-style:var(--border-style);border-color:var(--border-color);outline:none;background:var(--background);background-clip:padding-box;color:var(--color);-webkit-box-shadow:var(--box-shadow);box-shadow:var(--box-shadow);contain:strict;cursor:pointer;overflow:hidden;z-index:0;-webkit-appearance:none;-moz-appearance:none;appearance:none;-webkit-box-sizing:border-box;box-sizing:border-box}::slotted(ion-icon){line-height:1}.button-native::after{left:0;right:0;top:0;bottom:0;position:absolute;content:\"\";opacity:0}.button-inner{left:0;right:0;top:0;display:-ms-flexbox;display:flex;position:absolute;-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-negative:0;flex-shrink:0;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;height:100%;-webkit-transition:all ease-in-out 300ms;transition:all ease-in-out 300ms;-webkit-transition-property:opacity, -webkit-transform;transition-property:opacity, -webkit-transform;transition-property:transform, opacity;transition-property:transform, opacity, -webkit-transform;z-index:1}:host(.fab-button-disabled){cursor:default;opacity:0.5;pointer-events:none}@media (any-hover: hover){:host(:hover) .button-native{color:var(--color-hover)}:host(:hover) .button-native::after{background:var(--background-hover);opacity:var(--background-hover-opacity)}}:host(.ion-focused) .button-native{color:var(--color-focused)}:host(.ion-focused) .button-native::after{background:var(--background-focused);opacity:var(--background-focused-opacity)}:host(.ion-activated) .button-native{color:var(--color-activated)}:host(.ion-activated) .button-native::after{background:var(--background-activated);opacity:var(--background-activated-opacity)}::slotted(ion-icon){line-height:1}:host(.fab-button-small){-webkit-margin-start:8px;margin-inline-start:8px;-webkit-margin-end:8px;margin-inline-end:8px;margin-top:8px;margin-bottom:8px;width:40px;height:40px}.close-icon{-webkit-margin-start:auto;margin-inline-start:auto;-webkit-margin-end:auto;margin-inline-end:auto;margin-top:0;margin-bottom:0;left:0;right:0;top:0;position:absolute;height:100%;-webkit-transform:scale(0.4) rotateZ(-45deg);transform:scale(0.4) rotateZ(-45deg);-webkit-transition:all ease-in-out 300ms;transition:all ease-in-out 300ms;-webkit-transition-property:opacity, -webkit-transform;transition-property:opacity, -webkit-transform;transition-property:transform, opacity;transition-property:transform, opacity, -webkit-transform;font-size:var(--close-icon-font-size);opacity:0;z-index:1}:host(.fab-button-close-active) .close-icon{-webkit-transform:scale(1) rotateZ(0deg);transform:scale(1) rotateZ(0deg);opacity:1}:host(.fab-button-close-active) .button-inner{-webkit-transform:scale(0.4) rotateZ(45deg);transform:scale(0.4) rotateZ(45deg);opacity:0}ion-ripple-effect{color:var(--ripple-color)}@supports ((-webkit-backdrop-filter: blur(0)) or (backdrop-filter: blur(0))){:host(.fab-button-translucent) .button-native{-webkit-backdrop-filter:var(--backdrop-filter);backdrop-filter:var(--backdrop-filter)}}:host(.ion-color) .button-native{background:var(--ion-color-base);color:var(--ion-color-contrast)}:host{--background:var(--ion-color-primary, #0054e9);--background-activated:var(--ion-color-primary-shade, #004acd);--background-focused:var(--ion-color-primary-shade, #004acd);--background-hover:var(--ion-color-primary-tint, #1a65eb);--background-activated-opacity:1;--background-focused-opacity:1;--background-hover-opacity:1;--color:var(--ion-color-primary-contrast, #fff);--box-shadow:0 4px 16px rgba(0, 0, 0, 0.12);--transition:0.2s transform cubic-bezier(0.25, 1.11, 0.78, 1.59);--close-icon-font-size:28px}:host(.ion-activated){--box-shadow:0 4px 16px rgba(0, 0, 0, 0.12);--transform:scale(1.1);--transition:0.2s transform ease-out}::slotted(ion-icon){font-size:28px}:host(.fab-button-in-list){--background:var(--ion-color-light, #f4f5f8);--background-activated:var(--ion-color-light-shade, #d7d8da);--background-focused:var(--background-activated);--background-hover:var(--ion-color-light-tint, #f5f6f9);--color:var(--ion-color-light-contrast, #000);--color-activated:var(--ion-color-light-contrast, #000);--color-focused:var(--color-activated);--transition:transform 200ms ease 10ms, opacity 200ms ease 10ms}:host(.fab-button-in-list) ::slotted(ion-icon){font-size:18px}:host(.ion-color.ion-focused) .button-native::after{background:var(--ion-color-shade)}:host(.ion-color.ion-focused) .button-native,:host(.ion-color.ion-activated) .button-native{color:var(--ion-color-contrast)}:host(.ion-color.ion-focused) .button-native::after,:host(.ion-color.ion-activated) .button-native::after{background:var(--ion-color-shade)}@media (any-hover: hover){:host(.ion-color:hover) .button-native{color:var(--ion-color-contrast)}:host(.ion-color:hover) .button-native::after{background:var(--ion-color-tint)}}@supports ((-webkit-backdrop-filter: blur(0)) or (backdrop-filter: blur(0))){:host(.fab-button-translucent){--background:rgba(var(--ion-color-primary-rgb, 0, 84, 233), 0.9);--background-hover:rgba(var(--ion-color-primary-rgb, 0, 84, 233), 0.8);--background-focused:rgba(var(--ion-color-primary-rgb, 0, 84, 233), 0.82);--backdrop-filter:saturate(180%) blur(20px)}:host(.fab-button-translucent-in-list){--background:rgba(var(--ion-color-light-rgb, 244, 245, 248), 0.9);--background-hover:rgba(var(--ion-color-light-rgb, 244, 245, 248), 0.8);--background-focused:rgba(var(--ion-color-light-rgb, 244, 245, 248), 0.82)}}@supports ((-webkit-backdrop-filter: blur(0)) or (backdrop-filter: blur(0))){@media (any-hover: hover){:host(.fab-button-translucent.ion-color:hover) .button-native{background:rgba(var(--ion-color-base-rgb), 0.8)}}:host(.ion-color.fab-button-translucent) .button-native{background:rgba(var(--ion-color-base-rgb), 0.9)}:host(.ion-color.ion-focused.fab-button-translucent) .button-native,:host(.ion-color.ion-activated.fab-button-translucent) .button-native{background:var(--ion-color-base)}}";
  13088. var IonFabButtonIosStyle0 = fabButtonIosCss;
  13089. const fabButtonMdCss = ":host{--color-activated:var(--color);--color-focused:var(--color);--color-hover:var(--color);--background-hover:var(--ion-color-primary-contrast, #fff);--background-hover-opacity:.08;--transition:background-color, opacity 100ms linear;--ripple-color:currentColor;--border-radius:50%;--border-width:0;--border-style:none;--border-color:initial;--padding-top:0;--padding-end:0;--padding-bottom:0;--padding-start:0;margin-left:0;margin-right:0;margin-top:0;margin-bottom:0;display:block;width:56px;height:56px;font-size:14px;text-align:center;text-overflow:ellipsis;text-transform:none;white-space:nowrap;-webkit-font-kerning:none;font-kerning:none}.button-native{border-radius:var(--border-radius);-webkit-padding-start:var(--padding-start);padding-inline-start:var(--padding-start);-webkit-padding-end:var(--padding-end);padding-inline-end:var(--padding-end);padding-top:var(--padding-top);padding-bottom:var(--padding-bottom);font-family:inherit;font-size:inherit;font-style:inherit;font-weight:inherit;letter-spacing:inherit;text-decoration:inherit;text-indent:inherit;text-overflow:inherit;text-transform:inherit;text-align:inherit;white-space:inherit;color:inherit;display:block;position:relative;width:100%;height:100%;-webkit-transform:var(--transform);transform:var(--transform);-webkit-transition:var(--transition);transition:var(--transition);border-width:var(--border-width);border-style:var(--border-style);border-color:var(--border-color);outline:none;background:var(--background);background-clip:padding-box;color:var(--color);-webkit-box-shadow:var(--box-shadow);box-shadow:var(--box-shadow);contain:strict;cursor:pointer;overflow:hidden;z-index:0;-webkit-appearance:none;-moz-appearance:none;appearance:none;-webkit-box-sizing:border-box;box-sizing:border-box}::slotted(ion-icon){line-height:1}.button-native::after{left:0;right:0;top:0;bottom:0;position:absolute;content:\"\";opacity:0}.button-inner{left:0;right:0;top:0;display:-ms-flexbox;display:flex;position:absolute;-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-negative:0;flex-shrink:0;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;height:100%;-webkit-transition:all ease-in-out 300ms;transition:all ease-in-out 300ms;-webkit-transition-property:opacity, -webkit-transform;transition-property:opacity, -webkit-transform;transition-property:transform, opacity;transition-property:transform, opacity, -webkit-transform;z-index:1}:host(.fab-button-disabled){cursor:default;opacity:0.5;pointer-events:none}@media (any-hover: hover){:host(:hover) .button-native{color:var(--color-hover)}:host(:hover) .button-native::after{background:var(--background-hover);opacity:var(--background-hover-opacity)}}:host(.ion-focused) .button-native{color:var(--color-focused)}:host(.ion-focused) .button-native::after{background:var(--background-focused);opacity:var(--background-focused-opacity)}:host(.ion-activated) .button-native{color:var(--color-activated)}:host(.ion-activated) .button-native::after{background:var(--background-activated);opacity:var(--background-activated-opacity)}::slotted(ion-icon){line-height:1}:host(.fab-button-small){-webkit-margin-start:8px;margin-inline-start:8px;-webkit-margin-end:8px;margin-inline-end:8px;margin-top:8px;margin-bottom:8px;width:40px;height:40px}.close-icon{-webkit-margin-start:auto;margin-inline-start:auto;-webkit-margin-end:auto;margin-inline-end:auto;margin-top:0;margin-bottom:0;left:0;right:0;top:0;position:absolute;height:100%;-webkit-transform:scale(0.4) rotateZ(-45deg);transform:scale(0.4) rotateZ(-45deg);-webkit-transition:all ease-in-out 300ms;transition:all ease-in-out 300ms;-webkit-transition-property:opacity, -webkit-transform;transition-property:opacity, -webkit-transform;transition-property:transform, opacity;transition-property:transform, opacity, -webkit-transform;font-size:var(--close-icon-font-size);opacity:0;z-index:1}:host(.fab-button-close-active) .close-icon{-webkit-transform:scale(1) rotateZ(0deg);transform:scale(1) rotateZ(0deg);opacity:1}:host(.fab-button-close-active) .button-inner{-webkit-transform:scale(0.4) rotateZ(45deg);transform:scale(0.4) rotateZ(45deg);opacity:0}ion-ripple-effect{color:var(--ripple-color)}@supports ((-webkit-backdrop-filter: blur(0)) or (backdrop-filter: blur(0))){:host(.fab-button-translucent) .button-native{-webkit-backdrop-filter:var(--backdrop-filter);backdrop-filter:var(--backdrop-filter)}}:host(.ion-color) .button-native{background:var(--ion-color-base);color:var(--ion-color-contrast)}:host{--background:var(--ion-color-primary, #0054e9);--background-activated:transparent;--background-focused:currentColor;--background-hover:currentColor;--background-activated-opacity:0;--background-focused-opacity:.24;--background-hover-opacity:.08;--color:var(--ion-color-primary-contrast, #fff);--box-shadow:0 3px 5px -1px rgba(0, 0, 0, 0.2), 0 6px 10px 0 rgba(0, 0, 0, 0.14), 0 1px 18px 0 rgba(0, 0, 0, 0.12);--transition:box-shadow 280ms cubic-bezier(0.4, 0, 0.2, 1), background-color 280ms cubic-bezier(0.4, 0, 0.2, 1), color 280ms cubic-bezier(0.4, 0, 0.2, 1), opacity 15ms linear 30ms, transform 270ms cubic-bezier(0, 0, 0.2, 1) 0ms;--close-icon-font-size:24px}:host(.ion-activated){--box-shadow:0 7px 8px -4px rgba(0, 0, 0, 0.2), 0 12px 17px 2px rgba(0, 0, 0, 0.14), 0 5px 22px 4px rgba(0, 0, 0, 0.12)}::slotted(ion-icon){font-size:24px}:host(.fab-button-in-list){--color:rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.54);--color-activated:rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.54);--color-focused:var(--color-activated);--background:var(--ion-color-light, #f4f5f8);--background-activated:transparent;--background-focused:var(--ion-color-light-shade, #d7d8da);--background-hover:var(--ion-color-light-tint, #f5f6f9)}:host(.fab-button-in-list) ::slotted(ion-icon){font-size:18px}:host(.ion-color.ion-focused) .button-native{color:var(--ion-color-contrast)}:host(.ion-color.ion-focused) .button-native::after{background:var(--ion-color-contrast)}:host(.ion-color.ion-activated) .button-native{color:var(--ion-color-contrast)}:host(.ion-color.ion-activated) .button-native::after{background:transparent}@media (any-hover: hover){:host(.ion-color:hover) .button-native{color:var(--ion-color-contrast)}:host(.ion-color:hover) .button-native::after{background:var(--ion-color-contrast)}}";
  13090. var IonFabButtonMdStyle0 = fabButtonMdCss;
  13091. /**
  13092. * @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
  13093. *
  13094. * @part native - The native HTML button or anchor element that wraps all child elements.
  13095. * @part close-icon - The close icon that is displayed when a fab list opens (uses ion-icon).
  13096. */
  13097. class FabButton {
  13098. constructor(hostRef) {
  13099. registerInstance(this, hostRef);
  13100. this.ionFocus = createEvent(this, "ionFocus", 7);
  13101. this.ionBlur = createEvent(this, "ionBlur", 7);
  13102. this.fab = null;
  13103. this.inheritedAttributes = {};
  13104. this.onFocus = () => {
  13105. this.ionFocus.emit();
  13106. };
  13107. this.onBlur = () => {
  13108. this.ionBlur.emit();
  13109. };
  13110. this.onClick = () => {
  13111. const { fab } = this;
  13112. if (!fab) {
  13113. return;
  13114. }
  13115. fab.toggle();
  13116. };
  13117. this.color = undefined;
  13118. this.activated = false;
  13119. this.disabled = false;
  13120. this.download = undefined;
  13121. this.href = undefined;
  13122. this.rel = undefined;
  13123. this.routerDirection = 'forward';
  13124. this.routerAnimation = undefined;
  13125. this.target = undefined;
  13126. this.show = false;
  13127. this.translucent = false;
  13128. this.type = 'button';
  13129. this.size = undefined;
  13130. this.closeIcon = close;
  13131. }
  13132. connectedCallback() {
  13133. this.fab = this.el.closest('ion-fab');
  13134. }
  13135. componentWillLoad() {
  13136. this.inheritedAttributes = inheritAriaAttributes(this.el);
  13137. }
  13138. render() {
  13139. const { el, disabled, color, href, activated, show, translucent, size, inheritedAttributes } = this;
  13140. const inList = hostContext('ion-fab-list', el);
  13141. const mode = getIonMode$1(this);
  13142. const TagType = href === undefined ? 'button' : 'a';
  13143. const attrs = TagType === 'button'
  13144. ? { type: this.type }
  13145. : {
  13146. download: this.download,
  13147. href,
  13148. rel: this.rel,
  13149. target: this.target,
  13150. };
  13151. return (hAsync(Host, { key: '4eee204d20b0e2ffed49a88f6cb3e04b6697965c', onClick: this.onClick, "aria-disabled": disabled ? 'true' : null, class: createColorClasses$1(color, {
  13152. [mode]: true,
  13153. 'fab-button-in-list': inList,
  13154. 'fab-button-translucent-in-list': inList && translucent,
  13155. 'fab-button-close-active': activated,
  13156. 'fab-button-show': show,
  13157. 'fab-button-disabled': disabled,
  13158. 'fab-button-translucent': translucent,
  13159. 'ion-activatable': true,
  13160. 'ion-focusable': true,
  13161. [`fab-button-${size}`]: size !== undefined,
  13162. }) }, hAsync(TagType, Object.assign({ key: '914561622c0c6bd41453e828a7d8a39f924875ac' }, attrs, { class: "button-native", part: "native", disabled: disabled, onFocus: this.onFocus, onBlur: this.onBlur, onClick: (ev) => openURL(href, ev, this.routerDirection, this.routerAnimation) }, inheritedAttributes), hAsync("ion-icon", { key: '2c8090742a64c62a79243667027a195cca9d5912', "aria-hidden": "true", icon: this.closeIcon, part: "close-icon", class: "close-icon", lazy: false }), hAsync("span", { key: 'c3e55291e4c4d306d34a4b95dd2e727e87bdf39c', class: "button-inner" }, hAsync("slot", { key: 'f8e57f71d8f8878d9746cfece82f57f19ef9e988' })), mode === 'md' && hAsync("ion-ripple-effect", { key: 'a5e94fa0bb9836072300617245ed0c1b4887bac6' }))));
  13163. }
  13164. get el() { return getElement(this); }
  13165. static get style() { return {
  13166. ios: IonFabButtonIosStyle0,
  13167. md: IonFabButtonMdStyle0
  13168. }; }
  13169. static get cmpMeta() { return {
  13170. "$flags$": 41,
  13171. "$tagName$": "ion-fab-button",
  13172. "$members$": {
  13173. "color": [513],
  13174. "activated": [4],
  13175. "disabled": [4],
  13176. "download": [1],
  13177. "href": [1],
  13178. "rel": [1],
  13179. "routerDirection": [1, "router-direction"],
  13180. "routerAnimation": [16],
  13181. "target": [1],
  13182. "show": [4],
  13183. "translucent": [4],
  13184. "type": [1],
  13185. "size": [1],
  13186. "closeIcon": [1, "close-icon"]
  13187. },
  13188. "$listeners$": undefined,
  13189. "$lazyBundleId$": "-",
  13190. "$attrsToReflect$": [["color", "color"]]
  13191. }; }
  13192. }
  13193. const fabListCss = ":host{margin-left:0;margin-right:0;margin-top:calc(100% + 10px);margin-bottom:calc(100% + 10px);display:none;position:absolute;top:0;-ms-flex-direction:column;flex-direction:column;-ms-flex-align:center;align-items:center;min-width:56px;min-height:56px}:host(.fab-list-active){display:-ms-flexbox;display:flex}::slotted(.fab-button-in-list){margin-left:0;margin-right:0;margin-top:8px;margin-bottom:8px;width:40px;height:40px;-webkit-transform:scale(0);transform:scale(0);opacity:0;visibility:hidden}:host(.fab-list-side-top) ::slotted(.fab-button-in-list),:host(.fab-list-side-bottom) ::slotted(.fab-button-in-list){margin-left:0;margin-right:0;margin-top:5px;margin-bottom:5px}:host(.fab-list-side-start) ::slotted(.fab-button-in-list),:host(.fab-list-side-end) ::slotted(.fab-button-in-list){-webkit-margin-start:5px;margin-inline-start:5px;-webkit-margin-end:5px;margin-inline-end:5px;margin-top:0;margin-bottom:0}::slotted(.fab-button-in-list.fab-button-show){-webkit-transform:scale(1);transform:scale(1);opacity:1;visibility:visible}:host(.fab-list-side-top){top:auto;bottom:0;-ms-flex-direction:column-reverse;flex-direction:column-reverse}:host(.fab-list-side-start){-webkit-margin-start:calc(100% + 10px);margin-inline-start:calc(100% + 10px);-webkit-margin-end:calc(100% + 10px);margin-inline-end:calc(100% + 10px);margin-top:0;margin-bottom:0;-ms-flex-direction:row-reverse;flex-direction:row-reverse}:host(.fab-list-side-start){inset-inline-end:0}:host(.fab-list-side-end){-webkit-margin-start:calc(100% + 10px);margin-inline-start:calc(100% + 10px);-webkit-margin-end:calc(100% + 10px);margin-inline-end:calc(100% + 10px);margin-top:0;margin-bottom:0;-ms-flex-direction:row;flex-direction:row}:host(.fab-list-side-end){inset-inline-start:0}";
  13194. var IonFabListStyle0 = fabListCss;
  13195. class FabList {
  13196. constructor(hostRef) {
  13197. registerInstance(this, hostRef);
  13198. this.activated = false;
  13199. this.side = 'bottom';
  13200. }
  13201. activatedChanged(activated) {
  13202. const fabs = Array.from(this.el.querySelectorAll('ion-fab-button'));
  13203. // if showing the fabs add a timeout, else show immediately
  13204. const timeout = activated ? 30 : 0;
  13205. fabs.forEach((fab, i) => {
  13206. setTimeout(() => (fab.show = activated), i * timeout);
  13207. });
  13208. }
  13209. render() {
  13210. const mode = getIonMode$1(this);
  13211. return (hAsync(Host, { key: '64b33366447f66c7f979cfac56307fbb1a6fac1c', class: {
  13212. [mode]: true,
  13213. 'fab-list-active': this.activated,
  13214. [`fab-list-side-${this.side}`]: true,
  13215. } }, hAsync("slot", { key: 'd9f474f7f20fd7e813db358fddc720534ca05bb6' })));
  13216. }
  13217. get el() { return getElement(this); }
  13218. static get watchers() { return {
  13219. "activated": ["activatedChanged"]
  13220. }; }
  13221. static get style() { return IonFabListStyle0; }
  13222. static get cmpMeta() { return {
  13223. "$flags$": 9,
  13224. "$tagName$": "ion-fab-list",
  13225. "$members$": {
  13226. "activated": [4],
  13227. "side": [1]
  13228. },
  13229. "$listeners$": undefined,
  13230. "$lazyBundleId$": "-",
  13231. "$attrsToReflect$": []
  13232. }; }
  13233. }
  13234. const ION_CONTENT_TAG_NAME = 'ION-CONTENT';
  13235. const ION_CONTENT_ELEMENT_SELECTOR = 'ion-content';
  13236. const ION_CONTENT_CLASS_SELECTOR = '.ion-content-scroll-host';
  13237. /**
  13238. * Selector used for implementations reliant on `<ion-content>` for scroll event changes.
  13239. *
  13240. * Developers should use the `.ion-content-scroll-host` selector to target the element emitting
  13241. * scroll events. With virtual scroll implementations this will be the host element for
  13242. * the scroll viewport.
  13243. */
  13244. const ION_CONTENT_SELECTOR = `${ION_CONTENT_ELEMENT_SELECTOR}, ${ION_CONTENT_CLASS_SELECTOR}`;
  13245. const isIonContent = (el) => el.tagName === ION_CONTENT_TAG_NAME;
  13246. /**
  13247. * Waits for the element host fully initialize before
  13248. * returning the inner scroll element.
  13249. *
  13250. * For `ion-content` the scroll target will be the result
  13251. * of the `getScrollElement` function.
  13252. *
  13253. * For custom implementations it will be the element host
  13254. * or a selector within the host, if supplied through `scrollTarget`.
  13255. */
  13256. const getScrollElement = async (el) => {
  13257. if (isIonContent(el)) {
  13258. await new Promise((resolve) => componentOnReady(el, resolve));
  13259. return el.getScrollElement();
  13260. }
  13261. return el;
  13262. };
  13263. /**
  13264. * Queries the element matching the selector for IonContent.
  13265. * See ION_CONTENT_SELECTOR for the selector used.
  13266. */
  13267. const findIonContent = (el) => {
  13268. /**
  13269. * First we try to query the custom scroll host selector in cases where
  13270. * the implementation is using an outer `ion-content` with an inner custom
  13271. * scroll container.
  13272. */
  13273. const customContentHost = el.querySelector(ION_CONTENT_CLASS_SELECTOR);
  13274. if (customContentHost) {
  13275. return customContentHost;
  13276. }
  13277. return el.querySelector(ION_CONTENT_SELECTOR);
  13278. };
  13279. /**
  13280. * Queries the closest element matching the selector for IonContent.
  13281. */
  13282. const findClosestIonContent = (el) => {
  13283. return el.closest(ION_CONTENT_SELECTOR);
  13284. };
  13285. /**
  13286. * Prints an error informing developers that an implementation requires an element to be used
  13287. * within either the `ion-content` selector or the `.ion-content-scroll-host` class.
  13288. */
  13289. const printIonContentErrorMsg = (el) => {
  13290. return printRequiredElementError(el, ION_CONTENT_ELEMENT_SELECTOR);
  13291. };
  13292. /**
  13293. * Several components in Ionic need to prevent scrolling
  13294. * during a gesture (card modal, range, item sliding, etc).
  13295. * Use this utility to account for ion-content and custom content hosts.
  13296. */
  13297. const disableContentScrollY = (contentEl) => {
  13298. if (isIonContent(contentEl)) {
  13299. const ionContent = contentEl;
  13300. const initialScrollY = ionContent.scrollY;
  13301. ionContent.scrollY = false;
  13302. /**
  13303. * This should be passed into resetContentScrollY
  13304. * so that we can revert ion-content's scrollY to the
  13305. * correct state. For example, if scrollY = false
  13306. * initially, we do not want to enable scrolling
  13307. * when we call resetContentScrollY.
  13308. */
  13309. return initialScrollY;
  13310. }
  13311. else {
  13312. contentEl.style.setProperty('overflow', 'hidden');
  13313. return true;
  13314. }
  13315. };
  13316. const resetContentScrollY = (contentEl, initialScrollY) => {
  13317. if (isIonContent(contentEl)) {
  13318. contentEl.scrollY = initialScrollY;
  13319. }
  13320. else {
  13321. contentEl.style.removeProperty('overflow');
  13322. }
  13323. };
  13324. var ExceptionCode;
  13325. (function (ExceptionCode) {
  13326. /**
  13327. * API is not implemented.
  13328. *
  13329. * This usually means the API can't be used because it is not implemented for
  13330. * the current platform.
  13331. */
  13332. ExceptionCode["Unimplemented"] = "UNIMPLEMENTED";
  13333. /**
  13334. * API is not available.
  13335. *
  13336. * This means the API can't be used right now because:
  13337. * - it is currently missing a prerequisite, such as network connectivity
  13338. * - it requires a particular platform or browser version
  13339. */
  13340. ExceptionCode["Unavailable"] = "UNAVAILABLE";
  13341. })(ExceptionCode || (ExceptionCode = {}));
  13342. var KeyboardResize;
  13343. (function (KeyboardResize) {
  13344. /**
  13345. * Only the `body` HTML element will be resized.
  13346. * Relative units are not affected, because the viewport does not change.
  13347. *
  13348. * @since 1.0.0
  13349. */
  13350. KeyboardResize["Body"] = "body";
  13351. /**
  13352. * Only the `ion-app` HTML element will be resized.
  13353. * Use it only for Ionic Framework apps.
  13354. *
  13355. * @since 1.0.0
  13356. */
  13357. KeyboardResize["Ionic"] = "ionic";
  13358. /**
  13359. * The whole native Web View will be resized when the keyboard shows/hides.
  13360. * This affects the `vh` relative unit.
  13361. *
  13362. * @since 1.0.0
  13363. */
  13364. KeyboardResize["Native"] = "native";
  13365. /**
  13366. * Neither the app nor the Web View are resized.
  13367. *
  13368. * @since 1.0.0
  13369. */
  13370. KeyboardResize["None"] = "none";
  13371. })(KeyboardResize || (KeyboardResize = {}));
  13372. const Keyboard = {
  13373. getEngine() {
  13374. const capacitor = getCapacitor();
  13375. if (capacitor === null || capacitor === void 0 ? void 0 : capacitor.isPluginAvailable('Keyboard')) {
  13376. return capacitor.Plugins.Keyboard;
  13377. }
  13378. return undefined;
  13379. },
  13380. getResizeMode() {
  13381. const engine = this.getEngine();
  13382. if (!(engine === null || engine === void 0 ? void 0 : engine.getResizeMode)) {
  13383. return Promise.resolve(undefined);
  13384. }
  13385. return engine.getResizeMode().catch((e) => {
  13386. if (e.code === ExceptionCode.Unimplemented) {
  13387. // If the native implementation is not available
  13388. // we treat it the same as if the plugin is not available.
  13389. return undefined;
  13390. }
  13391. throw e;
  13392. });
  13393. },
  13394. };
  13395. /**
  13396. * The element that resizes when the keyboard opens
  13397. * is going to depend on the resize mode
  13398. * which is why we check that here.
  13399. */
  13400. const getResizeContainer = (resizeMode) => {
  13401. /**
  13402. * If doc is undefined then we are
  13403. * in an SSR environment, so the keyboard
  13404. * adjustment does not apply.
  13405. * If the webview does not resize then there
  13406. * is no container to resize.
  13407. */
  13408. if (doc === undefined || resizeMode === KeyboardResize.None || resizeMode === undefined) {
  13409. return null;
  13410. }
  13411. /**
  13412. * The three remaining resize modes: Native, Ionic, and Body
  13413. * all cause `ion-app` to resize, so we can listen for changes
  13414. * on that. In the event `ion-app` is not available then
  13415. * we can fall back to `body`.
  13416. */
  13417. const ionApp = doc.querySelector('ion-app');
  13418. return ionApp !== null && ionApp !== void 0 ? ionApp : doc.body;
  13419. };
  13420. /**
  13421. * Get the height of ion-app or body.
  13422. * This is used for determining if the webview
  13423. * has resized before the keyboard closed.
  13424. * */
  13425. const getResizeContainerHeight = (resizeMode) => {
  13426. const containerElement = getResizeContainer(resizeMode);
  13427. return containerElement === null ? 0 : containerElement.clientHeight;
  13428. };
  13429. /**
  13430. * Creates a controller that tracks and reacts to opening or closing the keyboard.
  13431. *
  13432. * @internal
  13433. * @param keyboardChangeCallback A function to call when the keyboard opens or closes.
  13434. */
  13435. const createKeyboardController = async (keyboardChangeCallback) => {
  13436. let keyboardWillShowHandler;
  13437. let keyboardWillHideHandler;
  13438. let keyboardVisible;
  13439. /**
  13440. * This lets us determine if the webview content
  13441. * has resized as a result of the keyboard.
  13442. */
  13443. let initialResizeContainerHeight;
  13444. const init = async () => {
  13445. const resizeOptions = await Keyboard.getResizeMode();
  13446. const resizeMode = resizeOptions === undefined ? undefined : resizeOptions.mode;
  13447. keyboardWillShowHandler = () => {
  13448. /**
  13449. * We need to compute initialResizeContainerHeight right before
  13450. * the keyboard opens to guarantee the resize container is visible.
  13451. * The resize container may not be visible if we compute this
  13452. * as soon as the keyboard controller is created.
  13453. * We should only need to do this once to avoid additional clientHeight
  13454. * computations.
  13455. */
  13456. if (initialResizeContainerHeight === undefined) {
  13457. initialResizeContainerHeight = getResizeContainerHeight(resizeMode);
  13458. }
  13459. keyboardVisible = true;
  13460. fireChangeCallback(keyboardVisible, resizeMode);
  13461. };
  13462. keyboardWillHideHandler = () => {
  13463. keyboardVisible = false;
  13464. fireChangeCallback(keyboardVisible, resizeMode);
  13465. };
  13466. win$1 === null || win$1 === void 0 ? void 0 : win$1.addEventListener('keyboardWillShow', keyboardWillShowHandler);
  13467. win$1 === null || win$1 === void 0 ? void 0 : win$1.addEventListener('keyboardWillHide', keyboardWillHideHandler);
  13468. };
  13469. const fireChangeCallback = (state, resizeMode) => {
  13470. if (keyboardChangeCallback) {
  13471. keyboardChangeCallback(state, createResizePromiseIfNeeded(resizeMode));
  13472. }
  13473. };
  13474. /**
  13475. * Code responding to keyboard lifecycles may need
  13476. * to show/hide content once the webview has
  13477. * resized as a result of the keyboard showing/hiding.
  13478. * createResizePromiseIfNeeded provides a way for code to wait for the
  13479. * resize event that was triggered as a result of the keyboard.
  13480. */
  13481. const createResizePromiseIfNeeded = (resizeMode) => {
  13482. if (
  13483. /**
  13484. * If we are in an SSR environment then there is
  13485. * no window to resize. Additionally, if there
  13486. * is no resize mode or the resize mode is "None"
  13487. * then initialResizeContainerHeight will be 0
  13488. */
  13489. initialResizeContainerHeight === 0 ||
  13490. /**
  13491. * If the keyboard is closed before the webview resizes initially
  13492. * then the webview will never resize.
  13493. */
  13494. initialResizeContainerHeight === getResizeContainerHeight(resizeMode)) {
  13495. return;
  13496. }
  13497. /**
  13498. * Get the resize container so we can
  13499. * attach the ResizeObserver below to
  13500. * the correct element.
  13501. */
  13502. const containerElement = getResizeContainer(resizeMode);
  13503. if (containerElement === null) {
  13504. return;
  13505. }
  13506. /**
  13507. * Some part of the web content should resize,
  13508. * and we need to listen for a resize.
  13509. */
  13510. return new Promise((resolve) => {
  13511. const callback = () => {
  13512. /**
  13513. * As per the spec, the ResizeObserver
  13514. * will fire when observation starts if
  13515. * the observed element is rendered and does not
  13516. * have a size of 0 x 0. However, the watched element
  13517. * may or may not have resized by the time this first
  13518. * callback is fired. As a result, we need to check
  13519. * the dimensions of the element.
  13520. *
  13521. * https://www.w3.org/TR/resize-observer/#intro
  13522. */
  13523. if (containerElement.clientHeight === initialResizeContainerHeight) {
  13524. /**
  13525. * The resize happened, so stop listening
  13526. * for resize on this element.
  13527. */
  13528. ro.disconnect();
  13529. resolve();
  13530. }
  13531. };
  13532. /**
  13533. * In Capacitor there can be delay between when the window
  13534. * resizes and when the container element resizes, so we cannot
  13535. * rely on a 'resize' event listener on the window.
  13536. * Instead, we need to determine when the container
  13537. * element resizes using a ResizeObserver.
  13538. */
  13539. const ro = new ResizeObserver(callback);
  13540. ro.observe(containerElement);
  13541. });
  13542. };
  13543. const destroy = () => {
  13544. win$1 === null || win$1 === void 0 ? void 0 : win$1.removeEventListener('keyboardWillShow', keyboardWillShowHandler);
  13545. win$1 === null || win$1 === void 0 ? void 0 : win$1.removeEventListener('keyboardWillHide', keyboardWillHideHandler);
  13546. keyboardWillShowHandler = keyboardWillHideHandler = undefined;
  13547. };
  13548. const isKeyboardVisible = () => keyboardVisible;
  13549. await init();
  13550. return { init, destroy, isKeyboardVisible };
  13551. };
  13552. const handleFooterFade = (scrollEl, baseEl) => {
  13553. readTask(() => {
  13554. const scrollTop = scrollEl.scrollTop;
  13555. const maxScroll = scrollEl.scrollHeight - scrollEl.clientHeight;
  13556. /**
  13557. * Toolbar background will fade
  13558. * out over fadeDuration in pixels.
  13559. */
  13560. const fadeDuration = 10;
  13561. /**
  13562. * Begin fading out maxScroll - 30px
  13563. * from the bottom of the content.
  13564. * Also determine how close we are
  13565. * to starting the fade. If we are
  13566. * before the starting point, the
  13567. * scale value will get clamped to 0.
  13568. * If we are after the maxScroll (rubber
  13569. * band scrolling), the scale value will
  13570. * get clamped to 1.
  13571. */
  13572. const fadeStart = maxScroll - fadeDuration;
  13573. const distanceToStart = scrollTop - fadeStart;
  13574. const scale = clamp(0, 1 - distanceToStart / fadeDuration, 1);
  13575. writeTask(() => {
  13576. baseEl.style.setProperty('--opacity-scale', scale.toString());
  13577. });
  13578. });
  13579. };
  13580. const footerIosCss = "ion-footer{display:block;position:relative;-ms-flex-order:1;order:1;width:100%;z-index:10}ion-footer.footer-toolbar-padding ion-toolbar:last-of-type{padding-bottom:var(--ion-safe-area-bottom, 0)}.footer-ios ion-toolbar:first-of-type{--border-width:0.55px 0 0}@supports ((-webkit-backdrop-filter: blur(0)) or (backdrop-filter: blur(0))){.footer-background{left:0;right:0;top:0;bottom:0;position:absolute;-webkit-backdrop-filter:saturate(180%) blur(20px);backdrop-filter:saturate(180%) blur(20px)}.footer-translucent-ios ion-toolbar{--opacity:.8}}.footer-ios.ion-no-border ion-toolbar:first-of-type{--border-width:0}.footer-collapse-fade ion-toolbar{--opacity-scale:inherit}";
  13581. var IonFooterIosStyle0 = footerIosCss;
  13582. const footerMdCss = "ion-footer{display:block;position:relative;-ms-flex-order:1;order:1;width:100%;z-index:10}ion-footer.footer-toolbar-padding ion-toolbar:last-of-type{padding-bottom:var(--ion-safe-area-bottom, 0)}.footer-md{-webkit-box-shadow:0 2px 4px -1px rgba(0, 0, 0, 0.2), 0 4px 5px 0 rgba(0, 0, 0, 0.14), 0 1px 10px 0 rgba(0, 0, 0, 0.12);box-shadow:0 2px 4px -1px rgba(0, 0, 0, 0.2), 0 4px 5px 0 rgba(0, 0, 0, 0.14), 0 1px 10px 0 rgba(0, 0, 0, 0.12)}.footer-md.ion-no-border{-webkit-box-shadow:none;box-shadow:none}";
  13583. var IonFooterMdStyle0 = footerMdCss;
  13584. /**
  13585. * @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
  13586. */
  13587. class Footer {
  13588. constructor(hostRef) {
  13589. registerInstance(this, hostRef);
  13590. this.keyboardCtrl = null;
  13591. this.checkCollapsibleFooter = () => {
  13592. const mode = getIonMode$1(this);
  13593. if (mode !== 'ios') {
  13594. return;
  13595. }
  13596. const { collapse } = this;
  13597. const hasFade = collapse === 'fade';
  13598. this.destroyCollapsibleFooter();
  13599. if (hasFade) {
  13600. const pageEl = this.el.closest('ion-app,ion-page,.ion-page,page-inner');
  13601. const contentEl = pageEl ? findIonContent(pageEl) : null;
  13602. if (!contentEl) {
  13603. printIonContentErrorMsg(this.el);
  13604. return;
  13605. }
  13606. this.setupFadeFooter(contentEl);
  13607. }
  13608. };
  13609. this.setupFadeFooter = async (contentEl) => {
  13610. const scrollEl = (this.scrollEl = await getScrollElement(contentEl));
  13611. /**
  13612. * Handle fading of toolbars on scroll
  13613. */
  13614. this.contentScrollCallback = () => {
  13615. handleFooterFade(scrollEl, this.el);
  13616. };
  13617. scrollEl.addEventListener('scroll', this.contentScrollCallback);
  13618. handleFooterFade(scrollEl, this.el);
  13619. };
  13620. this.keyboardVisible = false;
  13621. this.collapse = undefined;
  13622. this.translucent = false;
  13623. }
  13624. componentDidLoad() {
  13625. this.checkCollapsibleFooter();
  13626. }
  13627. componentDidUpdate() {
  13628. this.checkCollapsibleFooter();
  13629. }
  13630. async connectedCallback() {
  13631. this.keyboardCtrl = await createKeyboardController(async (keyboardOpen, waitForResize) => {
  13632. /**
  13633. * If the keyboard is hiding, then we need to wait
  13634. * for the webview to resize. Otherwise, the footer
  13635. * will flicker before the webview resizes.
  13636. */
  13637. if (keyboardOpen === false && waitForResize !== undefined) {
  13638. await waitForResize;
  13639. }
  13640. this.keyboardVisible = keyboardOpen; // trigger re-render by updating state
  13641. });
  13642. }
  13643. disconnectedCallback() {
  13644. if (this.keyboardCtrl) {
  13645. this.keyboardCtrl.destroy();
  13646. }
  13647. }
  13648. destroyCollapsibleFooter() {
  13649. if (this.scrollEl && this.contentScrollCallback) {
  13650. this.scrollEl.removeEventListener('scroll', this.contentScrollCallback);
  13651. this.contentScrollCallback = undefined;
  13652. }
  13653. }
  13654. render() {
  13655. const { translucent, collapse } = this;
  13656. const mode = getIonMode$1(this);
  13657. const tabs = this.el.closest('ion-tabs');
  13658. const tabBar = tabs === null || tabs === void 0 ? void 0 : tabs.querySelector(':scope > ion-tab-bar');
  13659. return (hAsync(Host, { key: 'ddc228f1a1e7fa4f707dccf74db2490ca3241137', role: "contentinfo", class: {
  13660. [mode]: true,
  13661. // Used internally for styling
  13662. [`footer-${mode}`]: true,
  13663. [`footer-translucent`]: translucent,
  13664. [`footer-translucent-${mode}`]: translucent,
  13665. ['footer-toolbar-padding']: !this.keyboardVisible && (!tabBar || tabBar.slot !== 'bottom'),
  13666. [`footer-collapse-${collapse}`]: collapse !== undefined,
  13667. } }, mode === 'ios' && translucent && hAsync("div", { key: 'e16ed4963ff94e06de77eb8038201820af73937c', class: "footer-background" }), hAsync("slot", { key: 'f186934febf85d37133d9351a96c1a64b0a4b203' })));
  13668. }
  13669. get el() { return getElement(this); }
  13670. static get style() { return {
  13671. ios: IonFooterIosStyle0,
  13672. md: IonFooterMdStyle0
  13673. }; }
  13674. static get cmpMeta() { return {
  13675. "$flags$": 36,
  13676. "$tagName$": "ion-footer",
  13677. "$members$": {
  13678. "collapse": [1],
  13679. "translucent": [4],
  13680. "keyboardVisible": [32]
  13681. },
  13682. "$listeners$": undefined,
  13683. "$lazyBundleId$": "-",
  13684. "$attrsToReflect$": []
  13685. }; }
  13686. }
  13687. const gridCss = ":host{-webkit-padding-start:var(--ion-grid-padding-xs, var(--ion-grid-padding, 5px));padding-inline-start:var(--ion-grid-padding-xs, var(--ion-grid-padding, 5px));-webkit-padding-end:var(--ion-grid-padding-xs, var(--ion-grid-padding, 5px));padding-inline-end:var(--ion-grid-padding-xs, var(--ion-grid-padding, 5px));padding-top:var(--ion-grid-padding-xs, var(--ion-grid-padding, 5px));padding-bottom:var(--ion-grid-padding-xs, var(--ion-grid-padding, 5px));-webkit-margin-start:auto;margin-inline-start:auto;-webkit-margin-end:auto;margin-inline-end:auto;display:block;-ms-flex:1;flex:1}@media (min-width: 576px){:host{-webkit-padding-start:var(--ion-grid-padding-sm, var(--ion-grid-padding, 5px));padding-inline-start:var(--ion-grid-padding-sm, var(--ion-grid-padding, 5px));-webkit-padding-end:var(--ion-grid-padding-sm, var(--ion-grid-padding, 5px));padding-inline-end:var(--ion-grid-padding-sm, var(--ion-grid-padding, 5px));padding-top:var(--ion-grid-padding-sm, var(--ion-grid-padding, 5px));padding-bottom:var(--ion-grid-padding-sm, var(--ion-grid-padding, 5px))}}@media (min-width: 768px){:host{-webkit-padding-start:var(--ion-grid-padding-md, var(--ion-grid-padding, 5px));padding-inline-start:var(--ion-grid-padding-md, var(--ion-grid-padding, 5px));-webkit-padding-end:var(--ion-grid-padding-md, var(--ion-grid-padding, 5px));padding-inline-end:var(--ion-grid-padding-md, var(--ion-grid-padding, 5px));padding-top:var(--ion-grid-padding-md, var(--ion-grid-padding, 5px));padding-bottom:var(--ion-grid-padding-md, var(--ion-grid-padding, 5px))}}@media (min-width: 992px){:host{-webkit-padding-start:var(--ion-grid-padding-lg, var(--ion-grid-padding, 5px));padding-inline-start:var(--ion-grid-padding-lg, var(--ion-grid-padding, 5px));-webkit-padding-end:var(--ion-grid-padding-lg, var(--ion-grid-padding, 5px));padding-inline-end:var(--ion-grid-padding-lg, var(--ion-grid-padding, 5px));padding-top:var(--ion-grid-padding-lg, var(--ion-grid-padding, 5px));padding-bottom:var(--ion-grid-padding-lg, var(--ion-grid-padding, 5px))}}@media (min-width: 1200px){:host{-webkit-padding-start:var(--ion-grid-padding-xl, var(--ion-grid-padding, 5px));padding-inline-start:var(--ion-grid-padding-xl, var(--ion-grid-padding, 5px));-webkit-padding-end:var(--ion-grid-padding-xl, var(--ion-grid-padding, 5px));padding-inline-end:var(--ion-grid-padding-xl, var(--ion-grid-padding, 5px));padding-top:var(--ion-grid-padding-xl, var(--ion-grid-padding, 5px));padding-bottom:var(--ion-grid-padding-xl, var(--ion-grid-padding, 5px))}}:host(.grid-fixed){width:var(--ion-grid-width-xs, var(--ion-grid-width, 100%));max-width:100%}@media (min-width: 576px){:host(.grid-fixed){width:var(--ion-grid-width-sm, var(--ion-grid-width, 540px))}}@media (min-width: 768px){:host(.grid-fixed){width:var(--ion-grid-width-md, var(--ion-grid-width, 720px))}}@media (min-width: 992px){:host(.grid-fixed){width:var(--ion-grid-width-lg, var(--ion-grid-width, 960px))}}@media (min-width: 1200px){:host(.grid-fixed){width:var(--ion-grid-width-xl, var(--ion-grid-width, 1140px))}}:host(.ion-no-padding){--ion-grid-column-padding:0;--ion-grid-column-padding-xs:0;--ion-grid-column-padding-sm:0;--ion-grid-column-padding-md:0;--ion-grid-column-padding-lg:0;--ion-grid-column-padding-xl:0}";
  13688. var IonGridStyle0 = gridCss;
  13689. class Grid {
  13690. constructor(hostRef) {
  13691. registerInstance(this, hostRef);
  13692. this.fixed = false;
  13693. }
  13694. render() {
  13695. const mode = getIonMode$1(this);
  13696. return (hAsync(Host, { key: '617127ecfabf9bf615bef1dda1be3fed5a065949', class: {
  13697. [mode]: true,
  13698. 'grid-fixed': this.fixed,
  13699. } }, hAsync("slot", { key: 'c781fff853b093d8f44bdb7943bbc4f17c903803' })));
  13700. }
  13701. static get style() { return IonGridStyle0; }
  13702. static get cmpMeta() { return {
  13703. "$flags$": 9,
  13704. "$tagName$": "ion-grid",
  13705. "$members$": {
  13706. "fixed": [4]
  13707. },
  13708. "$listeners$": undefined,
  13709. "$lazyBundleId$": "-",
  13710. "$attrsToReflect$": []
  13711. }; }
  13712. }
  13713. const TRANSITION = 'all 0.2s ease-in-out';
  13714. const cloneElement = (tagName) => {
  13715. const getCachedEl = document.querySelector(`${tagName}.ion-cloned-element`);
  13716. if (getCachedEl !== null) {
  13717. return getCachedEl;
  13718. }
  13719. const clonedEl = document.createElement(tagName);
  13720. clonedEl.classList.add('ion-cloned-element');
  13721. clonedEl.style.setProperty('display', 'none');
  13722. document.body.appendChild(clonedEl);
  13723. return clonedEl;
  13724. };
  13725. const createHeaderIndex = (headerEl) => {
  13726. if (!headerEl) {
  13727. return;
  13728. }
  13729. const toolbars = headerEl.querySelectorAll('ion-toolbar');
  13730. return {
  13731. el: headerEl,
  13732. toolbars: Array.from(toolbars).map((toolbar) => {
  13733. const ionTitleEl = toolbar.querySelector('ion-title');
  13734. return {
  13735. el: toolbar,
  13736. background: toolbar.shadowRoot.querySelector('.toolbar-background'),
  13737. ionTitleEl,
  13738. innerTitleEl: ionTitleEl ? ionTitleEl.shadowRoot.querySelector('.toolbar-title') : null,
  13739. ionButtonsEl: Array.from(toolbar.querySelectorAll('ion-buttons')),
  13740. };
  13741. }),
  13742. };
  13743. };
  13744. const handleContentScroll = (scrollEl, scrollHeaderIndex, contentEl) => {
  13745. readTask(() => {
  13746. const scrollTop = scrollEl.scrollTop;
  13747. const scale = clamp(1, 1 + -scrollTop / 500, 1.1);
  13748. // Native refresher should not cause titles to scale
  13749. const nativeRefresher = contentEl.querySelector('ion-refresher.refresher-native');
  13750. if (nativeRefresher === null) {
  13751. writeTask(() => {
  13752. scaleLargeTitles(scrollHeaderIndex.toolbars, scale);
  13753. });
  13754. }
  13755. });
  13756. };
  13757. const setToolbarBackgroundOpacity = (headerEl, opacity) => {
  13758. /**
  13759. * Fading in the backdrop opacity
  13760. * should happen after the large title
  13761. * has collapsed, so it is handled
  13762. * by handleHeaderFade()
  13763. */
  13764. if (headerEl.collapse === 'fade') {
  13765. return;
  13766. }
  13767. if (opacity === undefined) {
  13768. headerEl.style.removeProperty('--opacity-scale');
  13769. }
  13770. else {
  13771. headerEl.style.setProperty('--opacity-scale', opacity.toString());
  13772. }
  13773. };
  13774. const handleToolbarBorderIntersection = (ev, mainHeaderIndex, scrollTop) => {
  13775. if (!ev[0].isIntersecting) {
  13776. return;
  13777. }
  13778. /**
  13779. * There is a bug in Safari where overflow scrolling on a non-body element
  13780. * does not always reset the scrollTop position to 0 when letting go. It will
  13781. * set to 1 once the rubber band effect has ended. This causes the background to
  13782. * appear slightly on certain app setups.
  13783. *
  13784. * Additionally, we check if user is rubber banding (scrolling is negative)
  13785. * as this can mean they are using pull to refresh. Once the refresher starts,
  13786. * the content is transformed which can cause the intersection observer to erroneously
  13787. * fire here as well.
  13788. */
  13789. const scale = ev[0].intersectionRatio > 0.9 || scrollTop <= 0 ? 0 : ((1 - ev[0].intersectionRatio) * 100) / 75;
  13790. setToolbarBackgroundOpacity(mainHeaderIndex.el, scale === 1 ? undefined : scale);
  13791. };
  13792. /**
  13793. * If toolbars are intersecting, hide the scrollable toolbar content
  13794. * and show the primary toolbar content. If the toolbars are not intersecting,
  13795. * hide the primary toolbar content and show the scrollable toolbar content
  13796. */
  13797. const handleToolbarIntersection = (ev, // TODO(FW-2832): type (IntersectionObserverEntry[] triggers errors which should be sorted)
  13798. mainHeaderIndex, scrollHeaderIndex, scrollEl) => {
  13799. writeTask(() => {
  13800. const scrollTop = scrollEl.scrollTop;
  13801. handleToolbarBorderIntersection(ev, mainHeaderIndex, scrollTop);
  13802. const event = ev[0];
  13803. const intersection = event.intersectionRect;
  13804. const intersectionArea = intersection.width * intersection.height;
  13805. const rootArea = event.rootBounds.width * event.rootBounds.height;
  13806. const isPageHidden = intersectionArea === 0 && rootArea === 0;
  13807. const leftDiff = Math.abs(intersection.left - event.boundingClientRect.left);
  13808. const rightDiff = Math.abs(intersection.right - event.boundingClientRect.right);
  13809. const isPageTransitioning = intersectionArea > 0 && (leftDiff >= 5 || rightDiff >= 5);
  13810. if (isPageHidden || isPageTransitioning) {
  13811. return;
  13812. }
  13813. if (event.isIntersecting) {
  13814. setHeaderActive(mainHeaderIndex, false);
  13815. setHeaderActive(scrollHeaderIndex);
  13816. }
  13817. else {
  13818. /**
  13819. * There is a bug with IntersectionObserver on Safari
  13820. * where `event.isIntersecting === false` when cancelling
  13821. * a swipe to go back gesture. Checking the intersection
  13822. * x, y, width, and height provides a workaround. This bug
  13823. * does not happen when using Safari + Web Animations,
  13824. * only Safari + CSS Animations.
  13825. */
  13826. const hasValidIntersection = (intersection.x === 0 && intersection.y === 0) || (intersection.width !== 0 && intersection.height !== 0);
  13827. if (hasValidIntersection && scrollTop > 0) {
  13828. setHeaderActive(mainHeaderIndex);
  13829. setHeaderActive(scrollHeaderIndex, false);
  13830. setToolbarBackgroundOpacity(mainHeaderIndex.el);
  13831. }
  13832. }
  13833. });
  13834. };
  13835. const setHeaderActive = (headerIndex, active = true) => {
  13836. const headerEl = headerIndex.el;
  13837. const toolbars = headerIndex.toolbars;
  13838. const ionTitles = toolbars.map((toolbar) => toolbar.ionTitleEl);
  13839. if (active) {
  13840. headerEl.classList.remove('header-collapse-condense-inactive');
  13841. ionTitles.forEach((ionTitle) => {
  13842. if (ionTitle) {
  13843. ionTitle.removeAttribute('aria-hidden');
  13844. }
  13845. });
  13846. }
  13847. else {
  13848. headerEl.classList.add('header-collapse-condense-inactive');
  13849. /**
  13850. * The small title should only be accessed by screen readers
  13851. * when the large title collapses into the small title due
  13852. * to scrolling.
  13853. *
  13854. * Originally, the header was given `aria-hidden="true"`
  13855. * but this caused issues with screen readers not being
  13856. * able to access any focusable elements within the header.
  13857. */
  13858. ionTitles.forEach((ionTitle) => {
  13859. if (ionTitle) {
  13860. ionTitle.setAttribute('aria-hidden', 'true');
  13861. }
  13862. });
  13863. }
  13864. };
  13865. const scaleLargeTitles = (toolbars = [], scale = 1, transition = false) => {
  13866. toolbars.forEach((toolbar) => {
  13867. const ionTitle = toolbar.ionTitleEl;
  13868. const titleDiv = toolbar.innerTitleEl;
  13869. if (!ionTitle || ionTitle.size !== 'large') {
  13870. return;
  13871. }
  13872. titleDiv.style.transition = transition ? TRANSITION : '';
  13873. titleDiv.style.transform = `scale3d(${scale}, ${scale}, 1)`;
  13874. });
  13875. };
  13876. const handleHeaderFade = (scrollEl, baseEl, condenseHeader) => {
  13877. readTask(() => {
  13878. const scrollTop = scrollEl.scrollTop;
  13879. const baseElHeight = baseEl.clientHeight;
  13880. const fadeStart = condenseHeader ? condenseHeader.clientHeight : 0;
  13881. /**
  13882. * If we are using fade header with a condense
  13883. * header, then the toolbar backgrounds should
  13884. * not begin to fade in until the condense
  13885. * header has fully collapsed.
  13886. *
  13887. * Additionally, the main content should not
  13888. * overflow out of the container until the
  13889. * condense header has fully collapsed. When
  13890. * using just the condense header the content
  13891. * should overflow out of the container.
  13892. */
  13893. if (condenseHeader !== null && scrollTop < fadeStart) {
  13894. baseEl.style.setProperty('--opacity-scale', '0');
  13895. scrollEl.style.setProperty('clip-path', `inset(${baseElHeight}px 0px 0px 0px)`);
  13896. return;
  13897. }
  13898. const distanceToStart = scrollTop - fadeStart;
  13899. const fadeDuration = 10;
  13900. const scale = clamp(0, distanceToStart / fadeDuration, 1);
  13901. writeTask(() => {
  13902. scrollEl.style.removeProperty('clip-path');
  13903. baseEl.style.setProperty('--opacity-scale', scale.toString());
  13904. });
  13905. });
  13906. };
  13907. const headerIosCss = "ion-header{display:block;position:relative;-ms-flex-order:-1;order:-1;width:100%;z-index:10}ion-header ion-toolbar:first-of-type{padding-top:var(--ion-safe-area-top, 0)}.header-ios ion-toolbar:last-of-type{--border-width:0 0 0.55px}@supports ((-webkit-backdrop-filter: blur(0)) or (backdrop-filter: blur(0))){.header-background{left:0;right:0;top:0;bottom:0;position:absolute;-webkit-backdrop-filter:saturate(180%) blur(20px);backdrop-filter:saturate(180%) blur(20px)}.header-translucent-ios ion-toolbar{--opacity:.8}.header-collapse-condense-inactive .header-background{-webkit-backdrop-filter:blur(20px);backdrop-filter:blur(20px)}}.header-ios.ion-no-border ion-toolbar:last-of-type{--border-width:0}.header-collapse-fade ion-toolbar{--opacity-scale:inherit}.header-collapse-condense{z-index:9}.header-collapse-condense ion-toolbar{position:-webkit-sticky;position:sticky;top:0}.header-collapse-condense ion-toolbar:first-of-type{padding-top:0px;z-index:1}.header-collapse-condense ion-toolbar{--background:var(--ion-background-color, #fff);z-index:0}.header-collapse-condense ion-toolbar:last-of-type{--border-width:0px}.header-collapse-condense ion-toolbar ion-searchbar{padding-top:0px;padding-bottom:13px}.header-collapse-main{--opacity-scale:1}.header-collapse-main ion-toolbar{--opacity-scale:inherit}.header-collapse-main ion-toolbar.in-toolbar ion-title,.header-collapse-main ion-toolbar.in-toolbar ion-buttons{-webkit-transition:all 0.2s ease-in-out;transition:all 0.2s ease-in-out}.header-collapse-condense-inactive:not(.header-collapse-condense) ion-toolbar.in-toolbar ion-title,.header-collapse-condense-inactive:not(.header-collapse-condense) ion-toolbar.in-toolbar ion-buttons.buttons-collapse{opacity:0;pointer-events:none}.header-collapse-condense-inactive.header-collapse-condense ion-toolbar.in-toolbar ion-title,.header-collapse-condense-inactive.header-collapse-condense ion-toolbar.in-toolbar ion-buttons.buttons-collapse{visibility:hidden}ion-header.header-ios:not(.header-collapse-main):has(~ion-content ion-header.header-ios[collapse=condense],~ion-content ion-header.header-ios.header-collapse-condense){opacity:0}";
  13908. var IonHeaderIosStyle0 = headerIosCss;
  13909. const headerMdCss = "ion-header{display:block;position:relative;-ms-flex-order:-1;order:-1;width:100%;z-index:10}ion-header ion-toolbar:first-of-type{padding-top:var(--ion-safe-area-top, 0)}.header-md{-webkit-box-shadow:0 2px 4px -1px rgba(0, 0, 0, 0.2), 0 4px 5px 0 rgba(0, 0, 0, 0.14), 0 1px 10px 0 rgba(0, 0, 0, 0.12);box-shadow:0 2px 4px -1px rgba(0, 0, 0, 0.2), 0 4px 5px 0 rgba(0, 0, 0, 0.14), 0 1px 10px 0 rgba(0, 0, 0, 0.12)}.header-collapse-condense{display:none}.header-md.ion-no-border{-webkit-box-shadow:none;box-shadow:none}";
  13910. var IonHeaderMdStyle0 = headerMdCss;
  13911. /**
  13912. * @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
  13913. */
  13914. class Header {
  13915. constructor(hostRef) {
  13916. registerInstance(this, hostRef);
  13917. this.inheritedAttributes = {};
  13918. this.setupFadeHeader = async (contentEl, condenseHeader) => {
  13919. const scrollEl = (this.scrollEl = await getScrollElement(contentEl));
  13920. /**
  13921. * Handle fading of toolbars on scroll
  13922. */
  13923. this.contentScrollCallback = () => {
  13924. handleHeaderFade(this.scrollEl, this.el, condenseHeader);
  13925. };
  13926. scrollEl.addEventListener('scroll', this.contentScrollCallback);
  13927. handleHeaderFade(this.scrollEl, this.el, condenseHeader);
  13928. };
  13929. this.collapse = undefined;
  13930. this.translucent = false;
  13931. }
  13932. componentWillLoad() {
  13933. this.inheritedAttributes = inheritAriaAttributes(this.el);
  13934. }
  13935. componentDidLoad() {
  13936. this.checkCollapsibleHeader();
  13937. }
  13938. componentDidUpdate() {
  13939. this.checkCollapsibleHeader();
  13940. }
  13941. disconnectedCallback() {
  13942. this.destroyCollapsibleHeader();
  13943. }
  13944. async checkCollapsibleHeader() {
  13945. const mode = getIonMode$1(this);
  13946. if (mode !== 'ios') {
  13947. return;
  13948. }
  13949. const { collapse } = this;
  13950. const hasCondense = collapse === 'condense';
  13951. const hasFade = collapse === 'fade';
  13952. this.destroyCollapsibleHeader();
  13953. if (hasCondense) {
  13954. const pageEl = this.el.closest('ion-app,ion-page,.ion-page,page-inner');
  13955. const contentEl = pageEl ? findIonContent(pageEl) : null;
  13956. // Cloned elements are always needed in iOS transition
  13957. writeTask(() => {
  13958. const title = cloneElement('ion-title');
  13959. title.size = 'large';
  13960. cloneElement('ion-back-button');
  13961. });
  13962. await this.setupCondenseHeader(contentEl, pageEl);
  13963. }
  13964. else if (hasFade) {
  13965. const pageEl = this.el.closest('ion-app,ion-page,.ion-page,page-inner');
  13966. const contentEl = pageEl ? findIonContent(pageEl) : null;
  13967. if (!contentEl) {
  13968. printIonContentErrorMsg(this.el);
  13969. return;
  13970. }
  13971. const condenseHeader = contentEl.querySelector('ion-header[collapse="condense"]');
  13972. await this.setupFadeHeader(contentEl, condenseHeader);
  13973. }
  13974. }
  13975. destroyCollapsibleHeader() {
  13976. if (this.intersectionObserver) {
  13977. this.intersectionObserver.disconnect();
  13978. this.intersectionObserver = undefined;
  13979. }
  13980. if (this.scrollEl && this.contentScrollCallback) {
  13981. this.scrollEl.removeEventListener('scroll', this.contentScrollCallback);
  13982. this.contentScrollCallback = undefined;
  13983. }
  13984. if (this.collapsibleMainHeader) {
  13985. this.collapsibleMainHeader.classList.remove('header-collapse-main');
  13986. this.collapsibleMainHeader = undefined;
  13987. }
  13988. }
  13989. async setupCondenseHeader(contentEl, pageEl) {
  13990. if (!contentEl || !pageEl) {
  13991. printIonContentErrorMsg(this.el);
  13992. return;
  13993. }
  13994. if (typeof IntersectionObserver === 'undefined') {
  13995. return;
  13996. }
  13997. this.scrollEl = await getScrollElement(contentEl);
  13998. const headers = pageEl.querySelectorAll('ion-header');
  13999. this.collapsibleMainHeader = Array.from(headers).find((header) => header.collapse !== 'condense');
  14000. if (!this.collapsibleMainHeader) {
  14001. return;
  14002. }
  14003. const mainHeaderIndex = createHeaderIndex(this.collapsibleMainHeader);
  14004. const scrollHeaderIndex = createHeaderIndex(this.el);
  14005. if (!mainHeaderIndex || !scrollHeaderIndex) {
  14006. return;
  14007. }
  14008. setHeaderActive(mainHeaderIndex, false);
  14009. setToolbarBackgroundOpacity(mainHeaderIndex.el, 0);
  14010. /**
  14011. * Handle interaction between toolbar collapse and
  14012. * showing/hiding content in the primary ion-header
  14013. * as well as progressively showing/hiding the main header
  14014. * border as the top-most toolbar collapses or expands.
  14015. */
  14016. const toolbarIntersection = (ev) => {
  14017. handleToolbarIntersection(ev, mainHeaderIndex, scrollHeaderIndex, this.scrollEl);
  14018. };
  14019. this.intersectionObserver = new IntersectionObserver(toolbarIntersection, {
  14020. root: contentEl,
  14021. threshold: [0.25, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1],
  14022. });
  14023. this.intersectionObserver.observe(scrollHeaderIndex.toolbars[scrollHeaderIndex.toolbars.length - 1].el);
  14024. /**
  14025. * Handle scaling of large iOS titles and
  14026. * showing/hiding border on last toolbar
  14027. * in primary header
  14028. */
  14029. this.contentScrollCallback = () => {
  14030. handleContentScroll(this.scrollEl, scrollHeaderIndex, contentEl);
  14031. };
  14032. this.scrollEl.addEventListener('scroll', this.contentScrollCallback);
  14033. writeTask(() => {
  14034. if (this.collapsibleMainHeader !== undefined) {
  14035. this.collapsibleMainHeader.classList.add('header-collapse-main');
  14036. }
  14037. });
  14038. }
  14039. render() {
  14040. const { translucent, inheritedAttributes } = this;
  14041. const mode = getIonMode$1(this);
  14042. const collapse = this.collapse || 'none';
  14043. // banner role must be at top level, so remove role if inside a menu
  14044. const roleType = hostContext('ion-menu', this.el) ? 'none' : 'banner';
  14045. return (hAsync(Host, Object.assign({ key: 'b6cc27f0b08afc9fcc889683525da765d80ba672', role: roleType, class: {
  14046. [mode]: true,
  14047. // Used internally for styling
  14048. [`header-${mode}`]: true,
  14049. [`header-translucent`]: this.translucent,
  14050. [`header-collapse-${collapse}`]: true,
  14051. [`header-translucent-${mode}`]: this.translucent,
  14052. } }, inheritedAttributes), mode === 'ios' && translucent && hAsync("div", { key: '395766d4dcee3398bc91960db21f922095292f14', class: "header-background" }), hAsync("slot", { key: '09a67ece27b258ff1248805d43d92a49b2c6859a' })));
  14053. }
  14054. get el() { return getElement(this); }
  14055. static get style() { return {
  14056. ios: IonHeaderIosStyle0,
  14057. md: IonHeaderMdStyle0
  14058. }; }
  14059. static get cmpMeta() { return {
  14060. "$flags$": 36,
  14061. "$tagName$": "ion-header",
  14062. "$members$": {
  14063. "collapse": [1],
  14064. "translucent": [4]
  14065. },
  14066. "$listeners$": undefined,
  14067. "$lazyBundleId$": "-",
  14068. "$attrsToReflect$": []
  14069. }; }
  14070. }
  14071. const getName = (iconName, icon, mode, ios, md) => {
  14072. // default to "md" if somehow the mode wasn't set
  14073. mode = (mode && toLower(mode)) === 'ios' ? 'ios' : 'md';
  14074. // if an icon was passed in using the ios or md attributes
  14075. // set the iconName to whatever was passed in
  14076. if (ios && mode === 'ios') {
  14077. iconName = toLower(ios);
  14078. }
  14079. else if (md && mode === 'md') {
  14080. iconName = toLower(md);
  14081. }
  14082. else {
  14083. if (!iconName && icon && !isSrc(icon)) {
  14084. iconName = icon;
  14085. }
  14086. if (isStr(iconName)) {
  14087. iconName = toLower(iconName);
  14088. }
  14089. }
  14090. if (!isStr(iconName) || iconName.trim() === '') {
  14091. return null;
  14092. }
  14093. // only allow alpha characters and dash
  14094. const invalidChars = iconName.replace(/[a-z]|-|\d/gi, '');
  14095. if (invalidChars !== '') {
  14096. return null;
  14097. }
  14098. return iconName;
  14099. };
  14100. const isSrc = (str) => str.length > 0 && /(\/|\.)/.test(str);
  14101. const isStr = (val) => typeof val === 'string';
  14102. const toLower = (val) => val.toLowerCase();
  14103. /**
  14104. * Elements inside of web components sometimes need to inherit global attributes
  14105. * set on the host. For example, the inner input in `ion-input` should inherit
  14106. * the `title` attribute that developers set directly on `ion-input`. This
  14107. * helper function should be called in componentWillLoad and assigned to a variable
  14108. * that is later used in the render function.
  14109. *
  14110. * This does not need to be reactive as changing attributes on the host element
  14111. * does not trigger a re-render.
  14112. */
  14113. const inheritAttributes = (el, attributes = []) => {
  14114. const attributeObject = {};
  14115. attributes.forEach(attr => {
  14116. if (el.hasAttribute(attr)) {
  14117. const value = el.getAttribute(attr);
  14118. if (value !== null) {
  14119. attributeObject[attr] = el.getAttribute(attr);
  14120. }
  14121. el.removeAttribute(attr);
  14122. }
  14123. });
  14124. return attributeObject;
  14125. };
  14126. /**
  14127. * Returns `true` if the document or host element
  14128. * has a `dir` set to `rtl`. The host value will always
  14129. * take priority over the root document value.
  14130. */
  14131. const isRTL = (hostEl) => {
  14132. if (hostEl) {
  14133. if (hostEl.dir !== '') {
  14134. return hostEl.dir.toLowerCase() === 'rtl';
  14135. }
  14136. }
  14137. return (document === null || document === void 0 ? void 0 : document.dir.toLowerCase()) === 'rtl';
  14138. };
  14139. const iconCss = ":host{display:inline-block;width:1em;height:1em;contain:strict;fill:currentColor;-webkit-box-sizing:content-box !important;box-sizing:content-box !important}:host .ionicon{stroke:currentColor}.ionicon-fill-none{fill:none}.ionicon-stroke-width{stroke-width:32px;stroke-width:var(--ionicon-stroke-width, 32px)}.icon-inner,.ionicon,svg{display:block;height:100%;width:100%}@supports (background: -webkit-named-image(i)){:host(.icon-rtl) .icon-inner{-webkit-transform:scaleX(-1);transform:scaleX(-1)}}@supports not selector(:dir(rtl)) and selector(:host-context([dir='rtl'])){:host(.icon-rtl) .icon-inner{-webkit-transform:scaleX(-1);transform:scaleX(-1)}}:host(.flip-rtl):host-context([dir='rtl']) .icon-inner{-webkit-transform:scaleX(-1);transform:scaleX(-1)}@supports selector(:dir(rtl)){:host(.flip-rtl:dir(rtl)) .icon-inner{-webkit-transform:scaleX(-1);transform:scaleX(-1)}:host(.flip-rtl:dir(ltr)) .icon-inner{-webkit-transform:scaleX(1);transform:scaleX(1)}}:host(.icon-small){font-size:1.125rem !important}:host(.icon-large){font-size:2rem !important}:host(.ion-color){color:var(--ion-color-base) !important}:host(.ion-color-primary){--ion-color-base:var(--ion-color-primary, #3880ff)}:host(.ion-color-secondary){--ion-color-base:var(--ion-color-secondary, #0cd1e8)}:host(.ion-color-tertiary){--ion-color-base:var(--ion-color-tertiary, #f4a942)}:host(.ion-color-success){--ion-color-base:var(--ion-color-success, #10dc60)}:host(.ion-color-warning){--ion-color-base:var(--ion-color-warning, #ffce00)}:host(.ion-color-danger){--ion-color-base:var(--ion-color-danger, #f14141)}:host(.ion-color-light){--ion-color-base:var(--ion-color-light, #f4f5f8)}:host(.ion-color-medium){--ion-color-base:var(--ion-color-medium, #989aa2)}:host(.ion-color-dark){--ion-color-base:var(--ion-color-dark, #222428)}";
  14140. var IonIconStyle0 = iconCss;
  14141. class Icon {
  14142. constructor(hostRef) {
  14143. registerInstance(this, hostRef);
  14144. this.iconName = null;
  14145. this.inheritedAttributes = {};
  14146. this.didLoadIcon = false;
  14147. this.svgContent = undefined;
  14148. this.isVisible = false;
  14149. this.mode = getIonMode();
  14150. this.color = undefined;
  14151. this.ios = undefined;
  14152. this.md = undefined;
  14153. this.flipRtl = undefined;
  14154. this.name = undefined;
  14155. this.src = undefined;
  14156. this.icon = undefined;
  14157. this.size = undefined;
  14158. this.lazy = false;
  14159. this.sanitize = true;
  14160. }
  14161. componentWillLoad() {
  14162. this.inheritedAttributes = inheritAttributes(this.el, ['aria-label']);
  14163. }
  14164. connectedCallback() {
  14165. // purposely do not return the promise here because loading
  14166. // the svg file should not hold up loading the app
  14167. // only load the svg if it's visible
  14168. this.waitUntilVisible(this.el, '50px', () => {
  14169. this.isVisible = true;
  14170. this.loadIcon();
  14171. });
  14172. }
  14173. componentDidLoad() {
  14174. /**
  14175. * Addresses an Angular issue where property values are assigned after the 'connectedCallback' but prior to the registration of watchers.
  14176. * This enhancement ensures the loading of an icon when the component has finished rendering and the icon has yet to apply the SVG data.
  14177. * This modification pertains to the usage of Angular's binding syntax:
  14178. * `<ion-icon [name]="myIconName"></ion-icon>`
  14179. */
  14180. if (!this.didLoadIcon) {
  14181. this.loadIcon();
  14182. }
  14183. }
  14184. disconnectedCallback() {
  14185. if (this.io) {
  14186. this.io.disconnect();
  14187. this.io = undefined;
  14188. }
  14189. }
  14190. waitUntilVisible(el, rootMargin, cb) {
  14191. {
  14192. // browser doesn't support IntersectionObserver
  14193. // so just fallback to always show it
  14194. cb();
  14195. }
  14196. }
  14197. loadIcon() {
  14198. this.iconName = getName(this.name, this.icon, this.mode, this.ios, this.md);
  14199. }
  14200. render() {
  14201. const { flipRtl, iconName, inheritedAttributes, el } = this;
  14202. const mode = this.mode || 'md';
  14203. // we have designated that arrows & chevrons should automatically flip (unless flip-rtl is set to false) because "back" is left in ltr and right in rtl, and "forward" is the opposite
  14204. const shouldAutoFlip = iconName
  14205. ? (iconName.includes('arrow') || iconName.includes('chevron')) && flipRtl !== false
  14206. : false;
  14207. // if shouldBeFlippable is true, the icon should change direction when `dir` changes
  14208. const shouldBeFlippable = flipRtl || shouldAutoFlip;
  14209. return (hAsync(Host, Object.assign({ role: "img", class: Object.assign(Object.assign({ [mode]: true }, createColorClasses(this.color)), { [`icon-${this.size}`]: !!this.size, 'flip-rtl': shouldBeFlippable, 'icon-rtl': shouldBeFlippable && isRTL(el) }) }, inheritedAttributes), (hAsync("div", { class: "icon-inner" }))));
  14210. }
  14211. static get assetsDirs() { return ["svg"]; }
  14212. get el() { return getElement(this); }
  14213. static get watchers() { return {
  14214. "name": ["loadIcon"],
  14215. "src": ["loadIcon"],
  14216. "icon": ["loadIcon"],
  14217. "ios": ["loadIcon"],
  14218. "md": ["loadIcon"]
  14219. }; }
  14220. static get style() { return IonIconStyle0; }
  14221. static get cmpMeta() { return {
  14222. "$flags$": 9,
  14223. "$tagName$": "ion-icon",
  14224. "$members$": {
  14225. "mode": [1025],
  14226. "color": [1],
  14227. "ios": [1],
  14228. "md": [1],
  14229. "flipRtl": [4, "flip-rtl"],
  14230. "name": [513],
  14231. "src": [1],
  14232. "icon": [8],
  14233. "size": [1],
  14234. "lazy": [4],
  14235. "sanitize": [4],
  14236. "svgContent": [32],
  14237. "isVisible": [32]
  14238. },
  14239. "$listeners$": undefined,
  14240. "$lazyBundleId$": "-",
  14241. "$attrsToReflect$": [["name", "name"]]
  14242. }; }
  14243. }
  14244. const getIonMode = () => 'md';
  14245. const createColorClasses = (color) => {
  14246. return color
  14247. ? {
  14248. 'ion-color': true,
  14249. [`ion-color-${color}`]: true,
  14250. }
  14251. : null;
  14252. };
  14253. const imgCss = ":host{display:block;-o-object-fit:contain;object-fit:contain}img{display:block;width:100%;height:100%;-o-object-fit:inherit;object-fit:inherit;-o-object-position:inherit;object-position:inherit}";
  14254. var IonImgStyle0 = imgCss;
  14255. /**
  14256. * @part image - The inner `img` element.
  14257. */
  14258. class Img {
  14259. constructor(hostRef) {
  14260. registerInstance(this, hostRef);
  14261. this.ionImgWillLoad = createEvent(this, "ionImgWillLoad", 7);
  14262. this.ionImgDidLoad = createEvent(this, "ionImgDidLoad", 7);
  14263. this.ionError = createEvent(this, "ionError", 7);
  14264. this.inheritedAttributes = {};
  14265. this.onLoad = () => {
  14266. this.ionImgDidLoad.emit();
  14267. };
  14268. this.onError = () => {
  14269. this.ionError.emit();
  14270. };
  14271. this.loadSrc = undefined;
  14272. this.loadError = undefined;
  14273. this.alt = undefined;
  14274. this.src = undefined;
  14275. }
  14276. srcChanged() {
  14277. this.addIO();
  14278. }
  14279. componentWillLoad() {
  14280. this.inheritedAttributes = inheritAttributes$1(this.el, ['draggable']);
  14281. }
  14282. componentDidLoad() {
  14283. this.addIO();
  14284. }
  14285. addIO() {
  14286. if (this.src === undefined) {
  14287. return;
  14288. }
  14289. if (typeof window !== 'undefined' &&
  14290. 'IntersectionObserver' in window &&
  14291. 'IntersectionObserverEntry' in window &&
  14292. 'isIntersecting' in window.IntersectionObserverEntry.prototype) {
  14293. this.removeIO();
  14294. this.io = new IntersectionObserver((data) => {
  14295. /**
  14296. * On slower devices, it is possible for an intersection observer entry to contain multiple
  14297. * objects in the array. This happens when quickly scrolling an image into view and then out of
  14298. * view. In this case, the last object represents the current state of the component.
  14299. */
  14300. if (data[data.length - 1].isIntersecting) {
  14301. this.load();
  14302. this.removeIO();
  14303. }
  14304. });
  14305. this.io.observe(this.el);
  14306. }
  14307. else {
  14308. // fall back to setTimeout for Safari and IE
  14309. setTimeout(() => this.load(), 200);
  14310. }
  14311. }
  14312. load() {
  14313. this.loadError = this.onError;
  14314. this.loadSrc = this.src;
  14315. this.ionImgWillLoad.emit();
  14316. }
  14317. removeIO() {
  14318. if (this.io) {
  14319. this.io.disconnect();
  14320. this.io = undefined;
  14321. }
  14322. }
  14323. render() {
  14324. const { loadSrc, alt, onLoad, loadError, inheritedAttributes } = this;
  14325. const { draggable } = inheritedAttributes;
  14326. return (hAsync(Host, { key: 'da600442894427dee1974a28e545613afac69fca', class: getIonMode$1(this) }, hAsync("img", { key: '16df0c7069af86c0fa7ce5af598bc0f63b4eb71a', decoding: "async", src: loadSrc, alt: alt, onLoad: onLoad, onError: loadError, part: "image", draggable: isDraggable(draggable) })));
  14327. }
  14328. get el() { return getElement(this); }
  14329. static get watchers() { return {
  14330. "src": ["srcChanged"]
  14331. }; }
  14332. static get style() { return IonImgStyle0; }
  14333. static get cmpMeta() { return {
  14334. "$flags$": 9,
  14335. "$tagName$": "ion-img",
  14336. "$members$": {
  14337. "alt": [1],
  14338. "src": [1],
  14339. "loadSrc": [32],
  14340. "loadError": [32]
  14341. },
  14342. "$listeners$": undefined,
  14343. "$lazyBundleId$": "-",
  14344. "$attrsToReflect$": []
  14345. }; }
  14346. }
  14347. /**
  14348. * Enumerated strings must be set as booleans
  14349. * as Stencil will not render 'false' in the DOM.
  14350. * The need to explicitly render draggable="true"
  14351. * as only certain elements are draggable by default.
  14352. * https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/draggable.
  14353. */
  14354. const isDraggable = (draggable) => {
  14355. switch (draggable) {
  14356. case 'true':
  14357. return true;
  14358. case 'false':
  14359. return false;
  14360. default:
  14361. return undefined;
  14362. }
  14363. };
  14364. const infiniteScrollCss = "ion-infinite-scroll{display:none;width:100%}.infinite-scroll-enabled{display:block}";
  14365. var IonInfiniteScrollStyle0 = infiniteScrollCss;
  14366. class InfiniteScroll {
  14367. constructor(hostRef) {
  14368. registerInstance(this, hostRef);
  14369. this.ionInfinite = createEvent(this, "ionInfinite", 7);
  14370. this.thrPx = 0;
  14371. this.thrPc = 0;
  14372. /**
  14373. * didFire exists so that ionInfinite
  14374. * does not fire multiple times if
  14375. * users continue to scroll after
  14376. * scrolling into the infinite
  14377. * scroll threshold.
  14378. */
  14379. this.didFire = false;
  14380. this.isBusy = false;
  14381. this.onScroll = () => {
  14382. const scrollEl = this.scrollEl;
  14383. if (!scrollEl || !this.canStart()) {
  14384. return 1;
  14385. }
  14386. const infiniteHeight = this.el.offsetHeight;
  14387. if (infiniteHeight === 0) {
  14388. // if there is no height of this element then do nothing
  14389. return 2;
  14390. }
  14391. const scrollTop = scrollEl.scrollTop;
  14392. const scrollHeight = scrollEl.scrollHeight;
  14393. const height = scrollEl.offsetHeight;
  14394. const threshold = this.thrPc !== 0 ? height * this.thrPc : this.thrPx;
  14395. const distanceFromInfinite = this.position === 'bottom'
  14396. ? scrollHeight - infiniteHeight - scrollTop - threshold - height
  14397. : scrollTop - infiniteHeight - threshold;
  14398. if (distanceFromInfinite < 0) {
  14399. if (!this.didFire) {
  14400. this.isLoading = true;
  14401. this.didFire = true;
  14402. this.ionInfinite.emit();
  14403. return 3;
  14404. }
  14405. }
  14406. return 4;
  14407. };
  14408. this.isLoading = false;
  14409. this.threshold = '15%';
  14410. this.disabled = false;
  14411. this.position = 'bottom';
  14412. }
  14413. thresholdChanged() {
  14414. const val = this.threshold;
  14415. if (val.lastIndexOf('%') > -1) {
  14416. this.thrPx = 0;
  14417. this.thrPc = parseFloat(val) / 100;
  14418. }
  14419. else {
  14420. this.thrPx = parseFloat(val);
  14421. this.thrPc = 0;
  14422. }
  14423. }
  14424. disabledChanged() {
  14425. const disabled = this.disabled;
  14426. if (disabled) {
  14427. this.isLoading = false;
  14428. this.isBusy = false;
  14429. }
  14430. this.enableScrollEvents(!disabled);
  14431. }
  14432. async connectedCallback() {
  14433. const contentEl = findClosestIonContent(this.el);
  14434. if (!contentEl) {
  14435. printIonContentErrorMsg(this.el);
  14436. return;
  14437. }
  14438. this.scrollEl = await getScrollElement(contentEl);
  14439. this.thresholdChanged();
  14440. this.disabledChanged();
  14441. if (this.position === 'top') {
  14442. writeTask(() => {
  14443. if (this.scrollEl) {
  14444. this.scrollEl.scrollTop = this.scrollEl.scrollHeight - this.scrollEl.clientHeight;
  14445. }
  14446. });
  14447. }
  14448. }
  14449. disconnectedCallback() {
  14450. this.enableScrollEvents(false);
  14451. this.scrollEl = undefined;
  14452. }
  14453. /**
  14454. * Call `complete()` within the `ionInfinite` output event handler when
  14455. * your async operation has completed. For example, the `loading`
  14456. * state is while the app is performing an asynchronous operation,
  14457. * such as receiving more data from an AJAX request to add more items
  14458. * to a data list. Once the data has been received and UI updated, you
  14459. * then call this method to signify that the loading has completed.
  14460. * This method will change the infinite scroll's state from `loading`
  14461. * to `enabled`.
  14462. */
  14463. async complete() {
  14464. const scrollEl = this.scrollEl;
  14465. if (!this.isLoading || !scrollEl) {
  14466. return;
  14467. }
  14468. this.isLoading = false;
  14469. if (this.position === 'top') {
  14470. /**
  14471. * New content is being added at the top, but the scrollTop position stays the same,
  14472. * which causes a scroll jump visually. This algorithm makes sure to prevent this.
  14473. * (Frame 1)
  14474. * - complete() is called, but the UI hasn't had time to update yet.
  14475. * - Save the current content dimensions.
  14476. * - Wait for the next frame using _dom.read, so the UI will be updated.
  14477. * (Frame 2)
  14478. * - Read the new content dimensions.
  14479. * - Calculate the height difference and the new scroll position.
  14480. * - Delay the scroll position change until other possible dom reads are done using _dom.write to be performant.
  14481. * (Still frame 2, if I'm correct)
  14482. * - Change the scroll position (= visually maintain the scroll position).
  14483. * - Change the state to re-enable the InfiniteScroll.
  14484. * - This should be after changing the scroll position, or it could
  14485. * cause the InfiniteScroll to be triggered again immediately.
  14486. * (Frame 3)
  14487. * Done.
  14488. */
  14489. this.isBusy = true;
  14490. // ******** DOM READ ****************
  14491. // Save the current content dimensions before the UI updates
  14492. const prev = scrollEl.scrollHeight - scrollEl.scrollTop;
  14493. // ******** DOM READ ****************
  14494. requestAnimationFrame(() => {
  14495. readTask(() => {
  14496. // UI has updated, save the new content dimensions
  14497. const scrollHeight = scrollEl.scrollHeight;
  14498. // New content was added on top, so the scroll position should be changed immediately to prevent it from jumping around
  14499. const newScrollTop = scrollHeight - prev;
  14500. // ******** DOM WRITE ****************
  14501. requestAnimationFrame(() => {
  14502. writeTask(() => {
  14503. scrollEl.scrollTop = newScrollTop;
  14504. this.isBusy = false;
  14505. this.didFire = false;
  14506. });
  14507. });
  14508. });
  14509. });
  14510. }
  14511. else {
  14512. this.didFire = false;
  14513. }
  14514. }
  14515. canStart() {
  14516. return !this.disabled && !this.isBusy && !!this.scrollEl && !this.isLoading;
  14517. }
  14518. enableScrollEvents(shouldListen) {
  14519. if (this.scrollEl) {
  14520. if (shouldListen) {
  14521. this.scrollEl.addEventListener('scroll', this.onScroll);
  14522. }
  14523. else {
  14524. this.scrollEl.removeEventListener('scroll', this.onScroll);
  14525. }
  14526. }
  14527. }
  14528. render() {
  14529. const mode = getIonMode$1(this);
  14530. const disabled = this.disabled;
  14531. return (hAsync(Host, { key: 'e844956795f69be33396ce4480aa7a54ad01b28c', class: {
  14532. [mode]: true,
  14533. 'infinite-scroll-loading': this.isLoading,
  14534. 'infinite-scroll-enabled': !disabled,
  14535. } }));
  14536. }
  14537. get el() { return getElement(this); }
  14538. static get watchers() { return {
  14539. "threshold": ["thresholdChanged"],
  14540. "disabled": ["disabledChanged"]
  14541. }; }
  14542. static get style() { return IonInfiniteScrollStyle0; }
  14543. static get cmpMeta() { return {
  14544. "$flags$": 0,
  14545. "$tagName$": "ion-infinite-scroll",
  14546. "$members$": {
  14547. "threshold": [1],
  14548. "disabled": [4],
  14549. "position": [1],
  14550. "isLoading": [32],
  14551. "complete": [64]
  14552. },
  14553. "$listeners$": undefined,
  14554. "$lazyBundleId$": "-",
  14555. "$attrsToReflect$": []
  14556. }; }
  14557. }
  14558. const infiniteScrollContentIosCss = "ion-infinite-scroll-content{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;-ms-flex-pack:center;justify-content:center;min-height:84px;text-align:center;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.infinite-loading{margin-left:0;margin-right:0;margin-top:0;margin-bottom:32px;display:none;width:100%}.infinite-loading-text{-webkit-margin-start:32px;margin-inline-start:32px;-webkit-margin-end:32px;margin-inline-end:32px;margin-top:4px;margin-bottom:0}.infinite-scroll-loading ion-infinite-scroll-content>.infinite-loading{display:block}.infinite-scroll-content-ios .infinite-loading-text{color:var(--ion-color-step-600, var(--ion-text-color-step-400, #666666))}.infinite-scroll-content-ios .infinite-loading-spinner .spinner-lines-ios line,.infinite-scroll-content-ios .infinite-loading-spinner .spinner-lines-small-ios line,.infinite-scroll-content-ios .infinite-loading-spinner .spinner-crescent circle{stroke:var(--ion-color-step-600, var(--ion-text-color-step-400, #666666))}.infinite-scroll-content-ios .infinite-loading-spinner .spinner-bubbles circle,.infinite-scroll-content-ios .infinite-loading-spinner .spinner-circles circle,.infinite-scroll-content-ios .infinite-loading-spinner .spinner-dots circle{fill:var(--ion-color-step-600, var(--ion-text-color-step-400, #666666))}";
  14559. var IonInfiniteScrollContentIosStyle0 = infiniteScrollContentIosCss;
  14560. const infiniteScrollContentMdCss = "ion-infinite-scroll-content{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;-ms-flex-pack:center;justify-content:center;min-height:84px;text-align:center;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.infinite-loading{margin-left:0;margin-right:0;margin-top:0;margin-bottom:32px;display:none;width:100%}.infinite-loading-text{-webkit-margin-start:32px;margin-inline-start:32px;-webkit-margin-end:32px;margin-inline-end:32px;margin-top:4px;margin-bottom:0}.infinite-scroll-loading ion-infinite-scroll-content>.infinite-loading{display:block}.infinite-scroll-content-md .infinite-loading-text{color:var(--ion-color-step-600, var(--ion-text-color-step-400, #666666))}.infinite-scroll-content-md .infinite-loading-spinner .spinner-lines-md line,.infinite-scroll-content-md .infinite-loading-spinner .spinner-lines-small-md line,.infinite-scroll-content-md .infinite-loading-spinner .spinner-crescent circle{stroke:var(--ion-color-step-600, var(--ion-text-color-step-400, #666666))}.infinite-scroll-content-md .infinite-loading-spinner .spinner-bubbles circle,.infinite-scroll-content-md .infinite-loading-spinner .spinner-circles circle,.infinite-scroll-content-md .infinite-loading-spinner .spinner-dots circle{fill:var(--ion-color-step-600, var(--ion-text-color-step-400, #666666))}";
  14561. var IonInfiniteScrollContentMdStyle0 = infiniteScrollContentMdCss;
  14562. class InfiniteScrollContent {
  14563. constructor(hostRef) {
  14564. registerInstance(this, hostRef);
  14565. this.customHTMLEnabled = config.get('innerHTMLTemplatesEnabled', ENABLE_HTML_CONTENT_DEFAULT);
  14566. this.loadingSpinner = undefined;
  14567. this.loadingText = undefined;
  14568. }
  14569. componentDidLoad() {
  14570. if (this.loadingSpinner === undefined) {
  14571. const mode = getIonMode$1(this);
  14572. this.loadingSpinner = config.get('infiniteLoadingSpinner', config.get('spinner', mode === 'ios' ? 'lines' : 'crescent'));
  14573. }
  14574. }
  14575. renderLoadingText() {
  14576. const { customHTMLEnabled, loadingText } = this;
  14577. if (customHTMLEnabled) {
  14578. return hAsync("div", { class: "infinite-loading-text", innerHTML: sanitizeDOMString(loadingText) });
  14579. }
  14580. return hAsync("div", { class: "infinite-loading-text" }, this.loadingText);
  14581. }
  14582. render() {
  14583. const mode = getIonMode$1(this);
  14584. return (hAsync(Host, { key: '7c16060dcfe2a0b0fb3e2f8f4c449589a76f1baa', class: {
  14585. [mode]: true,
  14586. // Used internally for styling
  14587. [`infinite-scroll-content-${mode}`]: true,
  14588. } }, hAsync("div", { key: 'a94f4d8746e053dc718f97520bd7e48cb316443a', class: "infinite-loading" }, this.loadingSpinner && (hAsync("div", { key: '10143d5d2a50a2a2bc5de1cee8e7ab51263bcf23', class: "infinite-loading-spinner" }, hAsync("ion-spinner", { key: '8846e88191690d9c61a0b462889ed56fbfed8b0d', name: this.loadingSpinner }))), this.loadingText !== undefined && this.renderLoadingText())));
  14589. }
  14590. static get style() { return {
  14591. ios: IonInfiniteScrollContentIosStyle0,
  14592. md: IonInfiniteScrollContentMdStyle0
  14593. }; }
  14594. static get cmpMeta() { return {
  14595. "$flags$": 32,
  14596. "$tagName$": "ion-infinite-scroll-content",
  14597. "$members$": {
  14598. "loadingSpinner": [1025, "loading-spinner"],
  14599. "loadingText": [1, "loading-text"]
  14600. },
  14601. "$listeners$": undefined,
  14602. "$lazyBundleId$": "-",
  14603. "$attrsToReflect$": []
  14604. }; }
  14605. }
  14606. /**
  14607. * A utility to calculate the size of an outline notch
  14608. * width relative to the content passed. This is used in
  14609. * components such as `ion-select` with `fill="outline"`
  14610. * where we need to pass slotted HTML content. This is not
  14611. * needed when rendering plaintext content because we can
  14612. * render the plaintext again hidden with `opacity: 0` inside
  14613. * of the notch. As a result we can rely on the intrinsic size
  14614. * of the element to correctly compute the notch width. We
  14615. * cannot do this with slotted content because we cannot project
  14616. * it into 2 places at once.
  14617. *
  14618. * @internal
  14619. * @param el: The host element
  14620. * @param getNotchSpacerEl: A function that returns a reference to the notch spacer element inside of the component template.
  14621. * @param getLabelSlot: A function that returns a reference to the slotted content.
  14622. */
  14623. const createNotchController = (el, getNotchSpacerEl, getLabelSlot) => {
  14624. let notchVisibilityIO;
  14625. const needsExplicitNotchWidth = () => {
  14626. const notchSpacerEl = getNotchSpacerEl();
  14627. if (
  14628. /**
  14629. * If the notch is not being used
  14630. * then we do not need to set the notch width.
  14631. */
  14632. notchSpacerEl === undefined ||
  14633. /**
  14634. * If either the label property is being
  14635. * used or the label slot is not defined,
  14636. * then we do not need to estimate the notch width.
  14637. */
  14638. el.label !== undefined ||
  14639. getLabelSlot() === null) {
  14640. return false;
  14641. }
  14642. return true;
  14643. };
  14644. const calculateNotchWidth = () => {
  14645. if (needsExplicitNotchWidth()) {
  14646. /**
  14647. * Run this the frame after
  14648. * the browser has re-painted the host element.
  14649. * Otherwise, the label element may have a width
  14650. * of 0 and the IntersectionObserver will be used.
  14651. */
  14652. raf(() => {
  14653. setNotchWidth();
  14654. });
  14655. }
  14656. };
  14657. /**
  14658. * When using a label prop we can render
  14659. * the label value inside of the notch and
  14660. * let the browser calculate the size of the notch.
  14661. * However, we cannot render the label slot in multiple
  14662. * places so we need to manually calculate the notch dimension
  14663. * based on the size of the slotted content.
  14664. *
  14665. * This function should only be used to set the notch width
  14666. * on slotted label content. The notch width for label prop
  14667. * content is automatically calculated based on the
  14668. * intrinsic size of the label text.
  14669. */
  14670. const setNotchWidth = () => {
  14671. const notchSpacerEl = getNotchSpacerEl();
  14672. if (notchSpacerEl === undefined) {
  14673. return;
  14674. }
  14675. if (!needsExplicitNotchWidth()) {
  14676. notchSpacerEl.style.removeProperty('width');
  14677. return;
  14678. }
  14679. const width = getLabelSlot().scrollWidth;
  14680. if (
  14681. /**
  14682. * If the computed width of the label is 0
  14683. * and notchSpacerEl's offsetParent is null
  14684. * then that means the element is hidden.
  14685. * As a result, we need to wait for the element
  14686. * to become visible before setting the notch width.
  14687. *
  14688. * We do not check el.offsetParent because
  14689. * that can be null if the host element has
  14690. * position: fixed applied to it.
  14691. * notchSpacerEl does not have position: fixed.
  14692. */
  14693. width === 0 &&
  14694. notchSpacerEl.offsetParent === null &&
  14695. win$1 !== undefined &&
  14696. 'IntersectionObserver' in win$1) {
  14697. /**
  14698. * If there is an IO already attached
  14699. * then that will update the notch
  14700. * once the element becomes visible.
  14701. * As a result, there is no need to create
  14702. * another one.
  14703. */
  14704. if (notchVisibilityIO !== undefined) {
  14705. return;
  14706. }
  14707. const io = (notchVisibilityIO = new IntersectionObserver((ev) => {
  14708. /**
  14709. * If the element is visible then we
  14710. * can try setting the notch width again.
  14711. */
  14712. if (ev[0].intersectionRatio === 1) {
  14713. setNotchWidth();
  14714. io.disconnect();
  14715. notchVisibilityIO = undefined;
  14716. }
  14717. },
  14718. /**
  14719. * Set the root to be the host element
  14720. * This causes the IO callback
  14721. * to be fired in WebKit as soon as the element
  14722. * is visible. If we used the default root value
  14723. * then WebKit would only fire the IO callback
  14724. * after any animations (such as a modal transition)
  14725. * finished, and there would potentially be a flicker.
  14726. */
  14727. { threshold: 0.01, root: el }));
  14728. io.observe(notchSpacerEl);
  14729. return;
  14730. }
  14731. /**
  14732. * If the element is visible then we can set the notch width.
  14733. * The notch is only visible when the label is scaled,
  14734. * which is why we multiply the width by 0.75 as this is
  14735. * the same amount the label element is scaled by in the host CSS.
  14736. * (See $form-control-label-stacked-scale in ionic.globals.scss).
  14737. */
  14738. notchSpacerEl.style.setProperty('width', `${width * 0.75}px`);
  14739. };
  14740. const destroy = () => {
  14741. if (notchVisibilityIO) {
  14742. notchVisibilityIO.disconnect();
  14743. notchVisibilityIO = undefined;
  14744. }
  14745. };
  14746. return {
  14747. calculateNotchWidth,
  14748. destroy,
  14749. };
  14750. };
  14751. /**
  14752. * Uses the compareWith param to compare two values to determine if they are equal.
  14753. *
  14754. * @param currentValue The current value of the control.
  14755. * @param compareValue The value to compare against.
  14756. * @param compareWith The function or property name to use to compare values.
  14757. */
  14758. const compareOptions = (currentValue, compareValue, compareWith) => {
  14759. if (typeof compareWith === 'function') {
  14760. return compareWith(currentValue, compareValue);
  14761. }
  14762. else if (typeof compareWith === 'string') {
  14763. return currentValue[compareWith] === compareValue[compareWith];
  14764. }
  14765. else {
  14766. return Array.isArray(compareValue) ? compareValue.includes(currentValue) : currentValue === compareValue;
  14767. }
  14768. };
  14769. /**
  14770. * Compares a value against the current value(s) to determine if it is selected.
  14771. *
  14772. * @param currentValue The current value of the control.
  14773. * @param compareValue The value to compare against.
  14774. * @param compareWith The function or property name to use to compare values.
  14775. */
  14776. const isOptionSelected = (currentValue, compareValue, compareWith) => {
  14777. if (currentValue === undefined) {
  14778. return false;
  14779. }
  14780. if (Array.isArray(currentValue)) {
  14781. return currentValue.some((val) => compareOptions(val, compareValue, compareWith));
  14782. }
  14783. else {
  14784. return compareOptions(currentValue, compareValue, compareWith);
  14785. }
  14786. };
  14787. /**
  14788. * Used to update a scoped component that uses emulated slots. This fires when
  14789. * content is passed into the slot or when the content inside of a slot changes.
  14790. * This is not needed for components using native slots in the Shadow DOM.
  14791. * @internal
  14792. * @param el The host element to observe
  14793. * @param slotName mutationCallback will fire when nodes on these slot(s) change
  14794. * @param mutationCallback The callback to fire whenever the slotted content changes
  14795. */
  14796. const createSlotMutationController = (el, slotName, mutationCallback) => {
  14797. let hostMutationObserver;
  14798. let slottedContentMutationObserver;
  14799. if (win$1 !== undefined && 'MutationObserver' in win$1) {
  14800. const slots = Array.isArray(slotName) ? slotName : [slotName];
  14801. hostMutationObserver = new MutationObserver((entries) => {
  14802. for (const entry of entries) {
  14803. for (const node of entry.addedNodes) {
  14804. /**
  14805. * Check to see if the added node
  14806. * is our slotted content.
  14807. */
  14808. if (node.nodeType === Node.ELEMENT_NODE && slots.includes(node.slot)) {
  14809. /**
  14810. * If so, we want to watch the slotted
  14811. * content itself for changes. This lets us
  14812. * detect when content inside of the slot changes.
  14813. */
  14814. mutationCallback();
  14815. /**
  14816. * Adding the listener in an raf
  14817. * waits until Stencil moves the slotted element
  14818. * into the correct place in the event that
  14819. * slotted content is being added.
  14820. */
  14821. raf(() => watchForSlotChange(node));
  14822. return;
  14823. }
  14824. }
  14825. }
  14826. });
  14827. hostMutationObserver.observe(el, {
  14828. childList: true,
  14829. /**
  14830. * This fixes an issue with the `ion-input` and
  14831. * `ion-textarea` not re-rendering in some cases
  14832. * when using the label slot functionality.
  14833. *
  14834. * HTML element patches in Stencil that are enabled
  14835. * by the `experimentalSlotFixes` flag in Stencil v4
  14836. * result in DOM manipulations that won't trigger
  14837. * the current mutation observer configuration and
  14838. * callback.
  14839. */
  14840. subtree: true,
  14841. });
  14842. }
  14843. /**
  14844. * Listen for changes inside of the slotted content.
  14845. * We can listen for subtree changes here to be
  14846. * informed of text within the slotted content
  14847. * changing. Doing this on the host is possible
  14848. * but it is much more expensive to do because
  14849. * it also listens for changes to the internals
  14850. * of the component.
  14851. */
  14852. const watchForSlotChange = (slottedEl) => {
  14853. var _a;
  14854. if (slottedContentMutationObserver) {
  14855. slottedContentMutationObserver.disconnect();
  14856. slottedContentMutationObserver = undefined;
  14857. }
  14858. slottedContentMutationObserver = new MutationObserver((entries) => {
  14859. mutationCallback();
  14860. for (const entry of entries) {
  14861. for (const node of entry.removedNodes) {
  14862. /**
  14863. * If the element was removed then we
  14864. * need to destroy the MutationObserver
  14865. * so the element can be garbage collected.
  14866. */
  14867. if (node.nodeType === Node.ELEMENT_NODE && node.slot === slotName) {
  14868. destroySlottedContentObserver();
  14869. }
  14870. }
  14871. }
  14872. });
  14873. /**
  14874. * Listen for changes inside of the element
  14875. * as well as anything deep in the tree.
  14876. * We listen on the parentElement so that we can
  14877. * detect when slotted element itself is removed.
  14878. */
  14879. slottedContentMutationObserver.observe((_a = slottedEl.parentElement) !== null && _a !== void 0 ? _a : slottedEl, { subtree: true, childList: true });
  14880. };
  14881. const destroy = () => {
  14882. if (hostMutationObserver) {
  14883. hostMutationObserver.disconnect();
  14884. hostMutationObserver = undefined;
  14885. }
  14886. destroySlottedContentObserver();
  14887. };
  14888. const destroySlottedContentObserver = () => {
  14889. if (slottedContentMutationObserver) {
  14890. slottedContentMutationObserver.disconnect();
  14891. slottedContentMutationObserver = undefined;
  14892. }
  14893. };
  14894. return {
  14895. destroy,
  14896. };
  14897. };
  14898. const getCounterText = (value, maxLength, counterFormatter) => {
  14899. const valueLength = value == null ? 0 : value.toString().length;
  14900. const defaultCounterText = defaultCounterFormatter(valueLength, maxLength);
  14901. /**
  14902. * If developers did not pass a custom formatter,
  14903. * use the default one.
  14904. */
  14905. if (counterFormatter === undefined) {
  14906. return defaultCounterText;
  14907. }
  14908. /**
  14909. * Otherwise, try to use the custom formatter
  14910. * and fallback to the default formatter if
  14911. * there was an error.
  14912. */
  14913. try {
  14914. return counterFormatter(valueLength, maxLength);
  14915. }
  14916. catch (e) {
  14917. printIonError('[ion-input] - Exception in provided `counterFormatter`:', e);
  14918. return defaultCounterText;
  14919. }
  14920. };
  14921. const defaultCounterFormatter = (length, maxlength) => {
  14922. return `${length} / ${maxlength}`;
  14923. };
  14924. const inputIosCss = ".sc-ion-input-ios-h{--placeholder-color:initial;--placeholder-font-style:initial;--placeholder-font-weight:initial;--placeholder-opacity:var(--ion-placeholder-opacity, 0.6);--padding-top:0px;--padding-end:0px;--padding-bottom:0px;--padding-start:0px;--background:transparent;--color:initial;--border-style:solid;--highlight-color-focused:var(--ion-color-primary, #0054e9);--highlight-color-valid:var(--ion-color-success, #2dd55b);--highlight-color-invalid:var(--ion-color-danger, #c5000f);--highlight-color:var(--highlight-color-focused);display:block;position:relative;width:100%;min-height:44px;padding:0 !important;color:var(--color);font-family:var(--ion-font-family, inherit);z-index:2}ion-item[slot=start].sc-ion-input-ios-h,ion-item [slot=start].sc-ion-input-ios-h,ion-item[slot=end].sc-ion-input-ios-h,ion-item [slot=end].sc-ion-input-ios-h{width:auto}.ion-color.sc-ion-input-ios-h{--highlight-color-focused:var(--ion-color-base)}.input-label-placement-floating.sc-ion-input-ios-h,.input-label-placement-stacked.sc-ion-input-ios-h{min-height:56px}.native-input.sc-ion-input-ios{padding-left:0;padding-right:0;padding-top:0;padding-bottom:0;font-family:inherit;font-size:inherit;font-style:inherit;font-weight:inherit;letter-spacing:inherit;text-decoration:inherit;text-indent:inherit;text-overflow:inherit;text-transform:inherit;text-align:inherit;white-space:inherit;color:inherit;display:inline-block;position:relative;-ms-flex:1;flex:1;width:100%;max-width:100%;height:100%;max-height:100%;border:0;outline:none;background:transparent;-webkit-box-sizing:border-box;box-sizing:border-box;-webkit-appearance:none;-moz-appearance:none;appearance:none;z-index:1}.native-input.sc-ion-input-ios::-webkit-input-placeholder{color:var(--placeholder-color);font-family:inherit;font-style:var(--placeholder-font-style);font-weight:var(--placeholder-font-weight);opacity:var(--placeholder-opacity)}.native-input.sc-ion-input-ios::-moz-placeholder{color:var(--placeholder-color);font-family:inherit;font-style:var(--placeholder-font-style);font-weight:var(--placeholder-font-weight);opacity:var(--placeholder-opacity)}.native-input.sc-ion-input-ios:-ms-input-placeholder{color:var(--placeholder-color);font-family:inherit;font-style:var(--placeholder-font-style);font-weight:var(--placeholder-font-weight);opacity:var(--placeholder-opacity)}.native-input.sc-ion-input-ios::-ms-input-placeholder{color:var(--placeholder-color);font-family:inherit;font-style:var(--placeholder-font-style);font-weight:var(--placeholder-font-weight);opacity:var(--placeholder-opacity)}.native-input.sc-ion-input-ios::placeholder{color:var(--placeholder-color);font-family:inherit;font-style:var(--placeholder-font-style);font-weight:var(--placeholder-font-weight);opacity:var(--placeholder-opacity)}.native-input.sc-ion-input-ios:-webkit-autofill{background-color:transparent}.native-input.sc-ion-input-ios:invalid{-webkit-box-shadow:none;box-shadow:none}.native-input.sc-ion-input-ios::-ms-clear{display:none}.cloned-input.sc-ion-input-ios{top:0;bottom:0;position:absolute;pointer-events:none}.cloned-input.sc-ion-input-ios{inset-inline-start:0}.cloned-input.sc-ion-input-ios:disabled{opacity:1}.input-clear-icon.sc-ion-input-ios{-webkit-margin-start:auto;margin-inline-start:auto;-webkit-margin-end:auto;margin-inline-end:auto;margin-top:auto;margin-bottom:auto;padding-left:0;padding-right:0;padding-top:0;padding-bottom:0;background-position:center;display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;width:30px;height:30px;border:0;outline:none;background-color:transparent;background-repeat:no-repeat;color:var(--ion-color-step-600, var(--ion-text-color-step-400, #666666));visibility:hidden;-webkit-appearance:none;-moz-appearance:none;appearance:none}.in-item-color.sc-ion-input-ios-h .input-clear-icon.sc-ion-input-ios{color:inherit}.input-clear-icon.sc-ion-input-ios:focus{opacity:0.5}.has-value.sc-ion-input-ios-h .input-clear-icon.sc-ion-input-ios{visibility:visible}.input-wrapper.sc-ion-input-ios{-webkit-padding-start:var(--padding-start);padding-inline-start:var(--padding-start);-webkit-padding-end:var(--padding-end);padding-inline-end:var(--padding-end);padding-top:var(--padding-top);padding-bottom:var(--padding-bottom);border-radius:var(--border-radius);display:-ms-flexbox;display:flex;position:relative;-ms-flex-positive:1;flex-grow:1;-ms-flex-align:stretch;align-items:stretch;height:inherit;min-height:inherit;-webkit-transition:background-color 15ms linear;transition:background-color 15ms linear;background:var(--background);line-height:normal}.native-wrapper.sc-ion-input-ios{display:-ms-flexbox;display:flex;position:relative;-ms-flex-positive:1;flex-grow:1;-ms-flex-align:center;align-items:center;width:100%}.ion-touched.ion-invalid.sc-ion-input-ios-h{--highlight-color:var(--highlight-color-invalid)}.ion-valid.sc-ion-input-ios-h{--highlight-color:var(--highlight-color-valid)}.input-bottom.sc-ion-input-ios{-webkit-padding-start:var(--padding-start);padding-inline-start:var(--padding-start);-webkit-padding-end:var(--padding-end);padding-inline-end:var(--padding-end);padding-top:5px;padding-bottom:0;display:-ms-flexbox;display:flex;-ms-flex-pack:justify;justify-content:space-between;border-top:var(--border-width) var(--border-style) var(--border-color);font-size:0.75rem;white-space:normal}.has-focus.ion-valid.sc-ion-input-ios-h,.ion-touched.ion-invalid.sc-ion-input-ios-h{--border-color:var(--highlight-color)}.input-bottom.sc-ion-input-ios .error-text.sc-ion-input-ios{display:none;color:var(--highlight-color-invalid)}.input-bottom.sc-ion-input-ios .helper-text.sc-ion-input-ios{display:block;color:var(--ion-color-step-700, var(--ion-text-color-step-300, #4d4d4d))}.ion-touched.ion-invalid.sc-ion-input-ios-h .input-bottom.sc-ion-input-ios .error-text.sc-ion-input-ios{display:block}.ion-touched.ion-invalid.sc-ion-input-ios-h .input-bottom.sc-ion-input-ios .helper-text.sc-ion-input-ios{display:none}.input-bottom.sc-ion-input-ios .counter.sc-ion-input-ios{-webkit-margin-start:auto;margin-inline-start:auto;color:var(--ion-color-step-700, var(--ion-text-color-step-300, #4d4d4d));white-space:nowrap;-webkit-padding-start:16px;padding-inline-start:16px}.has-focus.sc-ion-input-ios-h input.sc-ion-input-ios{caret-color:var(--highlight-color)}.label-text-wrapper.sc-ion-input-ios{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;max-width:200px;-webkit-transition:color 150ms cubic-bezier(0.4, 0, 0.2, 1), -webkit-transform 150ms cubic-bezier(0.4, 0, 0.2, 1);transition:color 150ms cubic-bezier(0.4, 0, 0.2, 1), -webkit-transform 150ms cubic-bezier(0.4, 0, 0.2, 1);transition:color 150ms cubic-bezier(0.4, 0, 0.2, 1), transform 150ms cubic-bezier(0.4, 0, 0.2, 1);transition:color 150ms cubic-bezier(0.4, 0, 0.2, 1), transform 150ms cubic-bezier(0.4, 0, 0.2, 1), -webkit-transform 150ms cubic-bezier(0.4, 0, 0.2, 1);pointer-events:none}.label-text.sc-ion-input-ios,.sc-ion-input-ios-s>[slot=label]{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.label-text-wrapper-hidden.sc-ion-input-ios,.input-outline-notch-hidden.sc-ion-input-ios{display:none}.input-wrapper.sc-ion-input-ios input.sc-ion-input-ios{-webkit-transition:opacity 150ms cubic-bezier(0.4, 0, 0.2, 1);transition:opacity 150ms cubic-bezier(0.4, 0, 0.2, 1)}.input-label-placement-start.sc-ion-input-ios-h .input-wrapper.sc-ion-input-ios{-ms-flex-direction:row;flex-direction:row}.input-label-placement-start.sc-ion-input-ios-h .label-text-wrapper.sc-ion-input-ios{-webkit-margin-start:0;margin-inline-start:0;-webkit-margin-end:16px;margin-inline-end:16px;margin-top:0;margin-bottom:0}.input-label-placement-end.sc-ion-input-ios-h .input-wrapper.sc-ion-input-ios{-ms-flex-direction:row-reverse;flex-direction:row-reverse}.input-label-placement-end.sc-ion-input-ios-h .label-text-wrapper.sc-ion-input-ios{-webkit-margin-start:16px;margin-inline-start:16px;-webkit-margin-end:0;margin-inline-end:0;margin-top:0;margin-bottom:0}.input-label-placement-fixed.sc-ion-input-ios-h .label-text-wrapper.sc-ion-input-ios{-webkit-margin-start:0;margin-inline-start:0;-webkit-margin-end:16px;margin-inline-end:16px;margin-top:0;margin-bottom:0}.input-label-placement-fixed.sc-ion-input-ios-h .label-text.sc-ion-input-ios{-ms-flex:0 0 100px;flex:0 0 100px;width:100px;min-width:100px;max-width:200px}.input-label-placement-stacked.sc-ion-input-ios-h .input-wrapper.sc-ion-input-ios,.input-label-placement-floating.sc-ion-input-ios-h .input-wrapper.sc-ion-input-ios{-ms-flex-direction:column;flex-direction:column;-ms-flex-align:start;align-items:start}.input-label-placement-stacked.sc-ion-input-ios-h .label-text-wrapper.sc-ion-input-ios,.input-label-placement-floating.sc-ion-input-ios-h .label-text-wrapper.sc-ion-input-ios{-webkit-transform-origin:left top;transform-origin:left top;max-width:100%;z-index:2}[dir=rtl].sc-ion-input-ios-h -no-combinator.input-label-placement-stacked.sc-ion-input-ios-h .label-text-wrapper.sc-ion-input-ios,[dir=rtl] .sc-ion-input-ios-h -no-combinator.input-label-placement-stacked.sc-ion-input-ios-h .label-text-wrapper.sc-ion-input-ios,[dir=rtl].input-label-placement-stacked.sc-ion-input-ios-h .label-text-wrapper.sc-ion-input-ios,[dir=rtl] .input-label-placement-stacked.sc-ion-input-ios-h .label-text-wrapper.sc-ion-input-ios,[dir=rtl].sc-ion-input-ios-h -no-combinator.input-label-placement-floating.sc-ion-input-ios-h .label-text-wrapper.sc-ion-input-ios,[dir=rtl] .sc-ion-input-ios-h -no-combinator.input-label-placement-floating.sc-ion-input-ios-h .label-text-wrapper.sc-ion-input-ios,[dir=rtl].input-label-placement-floating.sc-ion-input-ios-h .label-text-wrapper.sc-ion-input-ios,[dir=rtl] .input-label-placement-floating.sc-ion-input-ios-h .label-text-wrapper.sc-ion-input-ios{-webkit-transform-origin:right top;transform-origin:right top}@supports selector(:dir(rtl)){.input-label-placement-stacked.sc-ion-input-ios-h:dir(rtl) .label-text-wrapper.sc-ion-input-ios,.input-label-placement-floating.sc-ion-input-ios-h:dir(rtl) .label-text-wrapper.sc-ion-input-ios{-webkit-transform-origin:right top;transform-origin:right top}}.input-label-placement-stacked.sc-ion-input-ios-h input.sc-ion-input-ios,.input-label-placement-floating.sc-ion-input-ios-h input.sc-ion-input-ios{margin-left:0;margin-right:0;margin-top:1px;margin-bottom:0}.input-label-placement-floating.sc-ion-input-ios-h .label-text-wrapper.sc-ion-input-ios{-webkit-transform:translateY(100%) scale(1);transform:translateY(100%) scale(1)}.input-label-placement-floating.sc-ion-input-ios-h input.sc-ion-input-ios{opacity:0}.has-focus.input-label-placement-floating.sc-ion-input-ios-h input.sc-ion-input-ios,.has-value.input-label-placement-floating.sc-ion-input-ios-h input.sc-ion-input-ios{opacity:1}.label-floating.sc-ion-input-ios-h .label-text-wrapper.sc-ion-input-ios{-webkit-transform:translateY(50%) scale(0.75);transform:translateY(50%) scale(0.75);max-width:calc(100% / 0.75)}.sc-ion-input-ios-s>[slot=start]:last-of-type{-webkit-margin-end:16px;margin-inline-end:16px;-webkit-margin-start:0;margin-inline-start:0}.sc-ion-input-ios-s>[slot=end]:first-of-type{-webkit-margin-start:16px;margin-inline-start:16px;-webkit-margin-end:0;margin-inline-end:0}.sc-ion-input-ios-h[disabled].sc-ion-input-ios-s>ion-input-password-toggle,.sc-ion-input-ios-h[disabled] .sc-ion-input-ios-s>ion-input-password-toggle,.sc-ion-input-ios-h[readonly].sc-ion-input-ios-s>ion-input-password-toggle,.sc-ion-input-ios-h[readonly] .sc-ion-input-ios-s>ion-input-password-toggle{display:none}.sc-ion-input-ios-h{--border-width:0.55px;--border-color:var(--ion-item-border-color, var(--ion-border-color, var(--ion-color-step-250, var(--ion-background-color-step-250, #c8c7cc))));--highlight-height:0px;font-size:inherit}.input-clear-icon.sc-ion-input-ios ion-icon.sc-ion-input-ios{width:18px;height:18px}.input-disabled.sc-ion-input-ios-h{opacity:0.3}.sc-ion-input-ios-s>ion-button[slot=start].button-has-icon-only,.sc-ion-input-ios-s>ion-button[slot=end].button-has-icon-only{--border-radius:50%;--padding-start:0;--padding-end:0;--padding-top:0;--padding-bottom:0;aspect-ratio:1}";
  14925. var IonInputIosStyle0 = inputIosCss;
  14926. const inputMdCss = ".sc-ion-input-md-h{--placeholder-color:initial;--placeholder-font-style:initial;--placeholder-font-weight:initial;--placeholder-opacity:var(--ion-placeholder-opacity, 0.6);--padding-top:0px;--padding-end:0px;--padding-bottom:0px;--padding-start:0px;--background:transparent;--color:initial;--border-style:solid;--highlight-color-focused:var(--ion-color-primary, #0054e9);--highlight-color-valid:var(--ion-color-success, #2dd55b);--highlight-color-invalid:var(--ion-color-danger, #c5000f);--highlight-color:var(--highlight-color-focused);display:block;position:relative;width:100%;min-height:44px;padding:0 !important;color:var(--color);font-family:var(--ion-font-family, inherit);z-index:2}ion-item[slot=start].sc-ion-input-md-h,ion-item [slot=start].sc-ion-input-md-h,ion-item[slot=end].sc-ion-input-md-h,ion-item [slot=end].sc-ion-input-md-h{width:auto}.ion-color.sc-ion-input-md-h{--highlight-color-focused:var(--ion-color-base)}.input-label-placement-floating.sc-ion-input-md-h,.input-label-placement-stacked.sc-ion-input-md-h{min-height:56px}.native-input.sc-ion-input-md{padding-left:0;padding-right:0;padding-top:0;padding-bottom:0;font-family:inherit;font-size:inherit;font-style:inherit;font-weight:inherit;letter-spacing:inherit;text-decoration:inherit;text-indent:inherit;text-overflow:inherit;text-transform:inherit;text-align:inherit;white-space:inherit;color:inherit;display:inline-block;position:relative;-ms-flex:1;flex:1;width:100%;max-width:100%;height:100%;max-height:100%;border:0;outline:none;background:transparent;-webkit-box-sizing:border-box;box-sizing:border-box;-webkit-appearance:none;-moz-appearance:none;appearance:none;z-index:1}.native-input.sc-ion-input-md::-webkit-input-placeholder{color:var(--placeholder-color);font-family:inherit;font-style:var(--placeholder-font-style);font-weight:var(--placeholder-font-weight);opacity:var(--placeholder-opacity)}.native-input.sc-ion-input-md::-moz-placeholder{color:var(--placeholder-color);font-family:inherit;font-style:var(--placeholder-font-style);font-weight:var(--placeholder-font-weight);opacity:var(--placeholder-opacity)}.native-input.sc-ion-input-md:-ms-input-placeholder{color:var(--placeholder-color);font-family:inherit;font-style:var(--placeholder-font-style);font-weight:var(--placeholder-font-weight);opacity:var(--placeholder-opacity)}.native-input.sc-ion-input-md::-ms-input-placeholder{color:var(--placeholder-color);font-family:inherit;font-style:var(--placeholder-font-style);font-weight:var(--placeholder-font-weight);opacity:var(--placeholder-opacity)}.native-input.sc-ion-input-md::placeholder{color:var(--placeholder-color);font-family:inherit;font-style:var(--placeholder-font-style);font-weight:var(--placeholder-font-weight);opacity:var(--placeholder-opacity)}.native-input.sc-ion-input-md:-webkit-autofill{background-color:transparent}.native-input.sc-ion-input-md:invalid{-webkit-box-shadow:none;box-shadow:none}.native-input.sc-ion-input-md::-ms-clear{display:none}.cloned-input.sc-ion-input-md{top:0;bottom:0;position:absolute;pointer-events:none}.cloned-input.sc-ion-input-md{inset-inline-start:0}.cloned-input.sc-ion-input-md:disabled{opacity:1}.input-clear-icon.sc-ion-input-md{-webkit-margin-start:auto;margin-inline-start:auto;-webkit-margin-end:auto;margin-inline-end:auto;margin-top:auto;margin-bottom:auto;padding-left:0;padding-right:0;padding-top:0;padding-bottom:0;background-position:center;display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;width:30px;height:30px;border:0;outline:none;background-color:transparent;background-repeat:no-repeat;color:var(--ion-color-step-600, var(--ion-text-color-step-400, #666666));visibility:hidden;-webkit-appearance:none;-moz-appearance:none;appearance:none}.in-item-color.sc-ion-input-md-h .input-clear-icon.sc-ion-input-md{color:inherit}.input-clear-icon.sc-ion-input-md:focus{opacity:0.5}.has-value.sc-ion-input-md-h .input-clear-icon.sc-ion-input-md{visibility:visible}.input-wrapper.sc-ion-input-md{-webkit-padding-start:var(--padding-start);padding-inline-start:var(--padding-start);-webkit-padding-end:var(--padding-end);padding-inline-end:var(--padding-end);padding-top:var(--padding-top);padding-bottom:var(--padding-bottom);border-radius:var(--border-radius);display:-ms-flexbox;display:flex;position:relative;-ms-flex-positive:1;flex-grow:1;-ms-flex-align:stretch;align-items:stretch;height:inherit;min-height:inherit;-webkit-transition:background-color 15ms linear;transition:background-color 15ms linear;background:var(--background);line-height:normal}.native-wrapper.sc-ion-input-md{display:-ms-flexbox;display:flex;position:relative;-ms-flex-positive:1;flex-grow:1;-ms-flex-align:center;align-items:center;width:100%}.ion-touched.ion-invalid.sc-ion-input-md-h{--highlight-color:var(--highlight-color-invalid)}.ion-valid.sc-ion-input-md-h{--highlight-color:var(--highlight-color-valid)}.input-bottom.sc-ion-input-md{-webkit-padding-start:var(--padding-start);padding-inline-start:var(--padding-start);-webkit-padding-end:var(--padding-end);padding-inline-end:var(--padding-end);padding-top:5px;padding-bottom:0;display:-ms-flexbox;display:flex;-ms-flex-pack:justify;justify-content:space-between;border-top:var(--border-width) var(--border-style) var(--border-color);font-size:0.75rem;white-space:normal}.has-focus.ion-valid.sc-ion-input-md-h,.ion-touched.ion-invalid.sc-ion-input-md-h{--border-color:var(--highlight-color)}.input-bottom.sc-ion-input-md .error-text.sc-ion-input-md{display:none;color:var(--highlight-color-invalid)}.input-bottom.sc-ion-input-md .helper-text.sc-ion-input-md{display:block;color:var(--ion-color-step-700, var(--ion-text-color-step-300, #4d4d4d))}.ion-touched.ion-invalid.sc-ion-input-md-h .input-bottom.sc-ion-input-md .error-text.sc-ion-input-md{display:block}.ion-touched.ion-invalid.sc-ion-input-md-h .input-bottom.sc-ion-input-md .helper-text.sc-ion-input-md{display:none}.input-bottom.sc-ion-input-md .counter.sc-ion-input-md{-webkit-margin-start:auto;margin-inline-start:auto;color:var(--ion-color-step-700, var(--ion-text-color-step-300, #4d4d4d));white-space:nowrap;-webkit-padding-start:16px;padding-inline-start:16px}.has-focus.sc-ion-input-md-h input.sc-ion-input-md{caret-color:var(--highlight-color)}.label-text-wrapper.sc-ion-input-md{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;max-width:200px;-webkit-transition:color 150ms cubic-bezier(0.4, 0, 0.2, 1), -webkit-transform 150ms cubic-bezier(0.4, 0, 0.2, 1);transition:color 150ms cubic-bezier(0.4, 0, 0.2, 1), -webkit-transform 150ms cubic-bezier(0.4, 0, 0.2, 1);transition:color 150ms cubic-bezier(0.4, 0, 0.2, 1), transform 150ms cubic-bezier(0.4, 0, 0.2, 1);transition:color 150ms cubic-bezier(0.4, 0, 0.2, 1), transform 150ms cubic-bezier(0.4, 0, 0.2, 1), -webkit-transform 150ms cubic-bezier(0.4, 0, 0.2, 1);pointer-events:none}.label-text.sc-ion-input-md,.sc-ion-input-md-s>[slot=label]{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.label-text-wrapper-hidden.sc-ion-input-md,.input-outline-notch-hidden.sc-ion-input-md{display:none}.input-wrapper.sc-ion-input-md input.sc-ion-input-md{-webkit-transition:opacity 150ms cubic-bezier(0.4, 0, 0.2, 1);transition:opacity 150ms cubic-bezier(0.4, 0, 0.2, 1)}.input-label-placement-start.sc-ion-input-md-h .input-wrapper.sc-ion-input-md{-ms-flex-direction:row;flex-direction:row}.input-label-placement-start.sc-ion-input-md-h .label-text-wrapper.sc-ion-input-md{-webkit-margin-start:0;margin-inline-start:0;-webkit-margin-end:16px;margin-inline-end:16px;margin-top:0;margin-bottom:0}.input-label-placement-end.sc-ion-input-md-h .input-wrapper.sc-ion-input-md{-ms-flex-direction:row-reverse;flex-direction:row-reverse}.input-label-placement-end.sc-ion-input-md-h .label-text-wrapper.sc-ion-input-md{-webkit-margin-start:16px;margin-inline-start:16px;-webkit-margin-end:0;margin-inline-end:0;margin-top:0;margin-bottom:0}.input-label-placement-fixed.sc-ion-input-md-h .label-text-wrapper.sc-ion-input-md{-webkit-margin-start:0;margin-inline-start:0;-webkit-margin-end:16px;margin-inline-end:16px;margin-top:0;margin-bottom:0}.input-label-placement-fixed.sc-ion-input-md-h .label-text.sc-ion-input-md{-ms-flex:0 0 100px;flex:0 0 100px;width:100px;min-width:100px;max-width:200px}.input-label-placement-stacked.sc-ion-input-md-h .input-wrapper.sc-ion-input-md,.input-label-placement-floating.sc-ion-input-md-h .input-wrapper.sc-ion-input-md{-ms-flex-direction:column;flex-direction:column;-ms-flex-align:start;align-items:start}.input-label-placement-stacked.sc-ion-input-md-h .label-text-wrapper.sc-ion-input-md,.input-label-placement-floating.sc-ion-input-md-h .label-text-wrapper.sc-ion-input-md{-webkit-transform-origin:left top;transform-origin:left top;max-width:100%;z-index:2}[dir=rtl].sc-ion-input-md-h -no-combinator.input-label-placement-stacked.sc-ion-input-md-h .label-text-wrapper.sc-ion-input-md,[dir=rtl] .sc-ion-input-md-h -no-combinator.input-label-placement-stacked.sc-ion-input-md-h .label-text-wrapper.sc-ion-input-md,[dir=rtl].input-label-placement-stacked.sc-ion-input-md-h .label-text-wrapper.sc-ion-input-md,[dir=rtl] .input-label-placement-stacked.sc-ion-input-md-h .label-text-wrapper.sc-ion-input-md,[dir=rtl].sc-ion-input-md-h -no-combinator.input-label-placement-floating.sc-ion-input-md-h .label-text-wrapper.sc-ion-input-md,[dir=rtl] .sc-ion-input-md-h -no-combinator.input-label-placement-floating.sc-ion-input-md-h .label-text-wrapper.sc-ion-input-md,[dir=rtl].input-label-placement-floating.sc-ion-input-md-h .label-text-wrapper.sc-ion-input-md,[dir=rtl] .input-label-placement-floating.sc-ion-input-md-h .label-text-wrapper.sc-ion-input-md{-webkit-transform-origin:right top;transform-origin:right top}@supports selector(:dir(rtl)){.input-label-placement-stacked.sc-ion-input-md-h:dir(rtl) .label-text-wrapper.sc-ion-input-md,.input-label-placement-floating.sc-ion-input-md-h:dir(rtl) .label-text-wrapper.sc-ion-input-md{-webkit-transform-origin:right top;transform-origin:right top}}.input-label-placement-stacked.sc-ion-input-md-h input.sc-ion-input-md,.input-label-placement-floating.sc-ion-input-md-h input.sc-ion-input-md{margin-left:0;margin-right:0;margin-top:1px;margin-bottom:0}.input-label-placement-floating.sc-ion-input-md-h .label-text-wrapper.sc-ion-input-md{-webkit-transform:translateY(100%) scale(1);transform:translateY(100%) scale(1)}.input-label-placement-floating.sc-ion-input-md-h input.sc-ion-input-md{opacity:0}.has-focus.input-label-placement-floating.sc-ion-input-md-h input.sc-ion-input-md,.has-value.input-label-placement-floating.sc-ion-input-md-h input.sc-ion-input-md{opacity:1}.label-floating.sc-ion-input-md-h .label-text-wrapper.sc-ion-input-md{-webkit-transform:translateY(50%) scale(0.75);transform:translateY(50%) scale(0.75);max-width:calc(100% / 0.75)}.sc-ion-input-md-s>[slot=start]:last-of-type{-webkit-margin-end:16px;margin-inline-end:16px;-webkit-margin-start:0;margin-inline-start:0}.sc-ion-input-md-s>[slot=end]:first-of-type{-webkit-margin-start:16px;margin-inline-start:16px;-webkit-margin-end:0;margin-inline-end:0}.sc-ion-input-md-h[disabled].sc-ion-input-md-s>ion-input-password-toggle,.sc-ion-input-md-h[disabled] .sc-ion-input-md-s>ion-input-password-toggle,.sc-ion-input-md-h[readonly].sc-ion-input-md-s>ion-input-password-toggle,.sc-ion-input-md-h[readonly] .sc-ion-input-md-s>ion-input-password-toggle{display:none}.input-fill-solid.sc-ion-input-md-h{--background:var(--ion-color-step-50, var(--ion-background-color-step-50, #f2f2f2));--border-color:var(--ion-color-step-500, var(--ion-background-color-step-500, gray));--border-radius:4px;--padding-start:16px;--padding-end:16px;min-height:56px}.input-fill-solid.sc-ion-input-md-h .input-wrapper.sc-ion-input-md{border-bottom:var(--border-width) var(--border-style) var(--border-color)}.has-focus.input-fill-solid.ion-valid.sc-ion-input-md-h,.input-fill-solid.ion-touched.ion-invalid.sc-ion-input-md-h{--border-color:var(--highlight-color)}.input-fill-solid.sc-ion-input-md-h .input-bottom.sc-ion-input-md{border-top:none}@media (any-hover: hover){.input-fill-solid.sc-ion-input-md-h:hover{--background:var(--ion-color-step-100, var(--ion-background-color-step-100, #e6e6e6));--border-color:var(--ion-color-step-750, var(--ion-background-color-step-750, #404040))}}.input-fill-solid.has-focus.sc-ion-input-md-h{--background:var(--ion-color-step-150, var(--ion-background-color-step-150, #d9d9d9));--border-color:var(--ion-color-step-750, var(--ion-background-color-step-750, #404040))}.input-fill-solid.sc-ion-input-md-h .input-wrapper.sc-ion-input-md{border-start-start-radius:var(--border-radius);border-start-end-radius:var(--border-radius);border-end-end-radius:0px;border-end-start-radius:0px}.label-floating.input-fill-solid.input-label-placement-floating.sc-ion-input-md-h .label-text-wrapper.sc-ion-input-md{max-width:calc(100% / 0.75)}.input-fill-outline.sc-ion-input-md-h{--border-color:var(--ion-color-step-300, var(--ion-background-color-step-300, #b3b3b3));--border-radius:4px;--padding-start:16px;--padding-end:16px;min-height:56px}.input-fill-outline.input-shape-round.sc-ion-input-md-h{--border-radius:28px;--padding-start:32px;--padding-end:32px}.has-focus.input-fill-outline.ion-valid.sc-ion-input-md-h,.input-fill-outline.ion-touched.ion-invalid.sc-ion-input-md-h{--border-color:var(--highlight-color)}@media (any-hover: hover){.input-fill-outline.sc-ion-input-md-h:hover{--border-color:var(--ion-color-step-750, var(--ion-background-color-step-750, #404040))}}.input-fill-outline.has-focus.sc-ion-input-md-h{--border-width:var(--highlight-height);--border-color:var(--highlight-color)}.input-fill-outline.sc-ion-input-md-h .input-bottom.sc-ion-input-md{border-top:none}.input-fill-outline.sc-ion-input-md-h .input-wrapper.sc-ion-input-md{border-bottom:none}.input-fill-outline.input-label-placement-stacked.sc-ion-input-md-h .label-text-wrapper.sc-ion-input-md,.input-fill-outline.input-label-placement-floating.sc-ion-input-md-h .label-text-wrapper.sc-ion-input-md{-webkit-transform-origin:left top;transform-origin:left top;position:absolute;max-width:calc(100% - var(--padding-start) - var(--padding-end))}[dir=rtl].sc-ion-input-md-h -no-combinator.input-fill-outline.input-label-placement-stacked.sc-ion-input-md-h .label-text-wrapper.sc-ion-input-md,[dir=rtl] .sc-ion-input-md-h -no-combinator.input-fill-outline.input-label-placement-stacked.sc-ion-input-md-h .label-text-wrapper.sc-ion-input-md,[dir=rtl].input-fill-outline.input-label-placement-stacked.sc-ion-input-md-h .label-text-wrapper.sc-ion-input-md,[dir=rtl] .input-fill-outline.input-label-placement-stacked.sc-ion-input-md-h .label-text-wrapper.sc-ion-input-md,[dir=rtl].sc-ion-input-md-h -no-combinator.input-fill-outline.input-label-placement-floating.sc-ion-input-md-h .label-text-wrapper.sc-ion-input-md,[dir=rtl] .sc-ion-input-md-h -no-combinator.input-fill-outline.input-label-placement-floating.sc-ion-input-md-h .label-text-wrapper.sc-ion-input-md,[dir=rtl].input-fill-outline.input-label-placement-floating.sc-ion-input-md-h .label-text-wrapper.sc-ion-input-md,[dir=rtl] .input-fill-outline.input-label-placement-floating.sc-ion-input-md-h .label-text-wrapper.sc-ion-input-md{-webkit-transform-origin:right top;transform-origin:right top}@supports selector(:dir(rtl)){.input-fill-outline.input-label-placement-stacked.sc-ion-input-md-h:dir(rtl) .label-text-wrapper.sc-ion-input-md,.input-fill-outline.input-label-placement-floating.sc-ion-input-md-h:dir(rtl) .label-text-wrapper.sc-ion-input-md{-webkit-transform-origin:right top;transform-origin:right top}}.input-fill-outline.sc-ion-input-md-h .label-text-wrapper.sc-ion-input-md{position:relative}.label-floating.input-fill-outline.sc-ion-input-md-h .label-text-wrapper.sc-ion-input-md{-webkit-transform:translateY(-32%) scale(0.75);transform:translateY(-32%) scale(0.75);margin-left:0;margin-right:0;margin-top:0;margin-bottom:0;max-width:calc((100% - var(--padding-start) - var(--padding-end) - 8px) / 0.75)}.input-fill-outline.input-label-placement-stacked.sc-ion-input-md-h input.sc-ion-input-md,.input-fill-outline.input-label-placement-floating.sc-ion-input-md-h input.sc-ion-input-md{margin-left:0;margin-right:0;margin-top:6px;margin-bottom:6px}.input-fill-outline.sc-ion-input-md-h .input-outline-container.sc-ion-input-md{left:0;right:0;top:0;bottom:0;display:-ms-flexbox;display:flex;position:absolute;width:100%;height:100%}.input-fill-outline.sc-ion-input-md-h .input-outline-start.sc-ion-input-md,.input-fill-outline.sc-ion-input-md-h .input-outline-end.sc-ion-input-md{pointer-events:none}.input-fill-outline.sc-ion-input-md-h .input-outline-start.sc-ion-input-md,.input-fill-outline.sc-ion-input-md-h .input-outline-notch.sc-ion-input-md,.input-fill-outline.sc-ion-input-md-h .input-outline-end.sc-ion-input-md{border-top:var(--border-width) var(--border-style) var(--border-color);border-bottom:var(--border-width) var(--border-style) var(--border-color)}.input-fill-outline.sc-ion-input-md-h .input-outline-notch.sc-ion-input-md{max-width:calc(100% - var(--padding-start) - var(--padding-end))}.input-fill-outline.sc-ion-input-md-h .notch-spacer.sc-ion-input-md{-webkit-padding-end:8px;padding-inline-end:8px;font-size:calc(1em * 0.75);opacity:0;pointer-events:none;-webkit-box-sizing:content-box;box-sizing:content-box}.input-fill-outline.sc-ion-input-md-h .input-outline-start.sc-ion-input-md{border-start-start-radius:var(--border-radius);border-start-end-radius:0px;border-end-end-radius:0px;border-end-start-radius:var(--border-radius);-webkit-border-start:var(--border-width) var(--border-style) var(--border-color);border-inline-start:var(--border-width) var(--border-style) var(--border-color);width:calc(var(--padding-start) - 4px)}.input-fill-outline.sc-ion-input-md-h .input-outline-end.sc-ion-input-md{-webkit-border-end:var(--border-width) var(--border-style) var(--border-color);border-inline-end:var(--border-width) var(--border-style) var(--border-color);border-start-start-radius:0px;border-start-end-radius:var(--border-radius);border-end-end-radius:var(--border-radius);border-end-start-radius:0px;-ms-flex-positive:1;flex-grow:1}.label-floating.input-fill-outline.sc-ion-input-md-h .input-outline-notch.sc-ion-input-md{border-top:none}.sc-ion-input-md-h{--border-width:1px;--border-color:var(--ion-item-border-color, var(--ion-border-color, var(--ion-color-step-150, var(--ion-background-color-step-150, rgba(0, 0, 0, 0.13)))));--highlight-height:2px;font-size:inherit}.input-clear-icon.sc-ion-input-md ion-icon.sc-ion-input-md{width:22px;height:22px}.input-disabled.sc-ion-input-md-h{opacity:0.38}.has-focus.ion-valid.sc-ion-input-md-h,.ion-touched.ion-invalid.sc-ion-input-md-h{--border-color:var(--highlight-color)}.input-bottom.sc-ion-input-md .counter.sc-ion-input-md{letter-spacing:0.0333333333em}.input-label-placement-floating.has-focus.sc-ion-input-md-h .label-text-wrapper.sc-ion-input-md,.input-label-placement-stacked.has-focus.sc-ion-input-md-h .label-text-wrapper.sc-ion-input-md{color:var(--highlight-color)}.has-focus.input-label-placement-floating.ion-valid.sc-ion-input-md-h .label-text-wrapper.sc-ion-input-md,.input-label-placement-floating.ion-touched.ion-invalid.sc-ion-input-md-h .label-text-wrapper.sc-ion-input-md,.has-focus.input-label-placement-stacked.ion-valid.sc-ion-input-md-h .label-text-wrapper.sc-ion-input-md,.input-label-placement-stacked.ion-touched.ion-invalid.sc-ion-input-md-h .label-text-wrapper.sc-ion-input-md{color:var(--highlight-color)}.input-highlight.sc-ion-input-md{bottom:-1px;position:absolute;width:100%;height:var(--highlight-height);-webkit-transform:scale(0);transform:scale(0);-webkit-transition:-webkit-transform 200ms;transition:-webkit-transform 200ms;transition:transform 200ms;transition:transform 200ms, -webkit-transform 200ms;background:var(--highlight-color)}.input-highlight.sc-ion-input-md{inset-inline-start:0}.has-focus.sc-ion-input-md-h .input-highlight.sc-ion-input-md{-webkit-transform:scale(1);transform:scale(1)}.in-item.sc-ion-input-md-h .input-highlight.sc-ion-input-md{bottom:0}.in-item.sc-ion-input-md-h .input-highlight.sc-ion-input-md{inset-inline-start:0}.input-shape-round.sc-ion-input-md-h{--border-radius:16px}.sc-ion-input-md-s>ion-button[slot=start].button-has-icon-only,.sc-ion-input-md-s>ion-button[slot=end].button-has-icon-only{--border-radius:50%;--padding-start:8px;--padding-end:8px;--padding-top:8px;--padding-bottom:8px;aspect-ratio:1;min-height:40px}";
  14927. var IonInputMdStyle0 = inputMdCss;
  14928. /**
  14929. * @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
  14930. *
  14931. * @slot label - The label text to associate with the input. Use the `labelPlacement` property to control where the label is placed relative to the input. Use this if you need to render a label with custom HTML. (EXPERIMENTAL)
  14932. * @slot start - Content to display at the leading edge of the input. (EXPERIMENTAL)
  14933. * @slot end - Content to display at the trailing edge of the input. (EXPERIMENTAL)
  14934. */
  14935. class Input {
  14936. constructor(hostRef) {
  14937. registerInstance(this, hostRef);
  14938. this.ionInput = createEvent(this, "ionInput", 7);
  14939. this.ionChange = createEvent(this, "ionChange", 7);
  14940. this.ionBlur = createEvent(this, "ionBlur", 7);
  14941. this.ionFocus = createEvent(this, "ionFocus", 7);
  14942. this.inputId = `ion-input-${inputIds++}`;
  14943. this.helperTextId = `${this.inputId}-helper-text`;
  14944. this.errorTextId = `${this.inputId}-error-text`;
  14945. this.inheritedAttributes = {};
  14946. this.isComposing = false;
  14947. /**
  14948. * `true` if the input was cleared as a result of the user typing
  14949. * with `clearOnEdit` enabled.
  14950. *
  14951. * Resets when the input loses focus.
  14952. */
  14953. this.didInputClearOnEdit = false;
  14954. this.onInput = (ev) => {
  14955. const input = ev.target;
  14956. if (input) {
  14957. this.value = input.value || '';
  14958. }
  14959. this.emitInputChange(ev);
  14960. };
  14961. this.onChange = (ev) => {
  14962. this.emitValueChange(ev);
  14963. };
  14964. this.onBlur = (ev) => {
  14965. this.hasFocus = false;
  14966. if (this.focusedValue !== this.value) {
  14967. /**
  14968. * Emits the `ionChange` event when the input value
  14969. * is different than the value when the input was focused.
  14970. */
  14971. this.emitValueChange(ev);
  14972. }
  14973. this.didInputClearOnEdit = false;
  14974. this.ionBlur.emit(ev);
  14975. };
  14976. this.onFocus = (ev) => {
  14977. this.hasFocus = true;
  14978. this.focusedValue = this.value;
  14979. this.ionFocus.emit(ev);
  14980. };
  14981. this.onKeydown = (ev) => {
  14982. this.checkClearOnEdit(ev);
  14983. };
  14984. this.onCompositionStart = () => {
  14985. this.isComposing = true;
  14986. };
  14987. this.onCompositionEnd = () => {
  14988. this.isComposing = false;
  14989. };
  14990. this.clearTextInput = (ev) => {
  14991. if (this.clearInput && !this.readonly && !this.disabled && ev) {
  14992. ev.preventDefault();
  14993. ev.stopPropagation();
  14994. // Attempt to focus input again after pressing clear button
  14995. this.setFocus();
  14996. }
  14997. this.value = '';
  14998. this.emitInputChange(ev);
  14999. };
  15000. /**
  15001. * Stops propagation when the label is clicked,
  15002. * otherwise, two clicks will be triggered.
  15003. */
  15004. this.onLabelClick = (ev) => {
  15005. // Only stop propagation if the click was directly on the label
  15006. // and not on the input or other child elements
  15007. if (ev.target === ev.currentTarget) {
  15008. ev.stopPropagation();
  15009. }
  15010. };
  15011. this.hasFocus = false;
  15012. this.color = undefined;
  15013. this.autocapitalize = 'off';
  15014. this.autocomplete = 'off';
  15015. this.autocorrect = 'off';
  15016. this.autofocus = false;
  15017. this.clearInput = false;
  15018. this.clearInputIcon = undefined;
  15019. this.clearOnEdit = undefined;
  15020. this.counter = false;
  15021. this.counterFormatter = undefined;
  15022. this.debounce = undefined;
  15023. this.disabled = false;
  15024. this.enterkeyhint = undefined;
  15025. this.errorText = undefined;
  15026. this.fill = undefined;
  15027. this.inputmode = undefined;
  15028. this.helperText = undefined;
  15029. this.label = undefined;
  15030. this.labelPlacement = 'start';
  15031. this.max = undefined;
  15032. this.maxlength = undefined;
  15033. this.min = undefined;
  15034. this.minlength = undefined;
  15035. this.multiple = undefined;
  15036. this.name = this.inputId;
  15037. this.pattern = undefined;
  15038. this.placeholder = undefined;
  15039. this.readonly = false;
  15040. this.required = false;
  15041. this.shape = undefined;
  15042. this.spellcheck = false;
  15043. this.step = undefined;
  15044. this.type = 'text';
  15045. this.value = '';
  15046. }
  15047. debounceChanged() {
  15048. const { ionInput, debounce, originalIonInput } = this;
  15049. /**
  15050. * If debounce is undefined, we have to manually revert the ionInput emitter in case
  15051. * debounce used to be set to a number. Otherwise, the event would stay debounced.
  15052. */
  15053. this.ionInput = debounce === undefined ? originalIonInput !== null && originalIonInput !== void 0 ? originalIonInput : ionInput : debounceEvent(ionInput, debounce);
  15054. }
  15055. /**
  15056. * Whenever the type on the input changes we need
  15057. * to update the internal type prop on the password
  15058. * toggle so that that correct icon is shown.
  15059. */
  15060. onTypeChange() {
  15061. const passwordToggle = this.el.querySelector('ion-input-password-toggle');
  15062. if (passwordToggle) {
  15063. passwordToggle.type = this.type;
  15064. }
  15065. }
  15066. /**
  15067. * Update the native input element when the value changes
  15068. */
  15069. valueChanged() {
  15070. const nativeInput = this.nativeInput;
  15071. const value = this.getValue();
  15072. if (nativeInput && nativeInput.value !== value && !this.isComposing) {
  15073. /**
  15074. * Assigning the native input's value on attribute
  15075. * value change, allows `ionInput` implementations
  15076. * to override the control's value.
  15077. *
  15078. * Used for patterns such as input trimming (removing whitespace),
  15079. * or input masking.
  15080. */
  15081. nativeInput.value = value;
  15082. }
  15083. }
  15084. /**
  15085. * dir is a globally enumerated attribute.
  15086. * As a result, creating these as properties
  15087. * can have unintended side effects. Instead, we
  15088. * listen for attribute changes and inherit them
  15089. * to the inner `<input>` element.
  15090. */
  15091. onDirChanged(newValue) {
  15092. this.inheritedAttributes = Object.assign(Object.assign({}, this.inheritedAttributes), { dir: newValue });
  15093. }
  15094. /**
  15095. * This prevents the native input from emitting the click event.
  15096. * Instead, the click event from the ion-input is emitted.
  15097. */
  15098. onClickCapture(ev) {
  15099. const nativeInput = this.nativeInput;
  15100. if (nativeInput && ev.target === nativeInput) {
  15101. ev.stopPropagation();
  15102. this.el.click();
  15103. }
  15104. }
  15105. componentWillLoad() {
  15106. this.inheritedAttributes = Object.assign(Object.assign({}, inheritAriaAttributes(this.el)), inheritAttributes$1(this.el, ['tabindex', 'title', 'data-form-type', 'dir']));
  15107. }
  15108. connectedCallback() {
  15109. const { el } = this;
  15110. this.slotMutationController = createSlotMutationController(el, ['label', 'start', 'end'], () => forceUpdate());
  15111. this.notchController = createNotchController(el, () => this.notchSpacerEl, () => this.labelSlot);
  15112. this.debounceChanged();
  15113. }
  15114. componentDidLoad() {
  15115. this.originalIonInput = this.ionInput;
  15116. /**
  15117. * Set the type on the password toggle in the event that this input's
  15118. * type was set async and does not match the default type for the password toggle.
  15119. * This can happen when the type is bound using a JS framework binding syntax
  15120. * such as [type] in Angular.
  15121. */
  15122. this.onTypeChange();
  15123. this.debounceChanged();
  15124. }
  15125. componentDidRender() {
  15126. var _a;
  15127. (_a = this.notchController) === null || _a === void 0 ? void 0 : _a.calculateNotchWidth();
  15128. }
  15129. disconnectedCallback() {
  15130. if (this.slotMutationController) {
  15131. this.slotMutationController.destroy();
  15132. this.slotMutationController = undefined;
  15133. }
  15134. if (this.notchController) {
  15135. this.notchController.destroy();
  15136. this.notchController = undefined;
  15137. }
  15138. }
  15139. /**
  15140. * Sets focus on the native `input` in `ion-input`. Use this method instead of the global
  15141. * `input.focus()`.
  15142. *
  15143. * Developers who wish to focus an input when a page enters
  15144. * should call `setFocus()` in the `ionViewDidEnter()` lifecycle method.
  15145. *
  15146. * Developers who wish to focus an input when an overlay is presented
  15147. * should call `setFocus` after `didPresent` has resolved.
  15148. *
  15149. * See [managing focus](/docs/developing/managing-focus) for more information.
  15150. */
  15151. async setFocus() {
  15152. if (this.nativeInput) {
  15153. this.nativeInput.focus();
  15154. }
  15155. }
  15156. /**
  15157. * Returns the native `<input>` element used under the hood.
  15158. */
  15159. async getInputElement() {
  15160. /**
  15161. * If this gets called in certain early lifecycle hooks (ex: Vue onMounted),
  15162. * nativeInput won't be defined yet with the custom elements build, so wait for it to load in.
  15163. */
  15164. if (!this.nativeInput) {
  15165. await new Promise((resolve) => componentOnReady(this.el, resolve));
  15166. }
  15167. return Promise.resolve(this.nativeInput);
  15168. }
  15169. /**
  15170. * Emits an `ionChange` event.
  15171. *
  15172. * This API should be called for user committed changes.
  15173. * This API should not be used for external value changes.
  15174. */
  15175. emitValueChange(event) {
  15176. const { value } = this;
  15177. // Checks for both null and undefined values
  15178. const newValue = value == null ? value : value.toString();
  15179. // Emitting a value change should update the internal state for tracking the focused value
  15180. this.focusedValue = newValue;
  15181. this.ionChange.emit({ value: newValue, event });
  15182. }
  15183. /**
  15184. * Emits an `ionInput` event.
  15185. */
  15186. emitInputChange(event) {
  15187. const { value } = this;
  15188. // Checks for both null and undefined values
  15189. const newValue = value == null ? value : value.toString();
  15190. this.ionInput.emit({ value: newValue, event });
  15191. }
  15192. shouldClearOnEdit() {
  15193. const { type, clearOnEdit } = this;
  15194. return clearOnEdit === undefined ? type === 'password' : clearOnEdit;
  15195. }
  15196. getValue() {
  15197. return typeof this.value === 'number' ? this.value.toString() : (this.value || '').toString();
  15198. }
  15199. checkClearOnEdit(ev) {
  15200. if (!this.shouldClearOnEdit()) {
  15201. return;
  15202. }
  15203. /**
  15204. * The following keys do not modify the
  15205. * contents of the input. As a result, pressing
  15206. * them should not edit the input.
  15207. *
  15208. * We can't check to see if the value of the input
  15209. * was changed because we call checkClearOnEdit
  15210. * in a keydown listener, and the key has not yet
  15211. * been added to the input.
  15212. */
  15213. const IGNORED_KEYS = ['Enter', 'Tab', 'Shift', 'Meta', 'Alt', 'Control'];
  15214. const pressedIgnoredKey = IGNORED_KEYS.includes(ev.key);
  15215. /**
  15216. * Clear the input if the control has not been previously cleared during focus.
  15217. * Do not clear if the user hitting enter to submit a form.
  15218. */
  15219. if (!this.didInputClearOnEdit && this.hasValue() && !pressedIgnoredKey) {
  15220. this.value = '';
  15221. this.emitInputChange(ev);
  15222. }
  15223. /**
  15224. * Pressing an IGNORED_KEYS first and
  15225. * then an allowed key will cause the input to not
  15226. * be cleared.
  15227. */
  15228. if (!pressedIgnoredKey) {
  15229. this.didInputClearOnEdit = true;
  15230. }
  15231. }
  15232. hasValue() {
  15233. return this.getValue().length > 0;
  15234. }
  15235. /**
  15236. * Renders the helper text or error text values
  15237. */
  15238. renderHintText() {
  15239. const { helperText, errorText, helperTextId, errorTextId } = this;
  15240. return [
  15241. hAsync("div", { id: helperTextId, class: "helper-text" }, helperText),
  15242. hAsync("div", { id: errorTextId, class: "error-text" }, errorText),
  15243. ];
  15244. }
  15245. getHintTextID() {
  15246. const { el, helperText, errorText, helperTextId, errorTextId } = this;
  15247. if (el.classList.contains('ion-touched') && el.classList.contains('ion-invalid') && errorText) {
  15248. return errorTextId;
  15249. }
  15250. if (helperText) {
  15251. return helperTextId;
  15252. }
  15253. return undefined;
  15254. }
  15255. renderCounter() {
  15256. const { counter, maxlength, counterFormatter, value } = this;
  15257. if (counter !== true || maxlength === undefined) {
  15258. return;
  15259. }
  15260. return hAsync("div", { class: "counter" }, getCounterText(value, maxlength, counterFormatter));
  15261. }
  15262. /**
  15263. * Responsible for rendering helper text,
  15264. * error text, and counter. This element should only
  15265. * be rendered if hint text is set or counter is enabled.
  15266. */
  15267. renderBottomContent() {
  15268. const { counter, helperText, errorText, maxlength } = this;
  15269. /**
  15270. * undefined and empty string values should
  15271. * be treated as not having helper/error text.
  15272. */
  15273. const hasHintText = !!helperText || !!errorText;
  15274. const hasCounter = counter === true && maxlength !== undefined;
  15275. if (!hasHintText && !hasCounter) {
  15276. return;
  15277. }
  15278. return (hAsync("div", { class: "input-bottom" }, this.renderHintText(), this.renderCounter()));
  15279. }
  15280. renderLabel() {
  15281. const { label } = this;
  15282. return (hAsync("div", { class: {
  15283. 'label-text-wrapper': true,
  15284. 'label-text-wrapper-hidden': !this.hasLabel,
  15285. } }, label === undefined ? hAsync("slot", { name: "label" }) : hAsync("div", { class: "label-text" }, label)));
  15286. }
  15287. /**
  15288. * Gets any content passed into the `label` slot,
  15289. * not the <slot> definition.
  15290. */
  15291. get labelSlot() {
  15292. return this.el.querySelector('[slot="label"]');
  15293. }
  15294. /**
  15295. * Returns `true` if label content is provided
  15296. * either by a prop or a content. If you want
  15297. * to get the plaintext value of the label use
  15298. * the `labelText` getter instead.
  15299. */
  15300. get hasLabel() {
  15301. return this.label !== undefined || this.labelSlot !== null;
  15302. }
  15303. /**
  15304. * Renders the border container
  15305. * when fill="outline".
  15306. */
  15307. renderLabelContainer() {
  15308. const mode = getIonMode$1(this);
  15309. const hasOutlineFill = mode === 'md' && this.fill === 'outline';
  15310. if (hasOutlineFill) {
  15311. /**
  15312. * The outline fill has a special outline
  15313. * that appears around the input and the label.
  15314. * Certain stacked and floating label placements cause the
  15315. * label to translate up and create a "cut out"
  15316. * inside of that border by using the notch-spacer element.
  15317. */
  15318. return [
  15319. hAsync("div", { class: "input-outline-container" }, hAsync("div", { class: "input-outline-start" }), hAsync("div", { class: {
  15320. 'input-outline-notch': true,
  15321. 'input-outline-notch-hidden': !this.hasLabel,
  15322. } }, hAsync("div", { class: "notch-spacer", "aria-hidden": "true", ref: (el) => (this.notchSpacerEl = el) }, this.label)), hAsync("div", { class: "input-outline-end" })),
  15323. this.renderLabel(),
  15324. ];
  15325. }
  15326. /**
  15327. * If not using the outline style,
  15328. * we can render just the label.
  15329. */
  15330. return this.renderLabel();
  15331. }
  15332. render() {
  15333. const { disabled, fill, readonly, shape, inputId, labelPlacement, el, hasFocus, clearInputIcon } = this;
  15334. const mode = getIonMode$1(this);
  15335. const value = this.getValue();
  15336. const inItem = hostContext('ion-item', this.el);
  15337. const shouldRenderHighlight = mode === 'md' && fill !== 'outline' && !inItem;
  15338. const defaultClearIcon = mode === 'ios' ? closeCircle : closeSharp;
  15339. const clearIconData = clearInputIcon !== null && clearInputIcon !== void 0 ? clearInputIcon : defaultClearIcon;
  15340. const hasValue = this.hasValue();
  15341. const hasStartEndSlots = el.querySelector('[slot="start"], [slot="end"]') !== null;
  15342. /**
  15343. * If the label is stacked, it should always sit above the input.
  15344. * For floating labels, the label should move above the input if
  15345. * the input has a value, is focused, or has anything in either
  15346. * the start or end slot.
  15347. *
  15348. * If there is content in the start slot, the label would overlap
  15349. * it if not forced to float. This is also applied to the end slot
  15350. * because with the default or solid fills, the input is not
  15351. * vertically centered in the container, but the label is. This
  15352. * causes the slots and label to appear vertically offset from each
  15353. * other when the label isn't floating above the input. This doesn't
  15354. * apply to the outline fill, but this was not accounted for to keep
  15355. * things consistent.
  15356. *
  15357. * TODO(FW-5592): Remove hasStartEndSlots condition
  15358. */
  15359. const labelShouldFloat = labelPlacement === 'stacked' || (labelPlacement === 'floating' && (hasValue || hasFocus || hasStartEndSlots));
  15360. return (hAsync(Host, { key: '41b2526627e7d2773a80f011b123284203a71ca0', class: createColorClasses$1(this.color, {
  15361. [mode]: true,
  15362. 'has-value': hasValue,
  15363. 'has-focus': hasFocus,
  15364. 'label-floating': labelShouldFloat,
  15365. [`input-fill-${fill}`]: fill !== undefined,
  15366. [`input-shape-${shape}`]: shape !== undefined,
  15367. [`input-label-placement-${labelPlacement}`]: true,
  15368. 'in-item': inItem,
  15369. 'in-item-color': hostContext('ion-item.ion-color', this.el),
  15370. 'input-disabled': disabled,
  15371. }) }, hAsync("label", { key: '9ab078363e32528102b441ad1791d83f86fdcbdc', class: "input-wrapper", htmlFor: inputId, onClick: this.onLabelClick }, this.renderLabelContainer(), hAsync("div", { key: 'e34b594980ec62e4c618e827fadf7669a39ad0d8', class: "native-wrapper", onClick: this.onLabelClick }, hAsync("slot", { key: '12dc04ead5502e9e5736240e918bf9331bf7b5d9', name: "start" }), hAsync("input", Object.assign({ key: 'df356eb4ced23109b2c0242f36dc043aba8782d6', class: "native-input", ref: (input) => (this.nativeInput = input), id: inputId, disabled: disabled, autoCapitalize: this.autocapitalize, autoComplete: this.autocomplete, autoCorrect: this.autocorrect, autoFocus: this.autofocus, enterKeyHint: this.enterkeyhint, inputMode: this.inputmode, min: this.min, max: this.max, minLength: this.minlength, maxLength: this.maxlength, multiple: this.multiple, name: this.name, pattern: this.pattern, placeholder: this.placeholder || '', readOnly: readonly, required: this.required, spellcheck: this.spellcheck, step: this.step, type: this.type, value: value, onInput: this.onInput, onChange: this.onChange, onBlur: this.onBlur, onFocus: this.onFocus, onKeyDown: this.onKeydown, onCompositionstart: this.onCompositionStart, onCompositionend: this.onCompositionEnd, "aria-describedby": this.getHintTextID(), "aria-invalid": this.getHintTextID() === this.errorTextId }, this.inheritedAttributes)), this.clearInput && !readonly && !disabled && (hAsync("button", { key: 'aa7cb47ac287140a68c5cb0ee9359abaa611e21b', "aria-label": "reset", type: "button", class: "input-clear-icon", onPointerDown: (ev) => {
  15372. /**
  15373. * This prevents mobile browsers from
  15374. * blurring the input when the clear
  15375. * button is activated.
  15376. */
  15377. ev.preventDefault();
  15378. }, onFocusin: (ev) => {
  15379. /**
  15380. * Prevent the focusin event from bubbling otherwise it will cause the focusin
  15381. * event listener in scroll assist to fire. When this fires, focus will be moved
  15382. * back to the input even if the clear button was never tapped. This poses issues
  15383. * for screen readers as it means users would be unable to swipe past the clear button.
  15384. */
  15385. ev.stopPropagation();
  15386. }, onClick: this.clearTextInput }, hAsync("ion-icon", { key: 'cd03e46b97299d9db5cedf81944ae9bbe72bacdc', "aria-hidden": "true", icon: clearIconData }))), hAsync("slot", { key: 'de36b79a89c4b413beba22e8a74c53dbf57a84ab', name: "end" })), shouldRenderHighlight && hAsync("div", { key: 'f088509073845bf767ea7ccfde1e917e1cf93cc1', class: "input-highlight" })), this.renderBottomContent()));
  15387. }
  15388. get el() { return getElement(this); }
  15389. static get watchers() { return {
  15390. "debounce": ["debounceChanged"],
  15391. "type": ["onTypeChange"],
  15392. "value": ["valueChanged"],
  15393. "dir": ["onDirChanged"]
  15394. }; }
  15395. static get style() { return {
  15396. ios: IonInputIosStyle0,
  15397. md: IonInputMdStyle0
  15398. }; }
  15399. static get cmpMeta() { return {
  15400. "$flags$": 38,
  15401. "$tagName$": "ion-input",
  15402. "$members$": {
  15403. "color": [513],
  15404. "autocapitalize": [1],
  15405. "autocomplete": [1],
  15406. "autocorrect": [1],
  15407. "autofocus": [4],
  15408. "clearInput": [4, "clear-input"],
  15409. "clearInputIcon": [1, "clear-input-icon"],
  15410. "clearOnEdit": [4, "clear-on-edit"],
  15411. "counter": [4],
  15412. "counterFormatter": [16],
  15413. "debounce": [2],
  15414. "disabled": [516],
  15415. "enterkeyhint": [1],
  15416. "errorText": [1, "error-text"],
  15417. "fill": [1],
  15418. "inputmode": [1],
  15419. "helperText": [1, "helper-text"],
  15420. "label": [1],
  15421. "labelPlacement": [1, "label-placement"],
  15422. "max": [8],
  15423. "maxlength": [2],
  15424. "min": [8],
  15425. "minlength": [2],
  15426. "multiple": [4],
  15427. "name": [1],
  15428. "pattern": [1],
  15429. "placeholder": [1],
  15430. "readonly": [516],
  15431. "required": [4],
  15432. "shape": [1],
  15433. "spellcheck": [4],
  15434. "step": [1],
  15435. "type": [1],
  15436. "value": [1032],
  15437. "hasFocus": [32],
  15438. "setFocus": [64],
  15439. "getInputElement": [64]
  15440. },
  15441. "$listeners$": [[2, "click", "onClickCapture"]],
  15442. "$lazyBundleId$": "-",
  15443. "$attrsToReflect$": [["color", "color"], ["disabled", "disabled"], ["readonly", "readonly"]]
  15444. }; }
  15445. }
  15446. let inputIds = 0;
  15447. const iosInputPasswordToggleCss = "";
  15448. var IonInputPasswordToggleIosStyle0 = iosInputPasswordToggleCss;
  15449. const mdInputPasswordToggleCss = "";
  15450. var IonInputPasswordToggleMdStyle0 = mdInputPasswordToggleCss;
  15451. /**
  15452. * @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
  15453. */
  15454. class InputPasswordToggle {
  15455. constructor(hostRef) {
  15456. registerInstance(this, hostRef);
  15457. this.togglePasswordVisibility = () => {
  15458. const { inputElRef } = this;
  15459. if (!inputElRef) {
  15460. return;
  15461. }
  15462. inputElRef.type = inputElRef.type === 'text' ? 'password' : 'text';
  15463. };
  15464. this.color = undefined;
  15465. this.showIcon = undefined;
  15466. this.hideIcon = undefined;
  15467. this.type = 'password';
  15468. }
  15469. /**
  15470. * Whenever the input type changes we need to re-run validation to ensure the password
  15471. * toggle is being used with the correct input type. If the application changes the type
  15472. * outside of this component we also need to re-render so the correct icon is shown.
  15473. */
  15474. onTypeChange(newValue) {
  15475. if (newValue !== 'text' && newValue !== 'password') {
  15476. printIonWarning(`[ion-input-password-toggle] - Only inputs of type "text" or "password" are supported. Input of type "${newValue}" is not compatible.`, this.el);
  15477. return;
  15478. }
  15479. }
  15480. connectedCallback() {
  15481. const { el } = this;
  15482. const inputElRef = (this.inputElRef = el.closest('ion-input'));
  15483. if (!inputElRef) {
  15484. printIonWarning('[ion-input-password-toggle] - No ancestor ion-input found. This component must be slotted inside of an ion-input.', el);
  15485. return;
  15486. }
  15487. /**
  15488. * Important: Set the type in connectedCallback because the default value
  15489. * of this.type may not always be accurate. Usually inputs have the "password" type
  15490. * but it is possible to have the input to initially have the "text" type. In that scenario
  15491. * the wrong icon will show briefly before switching to the correct icon. Setting the
  15492. * type here allows us to avoid that flicker.
  15493. */
  15494. this.type = inputElRef.type;
  15495. }
  15496. disconnectedCallback() {
  15497. this.inputElRef = null;
  15498. }
  15499. render() {
  15500. var _a, _b;
  15501. const { color, type } = this;
  15502. const mode = getIonMode$1(this);
  15503. const showPasswordIcon = (_a = this.showIcon) !== null && _a !== void 0 ? _a : eye;
  15504. const hidePasswordIcon = (_b = this.hideIcon) !== null && _b !== void 0 ? _b : eyeOff;
  15505. const isPasswordVisible = type === 'text';
  15506. return (hAsync(Host, { key: '1a28e078c83e74c72d8bb8189ece93ec2e3fa3d0', class: createColorClasses$1(color, {
  15507. [mode]: true,
  15508. }) }, hAsync("ion-button", { key: '039d1bab764093bb6fe4a34299b0872abda087fd', mode: mode, color: color, fill: "clear", shape: "round", "aria-checked": isPasswordVisible ? 'true' : 'false', "aria-label": "show password", role: "switch", type: "button", onPointerDown: (ev) => {
  15509. /**
  15510. * This prevents mobile browsers from
  15511. * blurring the input when the password toggle
  15512. * button is activated.
  15513. */
  15514. ev.preventDefault();
  15515. }, onClick: this.togglePasswordVisibility }, hAsync("ion-icon", { key: '26477ee97b808c3d79944bf5e33d4e05f1ae0b3f', slot: "icon-only", "aria-hidden": "true", icon: isPasswordVisible ? hidePasswordIcon : showPasswordIcon }))));
  15516. }
  15517. get el() { return getElement(this); }
  15518. static get watchers() { return {
  15519. "type": ["onTypeChange"]
  15520. }; }
  15521. static get style() { return {
  15522. ios: IonInputPasswordToggleIosStyle0,
  15523. md: IonInputPasswordToggleMdStyle0
  15524. }; }
  15525. static get cmpMeta() { return {
  15526. "$flags$": 41,
  15527. "$tagName$": "ion-input-password-toggle",
  15528. "$members$": {
  15529. "color": [513],
  15530. "showIcon": [1, "show-icon"],
  15531. "hideIcon": [1, "hide-icon"],
  15532. "type": [1025]
  15533. },
  15534. "$listeners$": undefined,
  15535. "$lazyBundleId$": "-",
  15536. "$attrsToReflect$": [["color", "color"]]
  15537. }; }
  15538. }
  15539. const itemIosCss = ":host{--border-radius:0px;--border-width:0px;--border-style:solid;--padding-top:0px;--padding-bottom:0px;--padding-end:0px;--padding-start:0px;--inner-border-width:0px;--inner-padding-top:0px;--inner-padding-bottom:0px;--inner-padding-start:0px;--inner-padding-end:0px;--inner-box-shadow:none;--detail-icon-color:initial;--detail-icon-font-size:1.25em;--detail-icon-opacity:0.25;--color-activated:var(--color);--color-focused:var(--color);--color-hover:var(--color);--ripple-color:currentColor;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;display:block;position:relative;-ms-flex-align:center;align-items:center;-ms-flex-pack:justify;justify-content:space-between;outline:none;color:var(--color);font-family:var(--ion-font-family, inherit);text-align:initial;text-decoration:none;overflow:hidden;-webkit-box-sizing:border-box;box-sizing:border-box}:host(.ion-color) .item-native{background:var(--ion-color-base);color:var(--ion-color-contrast)}:host(.ion-color) .item-native,:host(.ion-color) .item-inner{border-color:var(--ion-color-shade)}:host(.ion-activated) .item-native{color:var(--color-activated)}:host(.ion-activated) .item-native::after{background:var(--background-activated);opacity:var(--background-activated-opacity)}:host(.ion-color.ion-activated) .item-native{color:var(--ion-color-contrast)}:host(.ion-focused) .item-native{color:var(--color-focused)}:host(.ion-focused) .item-native::after{background:var(--background-focused);opacity:var(--background-focused-opacity)}:host(.ion-color.ion-focused) .item-native{color:var(--ion-color-contrast)}:host(.ion-color.ion-focused) .item-native::after{background:var(--ion-color-contrast)}@media (any-hover: hover){:host(.ion-activatable:not(.ion-focused):hover) .item-native{color:var(--color-hover)}:host(.ion-activatable:not(.ion-focused):hover) .item-native::after{background:var(--background-hover);opacity:var(--background-hover-opacity)}:host(.ion-color.ion-activatable:not(.ion-focused):hover) .item-native{color:var(--ion-color-contrast)}:host(.ion-color.ion-activatable:not(.ion-focused):hover) .item-native::after{background:var(--ion-color-contrast)}}:host(.item-control-needs-pointer-cursor){cursor:pointer}:host(.item-interactive-disabled:not(.item-multiple-inputs)){cursor:default;pointer-events:none}:host(.item-disabled){cursor:default;opacity:0.3;pointer-events:none}.item-native{border-radius:var(--border-radius);margin-left:0;margin-right:0;margin-top:0;margin-bottom:0;padding-top:var(--padding-top);padding-bottom:var(--padding-bottom);font-family:inherit;font-size:inherit;font-style:inherit;font-weight:inherit;letter-spacing:inherit;text-decoration:inherit;text-indent:inherit;text-overflow:inherit;text-transform:inherit;text-align:inherit;white-space:inherit;color:inherit;padding-right:var(--padding-end);padding-left:calc(var(--padding-start) + var(--ion-safe-area-left, 0px));display:-ms-flexbox;display:flex;position:relative;-ms-flex-align:inherit;align-items:inherit;-ms-flex-pack:inherit;justify-content:inherit;width:100%;min-height:var(--min-height);-webkit-transition:var(--transition);transition:var(--transition);border-width:var(--border-width);border-style:var(--border-style);border-color:var(--border-color);outline:none;background:var(--background);overflow:inherit;z-index:1;-webkit-box-sizing:border-box;box-sizing:border-box}:host-context([dir=rtl]) .item-native{padding-right:calc(var(--padding-start) + var(--ion-safe-area-right, 0px));padding-left:var(--padding-end)}[dir=rtl] .item-native{padding-right:calc(var(--padding-start) + var(--ion-safe-area-right, 0px));padding-left:var(--padding-end)}@supports selector(:dir(rtl)){.item-native:dir(rtl){padding-right:calc(var(--padding-start) + var(--ion-safe-area-right, 0px));padding-left:var(--padding-end)}}.item-native::-moz-focus-inner{border:0}.item-native::after{left:0;right:0;top:0;bottom:0;position:absolute;content:\"\";opacity:0;-webkit-transition:var(--transition);transition:var(--transition);z-index:-1}button,a{cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-user-drag:none}.item-inner{margin-left:0;margin-right:0;margin-top:0;margin-bottom:0;padding-top:var(--inner-padding-top);padding-bottom:var(--inner-padding-bottom);padding-right:calc(var(--ion-safe-area-right, 0px) + var(--inner-padding-end));padding-left:var(--inner-padding-start);display:-ms-flexbox;display:flex;position:relative;-ms-flex:1;flex:1;-ms-flex-direction:inherit;flex-direction:inherit;-ms-flex-align:inherit;align-items:inherit;-ms-flex-item-align:stretch;align-self:stretch;min-height:inherit;border-width:var(--inner-border-width);border-style:var(--border-style);border-color:var(--border-color);-webkit-box-shadow:var(--inner-box-shadow);box-shadow:var(--inner-box-shadow);overflow:inherit;-webkit-box-sizing:border-box;box-sizing:border-box}:host-context([dir=rtl]) .item-inner{padding-right:var(--inner-padding-start);padding-left:calc(var(--ion-safe-area-left, 0px) + var(--inner-padding-end))}[dir=rtl] .item-inner{padding-right:var(--inner-padding-start);padding-left:calc(var(--ion-safe-area-left, 0px) + var(--inner-padding-end))}@supports selector(:dir(rtl)){.item-inner:dir(rtl){padding-right:var(--inner-padding-start);padding-left:calc(var(--ion-safe-area-left, 0px) + var(--inner-padding-end))}}.item-detail-icon{-webkit-margin-start:calc(var(--inner-padding-end) / 2);margin-inline-start:calc(var(--inner-padding-end) / 2);-webkit-margin-end:-6px;margin-inline-end:-6px;color:var(--detail-icon-color);font-size:var(--detail-icon-font-size);opacity:var(--detail-icon-opacity)}::slotted(ion-icon){font-size:1.6em}::slotted(ion-button){--margin-top:0;--margin-bottom:0;--margin-start:0;--margin-end:0;z-index:1}::slotted(ion-label:not([slot=end])){-ms-flex:1;flex:1;width:-webkit-min-content;width:-moz-min-content;width:min-content;max-width:100%}:host(.item-input){-ms-flex-align:center;align-items:center}.input-wrapper{display:-ms-flexbox;display:flex;-ms-flex:1;flex:1;-ms-flex-direction:inherit;flex-direction:inherit;-ms-flex-align:inherit;align-items:inherit;-ms-flex-item-align:stretch;align-self:stretch;text-overflow:ellipsis;overflow:inherit;-webkit-box-sizing:border-box;box-sizing:border-box}:host(.item-label-stacked),:host(.item-label-floating){-ms-flex-align:start;align-items:start}:host(.item-label-stacked) .input-wrapper,:host(.item-label-floating) .input-wrapper{-ms-flex:1;flex:1;-ms-flex-direction:column;flex-direction:column}:host(.item-multiple-inputs) ::slotted(ion-checkbox),:host(.item-multiple-inputs) ::slotted(ion-datetime),:host(.item-multiple-inputs) ::slotted(ion-radio){position:relative}:host(.item-textarea){-ms-flex-align:stretch;align-items:stretch}::slotted(ion-reorder[slot]){margin-top:0;margin-bottom:0}ion-ripple-effect{color:var(--ripple-color)}:host{--min-height:44px;--transition:background-color 200ms linear, opacity 200ms linear;--padding-start:16px;--inner-padding-end:16px;--inner-border-width:0px 0px 0.55px 0px;--background:var(--ion-item-background, var(--ion-background-color, #fff));--background-activated:var(--ion-text-color, #000);--background-focused:var(--ion-text-color, #000);--background-hover:currentColor;--background-activated-opacity:.12;--background-focused-opacity:.15;--background-hover-opacity:.04;--border-color:var(--ion-item-border-color, var(--ion-border-color, var(--ion-color-step-250, var(--ion-background-color-step-250, #c8c7cc))));--color:var(--ion-item-color, var(--ion-text-color, #000));font-size:1rem}:host(.ion-activated){--transition:none}:host(.ion-color.ion-focused) .item-native::after{background:#000;opacity:0.15}:host(.ion-color.ion-activated) .item-native::after{background:#000;opacity:0.12}:host(.item-lines-full){--border-width:0px 0px 0.55px 0px}:host(.item-lines-inset){--inner-border-width:0px 0px 0.55px 0px}:host(.item-lines-inset),:host(.item-lines-none){--border-width:0px}:host(.item-lines-full),:host(.item-lines-none){--inner-border-width:0px}::slotted([slot=start]){-webkit-margin-start:0;margin-inline-start:0;-webkit-margin-end:16px;margin-inline-end:16px;margin-top:2px;margin-bottom:2px}::slotted(ion-icon[slot=start]),::slotted(ion-icon[slot=end]){margin-top:7px;margin-bottom:7px}::slotted(ion-toggle[slot=start]),::slotted(ion-toggle[slot=end]){margin-left:0;margin-right:0;margin-top:0;margin-bottom:0}:host(.item-label-stacked) ::slotted([slot=end]),:host(.item-label-floating) ::slotted([slot=end]){margin-top:7px;margin-bottom:7px}::slotted(.button-small){--padding-top:1px;--padding-bottom:1px;--padding-start:.5em;--padding-end:.5em;min-height:24px;font-size:0.8125rem}::slotted(ion-avatar){width:36px;height:36px}::slotted(ion-thumbnail){--size:56px}::slotted(ion-avatar[slot=end]),::slotted(ion-thumbnail[slot=end]){-webkit-margin-start:8px;margin-inline-start:8px;-webkit-margin-end:8px;margin-inline-end:8px;margin-top:8px;margin-bottom:8px}:host(.item-radio) ::slotted(ion-label),:host(.item-toggle) ::slotted(ion-label){-webkit-margin-start:0px;margin-inline-start:0px}::slotted(ion-label){-webkit-margin-start:0;margin-inline-start:0;-webkit-margin-end:8px;margin-inline-end:8px;margin-top:10px;margin-bottom:10px}:host(.item-label-floating),:host(.item-label-stacked){--min-height:68px}";
  15540. var IonItemIosStyle0 = itemIosCss;
  15541. const itemMdCss = ":host{--border-radius:0px;--border-width:0px;--border-style:solid;--padding-top:0px;--padding-bottom:0px;--padding-end:0px;--padding-start:0px;--inner-border-width:0px;--inner-padding-top:0px;--inner-padding-bottom:0px;--inner-padding-start:0px;--inner-padding-end:0px;--inner-box-shadow:none;--detail-icon-color:initial;--detail-icon-font-size:1.25em;--detail-icon-opacity:0.25;--color-activated:var(--color);--color-focused:var(--color);--color-hover:var(--color);--ripple-color:currentColor;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;display:block;position:relative;-ms-flex-align:center;align-items:center;-ms-flex-pack:justify;justify-content:space-between;outline:none;color:var(--color);font-family:var(--ion-font-family, inherit);text-align:initial;text-decoration:none;overflow:hidden;-webkit-box-sizing:border-box;box-sizing:border-box}:host(.ion-color) .item-native{background:var(--ion-color-base);color:var(--ion-color-contrast)}:host(.ion-color) .item-native,:host(.ion-color) .item-inner{border-color:var(--ion-color-shade)}:host(.ion-activated) .item-native{color:var(--color-activated)}:host(.ion-activated) .item-native::after{background:var(--background-activated);opacity:var(--background-activated-opacity)}:host(.ion-color.ion-activated) .item-native{color:var(--ion-color-contrast)}:host(.ion-focused) .item-native{color:var(--color-focused)}:host(.ion-focused) .item-native::after{background:var(--background-focused);opacity:var(--background-focused-opacity)}:host(.ion-color.ion-focused) .item-native{color:var(--ion-color-contrast)}:host(.ion-color.ion-focused) .item-native::after{background:var(--ion-color-contrast)}@media (any-hover: hover){:host(.ion-activatable:not(.ion-focused):hover) .item-native{color:var(--color-hover)}:host(.ion-activatable:not(.ion-focused):hover) .item-native::after{background:var(--background-hover);opacity:var(--background-hover-opacity)}:host(.ion-color.ion-activatable:not(.ion-focused):hover) .item-native{color:var(--ion-color-contrast)}:host(.ion-color.ion-activatable:not(.ion-focused):hover) .item-native::after{background:var(--ion-color-contrast)}}:host(.item-control-needs-pointer-cursor){cursor:pointer}:host(.item-interactive-disabled:not(.item-multiple-inputs)){cursor:default;pointer-events:none}:host(.item-disabled){cursor:default;opacity:0.3;pointer-events:none}.item-native{border-radius:var(--border-radius);margin-left:0;margin-right:0;margin-top:0;margin-bottom:0;padding-top:var(--padding-top);padding-bottom:var(--padding-bottom);font-family:inherit;font-size:inherit;font-style:inherit;font-weight:inherit;letter-spacing:inherit;text-decoration:inherit;text-indent:inherit;text-overflow:inherit;text-transform:inherit;text-align:inherit;white-space:inherit;color:inherit;padding-right:var(--padding-end);padding-left:calc(var(--padding-start) + var(--ion-safe-area-left, 0px));display:-ms-flexbox;display:flex;position:relative;-ms-flex-align:inherit;align-items:inherit;-ms-flex-pack:inherit;justify-content:inherit;width:100%;min-height:var(--min-height);-webkit-transition:var(--transition);transition:var(--transition);border-width:var(--border-width);border-style:var(--border-style);border-color:var(--border-color);outline:none;background:var(--background);overflow:inherit;z-index:1;-webkit-box-sizing:border-box;box-sizing:border-box}:host-context([dir=rtl]) .item-native{padding-right:calc(var(--padding-start) + var(--ion-safe-area-right, 0px));padding-left:var(--padding-end)}[dir=rtl] .item-native{padding-right:calc(var(--padding-start) + var(--ion-safe-area-right, 0px));padding-left:var(--padding-end)}@supports selector(:dir(rtl)){.item-native:dir(rtl){padding-right:calc(var(--padding-start) + var(--ion-safe-area-right, 0px));padding-left:var(--padding-end)}}.item-native::-moz-focus-inner{border:0}.item-native::after{left:0;right:0;top:0;bottom:0;position:absolute;content:\"\";opacity:0;-webkit-transition:var(--transition);transition:var(--transition);z-index:-1}button,a{cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-user-drag:none}.item-inner{margin-left:0;margin-right:0;margin-top:0;margin-bottom:0;padding-top:var(--inner-padding-top);padding-bottom:var(--inner-padding-bottom);padding-right:calc(var(--ion-safe-area-right, 0px) + var(--inner-padding-end));padding-left:var(--inner-padding-start);display:-ms-flexbox;display:flex;position:relative;-ms-flex:1;flex:1;-ms-flex-direction:inherit;flex-direction:inherit;-ms-flex-align:inherit;align-items:inherit;-ms-flex-item-align:stretch;align-self:stretch;min-height:inherit;border-width:var(--inner-border-width);border-style:var(--border-style);border-color:var(--border-color);-webkit-box-shadow:var(--inner-box-shadow);box-shadow:var(--inner-box-shadow);overflow:inherit;-webkit-box-sizing:border-box;box-sizing:border-box}:host-context([dir=rtl]) .item-inner{padding-right:var(--inner-padding-start);padding-left:calc(var(--ion-safe-area-left, 0px) + var(--inner-padding-end))}[dir=rtl] .item-inner{padding-right:var(--inner-padding-start);padding-left:calc(var(--ion-safe-area-left, 0px) + var(--inner-padding-end))}@supports selector(:dir(rtl)){.item-inner:dir(rtl){padding-right:var(--inner-padding-start);padding-left:calc(var(--ion-safe-area-left, 0px) + var(--inner-padding-end))}}.item-detail-icon{-webkit-margin-start:calc(var(--inner-padding-end) / 2);margin-inline-start:calc(var(--inner-padding-end) / 2);-webkit-margin-end:-6px;margin-inline-end:-6px;color:var(--detail-icon-color);font-size:var(--detail-icon-font-size);opacity:var(--detail-icon-opacity)}::slotted(ion-icon){font-size:1.6em}::slotted(ion-button){--margin-top:0;--margin-bottom:0;--margin-start:0;--margin-end:0;z-index:1}::slotted(ion-label:not([slot=end])){-ms-flex:1;flex:1;width:-webkit-min-content;width:-moz-min-content;width:min-content;max-width:100%}:host(.item-input){-ms-flex-align:center;align-items:center}.input-wrapper{display:-ms-flexbox;display:flex;-ms-flex:1;flex:1;-ms-flex-direction:inherit;flex-direction:inherit;-ms-flex-align:inherit;align-items:inherit;-ms-flex-item-align:stretch;align-self:stretch;text-overflow:ellipsis;overflow:inherit;-webkit-box-sizing:border-box;box-sizing:border-box}:host(.item-label-stacked),:host(.item-label-floating){-ms-flex-align:start;align-items:start}:host(.item-label-stacked) .input-wrapper,:host(.item-label-floating) .input-wrapper{-ms-flex:1;flex:1;-ms-flex-direction:column;flex-direction:column}:host(.item-multiple-inputs) ::slotted(ion-checkbox),:host(.item-multiple-inputs) ::slotted(ion-datetime),:host(.item-multiple-inputs) ::slotted(ion-radio){position:relative}:host(.item-textarea){-ms-flex-align:stretch;align-items:stretch}::slotted(ion-reorder[slot]){margin-top:0;margin-bottom:0}ion-ripple-effect{color:var(--ripple-color)}:host{--min-height:48px;--background:var(--ion-item-background, var(--ion-background-color, #fff));--background-activated:transparent;--background-focused:currentColor;--background-hover:currentColor;--background-activated-opacity:0;--background-focused-opacity:.12;--background-hover-opacity:.04;--border-color:var(--ion-item-border-color, var(--ion-border-color, var(--ion-color-step-150, var(--ion-background-color-step-150, rgba(0, 0, 0, 0.13)))));--color:var(--ion-item-color, var(--ion-text-color, #000));--transition:opacity 15ms linear, background-color 15ms linear;--padding-start:16px;--inner-padding-end:16px;--inner-border-width:0 0 1px 0;font-size:1rem;font-weight:normal;text-transform:none}:host(.ion-color.ion-activated) .item-native::after{background:transparent}:host(.item-interactive){--border-width:0 0 1px 0;--inner-border-width:0}:host(.item-lines-full){--border-width:0 0 1px 0}:host(.item-lines-inset){--inner-border-width:0 0 1px 0}:host(.item-lines-inset),:host(.item-lines-none){--border-width:0}:host(.item-lines-full),:host(.item-lines-none){--inner-border-width:0}:host(.item-multi-line) ::slotted([slot=start]),:host(.item-multi-line) ::slotted([slot=end]){margin-top:16px;margin-bottom:16px;-ms-flex-item-align:start;align-self:flex-start}::slotted([slot=start]){-webkit-margin-end:16px;margin-inline-end:16px}::slotted([slot=end]){-webkit-margin-start:16px;margin-inline-start:16px}::slotted(ion-icon){color:rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.54);font-size:1.5em}:host(.ion-color) ::slotted(ion-icon){color:var(--ion-color-contrast)}::slotted(ion-icon[slot]){margin-top:12px;margin-bottom:12px}::slotted(ion-icon[slot=start]){-webkit-margin-end:32px;margin-inline-end:32px}::slotted(ion-icon[slot=end]){-webkit-margin-start:16px;margin-inline-start:16px}::slotted(ion-toggle[slot=start]),::slotted(ion-toggle[slot=end]){margin-left:0;margin-right:0;margin-top:0;margin-bottom:0}::slotted(ion-note){margin-left:0;margin-right:0;margin-top:0;margin-bottom:0;-ms-flex-item-align:start;align-self:flex-start;font-size:0.6875rem}::slotted(ion-note[slot]){padding-left:0;padding-right:0;padding-top:18px;padding-bottom:10px}::slotted(ion-avatar){width:40px;height:40px}::slotted(ion-thumbnail){--size:56px}::slotted(ion-avatar),::slotted(ion-thumbnail){margin-top:8px;margin-bottom:8px}::slotted(ion-avatar[slot=start]),::slotted(ion-thumbnail[slot=start]){-webkit-margin-end:16px;margin-inline-end:16px}::slotted(ion-avatar[slot=end]),::slotted(ion-thumbnail[slot=end]){-webkit-margin-start:16px;margin-inline-start:16px}::slotted(ion-label){margin-left:0;margin-right:0;margin-top:10px;margin-bottom:10px}:host(.item-label-stacked) ::slotted([slot=end]),:host(.item-label-floating) ::slotted([slot=end]){margin-top:7px;margin-bottom:7px}:host(.item-toggle) ::slotted(ion-label),:host(.item-radio) ::slotted(ion-label){-webkit-margin-start:0;margin-inline-start:0}::slotted(.button-small){--padding-top:2px;--padding-bottom:2px;--padding-start:.6em;--padding-end:.6em;min-height:25px;font-size:0.75rem}:host(.item-label-floating),:host(.item-label-stacked){--min-height:55px}:host(.ion-focused:not(.ion-color)) ::slotted(.label-stacked),:host(.ion-focused:not(.ion-color)) ::slotted(.label-floating),:host(.item-has-focus:not(.ion-color)) ::slotted(.label-stacked),:host(.item-has-focus:not(.ion-color)) ::slotted(.label-floating){color:var(--ion-color-primary, #0054e9)}";
  15542. var IonItemMdStyle0 = itemMdCss;
  15543. /**
  15544. * @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
  15545. *
  15546. * @slot - Content is placed between the named slots if provided without a slot.
  15547. * @slot start - Content is placed to the left of the item text in LTR, and to the right in RTL.
  15548. * @slot end - Content is placed to the right of the item text in LTR, and to the left in RTL.
  15549. *
  15550. * @part native - The native HTML button, anchor or div element that wraps all child elements.
  15551. * @part detail-icon - The chevron icon for the item. Only applies when `detail="true"`.
  15552. */
  15553. class Item {
  15554. constructor(hostRef) {
  15555. registerInstance(this, hostRef);
  15556. this.labelColorStyles = {};
  15557. this.itemStyles = new Map();
  15558. this.inheritedAriaAttributes = {};
  15559. this.multipleInputs = false;
  15560. this.focusable = true;
  15561. this.color = undefined;
  15562. this.button = false;
  15563. this.detail = undefined;
  15564. this.detailIcon = chevronForward;
  15565. this.disabled = false;
  15566. this.download = undefined;
  15567. this.href = undefined;
  15568. this.rel = undefined;
  15569. this.lines = undefined;
  15570. this.routerAnimation = undefined;
  15571. this.routerDirection = 'forward';
  15572. this.target = undefined;
  15573. this.type = 'button';
  15574. }
  15575. buttonChanged() {
  15576. // Update the focusable option when the button option is changed
  15577. this.focusable = this.isFocusable();
  15578. }
  15579. labelColorChanged(ev) {
  15580. const { color } = this;
  15581. // There will be a conflict with item color if
  15582. // we apply the label color to item, so we ignore
  15583. // the label color if the user sets a color on item
  15584. if (color === undefined) {
  15585. this.labelColorStyles = ev.detail;
  15586. }
  15587. }
  15588. itemStyle(ev) {
  15589. ev.stopPropagation();
  15590. const tagName = ev.target.tagName;
  15591. const updatedStyles = ev.detail;
  15592. const newStyles = {};
  15593. const childStyles = this.itemStyles.get(tagName) || {};
  15594. let hasStyleChange = false;
  15595. Object.keys(updatedStyles).forEach((key) => {
  15596. if (updatedStyles[key]) {
  15597. const itemKey = `item-${key}`;
  15598. if (!childStyles[itemKey]) {
  15599. hasStyleChange = true;
  15600. }
  15601. newStyles[itemKey] = true;
  15602. }
  15603. });
  15604. if (!hasStyleChange && Object.keys(newStyles).length !== Object.keys(childStyles).length) {
  15605. hasStyleChange = true;
  15606. }
  15607. if (hasStyleChange) {
  15608. this.itemStyles.set(tagName, newStyles);
  15609. }
  15610. }
  15611. connectedCallback() {
  15612. this.hasStartEl();
  15613. }
  15614. componentWillLoad() {
  15615. this.inheritedAriaAttributes = inheritAttributes$1(this.el, ['aria-label']);
  15616. }
  15617. componentDidLoad() {
  15618. raf(() => {
  15619. this.setMultipleInputs();
  15620. this.focusable = this.isFocusable();
  15621. });
  15622. }
  15623. // If the item contains multiple clickable elements and/or inputs, then the item
  15624. // should not have a clickable input cover over the entire item to prevent
  15625. // interfering with their individual click events
  15626. setMultipleInputs() {
  15627. // The following elements have a clickable cover that is relative to the entire item
  15628. const covers = this.el.querySelectorAll('ion-checkbox, ion-datetime, ion-select, ion-radio');
  15629. // The following elements can accept focus alongside the previous elements
  15630. // therefore if these elements are also a child of item, we don't want the
  15631. // input cover on top of those interfering with their clicks
  15632. const inputs = this.el.querySelectorAll('ion-input, ion-range, ion-searchbar, ion-segment, ion-textarea, ion-toggle');
  15633. // The following elements should also stay clickable when an input with cover is present
  15634. const clickables = this.el.querySelectorAll('ion-router-link, ion-button, a, button');
  15635. // Check for multiple inputs to change the position of the input cover to relative
  15636. // for all of the covered inputs above
  15637. this.multipleInputs =
  15638. covers.length + inputs.length > 1 ||
  15639. covers.length + clickables.length > 1 ||
  15640. (covers.length > 0 && this.isClickable());
  15641. }
  15642. // If the item contains an input including a checkbox, datetime, select, or radio
  15643. // then the item will have a clickable input cover that covers the item
  15644. // that should get the hover, focused and activated states UNLESS it has multiple
  15645. // inputs, then those need to individually get each click
  15646. hasCover() {
  15647. const inputs = this.el.querySelectorAll('ion-checkbox, ion-datetime, ion-select, ion-radio');
  15648. return inputs.length === 1 && !this.multipleInputs;
  15649. }
  15650. // If the item has an href or button property it will render a native
  15651. // anchor or button that is clickable
  15652. isClickable() {
  15653. return this.href !== undefined || this.button;
  15654. }
  15655. canActivate() {
  15656. return this.isClickable() || this.hasCover();
  15657. }
  15658. isFocusable() {
  15659. const focusableChild = this.el.querySelector('.ion-focusable');
  15660. return this.canActivate() || focusableChild !== null;
  15661. }
  15662. hasStartEl() {
  15663. const startEl = this.el.querySelector('[slot="start"]');
  15664. if (startEl !== null) {
  15665. this.el.classList.add('item-has-start-slot');
  15666. }
  15667. }
  15668. getFirstInteractive() {
  15669. const controls = this.el.querySelectorAll('ion-toggle:not([disabled]), ion-checkbox:not([disabled]), ion-radio:not([disabled]), ion-select:not([disabled]), ion-input:not([disabled]), ion-textarea:not([disabled])');
  15670. return controls[0];
  15671. }
  15672. render() {
  15673. const { detail, detailIcon, download, labelColorStyles, lines, disabled, href, rel, target, routerAnimation, routerDirection, inheritedAriaAttributes, multipleInputs, } = this;
  15674. const childStyles = {};
  15675. const mode = getIonMode$1(this);
  15676. const clickable = this.isClickable();
  15677. const canActivate = this.canActivate();
  15678. const TagType = clickable ? (href === undefined ? 'button' : 'a') : 'div';
  15679. const attrs = TagType === 'button'
  15680. ? { type: this.type }
  15681. : {
  15682. download,
  15683. href,
  15684. rel,
  15685. target,
  15686. };
  15687. let clickFn = {};
  15688. const firstInteractive = this.getFirstInteractive();
  15689. // Only set onClick if the item is clickable to prevent screen
  15690. // readers from reading all items as clickable
  15691. if (clickable || (firstInteractive !== undefined && !multipleInputs)) {
  15692. clickFn = {
  15693. onClick: (ev) => {
  15694. if (clickable) {
  15695. openURL(href, ev, routerDirection, routerAnimation);
  15696. }
  15697. if (firstInteractive !== undefined && !multipleInputs) {
  15698. const path = ev.composedPath();
  15699. const target = path[0];
  15700. if (ev.isTrusted) {
  15701. /**
  15702. * Dispatches a click event to the first interactive element,
  15703. * when it is the result of a user clicking on the item.
  15704. *
  15705. * We check if the click target is in the shadow root,
  15706. * which means the user clicked on the .item-native or
  15707. * .item-inner padding.
  15708. */
  15709. const clickedWithinShadowRoot = this.el.shadowRoot.contains(target);
  15710. if (clickedWithinShadowRoot) {
  15711. /**
  15712. * For input/textarea clicking the padding should focus the
  15713. * text field (thus making it editable). For everything else,
  15714. * we want to click the control so it activates.
  15715. */
  15716. if (firstInteractive.tagName === 'ION-INPUT' || firstInteractive.tagName === 'ION-TEXTAREA') {
  15717. firstInteractive.setFocus();
  15718. }
  15719. firstInteractive.click();
  15720. /**
  15721. * Stop the item event from being triggered
  15722. * as the firstInteractive click event will also
  15723. * trigger the item click event.
  15724. */
  15725. ev.stopImmediatePropagation();
  15726. }
  15727. }
  15728. }
  15729. },
  15730. };
  15731. }
  15732. const showDetail = detail !== undefined ? detail : mode === 'ios' && clickable;
  15733. this.itemStyles.forEach((value) => {
  15734. Object.assign(childStyles, value);
  15735. });
  15736. const ariaDisabled = disabled || childStyles['item-interactive-disabled'] ? 'true' : null;
  15737. const inList = hostContext('ion-list', this.el) && !hostContext('ion-radio-group', this.el);
  15738. /**
  15739. * Inputs and textareas do not need to show a cursor pointer.
  15740. * However, other form controls such as checkboxes and radios do.
  15741. */
  15742. const firstInteractiveNeedsPointerCursor = firstInteractive !== undefined && !['ION-INPUT', 'ION-TEXTAREA'].includes(firstInteractive.tagName);
  15743. return (hAsync(Host, { key: '15e7d3b674c25232bc2d51573b291c72548690e5', "aria-disabled": ariaDisabled, class: Object.assign(Object.assign(Object.assign({}, childStyles), labelColorStyles), createColorClasses$1(this.color, {
  15744. item: true,
  15745. [mode]: true,
  15746. 'item-lines-default': lines === undefined,
  15747. [`item-lines-${lines}`]: lines !== undefined,
  15748. 'item-control-needs-pointer-cursor': firstInteractiveNeedsPointerCursor,
  15749. 'item-disabled': disabled,
  15750. 'in-list': inList,
  15751. 'item-multiple-inputs': this.multipleInputs,
  15752. 'ion-activatable': canActivate,
  15753. 'ion-focusable': this.focusable,
  15754. 'item-rtl': document.dir === 'rtl',
  15755. })), role: inList ? 'listitem' : null }, hAsync(TagType, Object.assign({ key: 'f27ae647501e29db554efe8f12f498b165d1dbf6' }, attrs, inheritedAriaAttributes, { class: "item-native", part: "native", disabled: disabled }, clickFn), hAsync("slot", { key: 'ba039a321df0e4bd5ce11e7a6e7e174c8623b112', name: "start" }), hAsync("div", { key: 'e67fdf4ad9086d855da8402ca04ffe292cf6ce67', class: "item-inner" }, hAsync("div", { key: '2434348a0b3f10052a340c57a7ac127ddc851729', class: "input-wrapper" }, hAsync("slot", { key: '3e27090ae4dab734541b3fd2c94de0f98c0f0030' })), hAsync("slot", { key: '52dc633b60fe612d48d2efffbf2c4c62692bef85', name: "end" }), showDetail && (hAsync("ion-icon", { key: '4fb7397dc8cf4cecb82f19a6151f85112b73992b', icon: detailIcon, lazy: false, class: "item-detail-icon", part: "detail-icon", "aria-hidden": "true", "flip-rtl": detailIcon === chevronForward }))), canActivate && mode === 'md' && hAsync("ion-ripple-effect", { key: '09b2413a7a484ecd8ffb00805223727da4d4e344' }))));
  15756. }
  15757. get el() { return getElement(this); }
  15758. static get watchers() { return {
  15759. "button": ["buttonChanged"]
  15760. }; }
  15761. static get style() { return {
  15762. ios: IonItemIosStyle0,
  15763. md: IonItemMdStyle0
  15764. }; }
  15765. static get cmpMeta() { return {
  15766. "$flags$": 41,
  15767. "$tagName$": "ion-item",
  15768. "$members$": {
  15769. "color": [513],
  15770. "button": [4],
  15771. "detail": [4],
  15772. "detailIcon": [1, "detail-icon"],
  15773. "disabled": [516],
  15774. "download": [1],
  15775. "href": [1],
  15776. "rel": [1],
  15777. "lines": [1],
  15778. "routerAnimation": [16],
  15779. "routerDirection": [1, "router-direction"],
  15780. "target": [1],
  15781. "type": [1],
  15782. "multipleInputs": [32],
  15783. "focusable": [32]
  15784. },
  15785. "$listeners$": [[0, "ionColor", "labelColorChanged"], [0, "ionStyle", "itemStyle"]],
  15786. "$lazyBundleId$": "-",
  15787. "$attrsToReflect$": [["color", "color"], ["disabled", "disabled"]]
  15788. }; }
  15789. }
  15790. const itemDividerIosCss = ":host{--padding-top:0px;--padding-end:0px;--padding-bottom:0px;--padding-start:0px;--inner-padding-top:0px;--inner-padding-end:0px;--inner-padding-bottom:0px;--inner-padding-start:0px;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;margin-left:0;margin-right:0;margin-top:0;margin-bottom:0;padding-top:var(--padding-top);padding-bottom:var(--padding-bottom);padding-right:var(--padding-end);padding-left:calc(var(--padding-start) + var(--ion-safe-area-left, 0px));display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:justify;justify-content:space-between;width:100%;background:var(--background);color:var(--color);font-family:var(--ion-font-family, inherit);overflow:hidden;z-index:100;-webkit-box-sizing:border-box;box-sizing:border-box}:host-context([dir=rtl]){padding-right:calc(var(--padding-start) + var(--ion-safe-area-right, 0px));padding-left:var(--padding-end)}@supports selector(:dir(rtl)){:host(:dir(rtl)){padding-right:calc(var(--padding-start) + var(--ion-safe-area-right, 0px));padding-left:var(--padding-end)}}:host(.ion-color){background:var(--ion-color-base);color:var(--ion-color-contrast)}:host(.item-divider-sticky){position:-webkit-sticky;position:sticky;top:0}.item-divider-inner{margin-left:0;margin-right:0;margin-top:0;margin-bottom:0;padding-top:var(--inner-padding-top);padding-bottom:var(--inner-padding-bottom);padding-right:calc(var(--ion-safe-area-right, 0px) + var(--inner-padding-end));padding-left:var(--inner-padding-start);display:-ms-flexbox;display:flex;-ms-flex:1;flex:1;-ms-flex-direction:inherit;flex-direction:inherit;-ms-flex-align:inherit;align-items:inherit;-ms-flex-item-align:stretch;align-self:stretch;min-height:inherit;border:0;overflow:hidden}:host-context([dir=rtl]) .item-divider-inner{padding-right:var(--inner-padding-start);padding-left:calc(var(--ion-safe-area-left, 0px) + var(--inner-padding-end))}[dir=rtl] .item-divider-inner{padding-right:var(--inner-padding-start);padding-left:calc(var(--ion-safe-area-left, 0px) + var(--inner-padding-end))}@supports selector(:dir(rtl)){.item-divider-inner:dir(rtl){padding-right:var(--inner-padding-start);padding-left:calc(var(--ion-safe-area-left, 0px) + var(--inner-padding-end))}}.item-divider-wrapper{display:-ms-flexbox;display:flex;-ms-flex:1;flex:1;-ms-flex-direction:inherit;flex-direction:inherit;-ms-flex-align:inherit;align-items:inherit;-ms-flex-item-align:stretch;align-self:stretch;text-overflow:ellipsis;overflow:hidden}:host{--background:var(--ion-color-step-100, var(--ion-background-color-step-100, #e6e6e6));--color:var(--ion-color-step-850, var(--ion-text-color-step-150, #262626));--padding-start:16px;--inner-padding-end:8px;border-radius:0;position:relative;min-height:28px;font-size:1.0625rem;font-weight:600}:host([slot=start]){-webkit-margin-start:0;margin-inline-start:0;-webkit-margin-end:16px;margin-inline-end:16px;margin-top:2px;margin-bottom:2px}::slotted(ion-icon[slot=start]),::slotted(ion-icon[slot=end]){margin-top:7px;margin-bottom:7px}::slotted(h1){margin-left:0;margin-right:0;margin-top:0;margin-bottom:2px}::slotted(h2){margin-left:0;margin-right:0;margin-top:0;margin-bottom:2px}::slotted(h3),::slotted(h4),::slotted(h5),::slotted(h6){margin-left:0;margin-right:0;margin-top:0;margin-bottom:3px}::slotted(p){margin-left:0;margin-right:0;margin-top:0;margin-bottom:2px;color:var(--ion-text-color-step-550, #a3a3a3);font-size:0.875rem;line-height:normal;text-overflow:inherit;overflow:inherit}::slotted(h2:last-child) ::slotted(h3:last-child),::slotted(h4:last-child),::slotted(h5:last-child),::slotted(h6:last-child),::slotted(p:last-child){margin-bottom:0}";
  15791. var IonItemDividerIosStyle0 = itemDividerIosCss;
  15792. const itemDividerMdCss = ":host{--padding-top:0px;--padding-end:0px;--padding-bottom:0px;--padding-start:0px;--inner-padding-top:0px;--inner-padding-end:0px;--inner-padding-bottom:0px;--inner-padding-start:0px;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;margin-left:0;margin-right:0;margin-top:0;margin-bottom:0;padding-top:var(--padding-top);padding-bottom:var(--padding-bottom);padding-right:var(--padding-end);padding-left:calc(var(--padding-start) + var(--ion-safe-area-left, 0px));display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:justify;justify-content:space-between;width:100%;background:var(--background);color:var(--color);font-family:var(--ion-font-family, inherit);overflow:hidden;z-index:100;-webkit-box-sizing:border-box;box-sizing:border-box}:host-context([dir=rtl]){padding-right:calc(var(--padding-start) + var(--ion-safe-area-right, 0px));padding-left:var(--padding-end)}@supports selector(:dir(rtl)){:host(:dir(rtl)){padding-right:calc(var(--padding-start) + var(--ion-safe-area-right, 0px));padding-left:var(--padding-end)}}:host(.ion-color){background:var(--ion-color-base);color:var(--ion-color-contrast)}:host(.item-divider-sticky){position:-webkit-sticky;position:sticky;top:0}.item-divider-inner{margin-left:0;margin-right:0;margin-top:0;margin-bottom:0;padding-top:var(--inner-padding-top);padding-bottom:var(--inner-padding-bottom);padding-right:calc(var(--ion-safe-area-right, 0px) + var(--inner-padding-end));padding-left:var(--inner-padding-start);display:-ms-flexbox;display:flex;-ms-flex:1;flex:1;-ms-flex-direction:inherit;flex-direction:inherit;-ms-flex-align:inherit;align-items:inherit;-ms-flex-item-align:stretch;align-self:stretch;min-height:inherit;border:0;overflow:hidden}:host-context([dir=rtl]) .item-divider-inner{padding-right:var(--inner-padding-start);padding-left:calc(var(--ion-safe-area-left, 0px) + var(--inner-padding-end))}[dir=rtl] .item-divider-inner{padding-right:var(--inner-padding-start);padding-left:calc(var(--ion-safe-area-left, 0px) + var(--inner-padding-end))}@supports selector(:dir(rtl)){.item-divider-inner:dir(rtl){padding-right:var(--inner-padding-start);padding-left:calc(var(--ion-safe-area-left, 0px) + var(--inner-padding-end))}}.item-divider-wrapper{display:-ms-flexbox;display:flex;-ms-flex:1;flex:1;-ms-flex-direction:inherit;flex-direction:inherit;-ms-flex-align:inherit;align-items:inherit;-ms-flex-item-align:stretch;align-self:stretch;text-overflow:ellipsis;overflow:hidden}:host{--background:var(--ion-background-color, #fff);--color:var(--ion-color-step-400, var(--ion-text-color-step-600, #999999));--padding-start:16px;--inner-padding-end:16px;min-height:30px;border-bottom:1px solid var(--ion-item-border-color, var(--ion-border-color, var(--ion-color-step-150, var(--ion-background-color-step-150, rgba(0, 0, 0, 0.13)))));font-size:0.875rem}::slotted([slot=start]){-webkit-margin-end:16px;margin-inline-end:16px}::slotted([slot=end]){-webkit-margin-start:16px;margin-inline-start:16px}::slotted(ion-label){margin-left:0;margin-right:0;margin-top:13px;margin-bottom:10px}::slotted(ion-icon){color:rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.54);font-size:1.7142857143em}:host(.ion-color) ::slotted(ion-icon){color:var(--ion-color-contrast)}::slotted(ion-icon[slot]){margin-top:12px;margin-bottom:12px}::slotted(ion-icon[slot=start]){-webkit-margin-end:32px;margin-inline-end:32px}::slotted(ion-icon[slot=end]){-webkit-margin-start:16px;margin-inline-start:16px}::slotted(ion-note){margin-left:0;margin-right:0;margin-top:0;margin-bottom:0;-ms-flex-item-align:start;align-self:flex-start;font-size:0.6875rem}::slotted(ion-note[slot]){padding-left:0;padding-right:0;padding-top:18px;padding-bottom:10px}::slotted(ion-avatar){width:40px;height:40px}::slotted(ion-thumbnail){--size:56px}::slotted(ion-avatar),::slotted(ion-thumbnail){margin-top:8px;margin-bottom:8px}::slotted(ion-avatar[slot=start]),::slotted(ion-thumbnail[slot=start]){-webkit-margin-end:16px;margin-inline-end:16px}::slotted(ion-avatar[slot=end]),::slotted(ion-thumbnail[slot=end]){-webkit-margin-start:16px;margin-inline-start:16px}::slotted(h1){margin-left:0;margin-right:0;margin-top:0;margin-bottom:2px}::slotted(h2){margin-left:0;margin-right:0;margin-top:2px;margin-bottom:2px}::slotted(h3,h4,h5,h6){margin-left:0;margin-right:0;margin-top:2px;margin-bottom:2px}::slotted(p){margin-left:0;margin-right:0;margin-top:0;margin-bottom:2px;color:var(--ion-color-step-600, var(--ion-text-color-step-400, #666666));font-size:0.875rem;line-height:normal;text-overflow:inherit;overflow:inherit}";
  15793. var IonItemDividerMdStyle0 = itemDividerMdCss;
  15794. /**
  15795. * @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
  15796. *
  15797. * @slot - Content is placed between the named slots if provided without a slot.
  15798. * @slot start - Content is placed to the left of the divider text in LTR, and to the right in RTL.
  15799. * @slot end - Content is placed to the right of the divider text in LTR, and to the left in RTL.
  15800. */
  15801. class ItemDivider {
  15802. constructor(hostRef) {
  15803. registerInstance(this, hostRef);
  15804. this.color = undefined;
  15805. this.sticky = false;
  15806. }
  15807. render() {
  15808. const mode = getIonMode$1(this);
  15809. return (hAsync(Host, { key: '7150b1a3a881c3c312db40821acb9830c2885ccf', class: createColorClasses$1(this.color, {
  15810. [mode]: true,
  15811. 'item-divider-sticky': this.sticky,
  15812. item: true,
  15813. }) }, hAsync("slot", { key: '6e9d9615f475392a81177bc49b4b01dbdab67925', name: "start" }), hAsync("div", { key: '12fe6b840ad1a1897cc34529e488207b2df448f7', class: "item-divider-inner" }, hAsync("div", { key: '626776a8c9887dd2df5ecf3b7861beb742b41e03', class: "item-divider-wrapper" }, hAsync("slot", { key: '90379dd99914e24ae45c9571c8d390f9b6622fd4' })), hAsync("slot", { key: '105644332c08530155b9cd8e8c6fa9e332072a63', name: "end" }))));
  15814. }
  15815. get el() { return getElement(this); }
  15816. static get style() { return {
  15817. ios: IonItemDividerIosStyle0,
  15818. md: IonItemDividerMdStyle0
  15819. }; }
  15820. static get cmpMeta() { return {
  15821. "$flags$": 41,
  15822. "$tagName$": "ion-item-divider",
  15823. "$members$": {
  15824. "color": [513],
  15825. "sticky": [4]
  15826. },
  15827. "$listeners$": undefined,
  15828. "$lazyBundleId$": "-",
  15829. "$attrsToReflect$": [["color", "color"]]
  15830. }; }
  15831. }
  15832. const itemGroupIosCss = "ion-item-group{display:block}";
  15833. var IonItemGroupIosStyle0 = itemGroupIosCss;
  15834. const itemGroupMdCss = "ion-item-group{display:block}";
  15835. var IonItemGroupMdStyle0 = itemGroupMdCss;
  15836. class ItemGroup {
  15837. constructor(hostRef) {
  15838. registerInstance(this, hostRef);
  15839. }
  15840. render() {
  15841. const mode = getIonMode$1(this);
  15842. return (hAsync(Host, { key: 'de2a969ed0dda880bc560a325848b28d0287fdb9', role: "group", class: {
  15843. [mode]: true,
  15844. // Used internally for styling
  15845. [`item-group-${mode}`]: true,
  15846. item: true,
  15847. } }));
  15848. }
  15849. static get style() { return {
  15850. ios: IonItemGroupIosStyle0,
  15851. md: IonItemGroupMdStyle0
  15852. }; }
  15853. static get cmpMeta() { return {
  15854. "$flags$": 32,
  15855. "$tagName$": "ion-item-group",
  15856. "$members$": undefined,
  15857. "$listeners$": undefined,
  15858. "$lazyBundleId$": "-",
  15859. "$attrsToReflect$": []
  15860. }; }
  15861. }
  15862. const itemOptionIosCss = ":host{--background:var(--ion-color-primary, #0054e9);--color:var(--ion-color-primary-contrast, #fff);background:var(--background);color:var(--color);font-family:var(--ion-font-family, inherit)}:host(.ion-color){background:var(--ion-color-base);color:var(--ion-color-contrast)}.button-native{font-family:inherit;font-size:inherit;font-style:inherit;font-weight:inherit;letter-spacing:inherit;text-decoration:inherit;text-indent:inherit;text-overflow:inherit;text-transform:inherit;text-align:inherit;white-space:inherit;color:inherit;-webkit-padding-start:0.7em;padding-inline-start:0.7em;-webkit-padding-end:0.7em;padding-inline-end:0.7em;padding-top:0;padding-bottom:0;display:inline-block;position:relative;width:100%;height:100%;border:0;outline:none;background:transparent;cursor:pointer;-webkit-appearance:none;-moz-appearance:none;appearance:none;-webkit-box-sizing:border-box;box-sizing:border-box}.button-inner{display:-ms-flexbox;display:flex;-ms-flex-flow:column nowrap;flex-flow:column nowrap;-ms-flex-negative:0;flex-shrink:0;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;width:100%;height:100%}.horizontal-wrapper{display:-ms-flexbox;display:flex;-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-negative:0;flex-shrink:0;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;width:100%}::slotted(*){-ms-flex-negative:0;flex-shrink:0}::slotted([slot=start]){-webkit-margin-start:0;margin-inline-start:0;-webkit-margin-end:5px;margin-inline-end:5px;margin-top:0;margin-bottom:0}::slotted([slot=end]){-webkit-margin-start:5px;margin-inline-start:5px;-webkit-margin-end:0;margin-inline-end:0;margin-top:0;margin-bottom:0}::slotted([slot=icon-only]){padding-left:0;padding-right:0;padding-top:0;padding-bottom:0;-webkit-margin-start:10px;margin-inline-start:10px;-webkit-margin-end:10px;margin-inline-end:10px;margin-top:0;margin-bottom:0;min-width:0.9em;font-size:1.8em}:host(.item-option-expandable){-ms-flex-negative:0;flex-shrink:0;-webkit-transition-duration:0;transition-duration:0;-webkit-transition-property:none;transition-property:none;-webkit-transition-timing-function:cubic-bezier(0.65, 0.05, 0.36, 1);transition-timing-function:cubic-bezier(0.65, 0.05, 0.36, 1)}:host(.item-option-disabled){pointer-events:none}:host(.item-option-disabled) .button-native{cursor:default;opacity:0.5;pointer-events:none}:host{font-size:clamp(16px, 1rem, 35.2px)}:host(.ion-activated){background:var(--ion-color-primary-shade, #004acd)}:host(.ion-color.ion-activated){background:var(--ion-color-shade)}";
  15863. var IonItemOptionIosStyle0 = itemOptionIosCss;
  15864. const itemOptionMdCss = ":host{--background:var(--ion-color-primary, #0054e9);--color:var(--ion-color-primary-contrast, #fff);background:var(--background);color:var(--color);font-family:var(--ion-font-family, inherit)}:host(.ion-color){background:var(--ion-color-base);color:var(--ion-color-contrast)}.button-native{font-family:inherit;font-size:inherit;font-style:inherit;font-weight:inherit;letter-spacing:inherit;text-decoration:inherit;text-indent:inherit;text-overflow:inherit;text-transform:inherit;text-align:inherit;white-space:inherit;color:inherit;-webkit-padding-start:0.7em;padding-inline-start:0.7em;-webkit-padding-end:0.7em;padding-inline-end:0.7em;padding-top:0;padding-bottom:0;display:inline-block;position:relative;width:100%;height:100%;border:0;outline:none;background:transparent;cursor:pointer;-webkit-appearance:none;-moz-appearance:none;appearance:none;-webkit-box-sizing:border-box;box-sizing:border-box}.button-inner{display:-ms-flexbox;display:flex;-ms-flex-flow:column nowrap;flex-flow:column nowrap;-ms-flex-negative:0;flex-shrink:0;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;width:100%;height:100%}.horizontal-wrapper{display:-ms-flexbox;display:flex;-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-negative:0;flex-shrink:0;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;width:100%}::slotted(*){-ms-flex-negative:0;flex-shrink:0}::slotted([slot=start]){-webkit-margin-start:0;margin-inline-start:0;-webkit-margin-end:5px;margin-inline-end:5px;margin-top:0;margin-bottom:0}::slotted([slot=end]){-webkit-margin-start:5px;margin-inline-start:5px;-webkit-margin-end:0;margin-inline-end:0;margin-top:0;margin-bottom:0}::slotted([slot=icon-only]){padding-left:0;padding-right:0;padding-top:0;padding-bottom:0;-webkit-margin-start:10px;margin-inline-start:10px;-webkit-margin-end:10px;margin-inline-end:10px;margin-top:0;margin-bottom:0;min-width:0.9em;font-size:1.8em}:host(.item-option-expandable){-ms-flex-negative:0;flex-shrink:0;-webkit-transition-duration:0;transition-duration:0;-webkit-transition-property:none;transition-property:none;-webkit-transition-timing-function:cubic-bezier(0.65, 0.05, 0.36, 1);transition-timing-function:cubic-bezier(0.65, 0.05, 0.36, 1)}:host(.item-option-disabled){pointer-events:none}:host(.item-option-disabled) .button-native{cursor:default;opacity:0.5;pointer-events:none}:host{font-size:0.875rem;font-weight:500;text-transform:uppercase}";
  15865. var IonItemOptionMdStyle0 = itemOptionMdCss;
  15866. /**
  15867. * @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
  15868. *
  15869. * @slot - Content is placed between the named slots if provided without a slot.
  15870. * @slot start - Content is placed to the left of the option text in LTR, and to the right in RTL.
  15871. * @slot top - Content is placed above the option text.
  15872. * @slot icon-only - Should be used on an icon in an option that has no text.
  15873. * @slot bottom - Content is placed below the option text.
  15874. * @slot end - Content is placed to the right of the option text in LTR, and to the left in RTL.
  15875. *
  15876. * @part native - The native HTML button or anchor element that wraps all child elements.
  15877. */
  15878. class ItemOption {
  15879. constructor(hostRef) {
  15880. registerInstance(this, hostRef);
  15881. this.onClick = (ev) => {
  15882. const el = ev.target.closest('ion-item-option');
  15883. if (el) {
  15884. ev.preventDefault();
  15885. }
  15886. };
  15887. this.color = undefined;
  15888. this.disabled = false;
  15889. this.download = undefined;
  15890. this.expandable = false;
  15891. this.href = undefined;
  15892. this.rel = undefined;
  15893. this.target = undefined;
  15894. this.type = 'button';
  15895. }
  15896. render() {
  15897. const { disabled, expandable, href } = this;
  15898. const TagType = href === undefined ? 'button' : 'a';
  15899. const mode = getIonMode$1(this);
  15900. const attrs = TagType === 'button'
  15901. ? { type: this.type }
  15902. : {
  15903. download: this.download,
  15904. href: this.href,
  15905. target: this.target,
  15906. };
  15907. return (hAsync(Host, { key: '1b7708dd178dc2c9280652ca3da38c84ba7b767f', onClick: this.onClick, class: createColorClasses$1(this.color, {
  15908. [mode]: true,
  15909. 'item-option-disabled': disabled,
  15910. 'item-option-expandable': expandable,
  15911. 'ion-activatable': true,
  15912. }) }, hAsync(TagType, Object.assign({ key: 'd9f899f5425ad6b97071494485aa3ca90bc89d30' }, attrs, { class: "button-native", part: "native", disabled: disabled }), hAsync("span", { key: 'adc2cf72b4363be9b9eeb3584723e2bfc862af20', class: "button-inner" }, hAsync("slot", { key: 'e668fe8e655a74e6a35e979e0cd488506b962dbf', name: "top" }), hAsync("div", { key: '2ddcdb92b6b19c3cc549a7aee2400d1a6eeb51f1', class: "horizontal-wrapper" }, hAsync("slot", { key: '441f13df18b72e5ed6bb51b157722e065b5847d2', name: "start" }), hAsync("slot", { key: '425d815874b49e1628880160d7175ed3ca36ca39', name: "icon-only" }), hAsync("slot", { key: '27437d3fa3365b12bc030704e18481fdfb14aebb' }), hAsync("slot", { key: 'bd39330771c7f85c6df10f7f9050335ee7f14ff0', name: "end" })), hAsync("slot", { key: '440cb6dc7743d50b261d4bf61d2c24e24b89e58c', name: "bottom" })), mode === 'md' && hAsync("ion-ripple-effect", { key: '29632941464bbb34551cf64961187643f62bf755' }))));
  15913. }
  15914. get el() { return getElement(this); }
  15915. static get style() { return {
  15916. ios: IonItemOptionIosStyle0,
  15917. md: IonItemOptionMdStyle0
  15918. }; }
  15919. static get cmpMeta() { return {
  15920. "$flags$": 41,
  15921. "$tagName$": "ion-item-option",
  15922. "$members$": {
  15923. "color": [513],
  15924. "disabled": [4],
  15925. "download": [1],
  15926. "expandable": [4],
  15927. "href": [1],
  15928. "rel": [1],
  15929. "target": [1],
  15930. "type": [1]
  15931. },
  15932. "$listeners$": undefined,
  15933. "$lazyBundleId$": "-",
  15934. "$attrsToReflect$": [["color", "color"]]
  15935. }; }
  15936. }
  15937. const itemOptionsIosCss = "ion-item-options{top:0;right:0;-ms-flex-pack:end;justify-content:flex-end;display:none;position:absolute;height:100%;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;z-index:1}:host-context([dir=rtl]) ion-item-options{-ms-flex-pack:start;justify-content:flex-start}:host-context([dir=rtl]) ion-item-options:not(.item-options-end){right:auto;left:0;-ms-flex-pack:end;justify-content:flex-end}[dir=rtl] ion-item-options{-ms-flex-pack:start;justify-content:flex-start}[dir=rtl] ion-item-options:not(.item-options-end){right:auto;left:0;-ms-flex-pack:end;justify-content:flex-end}@supports selector(:dir(rtl)){ion-item-options:dir(rtl){-ms-flex-pack:start;justify-content:flex-start}ion-item-options:dir(rtl):not(.item-options-end){right:auto;left:0;-ms-flex-pack:end;justify-content:flex-end}}.item-options-start{right:auto;left:0;-ms-flex-pack:start;justify-content:flex-start}:host-context([dir=rtl]) .item-options-start{-ms-flex-pack:end;justify-content:flex-end}[dir=rtl] .item-options-start{-ms-flex-pack:end;justify-content:flex-end}@supports selector(:dir(rtl)){.item-options-start:dir(rtl){-ms-flex-pack:end;justify-content:flex-end}}[dir=ltr] .item-options-start ion-item-option:first-child,[dir=rtl] .item-options-start ion-item-option:last-child{padding-left:var(--ion-safe-area-left)}[dir=ltr] .item-options-end ion-item-option:last-child,[dir=rtl] .item-options-end ion-item-option:first-child{padding-right:var(--ion-safe-area-right)}:host-context([dir=rtl]) .item-sliding-active-slide.item-sliding-active-options-start ion-item-options:not(.item-options-end){width:100%;visibility:visible}[dir=rtl] .item-sliding-active-slide.item-sliding-active-options-start ion-item-options:not(.item-options-end){width:100%;visibility:visible}@supports selector(:dir(rtl)){.item-sliding-active-slide:dir(rtl).item-sliding-active-options-start ion-item-options:not(.item-options-end){width:100%;visibility:visible}}.item-sliding-active-slide ion-item-options{display:-ms-flexbox;display:flex;visibility:hidden}.item-sliding-active-slide.item-sliding-active-options-start .item-options-start,.item-sliding-active-slide.item-sliding-active-options-end ion-item-options:not(.item-options-start){width:100%;visibility:visible}.item-options-ios{border-bottom-width:0;border-bottom-style:solid;border-bottom-color:var(--ion-item-border-color, var(--ion-border-color, var(--ion-color-step-250, var(--ion-background-color-step-250, #c8c7cc))))}.item-options-ios.item-options-end{border-bottom-width:0.55px}.list-ios-lines-none .item-options-ios{border-bottom-width:0}.list-ios-lines-full .item-options-ios,.list-ios-lines-inset .item-options-ios.item-options-end{border-bottom-width:0.55px}";
  15938. var IonItemOptionsIosStyle0 = itemOptionsIosCss;
  15939. const itemOptionsMdCss = "ion-item-options{top:0;right:0;-ms-flex-pack:end;justify-content:flex-end;display:none;position:absolute;height:100%;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;z-index:1}:host-context([dir=rtl]) ion-item-options{-ms-flex-pack:start;justify-content:flex-start}:host-context([dir=rtl]) ion-item-options:not(.item-options-end){right:auto;left:0;-ms-flex-pack:end;justify-content:flex-end}[dir=rtl] ion-item-options{-ms-flex-pack:start;justify-content:flex-start}[dir=rtl] ion-item-options:not(.item-options-end){right:auto;left:0;-ms-flex-pack:end;justify-content:flex-end}@supports selector(:dir(rtl)){ion-item-options:dir(rtl){-ms-flex-pack:start;justify-content:flex-start}ion-item-options:dir(rtl):not(.item-options-end){right:auto;left:0;-ms-flex-pack:end;justify-content:flex-end}}.item-options-start{right:auto;left:0;-ms-flex-pack:start;justify-content:flex-start}:host-context([dir=rtl]) .item-options-start{-ms-flex-pack:end;justify-content:flex-end}[dir=rtl] .item-options-start{-ms-flex-pack:end;justify-content:flex-end}@supports selector(:dir(rtl)){.item-options-start:dir(rtl){-ms-flex-pack:end;justify-content:flex-end}}[dir=ltr] .item-options-start ion-item-option:first-child,[dir=rtl] .item-options-start ion-item-option:last-child{padding-left:var(--ion-safe-area-left)}[dir=ltr] .item-options-end ion-item-option:last-child,[dir=rtl] .item-options-end ion-item-option:first-child{padding-right:var(--ion-safe-area-right)}:host-context([dir=rtl]) .item-sliding-active-slide.item-sliding-active-options-start ion-item-options:not(.item-options-end){width:100%;visibility:visible}[dir=rtl] .item-sliding-active-slide.item-sliding-active-options-start ion-item-options:not(.item-options-end){width:100%;visibility:visible}@supports selector(:dir(rtl)){.item-sliding-active-slide:dir(rtl).item-sliding-active-options-start ion-item-options:not(.item-options-end){width:100%;visibility:visible}}.item-sliding-active-slide ion-item-options{display:-ms-flexbox;display:flex;visibility:hidden}.item-sliding-active-slide.item-sliding-active-options-start .item-options-start,.item-sliding-active-slide.item-sliding-active-options-end ion-item-options:not(.item-options-start){width:100%;visibility:visible}.item-options-md{border-bottom-width:0;border-bottom-style:solid;border-bottom-color:var(--ion-item-border-color, var(--ion-border-color, var(--ion-color-step-150, var(--ion-background-color-step-150, rgba(0, 0, 0, 0.13)))))}.list-md-lines-none .item-options-md{border-bottom-width:0}.list-md-lines-full .item-options-md,.list-md-lines-inset .item-options-md.item-options-end{border-bottom-width:1px}";
  15940. var IonItemOptionsMdStyle0 = itemOptionsMdCss;
  15941. class ItemOptions {
  15942. constructor(hostRef) {
  15943. registerInstance(this, hostRef);
  15944. this.ionSwipe = createEvent(this, "ionSwipe", 7);
  15945. this.side = 'end';
  15946. }
  15947. /** @internal */
  15948. async fireSwipeEvent() {
  15949. this.ionSwipe.emit({
  15950. side: this.side,
  15951. });
  15952. }
  15953. render() {
  15954. const mode = getIonMode$1(this);
  15955. const isEnd = isEndSide(this.side);
  15956. return (hAsync(Host, { key: '7df4b71547524bf359c48e1b40ccbc44e850f632', class: {
  15957. [mode]: true,
  15958. // Used internally for styling
  15959. [`item-options-${mode}`]: true,
  15960. /**
  15961. * Note: The "start" and "end" terms refer to the
  15962. * direction ion-item-option instances within ion-item-options flow.
  15963. * They do not refer to how ion-item-options flows within ion-item-sliding.
  15964. * As a result, "item-options-start" means the ion-item-options container
  15965. * always appears on the left, and "item-options-end" means the ion-item-options
  15966. * container always appears on the right.
  15967. */
  15968. 'item-options-start': !isEnd,
  15969. 'item-options-end': isEnd,
  15970. } }));
  15971. }
  15972. get el() { return getElement(this); }
  15973. static get style() { return {
  15974. ios: IonItemOptionsIosStyle0,
  15975. md: IonItemOptionsMdStyle0
  15976. }; }
  15977. static get cmpMeta() { return {
  15978. "$flags$": 32,
  15979. "$tagName$": "ion-item-options",
  15980. "$members$": {
  15981. "side": [1],
  15982. "fireSwipeEvent": [64]
  15983. },
  15984. "$listeners$": undefined,
  15985. "$lazyBundleId$": "-",
  15986. "$attrsToReflect$": []
  15987. }; }
  15988. }
  15989. const watchForOptions = (containerEl, tagName, onChange) => {
  15990. if (typeof MutationObserver === 'undefined') {
  15991. return;
  15992. }
  15993. const mutation = new MutationObserver((mutationList) => {
  15994. onChange(getSelectedOption(mutationList, tagName));
  15995. });
  15996. mutation.observe(containerEl, {
  15997. childList: true,
  15998. subtree: true,
  15999. });
  16000. return mutation;
  16001. };
  16002. const getSelectedOption = (mutationList, tagName) => {
  16003. let newOption;
  16004. mutationList.forEach((mut) => {
  16005. // eslint-disable-next-line @typescript-eslint/prefer-for-of
  16006. for (let i = 0; i < mut.addedNodes.length; i++) {
  16007. newOption = findCheckedOption(mut.addedNodes[i], tagName) || newOption;
  16008. }
  16009. });
  16010. return newOption;
  16011. };
  16012. /**
  16013. * The "value" key is only set on some components such as ion-select-option.
  16014. * As a result, we create a default union type of HTMLElement and the "value" key.
  16015. * However, implementers are required to provide the appropriate component type
  16016. * such as HTMLIonSelectOptionElement.
  16017. */
  16018. const findCheckedOption = (node, tagName) => {
  16019. /**
  16020. * https://developer.mozilla.org/en-US/docs/Web/API/Node/nodeType
  16021. * The above check ensures "node" is an Element (nodeType 1).
  16022. */
  16023. if (node.nodeType !== 1) {
  16024. return undefined;
  16025. }
  16026. // HTMLElement inherits from Element, so we cast "el" as T.
  16027. const el = node;
  16028. const options = el.tagName === tagName.toUpperCase() ? [el] : Array.from(el.querySelectorAll(tagName));
  16029. return options.find((o) => o.value === el.value);
  16030. };
  16031. const itemSlidingCss = "ion-item-sliding{display:block;position:relative;width:100%;overflow:hidden;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}ion-item-sliding .item{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.item-sliding-active-slide .item{position:relative;-webkit-transition:-webkit-transform 500ms cubic-bezier(0.36, 0.66, 0.04, 1);transition:-webkit-transform 500ms cubic-bezier(0.36, 0.66, 0.04, 1);transition:transform 500ms cubic-bezier(0.36, 0.66, 0.04, 1);transition:transform 500ms cubic-bezier(0.36, 0.66, 0.04, 1), -webkit-transform 500ms cubic-bezier(0.36, 0.66, 0.04, 1);opacity:1;z-index:2;pointer-events:none;will-change:transform}.item-sliding-closing ion-item-options{pointer-events:none}.item-sliding-active-swipe-end .item-options-end .item-option-expandable{padding-left:100%;-ms-flex-order:1;order:1;-webkit-transition-duration:0.6s;transition-duration:0.6s;-webkit-transition-property:padding-left;transition-property:padding-left}:host-context([dir=rtl]) .item-sliding-active-swipe-end .item-options-end .item-option-expandable{-ms-flex-order:-1;order:-1}[dir=rtl] .item-sliding-active-swipe-end .item-options-end .item-option-expandable{-ms-flex-order:-1;order:-1}@supports selector(:dir(rtl)){.item-sliding-active-swipe-end .item-options-end .item-option-expandable:dir(rtl){-ms-flex-order:-1;order:-1}}.item-sliding-active-swipe-start .item-options-start .item-option-expandable{padding-right:100%;-ms-flex-order:-1;order:-1;-webkit-transition-duration:0.6s;transition-duration:0.6s;-webkit-transition-property:padding-right;transition-property:padding-right}:host-context([dir=rtl]) .item-sliding-active-swipe-start .item-options-start .item-option-expandable{-ms-flex-order:1;order:1}[dir=rtl] .item-sliding-active-swipe-start .item-options-start .item-option-expandable{-ms-flex-order:1;order:1}@supports selector(:dir(rtl)){.item-sliding-active-swipe-start .item-options-start .item-option-expandable:dir(rtl){-ms-flex-order:1;order:1}}";
  16032. var IonItemSlidingStyle0 = itemSlidingCss;
  16033. const SWIPE_MARGIN = 30;
  16034. const ELASTIC_FACTOR = 0.55;
  16035. let openSlidingItem;
  16036. class ItemSliding {
  16037. constructor(hostRef) {
  16038. registerInstance(this, hostRef);
  16039. this.ionDrag = createEvent(this, "ionDrag", 7);
  16040. this.item = null;
  16041. this.openAmount = 0;
  16042. this.initialOpenAmount = 0;
  16043. this.optsWidthRightSide = 0;
  16044. this.optsWidthLeftSide = 0;
  16045. this.sides = 0 /* ItemSide.None */;
  16046. this.optsDirty = true;
  16047. this.contentEl = null;
  16048. this.initialContentScrollY = true;
  16049. this.state = 2 /* SlidingState.Disabled */;
  16050. this.disabled = false;
  16051. }
  16052. disabledChanged() {
  16053. if (this.gesture) {
  16054. this.gesture.enable(!this.disabled);
  16055. }
  16056. }
  16057. async connectedCallback() {
  16058. const { el } = this;
  16059. this.item = el.querySelector('ion-item');
  16060. this.contentEl = findClosestIonContent(el);
  16061. /**
  16062. * The MutationObserver needs to be added before we
  16063. * call updateOptions below otherwise we may miss
  16064. * ion-item-option elements that are added to the DOM
  16065. * while updateOptions is running and before the MutationObserver
  16066. * has been initialized.
  16067. */
  16068. this.mutationObserver = watchForOptions(el, 'ion-item-option', async () => {
  16069. await this.updateOptions();
  16070. });
  16071. await this.updateOptions();
  16072. this.gesture = (await Promise.resolve().then(function () { return index; })).createGesture({
  16073. el,
  16074. gestureName: 'item-swipe',
  16075. gesturePriority: 100,
  16076. threshold: 5,
  16077. canStart: (ev) => this.canStart(ev),
  16078. onStart: () => this.onStart(),
  16079. onMove: (ev) => this.onMove(ev),
  16080. onEnd: (ev) => this.onEnd(ev),
  16081. });
  16082. this.disabledChanged();
  16083. }
  16084. disconnectedCallback() {
  16085. if (this.gesture) {
  16086. this.gesture.destroy();
  16087. this.gesture = undefined;
  16088. }
  16089. this.item = null;
  16090. this.leftOptions = this.rightOptions = undefined;
  16091. if (openSlidingItem === this.el) {
  16092. openSlidingItem = undefined;
  16093. }
  16094. if (this.mutationObserver) {
  16095. this.mutationObserver.disconnect();
  16096. this.mutationObserver = undefined;
  16097. }
  16098. }
  16099. /**
  16100. * Get the amount the item is open in pixels.
  16101. */
  16102. getOpenAmount() {
  16103. return Promise.resolve(this.openAmount);
  16104. }
  16105. /**
  16106. * Get the ratio of the open amount of the item compared to the width of the options.
  16107. * If the number returned is positive, then the options on the right side are open.
  16108. * If the number returned is negative, then the options on the left side are open.
  16109. * If the absolute value of the number is greater than 1, the item is open more than
  16110. * the width of the options.
  16111. */
  16112. getSlidingRatio() {
  16113. return Promise.resolve(this.getSlidingRatioSync());
  16114. }
  16115. /**
  16116. * Open the sliding item.
  16117. *
  16118. * @param side The side of the options to open. If a side is not provided, it will open the first set of options it finds within the item.
  16119. */
  16120. async open(side) {
  16121. var _a;
  16122. /**
  16123. * It is possible for the item to be added to the DOM
  16124. * after the item-sliding component was created. As a result,
  16125. * if this.item is null, then we should attempt to
  16126. * query for the ion-item again.
  16127. * However, if the item is already defined then
  16128. * we do not query for it again.
  16129. */
  16130. const item = (this.item = (_a = this.item) !== null && _a !== void 0 ? _a : this.el.querySelector('ion-item'));
  16131. if (item === null) {
  16132. return;
  16133. }
  16134. const optionsToOpen = this.getOptions(side);
  16135. if (!optionsToOpen) {
  16136. return;
  16137. }
  16138. /**
  16139. * If side is not set, we need to infer the side
  16140. * so we know which direction to move the options
  16141. */
  16142. if (side === undefined) {
  16143. side = optionsToOpen === this.leftOptions ? 'start' : 'end';
  16144. }
  16145. // In RTL we want to switch the sides
  16146. side = isEndSide(side) ? 'end' : 'start';
  16147. const isStartOpen = this.openAmount < 0;
  16148. const isEndOpen = this.openAmount > 0;
  16149. /**
  16150. * If a side is open and a user tries to
  16151. * re-open the same side, we should not do anything
  16152. */
  16153. if (isStartOpen && optionsToOpen === this.leftOptions) {
  16154. return;
  16155. }
  16156. if (isEndOpen && optionsToOpen === this.rightOptions) {
  16157. return;
  16158. }
  16159. this.closeOpened();
  16160. this.state = 4 /* SlidingState.Enabled */;
  16161. requestAnimationFrame(() => {
  16162. this.calculateOptsWidth();
  16163. const width = side === 'end' ? this.optsWidthRightSide : -this.optsWidthLeftSide;
  16164. openSlidingItem = this.el;
  16165. this.setOpenAmount(width, false);
  16166. this.state = side === 'end' ? 8 /* SlidingState.End */ : 16 /* SlidingState.Start */;
  16167. });
  16168. }
  16169. /**
  16170. * Close the sliding item. Items can also be closed from the [List](./list).
  16171. */
  16172. async close() {
  16173. this.setOpenAmount(0, true);
  16174. }
  16175. /**
  16176. * Close all of the sliding items in the list. Items can also be closed from the [List](./list).
  16177. */
  16178. async closeOpened() {
  16179. if (openSlidingItem !== undefined) {
  16180. openSlidingItem.close();
  16181. openSlidingItem = undefined;
  16182. return true;
  16183. }
  16184. return false;
  16185. }
  16186. /**
  16187. * Given an optional side, return the ion-item-options element.
  16188. *
  16189. * @param side This side of the options to get. If a side is not provided it will
  16190. * return the first one available.
  16191. */
  16192. getOptions(side) {
  16193. if (side === undefined) {
  16194. return this.leftOptions || this.rightOptions;
  16195. }
  16196. else if (side === 'start') {
  16197. return this.leftOptions;
  16198. }
  16199. else {
  16200. return this.rightOptions;
  16201. }
  16202. }
  16203. async updateOptions() {
  16204. const options = this.el.querySelectorAll('ion-item-options');
  16205. let sides = 0;
  16206. // Reset left and right options in case they were removed
  16207. this.leftOptions = this.rightOptions = undefined;
  16208. for (let i = 0; i < options.length; i++) {
  16209. const item = options.item(i);
  16210. /**
  16211. * We cannot use the componentOnReady helper
  16212. * util here since we need to wait for all of these items
  16213. * to be ready before we set `this.sides` and `this.optsDirty`.
  16214. */
  16215. // eslint-disable-next-line custom-rules/no-component-on-ready-method
  16216. const option = item.componentOnReady !== undefined ? await item.componentOnReady() : item;
  16217. const side = isEndSide(option.side) ? 'end' : 'start';
  16218. if (side === 'start') {
  16219. this.leftOptions = option;
  16220. sides |= 1 /* ItemSide.Start */;
  16221. }
  16222. else {
  16223. this.rightOptions = option;
  16224. sides |= 2 /* ItemSide.End */;
  16225. }
  16226. }
  16227. this.optsDirty = true;
  16228. this.sides = sides;
  16229. }
  16230. canStart(gesture) {
  16231. /**
  16232. * If very close to start of the screen
  16233. * do not open left side so swipe to go
  16234. * back will still work.
  16235. */
  16236. const rtl = document.dir === 'rtl';
  16237. const atEdge = rtl ? window.innerWidth - gesture.startX < 15 : gesture.startX < 15;
  16238. if (atEdge) {
  16239. return false;
  16240. }
  16241. const selected = openSlidingItem;
  16242. if (selected && selected !== this.el) {
  16243. this.closeOpened();
  16244. }
  16245. return !!(this.rightOptions || this.leftOptions);
  16246. }
  16247. onStart() {
  16248. /**
  16249. * We need to query for the ion-item
  16250. * every time the gesture starts. Developers
  16251. * may toggle ion-item elements via *ngIf.
  16252. */
  16253. this.item = this.el.querySelector('ion-item');
  16254. const { contentEl } = this;
  16255. if (contentEl) {
  16256. this.initialContentScrollY = disableContentScrollY(contentEl);
  16257. }
  16258. openSlidingItem = this.el;
  16259. if (this.tmr !== undefined) {
  16260. clearTimeout(this.tmr);
  16261. this.tmr = undefined;
  16262. }
  16263. if (this.openAmount === 0) {
  16264. this.optsDirty = true;
  16265. this.state = 4 /* SlidingState.Enabled */;
  16266. }
  16267. this.initialOpenAmount = this.openAmount;
  16268. if (this.item) {
  16269. this.item.style.transition = 'none';
  16270. }
  16271. }
  16272. onMove(gesture) {
  16273. if (this.optsDirty) {
  16274. this.calculateOptsWidth();
  16275. }
  16276. let openAmount = this.initialOpenAmount - gesture.deltaX;
  16277. switch (this.sides) {
  16278. case 2 /* ItemSide.End */:
  16279. openAmount = Math.max(0, openAmount);
  16280. break;
  16281. case 1 /* ItemSide.Start */:
  16282. openAmount = Math.min(0, openAmount);
  16283. break;
  16284. case 3 /* ItemSide.Both */:
  16285. break;
  16286. case 0 /* ItemSide.None */:
  16287. return;
  16288. default:
  16289. printIonWarning('[ion-item-sliding] - invalid ItemSideFlags value', this.sides);
  16290. break;
  16291. }
  16292. let optsWidth;
  16293. if (openAmount > this.optsWidthRightSide) {
  16294. optsWidth = this.optsWidthRightSide;
  16295. openAmount = optsWidth + (openAmount - optsWidth) * ELASTIC_FACTOR;
  16296. }
  16297. else if (openAmount < -this.optsWidthLeftSide) {
  16298. optsWidth = -this.optsWidthLeftSide;
  16299. openAmount = optsWidth + (openAmount - optsWidth) * ELASTIC_FACTOR;
  16300. }
  16301. this.setOpenAmount(openAmount, false);
  16302. }
  16303. onEnd(gesture) {
  16304. const { contentEl, initialContentScrollY } = this;
  16305. if (contentEl) {
  16306. resetContentScrollY(contentEl, initialContentScrollY);
  16307. }
  16308. const velocity = gesture.velocityX;
  16309. let restingPoint = this.openAmount > 0 ? this.optsWidthRightSide : -this.optsWidthLeftSide;
  16310. // Check if the drag didn't clear the buttons mid-point
  16311. // and we aren't moving fast enough to swipe open
  16312. const isResetDirection = this.openAmount > 0 === !(velocity < 0);
  16313. const isMovingFast = Math.abs(velocity) > 0.3;
  16314. const isOnCloseZone = Math.abs(this.openAmount) < Math.abs(restingPoint / 2);
  16315. if (swipeShouldReset(isResetDirection, isMovingFast, isOnCloseZone)) {
  16316. restingPoint = 0;
  16317. }
  16318. const state = this.state;
  16319. this.setOpenAmount(restingPoint, true);
  16320. if ((state & 32 /* SlidingState.SwipeEnd */) !== 0 && this.rightOptions) {
  16321. this.rightOptions.fireSwipeEvent();
  16322. }
  16323. else if ((state & 64 /* SlidingState.SwipeStart */) !== 0 && this.leftOptions) {
  16324. this.leftOptions.fireSwipeEvent();
  16325. }
  16326. }
  16327. calculateOptsWidth() {
  16328. this.optsWidthRightSide = 0;
  16329. if (this.rightOptions) {
  16330. this.rightOptions.style.display = 'flex';
  16331. this.optsWidthRightSide = this.rightOptions.offsetWidth;
  16332. this.rightOptions.style.display = '';
  16333. }
  16334. this.optsWidthLeftSide = 0;
  16335. if (this.leftOptions) {
  16336. this.leftOptions.style.display = 'flex';
  16337. this.optsWidthLeftSide = this.leftOptions.offsetWidth;
  16338. this.leftOptions.style.display = '';
  16339. }
  16340. this.optsDirty = false;
  16341. }
  16342. setOpenAmount(openAmount, isFinal) {
  16343. if (this.tmr !== undefined) {
  16344. clearTimeout(this.tmr);
  16345. this.tmr = undefined;
  16346. }
  16347. if (!this.item) {
  16348. return;
  16349. }
  16350. const { el } = this;
  16351. const style = this.item.style;
  16352. this.openAmount = openAmount;
  16353. if (isFinal) {
  16354. style.transition = '';
  16355. }
  16356. if (openAmount > 0) {
  16357. this.state =
  16358. openAmount >= this.optsWidthRightSide + SWIPE_MARGIN
  16359. ? 8 /* SlidingState.End */ | 32 /* SlidingState.SwipeEnd */
  16360. : 8 /* SlidingState.End */;
  16361. }
  16362. else if (openAmount < 0) {
  16363. this.state =
  16364. openAmount <= -this.optsWidthLeftSide - SWIPE_MARGIN
  16365. ? 16 /* SlidingState.Start */ | 64 /* SlidingState.SwipeStart */
  16366. : 16 /* SlidingState.Start */;
  16367. }
  16368. else {
  16369. /**
  16370. * The sliding options should not be
  16371. * clickable while the item is closing.
  16372. */
  16373. el.classList.add('item-sliding-closing');
  16374. /**
  16375. * Item sliding cannot be interrupted
  16376. * while closing the item. If it did,
  16377. * it would allow the item to get into an
  16378. * inconsistent state where multiple
  16379. * items are then open at the same time.
  16380. */
  16381. if (this.gesture) {
  16382. this.gesture.enable(false);
  16383. }
  16384. this.tmr = setTimeout(() => {
  16385. this.state = 2 /* SlidingState.Disabled */;
  16386. this.tmr = undefined;
  16387. if (this.gesture) {
  16388. this.gesture.enable(!this.disabled);
  16389. }
  16390. el.classList.remove('item-sliding-closing');
  16391. }, 600);
  16392. openSlidingItem = undefined;
  16393. style.transform = '';
  16394. return;
  16395. }
  16396. style.transform = `translate3d(${-openAmount}px,0,0)`;
  16397. this.ionDrag.emit({
  16398. amount: openAmount,
  16399. ratio: this.getSlidingRatioSync(),
  16400. });
  16401. }
  16402. getSlidingRatioSync() {
  16403. if (this.openAmount > 0) {
  16404. return this.openAmount / this.optsWidthRightSide;
  16405. }
  16406. else if (this.openAmount < 0) {
  16407. return this.openAmount / this.optsWidthLeftSide;
  16408. }
  16409. else {
  16410. return 0;
  16411. }
  16412. }
  16413. render() {
  16414. const mode = getIonMode$1(this);
  16415. return (hAsync(Host, { key: 'f8aea4bb9802b111ef358cc6c172a635637ae1f8', class: {
  16416. [mode]: true,
  16417. 'item-sliding-active-slide': this.state !== 2 /* SlidingState.Disabled */,
  16418. 'item-sliding-active-options-end': (this.state & 8 /* SlidingState.End */) !== 0,
  16419. 'item-sliding-active-options-start': (this.state & 16 /* SlidingState.Start */) !== 0,
  16420. 'item-sliding-active-swipe-end': (this.state & 32 /* SlidingState.SwipeEnd */) !== 0,
  16421. 'item-sliding-active-swipe-start': (this.state & 64 /* SlidingState.SwipeStart */) !== 0,
  16422. } }));
  16423. }
  16424. get el() { return getElement(this); }
  16425. static get watchers() { return {
  16426. "disabled": ["disabledChanged"]
  16427. }; }
  16428. static get style() { return IonItemSlidingStyle0; }
  16429. static get cmpMeta() { return {
  16430. "$flags$": 0,
  16431. "$tagName$": "ion-item-sliding",
  16432. "$members$": {
  16433. "disabled": [4],
  16434. "state": [32],
  16435. "getOpenAmount": [64],
  16436. "getSlidingRatio": [64],
  16437. "open": [64],
  16438. "close": [64],
  16439. "closeOpened": [64]
  16440. },
  16441. "$listeners$": undefined,
  16442. "$lazyBundleId$": "-",
  16443. "$attrsToReflect$": []
  16444. }; }
  16445. }
  16446. const swipeShouldReset = (isResetDirection, isMovingFast, isOnResetZone) => {
  16447. // The logic required to know when the sliding item should close (openAmount=0)
  16448. // depends on three booleans (isResetDirection, isMovingFast, isOnResetZone)
  16449. // and it ended up being too complicated to be written manually without errors
  16450. // so the truth table is attached below: (0=false, 1=true)
  16451. // isResetDirection | isMovingFast | isOnResetZone || shouldClose
  16452. // 0 | 0 | 0 || 0
  16453. // 0 | 0 | 1 || 1
  16454. // 0 | 1 | 0 || 0
  16455. // 0 | 1 | 1 || 0
  16456. // 1 | 0 | 0 || 0
  16457. // 1 | 0 | 1 || 1
  16458. // 1 | 1 | 0 || 1
  16459. // 1 | 1 | 1 || 1
  16460. // The resulting expression was generated by resolving the K-map (Karnaugh map):
  16461. return (!isMovingFast && isOnResetZone) || (isResetDirection && isMovingFast);
  16462. };
  16463. const labelIosCss = ".item.sc-ion-label-ios-h,.item .sc-ion-label-ios-h{--color:initial;display:block;color:var(--color);font-family:var(--ion-font-family, inherit);font-size:inherit;text-overflow:ellipsis;-webkit-box-sizing:border-box;box-sizing:border-box}.ion-color.sc-ion-label-ios-h{color:var(--ion-color-base)}.ion-text-nowrap.sc-ion-label-ios-h{overflow:hidden}.item-interactive-disabled.sc-ion-label-ios-h:not(.item-multiple-inputs),.item-interactive-disabled:not(.item-multiple-inputs) .sc-ion-label-ios-h{cursor:default;opacity:0.3;pointer-events:none}.item-input.sc-ion-label-ios-h,.item-input .sc-ion-label-ios-h{-ms-flex:initial;flex:initial;max-width:200px;pointer-events:none}.item-textarea.sc-ion-label-ios-h,.item-textarea .sc-ion-label-ios-h{-ms-flex-item-align:baseline;align-self:baseline}.item-skeleton-text.sc-ion-label-ios-h,.item-skeleton-text .sc-ion-label-ios-h{overflow:hidden}.label-fixed.sc-ion-label-ios-h{-ms-flex:0 0 100px;flex:0 0 100px;width:100px;min-width:100px;max-width:200px}.label-stacked.sc-ion-label-ios-h,.label-floating.sc-ion-label-ios-h{margin-bottom:0;-ms-flex-item-align:stretch;align-self:stretch;width:auto;max-width:100%}.label-no-animate.label-floating.sc-ion-label-ios-h{-webkit-transition:none;transition:none}.sc-ion-label-ios-s h1,.sc-ion-label-ios-s h2,.sc-ion-label-ios-s h3,.sc-ion-label-ios-s h4,.sc-ion-label-ios-s h5,.sc-ion-label-ios-s h6{text-overflow:inherit;overflow:inherit}.ion-text-wrap.sc-ion-label-ios-h{font-size:0.875rem;line-height:1.5}.label-stacked.sc-ion-label-ios-h{margin-bottom:4px;font-size:0.875rem}.label-floating.sc-ion-label-ios-h{margin-bottom:0;-webkit-transform:translate(0, 29px);transform:translate(0, 29px);-webkit-transform-origin:left top;transform-origin:left top;-webkit-transition:-webkit-transform 150ms ease-in-out;transition:-webkit-transform 150ms ease-in-out;transition:transform 150ms ease-in-out;transition:transform 150ms ease-in-out, -webkit-transform 150ms ease-in-out}[dir=rtl].sc-ion-label-ios-h -no-combinator.label-floating.sc-ion-label-ios-h,[dir=rtl] .sc-ion-label-ios-h -no-combinator.label-floating.sc-ion-label-ios-h,[dir=rtl].label-floating.sc-ion-label-ios-h,[dir=rtl] .label-floating.sc-ion-label-ios-h{-webkit-transform-origin:right top;transform-origin:right top}@supports selector(:dir(rtl)){.label-floating.sc-ion-label-ios-h:dir(rtl){-webkit-transform-origin:right top;transform-origin:right top}}.item-textarea.label-floating.sc-ion-label-ios-h,.item-textarea .label-floating.sc-ion-label-ios-h{-webkit-transform:translate(0, 28px);transform:translate(0, 28px)}.item-has-focus.label-floating.sc-ion-label-ios-h,.item-has-focus .label-floating.sc-ion-label-ios-h,.item-has-placeholder.sc-ion-label-ios-h:not(.item-input).label-floating,.item-has-placeholder:not(.item-input) .label-floating.sc-ion-label-ios-h,.item-has-value.label-floating.sc-ion-label-ios-h,.item-has-value .label-floating.sc-ion-label-ios-h{-webkit-transform:scale(0.82);transform:scale(0.82)}.sc-ion-label-ios-s h1{margin-left:0;margin-right:0;margin-top:3px;margin-bottom:2px;font-size:1.375rem;font-weight:normal}.sc-ion-label-ios-s h2{margin-left:0;margin-right:0;margin-top:0;margin-bottom:2px;font-size:1.0625rem;font-weight:normal}.sc-ion-label-ios-s h3,.sc-ion-label-ios-s h4,.sc-ion-label-ios-s h5,.sc-ion-label-ios-s h6{margin-left:0;margin-right:0;margin-top:0;margin-bottom:3px;font-size:0.875rem;font-weight:normal;line-height:normal}.sc-ion-label-ios-s p{margin-left:0;margin-right:0;margin-top:0;margin-bottom:2px;font-size:0.875rem;line-height:normal;text-overflow:inherit;overflow:inherit}.sc-ion-label-ios-s>p{color:var(--ion-color-step-400, var(--ion-text-color-step-600, #999999))}.sc-ion-label-ios-h.in-item-color.sc-ion-label-ios-s>p{color:inherit}.sc-ion-label-ios-s h2:last-child,.sc-ion-label-ios-s h3:last-child,.sc-ion-label-ios-s h4:last-child,.sc-ion-label-ios-s h5:last-child,.sc-ion-label-ios-s h6:last-child,.sc-ion-label-ios-s p:last-child{margin-bottom:0}";
  16464. var IonLabelIosStyle0 = labelIosCss;
  16465. const labelMdCss = ".item.sc-ion-label-md-h,.item .sc-ion-label-md-h{--color:initial;display:block;color:var(--color);font-family:var(--ion-font-family, inherit);font-size:inherit;text-overflow:ellipsis;-webkit-box-sizing:border-box;box-sizing:border-box}.ion-color.sc-ion-label-md-h{color:var(--ion-color-base)}.ion-text-nowrap.sc-ion-label-md-h{overflow:hidden}.item-interactive-disabled.sc-ion-label-md-h:not(.item-multiple-inputs),.item-interactive-disabled:not(.item-multiple-inputs) .sc-ion-label-md-h{cursor:default;opacity:0.3;pointer-events:none}.item-input.sc-ion-label-md-h,.item-input .sc-ion-label-md-h{-ms-flex:initial;flex:initial;max-width:200px;pointer-events:none}.item-textarea.sc-ion-label-md-h,.item-textarea .sc-ion-label-md-h{-ms-flex-item-align:baseline;align-self:baseline}.item-skeleton-text.sc-ion-label-md-h,.item-skeleton-text .sc-ion-label-md-h{overflow:hidden}.label-fixed.sc-ion-label-md-h{-ms-flex:0 0 100px;flex:0 0 100px;width:100px;min-width:100px;max-width:200px}.label-stacked.sc-ion-label-md-h,.label-floating.sc-ion-label-md-h{margin-bottom:0;-ms-flex-item-align:stretch;align-self:stretch;width:auto;max-width:100%}.label-no-animate.label-floating.sc-ion-label-md-h{-webkit-transition:none;transition:none}.sc-ion-label-md-s h1,.sc-ion-label-md-s h2,.sc-ion-label-md-s h3,.sc-ion-label-md-s h4,.sc-ion-label-md-s h5,.sc-ion-label-md-s h6{text-overflow:inherit;overflow:inherit}.ion-text-wrap.sc-ion-label-md-h{line-height:1.5}.label-stacked.sc-ion-label-md-h,.label-floating.sc-ion-label-md-h{margin-left:0;margin-right:0;margin-top:0;margin-bottom:0;-webkit-transform-origin:top left;transform-origin:top left}.label-stacked.label-rtl.sc-ion-label-md-h,.label-floating.label-rtl.sc-ion-label-md-h{-webkit-transform-origin:top right;transform-origin:top right}.label-stacked.sc-ion-label-md-h{-webkit-transform:translateY(50%) scale(0.75);transform:translateY(50%) scale(0.75);-webkit-transition:color 150ms cubic-bezier(0.4, 0, 0.2, 1);transition:color 150ms cubic-bezier(0.4, 0, 0.2, 1)}.label-floating.sc-ion-label-md-h{-webkit-transform:translateY(96%);transform:translateY(96%);-webkit-transition:color 150ms cubic-bezier(0.4, 0, 0.2, 1), -webkit-transform 150ms cubic-bezier(0.4, 0, 0.2, 1);transition:color 150ms cubic-bezier(0.4, 0, 0.2, 1), -webkit-transform 150ms cubic-bezier(0.4, 0, 0.2, 1);transition:color 150ms cubic-bezier(0.4, 0, 0.2, 1), transform 150ms cubic-bezier(0.4, 0, 0.2, 1);transition:color 150ms cubic-bezier(0.4, 0, 0.2, 1), transform 150ms cubic-bezier(0.4, 0, 0.2, 1), -webkit-transform 150ms cubic-bezier(0.4, 0, 0.2, 1)}.ion-focused.label-floating.sc-ion-label-md-h,.ion-focused .label-floating.sc-ion-label-md-h,.item-has-focus.label-floating.sc-ion-label-md-h,.item-has-focus .label-floating.sc-ion-label-md-h,.item-has-placeholder.sc-ion-label-md-h:not(.item-input).label-floating,.item-has-placeholder:not(.item-input) .label-floating.sc-ion-label-md-h,.item-has-value.label-floating.sc-ion-label-md-h,.item-has-value .label-floating.sc-ion-label-md-h{-webkit-transform:translateY(50%) scale(0.75);transform:translateY(50%) scale(0.75)}.ion-focused.label-stacked.sc-ion-label-md-h:not(.ion-color),.ion-focused .label-stacked.sc-ion-label-md-h:not(.ion-color),.ion-focused.label-floating.sc-ion-label-md-h:not(.ion-color),.ion-focused .label-floating.sc-ion-label-md-h:not(.ion-color),.item-has-focus.label-stacked.sc-ion-label-md-h:not(.ion-color),.item-has-focus .label-stacked.sc-ion-label-md-h:not(.ion-color),.item-has-focus.label-floating.sc-ion-label-md-h:not(.ion-color),.item-has-focus .label-floating.sc-ion-label-md-h:not(.ion-color){color:var(--ion-color-primary, #0054e9)}.ion-focused.ion-color.label-stacked.sc-ion-label-md-h:not(.ion-color),.ion-focused.ion-color .label-stacked.sc-ion-label-md-h:not(.ion-color),.ion-focused.ion-color.label-floating.sc-ion-label-md-h:not(.ion-color),.ion-focused.ion-color .label-floating.sc-ion-label-md-h:not(.ion-color),.item-has-focus.ion-color.label-stacked.sc-ion-label-md-h:not(.ion-color),.item-has-focus.ion-color .label-stacked.sc-ion-label-md-h:not(.ion-color),.item-has-focus.ion-color.label-floating.sc-ion-label-md-h:not(.ion-color),.item-has-focus.ion-color .label-floating.sc-ion-label-md-h:not(.ion-color){color:var(--ion-color-contrast)}.ion-invalid.ion-touched.label-stacked.sc-ion-label-md-h:not(.ion-color),.ion-invalid.ion-touched .label-stacked.sc-ion-label-md-h:not(.ion-color),.ion-invalid.ion-touched.label-floating.sc-ion-label-md-h:not(.ion-color),.ion-invalid.ion-touched .label-floating.sc-ion-label-md-h:not(.ion-color){color:var(--highlight-color-invalid)}.sc-ion-label-md-s h1{margin-left:0;margin-right:0;margin-top:0;margin-bottom:2px;font-size:1.5rem;font-weight:normal}.sc-ion-label-md-s h2{margin-left:0;margin-right:0;margin-top:2px;margin-bottom:2px;font-size:1rem;font-weight:normal}.sc-ion-label-md-s h3,.sc-ion-label-md-s h4,.sc-ion-label-md-s h5,.sc-ion-label-md-s h6{margin-left:0;margin-right:0;margin-top:2px;margin-bottom:2px;font-size:0.875rem;font-weight:normal;line-height:normal}.sc-ion-label-md-s p{margin-left:0;margin-right:0;margin-top:0;margin-bottom:2px;font-size:0.875rem;line-height:1.25rem;text-overflow:inherit;overflow:inherit}.sc-ion-label-md-s>p{color:var(--ion-color-step-600, var(--ion-text-color-step-400, #666666))}.sc-ion-label-md-h.in-item-color.sc-ion-label-md-s>p{color:inherit}";
  16466. var IonLabelMdStyle0 = labelMdCss;
  16467. /**
  16468. * @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
  16469. */
  16470. class Label {
  16471. constructor(hostRef) {
  16472. registerInstance(this, hostRef);
  16473. this.ionColor = createEvent(this, "ionColor", 7);
  16474. this.ionStyle = createEvent(this, "ionStyle", 7);
  16475. this.inRange = false;
  16476. this.color = undefined;
  16477. this.position = undefined;
  16478. this.noAnimate = false;
  16479. }
  16480. componentWillLoad() {
  16481. this.inRange = !!this.el.closest('ion-range');
  16482. this.noAnimate = this.position === 'floating';
  16483. this.emitStyle();
  16484. this.emitColor();
  16485. }
  16486. componentDidLoad() {
  16487. if (this.noAnimate) {
  16488. setTimeout(() => {
  16489. this.noAnimate = false;
  16490. }, 1000);
  16491. }
  16492. }
  16493. colorChanged() {
  16494. this.emitColor();
  16495. }
  16496. positionChanged() {
  16497. this.emitStyle();
  16498. }
  16499. emitColor() {
  16500. const { color } = this;
  16501. this.ionColor.emit({
  16502. 'item-label-color': color !== undefined,
  16503. [`ion-color-${color}`]: color !== undefined,
  16504. });
  16505. }
  16506. emitStyle() {
  16507. const { inRange, position } = this;
  16508. // If the label is inside of a range we don't want
  16509. // to override the classes added by the label that
  16510. // is a direct child of the item
  16511. if (!inRange) {
  16512. this.ionStyle.emit({
  16513. label: true,
  16514. [`label-${position}`]: position !== undefined,
  16515. });
  16516. }
  16517. }
  16518. render() {
  16519. const position = this.position;
  16520. const mode = getIonMode$1(this);
  16521. return (hAsync(Host, { key: '4da84c95351a74b547f8224ecfa66924d21398c5', class: createColorClasses$1(this.color, {
  16522. [mode]: true,
  16523. 'in-item-color': hostContext('ion-item.ion-color', this.el),
  16524. [`label-${position}`]: position !== undefined,
  16525. [`label-no-animate`]: this.noAnimate,
  16526. 'label-rtl': document.dir === 'rtl',
  16527. }) }, hAsync("slot", { key: 'ea158ebb620275e5492965234d0ab925d391f919' })));
  16528. }
  16529. get el() { return getElement(this); }
  16530. static get watchers() { return {
  16531. "color": ["colorChanged"],
  16532. "position": ["positionChanged"]
  16533. }; }
  16534. static get style() { return {
  16535. ios: IonLabelIosStyle0,
  16536. md: IonLabelMdStyle0
  16537. }; }
  16538. static get cmpMeta() { return {
  16539. "$flags$": 38,
  16540. "$tagName$": "ion-label",
  16541. "$members$": {
  16542. "color": [513],
  16543. "position": [1],
  16544. "noAnimate": [32]
  16545. },
  16546. "$listeners$": undefined,
  16547. "$lazyBundleId$": "-",
  16548. "$attrsToReflect$": [["color", "color"]]
  16549. }; }
  16550. }
  16551. const listIosCss = "ion-list{margin-left:0;margin-right:0;margin-top:0;margin-bottom:0;padding-left:0;padding-right:0;padding-top:0;padding-bottom:0;display:block;contain:content;list-style-type:none}ion-list.list-inset{-webkit-transform:translateZ(0);transform:translateZ(0);overflow:hidden}.list-ios{background:var(--ion-item-background, var(--ion-background-color, #fff))}.list-ios.list-inset{-webkit-margin-start:16px;margin-inline-start:16px;-webkit-margin-end:16px;margin-inline-end:16px;margin-top:16px;margin-bottom:16px;border-radius:10px}.list-ios.list-inset ion-item:only-child,.list-ios.list-inset ion-item:not(:only-of-type):last-of-type,.list-ios.list-inset ion-item-sliding:last-of-type ion-item{--border-width:0;--inner-border-width:0}.list-ios.list-inset+ion-list.list-inset{margin-top:0}.list-ios-lines-none .item-lines-default{--inner-border-width:0px;--border-width:0px}.list-ios-lines-full .item-lines-default{--inner-border-width:0px;--border-width:0 0 0.55px 0}.list-ios-lines-inset .item-lines-default{--inner-border-width:0 0 0.55px 0;--border-width:0px}ion-card .list-ios{margin-left:0;margin-right:0;margin-top:0;margin-bottom:0}";
  16552. var IonListIosStyle0 = listIosCss;
  16553. const listMdCss = "ion-list{margin-left:0;margin-right:0;margin-top:0;margin-bottom:0;padding-left:0;padding-right:0;padding-top:0;padding-bottom:0;display:block;contain:content;list-style-type:none}ion-list.list-inset{-webkit-transform:translateZ(0);transform:translateZ(0);overflow:hidden}.list-md{margin-left:0;margin-right:0;margin-top:0;margin-bottom:0;padding-left:0;padding-right:0;padding-top:8px;padding-bottom:8px;background:var(--ion-item-background, var(--ion-background-color, #fff))}.list-md>.input:last-child::after{inset-inline-start:0}.list-md.list-inset{-webkit-margin-start:16px;margin-inline-start:16px;-webkit-margin-end:16px;margin-inline-end:16px;margin-top:16px;margin-bottom:16px;border-radius:2px}.list-md.list-inset ion-item:not(:only-of-type):last-of-type,.list-md.list-inset ion-item-sliding:last-of-type ion-item{--border-width:0;--inner-border-width:0}.list-md.list-inset ion-item:only-child{--border-width:0;--inner-border-width:0}.list-md.list-inset+ion-list.list-inset{margin-top:0}.list-md-lines-none .item-lines-default{--inner-border-width:0px;--border-width:0px}.list-md-lines-full .item-lines-default{--inner-border-width:0px;--border-width:0 0 1px 0}.list-md-lines-inset .item-lines-default{--inner-border-width:0 0 1px 0;--border-width:0px}ion-card .list-md{margin-left:0;margin-right:0;margin-top:0;margin-bottom:0}";
  16554. var IonListMdStyle0 = listMdCss;
  16555. /**
  16556. * @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
  16557. */
  16558. class List {
  16559. constructor(hostRef) {
  16560. registerInstance(this, hostRef);
  16561. this.lines = undefined;
  16562. this.inset = false;
  16563. }
  16564. /**
  16565. * If `ion-item-sliding` are used inside the list, this method closes
  16566. * any open sliding item.
  16567. *
  16568. * Returns `true` if an actual `ion-item-sliding` is closed.
  16569. */
  16570. async closeSlidingItems() {
  16571. const item = this.el.querySelector('ion-item-sliding');
  16572. if (item === null || item === void 0 ? void 0 : item.closeOpened) {
  16573. return item.closeOpened();
  16574. }
  16575. return false;
  16576. }
  16577. render() {
  16578. const mode = getIonMode$1(this);
  16579. const { lines, inset } = this;
  16580. return (hAsync(Host, { key: '5ff2b0b3989cc99ce17abb8bcd7ec1847940d1ec', role: "list", class: {
  16581. [mode]: true,
  16582. // Used internally for styling
  16583. [`list-${mode}`]: true,
  16584. 'list-inset': inset,
  16585. [`list-lines-${lines}`]: lines !== undefined,
  16586. [`list-${mode}-lines-${lines}`]: lines !== undefined,
  16587. } }));
  16588. }
  16589. get el() { return getElement(this); }
  16590. static get style() { return {
  16591. ios: IonListIosStyle0,
  16592. md: IonListMdStyle0
  16593. }; }
  16594. static get cmpMeta() { return {
  16595. "$flags$": 32,
  16596. "$tagName$": "ion-list",
  16597. "$members$": {
  16598. "lines": [1],
  16599. "inset": [4],
  16600. "closeSlidingItems": [64]
  16601. },
  16602. "$listeners$": undefined,
  16603. "$lazyBundleId$": "-",
  16604. "$attrsToReflect$": []
  16605. }; }
  16606. }
  16607. const listHeaderIosCss = ":host{--border-style:solid;--border-width:0;--inner-border-width:0;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;margin-left:0;margin-right:0;margin-top:0;margin-bottom:0;padding-left:0;padding-right:0;padding-top:0;padding-bottom:0;display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:justify;justify-content:space-between;width:100%;min-height:40px;border-width:var(--border-width);border-style:var(--border-style);border-color:var(--border-color);background:var(--background);color:var(--color);overflow:hidden}:host(.ion-color){background:var(--ion-color-base);color:var(--ion-color-contrast)}.list-header-inner{display:-ms-flexbox;display:flex;position:relative;-ms-flex:1;flex:1;-ms-flex-direction:inherit;flex-direction:inherit;-ms-flex-align:inherit;align-items:inherit;-ms-flex-item-align:stretch;align-self:stretch;min-height:inherit;border-width:var(--inner-border-width);border-style:var(--border-style);border-color:var(--border-color);overflow:inherit;-webkit-box-sizing:border-box;box-sizing:border-box}::slotted(ion-label){-ms-flex:1 1 auto;flex:1 1 auto}:host(.list-header-lines-inset),:host(.list-header-lines-none){--border-width:0}:host(.list-header-lines-full),:host(.list-header-lines-none){--inner-border-width:0}:host{--background:transparent;--color:var(--ion-color-step-850, var(--ion-text-color-step-150, #262626));--border-color:var(--ion-item-border-color, var(--ion-border-color, var(--ion-color-step-250, var(--ion-background-color-step-250, #c8c7cc))));padding-right:var(--ion-safe-area-right);padding-left:calc(var(--ion-safe-area-left, 0px) + 16px);position:relative;-ms-flex-align:end;align-items:flex-end;font-size:min(1.375rem, 56.1px);font-weight:700;letter-spacing:0}:host-context([dir=rtl]){padding-right:calc(var(--ion-safe-area-right, 0px) + 16px);padding-left:var(--ion-safe-area-left)}@supports selector(:dir(rtl)){:host(:dir(rtl)){padding-right:calc(var(--ion-safe-area-right, 0px) + 16px);padding-left:var(--ion-safe-area-left)}}::slotted(ion-button),::slotted(ion-label){margin-top:29px;margin-bottom:6px}::slotted(ion-button){--padding-top:0;--padding-bottom:0;-webkit-margin-start:3px;margin-inline-start:3px;-webkit-margin-end:3px;margin-inline-end:3px;min-height:1.4em}:host(.list-header-lines-full){--border-width:0 0 0.55px 0}:host(.list-header-lines-inset){--inner-border-width:0 0 0.55px 0}";
  16608. var IonListHeaderIosStyle0 = listHeaderIosCss;
  16609. const listHeaderMdCss = ":host{--border-style:solid;--border-width:0;--inner-border-width:0;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;margin-left:0;margin-right:0;margin-top:0;margin-bottom:0;padding-left:0;padding-right:0;padding-top:0;padding-bottom:0;display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:justify;justify-content:space-between;width:100%;min-height:40px;border-width:var(--border-width);border-style:var(--border-style);border-color:var(--border-color);background:var(--background);color:var(--color);overflow:hidden}:host(.ion-color){background:var(--ion-color-base);color:var(--ion-color-contrast)}.list-header-inner{display:-ms-flexbox;display:flex;position:relative;-ms-flex:1;flex:1;-ms-flex-direction:inherit;flex-direction:inherit;-ms-flex-align:inherit;align-items:inherit;-ms-flex-item-align:stretch;align-self:stretch;min-height:inherit;border-width:var(--inner-border-width);border-style:var(--border-style);border-color:var(--border-color);overflow:inherit;-webkit-box-sizing:border-box;box-sizing:border-box}::slotted(ion-label){-ms-flex:1 1 auto;flex:1 1 auto}:host(.list-header-lines-inset),:host(.list-header-lines-none){--border-width:0}:host(.list-header-lines-full),:host(.list-header-lines-none){--inner-border-width:0}:host{--background:transparent;--color:var(--ion-text-color, #000);--border-color:var(--ion-item-border-color, var(--ion-border-color, var(--ion-color-step-150, var(--ion-background-color-step-150, rgba(0, 0, 0, 0.13)))));padding-right:var(--ion-safe-area-right);padding-left:calc(var(--ion-safe-area-left, 0px) + 16px);min-height:45px;font-size:0.875rem}:host-context([dir=rtl]){padding-right:calc(var(--ion-safe-area-right, 0px) + 16px);padding-left:var(--ion-safe-area-left)}@supports selector(:dir(rtl)){:host(:dir(rtl)){padding-right:calc(var(--ion-safe-area-right, 0px) + 16px);padding-left:var(--ion-safe-area-left)}}:host(.list-header-lines-full){--border-width:0 0 1px 0}:host(.list-header-lines-inset){--inner-border-width:0 0 1px 0}";
  16610. var IonListHeaderMdStyle0 = listHeaderMdCss;
  16611. /**
  16612. * @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
  16613. */
  16614. class ListHeader {
  16615. constructor(hostRef) {
  16616. registerInstance(this, hostRef);
  16617. this.color = undefined;
  16618. this.lines = undefined;
  16619. }
  16620. render() {
  16621. const { lines } = this;
  16622. const mode = getIonMode$1(this);
  16623. return (hAsync(Host, { key: '95ce2135e2b1ad4d7d6020b0fb9bc6e02b3c0851', class: createColorClasses$1(this.color, {
  16624. [mode]: true,
  16625. [`list-header-lines-${lines}`]: lines !== undefined,
  16626. }) }, hAsync("div", { key: '3065b0a094bc31a90518898a5126a813c8a33816', class: "list-header-inner" }, hAsync("slot", { key: 'fe15c87d7867f3e5d8185645c49c0228496697b8' }))));
  16627. }
  16628. static get style() { return {
  16629. ios: IonListHeaderIosStyle0,
  16630. md: IonListHeaderMdStyle0
  16631. }; }
  16632. static get cmpMeta() { return {
  16633. "$flags$": 41,
  16634. "$tagName$": "ion-list-header",
  16635. "$members$": {
  16636. "color": [513],
  16637. "lines": [1]
  16638. },
  16639. "$listeners$": undefined,
  16640. "$lazyBundleId$": "-",
  16641. "$attrsToReflect$": [["color", "color"]]
  16642. }; }
  16643. }
  16644. /**
  16645. * iOS Loading Enter Animation
  16646. */
  16647. const iosEnterAnimation$4 = (baseEl) => {
  16648. const baseAnimation = createAnimation();
  16649. const backdropAnimation = createAnimation();
  16650. const wrapperAnimation = createAnimation();
  16651. backdropAnimation
  16652. .addElement(baseEl.querySelector('ion-backdrop'))
  16653. .fromTo('opacity', 0.01, 'var(--backdrop-opacity)')
  16654. .beforeStyles({
  16655. 'pointer-events': 'none',
  16656. })
  16657. .afterClearStyles(['pointer-events']);
  16658. wrapperAnimation.addElement(baseEl.querySelector('.loading-wrapper')).keyframes([
  16659. { offset: 0, opacity: 0.01, transform: 'scale(1.1)' },
  16660. { offset: 1, opacity: 1, transform: 'scale(1)' },
  16661. ]);
  16662. return baseAnimation
  16663. .addElement(baseEl)
  16664. .easing('ease-in-out')
  16665. .duration(200)
  16666. .addAnimation([backdropAnimation, wrapperAnimation]);
  16667. };
  16668. /**
  16669. * iOS Loading Leave Animation
  16670. */
  16671. const iosLeaveAnimation$4 = (baseEl) => {
  16672. const baseAnimation = createAnimation();
  16673. const backdropAnimation = createAnimation();
  16674. const wrapperAnimation = createAnimation();
  16675. backdropAnimation.addElement(baseEl.querySelector('ion-backdrop')).fromTo('opacity', 'var(--backdrop-opacity)', 0);
  16676. wrapperAnimation.addElement(baseEl.querySelector('.loading-wrapper')).keyframes([
  16677. { offset: 0, opacity: 0.99, transform: 'scale(1)' },
  16678. { offset: 1, opacity: 0, transform: 'scale(0.9)' },
  16679. ]);
  16680. return baseAnimation
  16681. .addElement(baseEl)
  16682. .easing('ease-in-out')
  16683. .duration(200)
  16684. .addAnimation([backdropAnimation, wrapperAnimation]);
  16685. };
  16686. /**
  16687. * Md Loading Enter Animation
  16688. */
  16689. const mdEnterAnimation$3 = (baseEl) => {
  16690. const baseAnimation = createAnimation();
  16691. const backdropAnimation = createAnimation();
  16692. const wrapperAnimation = createAnimation();
  16693. backdropAnimation
  16694. .addElement(baseEl.querySelector('ion-backdrop'))
  16695. .fromTo('opacity', 0.01, 'var(--backdrop-opacity)')
  16696. .beforeStyles({
  16697. 'pointer-events': 'none',
  16698. })
  16699. .afterClearStyles(['pointer-events']);
  16700. wrapperAnimation.addElement(baseEl.querySelector('.loading-wrapper')).keyframes([
  16701. { offset: 0, opacity: 0.01, transform: 'scale(1.1)' },
  16702. { offset: 1, opacity: 1, transform: 'scale(1)' },
  16703. ]);
  16704. return baseAnimation
  16705. .addElement(baseEl)
  16706. .easing('ease-in-out')
  16707. .duration(200)
  16708. .addAnimation([backdropAnimation, wrapperAnimation]);
  16709. };
  16710. /**
  16711. * Md Loading Leave Animation
  16712. */
  16713. const mdLeaveAnimation$3 = (baseEl) => {
  16714. const baseAnimation = createAnimation();
  16715. const backdropAnimation = createAnimation();
  16716. const wrapperAnimation = createAnimation();
  16717. backdropAnimation.addElement(baseEl.querySelector('ion-backdrop')).fromTo('opacity', 'var(--backdrop-opacity)', 0);
  16718. wrapperAnimation.addElement(baseEl.querySelector('.loading-wrapper')).keyframes([
  16719. { offset: 0, opacity: 0.99, transform: 'scale(1)' },
  16720. { offset: 1, opacity: 0, transform: 'scale(0.9)' },
  16721. ]);
  16722. return baseAnimation
  16723. .addElement(baseEl)
  16724. .easing('ease-in-out')
  16725. .duration(200)
  16726. .addAnimation([backdropAnimation, wrapperAnimation]);
  16727. };
  16728. const loadingIosCss = ".sc-ion-loading-ios-h{--min-width:auto;--width:auto;--min-height:auto;--height:auto;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;left:0;right:0;top:0;bottom:0;display:-ms-flexbox;display:flex;position:fixed;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;outline:none;font-family:var(--ion-font-family, inherit);contain:strict;-ms-touch-action:none;touch-action:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;z-index:1001}.overlay-hidden.sc-ion-loading-ios-h{display:none}.loading-wrapper.sc-ion-loading-ios{display:-ms-flexbox;display:flex;-ms-flex-align:inherit;align-items:inherit;-ms-flex-pack:inherit;justify-content:inherit;width:var(--width);min-width:var(--min-width);max-width:var(--max-width);height:var(--height);min-height:var(--min-height);max-height:var(--max-height);background:var(--background);opacity:0;z-index:10}ion-spinner.sc-ion-loading-ios{color:var(--spinner-color)}.sc-ion-loading-ios-h{--background:var(--ion-overlay-background-color, var(--ion-color-step-100, var(--ion-background-color-step-100, #f9f9f9)));--max-width:270px;--max-height:90%;--spinner-color:var(--ion-color-step-600, var(--ion-text-color-step-400, #666666));--backdrop-opacity:var(--ion-backdrop-opacity, 0.3);color:var(--ion-text-color, #000);font-size:0.875rem}.loading-wrapper.sc-ion-loading-ios{border-radius:8px;-webkit-padding-start:34px;padding-inline-start:34px;-webkit-padding-end:34px;padding-inline-end:34px;padding-top:24px;padding-bottom:24px}@supports ((-webkit-backdrop-filter: blur(0)) or (backdrop-filter: blur(0))){.loading-translucent.sc-ion-loading-ios-h .loading-wrapper.sc-ion-loading-ios{background-color:rgba(var(--ion-background-color-rgb, 255, 255, 255), 0.8);-webkit-backdrop-filter:saturate(180%) blur(20px);backdrop-filter:saturate(180%) blur(20px)}}.loading-content.sc-ion-loading-ios{font-weight:bold}.loading-spinner.sc-ion-loading-ios+.loading-content.sc-ion-loading-ios{-webkit-margin-start:16px;margin-inline-start:16px}";
  16729. var IonLoadingIosStyle0 = loadingIosCss;
  16730. const loadingMdCss = ".sc-ion-loading-md-h{--min-width:auto;--width:auto;--min-height:auto;--height:auto;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;left:0;right:0;top:0;bottom:0;display:-ms-flexbox;display:flex;position:fixed;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;outline:none;font-family:var(--ion-font-family, inherit);contain:strict;-ms-touch-action:none;touch-action:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;z-index:1001}.overlay-hidden.sc-ion-loading-md-h{display:none}.loading-wrapper.sc-ion-loading-md{display:-ms-flexbox;display:flex;-ms-flex-align:inherit;align-items:inherit;-ms-flex-pack:inherit;justify-content:inherit;width:var(--width);min-width:var(--min-width);max-width:var(--max-width);height:var(--height);min-height:var(--min-height);max-height:var(--max-height);background:var(--background);opacity:0;z-index:10}ion-spinner.sc-ion-loading-md{color:var(--spinner-color)}.sc-ion-loading-md-h{--background:var(--ion-color-step-50, var(--ion-background-color-step-50, #f2f2f2));--max-width:280px;--max-height:90%;--spinner-color:var(--ion-color-primary, #0054e9);--backdrop-opacity:var(--ion-backdrop-opacity, 0.32);color:var(--ion-color-step-850, var(--ion-text-color-step-150, #262626));font-size:0.875rem}.loading-wrapper.sc-ion-loading-md{border-radius:2px;-webkit-padding-start:24px;padding-inline-start:24px;-webkit-padding-end:24px;padding-inline-end:24px;padding-top:24px;padding-bottom:24px;-webkit-box-shadow:0 16px 20px rgba(0, 0, 0, 0.4);box-shadow:0 16px 20px rgba(0, 0, 0, 0.4)}.loading-spinner.sc-ion-loading-md+.loading-content.sc-ion-loading-md{-webkit-margin-start:16px;margin-inline-start:16px}";
  16731. var IonLoadingMdStyle0 = loadingMdCss;
  16732. // TODO(FW-2832): types
  16733. /**
  16734. * @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
  16735. */
  16736. class Loading {
  16737. constructor(hostRef) {
  16738. registerInstance(this, hostRef);
  16739. this.didPresent = createEvent(this, "ionLoadingDidPresent", 7);
  16740. this.willPresent = createEvent(this, "ionLoadingWillPresent", 7);
  16741. this.willDismiss = createEvent(this, "ionLoadingWillDismiss", 7);
  16742. this.didDismiss = createEvent(this, "ionLoadingDidDismiss", 7);
  16743. this.didPresentShorthand = createEvent(this, "didPresent", 7);
  16744. this.willPresentShorthand = createEvent(this, "willPresent", 7);
  16745. this.willDismissShorthand = createEvent(this, "willDismiss", 7);
  16746. this.didDismissShorthand = createEvent(this, "didDismiss", 7);
  16747. this.delegateController = createDelegateController(this);
  16748. this.lockController = createLockController();
  16749. this.triggerController = createTriggerController();
  16750. this.customHTMLEnabled = config.get('innerHTMLTemplatesEnabled', ENABLE_HTML_CONTENT_DEFAULT);
  16751. this.presented = false;
  16752. this.onBackdropTap = () => {
  16753. this.dismiss(undefined, BACKDROP);
  16754. };
  16755. this.overlayIndex = undefined;
  16756. this.delegate = undefined;
  16757. this.hasController = false;
  16758. this.keyboardClose = true;
  16759. this.enterAnimation = undefined;
  16760. this.leaveAnimation = undefined;
  16761. this.message = undefined;
  16762. this.cssClass = undefined;
  16763. this.duration = 0;
  16764. this.backdropDismiss = false;
  16765. this.showBackdrop = true;
  16766. this.spinner = undefined;
  16767. this.translucent = false;
  16768. this.animated = true;
  16769. this.htmlAttributes = undefined;
  16770. this.isOpen = false;
  16771. this.trigger = undefined;
  16772. }
  16773. onIsOpenChange(newValue, oldValue) {
  16774. if (newValue === true && oldValue === false) {
  16775. this.present();
  16776. }
  16777. else if (newValue === false && oldValue === true) {
  16778. this.dismiss();
  16779. }
  16780. }
  16781. triggerChanged() {
  16782. const { trigger, el, triggerController } = this;
  16783. if (trigger) {
  16784. triggerController.addClickListener(el, trigger);
  16785. }
  16786. }
  16787. connectedCallback() {
  16788. prepareOverlay(this.el);
  16789. this.triggerChanged();
  16790. }
  16791. componentWillLoad() {
  16792. var _a;
  16793. if (this.spinner === undefined) {
  16794. const mode = getIonMode$1(this);
  16795. this.spinner = config.get('loadingSpinner', config.get('spinner', mode === 'ios' ? 'lines' : 'crescent'));
  16796. }
  16797. if (!((_a = this.htmlAttributes) === null || _a === void 0 ? void 0 : _a.id)) {
  16798. setOverlayId(this.el);
  16799. }
  16800. }
  16801. componentDidLoad() {
  16802. /**
  16803. * If loading indicator was rendered with isOpen="true"
  16804. * then we should open loading indicator immediately.
  16805. */
  16806. if (this.isOpen === true) {
  16807. raf(() => this.present());
  16808. }
  16809. /**
  16810. * When binding values in frameworks such as Angular
  16811. * it is possible for the value to be set after the Web Component
  16812. * initializes but before the value watcher is set up in Stencil.
  16813. * As a result, the watcher callback may not be fired.
  16814. * We work around this by manually calling the watcher
  16815. * callback when the component has loaded and the watcher
  16816. * is configured.
  16817. */
  16818. this.triggerChanged();
  16819. }
  16820. disconnectedCallback() {
  16821. this.triggerController.removeClickListener();
  16822. }
  16823. /**
  16824. * Present the loading overlay after it has been created.
  16825. */
  16826. async present() {
  16827. const unlock = await this.lockController.lock();
  16828. await this.delegateController.attachViewToDom();
  16829. await present(this, 'loadingEnter', iosEnterAnimation$4, mdEnterAnimation$3);
  16830. if (this.duration > 0) {
  16831. this.durationTimeout = setTimeout(() => this.dismiss(), this.duration + 10);
  16832. }
  16833. unlock();
  16834. }
  16835. /**
  16836. * Dismiss the loading overlay after it has been presented.
  16837. *
  16838. * @param data Any data to emit in the dismiss events.
  16839. * @param role The role of the element that is dismissing the loading.
  16840. * This can be useful in a button handler for determining which button was
  16841. * clicked to dismiss the loading.
  16842. * Some examples include: ``"cancel"`, `"destructive"`, "selected"`, and `"backdrop"`.
  16843. *
  16844. * This is a no-op if the overlay has not been presented yet. If you want
  16845. * to remove an overlay from the DOM that was never presented, use the
  16846. * [remove](https://developer.mozilla.org/en-US/docs/Web/API/Element/remove) method.
  16847. */
  16848. async dismiss(data, role) {
  16849. const unlock = await this.lockController.lock();
  16850. if (this.durationTimeout) {
  16851. clearTimeout(this.durationTimeout);
  16852. }
  16853. const dismissed = await dismiss(this, data, role, 'loadingLeave', iosLeaveAnimation$4, mdLeaveAnimation$3);
  16854. if (dismissed) {
  16855. this.delegateController.removeViewFromDom();
  16856. }
  16857. unlock();
  16858. return dismissed;
  16859. }
  16860. /**
  16861. * Returns a promise that resolves when the loading did dismiss.
  16862. */
  16863. onDidDismiss() {
  16864. return eventMethod(this.el, 'ionLoadingDidDismiss');
  16865. }
  16866. /**
  16867. * Returns a promise that resolves when the loading will dismiss.
  16868. */
  16869. onWillDismiss() {
  16870. return eventMethod(this.el, 'ionLoadingWillDismiss');
  16871. }
  16872. renderLoadingMessage(msgId) {
  16873. const { customHTMLEnabled, message } = this;
  16874. if (customHTMLEnabled) {
  16875. return hAsync("div", { class: "loading-content", id: msgId, innerHTML: sanitizeDOMString(message) });
  16876. }
  16877. return (hAsync("div", { class: "loading-content", id: msgId }, message));
  16878. }
  16879. render() {
  16880. const { message, spinner, htmlAttributes, overlayIndex } = this;
  16881. const mode = getIonMode$1(this);
  16882. const msgId = `loading-${overlayIndex}-msg`;
  16883. /**
  16884. * If the message is defined, use that as the label.
  16885. * Otherwise, don't set aria-labelledby.
  16886. */
  16887. const ariaLabelledBy = message !== undefined ? msgId : null;
  16888. return (hAsync(Host, Object.assign({ key: 'd6066c8b56b1fe4b597a243a7dab191ef0d21286', role: "dialog", "aria-modal": "true", "aria-labelledby": ariaLabelledBy, tabindex: "-1" }, htmlAttributes, { style: {
  16889. zIndex: `${40000 + this.overlayIndex}`,
  16890. }, onIonBackdropTap: this.onBackdropTap, class: Object.assign(Object.assign({}, getClassMap(this.cssClass)), { [mode]: true, 'overlay-hidden': true, 'loading-translucent': this.translucent }) }), hAsync("ion-backdrop", { key: '2431eda00a2a3f510f5dfc39b7c7d47c056dfa3d', visible: this.showBackdrop, tappable: this.backdropDismiss }), hAsync("div", { key: 'cf210aaf5e754e4eccdb49cf7ead4647b3f9b2d1', tabindex: "0", "aria-hidden": "true" }), hAsync("div", { key: 'fa9375143d391656d70e181d25b952c77c2fc6ec', class: "loading-wrapper ion-overlay-wrapper" }, spinner && (hAsync("div", { key: '8e4a4ed994f7f62df86b03696ac95162df41f52d', class: "loading-spinner" }, hAsync("ion-spinner", { key: 'e5b323c272d365853ba92bd211e390b4fd4751d2', name: spinner, "aria-hidden": "true" }))), message !== undefined && this.renderLoadingMessage(msgId)), hAsync("div", { key: 'cae35ec8c34800477bff3ebcec8010e632158233', tabindex: "0", "aria-hidden": "true" })));
  16891. }
  16892. get el() { return getElement(this); }
  16893. static get watchers() { return {
  16894. "isOpen": ["onIsOpenChange"],
  16895. "trigger": ["triggerChanged"]
  16896. }; }
  16897. static get style() { return {
  16898. ios: IonLoadingIosStyle0,
  16899. md: IonLoadingMdStyle0
  16900. }; }
  16901. static get cmpMeta() { return {
  16902. "$flags$": 34,
  16903. "$tagName$": "ion-loading",
  16904. "$members$": {
  16905. "overlayIndex": [2, "overlay-index"],
  16906. "delegate": [16],
  16907. "hasController": [4, "has-controller"],
  16908. "keyboardClose": [4, "keyboard-close"],
  16909. "enterAnimation": [16],
  16910. "leaveAnimation": [16],
  16911. "message": [1],
  16912. "cssClass": [1, "css-class"],
  16913. "duration": [2],
  16914. "backdropDismiss": [4, "backdrop-dismiss"],
  16915. "showBackdrop": [4, "show-backdrop"],
  16916. "spinner": [1025],
  16917. "translucent": [4],
  16918. "animated": [4],
  16919. "htmlAttributes": [16],
  16920. "isOpen": [4, "is-open"],
  16921. "trigger": [1],
  16922. "present": [64],
  16923. "dismiss": [64],
  16924. "onDidDismiss": [64],
  16925. "onWillDismiss": [64]
  16926. },
  16927. "$listeners$": undefined,
  16928. "$lazyBundleId$": "-",
  16929. "$attrsToReflect$": []
  16930. }; }
  16931. }
  16932. /**
  16933. * Based on:
  16934. * https://stackoverflow.com/questions/7348009/y-coordinate-for-a-given-x-cubic-bezier
  16935. * https://math.stackexchange.com/questions/26846/is-there-an-explicit-form-for-cubic-b%C3%A9zier-curves
  16936. */
  16937. /**
  16938. * EXPERIMENTAL
  16939. * Given a cubic-bezier curve, get the x value (time) given
  16940. * the y value (progression).
  16941. * Ex: cubic-bezier(0.32, 0.72, 0, 1);
  16942. * P0: (0, 0)
  16943. * P1: (0.32, 0.72)
  16944. * P2: (0, 1)
  16945. * P3: (1, 1)
  16946. *
  16947. * If you give a cubic bezier curve that never reaches the
  16948. * provided progression, this function will return an empty array.
  16949. */
  16950. const getTimeGivenProgression = (p0, p1, p2, p3, progression) => {
  16951. return solveCubicBezier(p0[1], p1[1], p2[1], p3[1], progression).map((tValue) => {
  16952. return solveCubicParametricEquation(p0[0], p1[0], p2[0], p3[0], tValue);
  16953. });
  16954. };
  16955. /**
  16956. * Solve a cubic equation in one dimension (time)
  16957. */
  16958. const solveCubicParametricEquation = (p0, p1, p2, p3, t) => {
  16959. const partA = 3 * p1 * Math.pow(t - 1, 2);
  16960. const partB = -3 * p2 * t + 3 * p2 + p3 * t;
  16961. const partC = p0 * Math.pow(t - 1, 3);
  16962. return t * (partA + t * partB) - partC;
  16963. };
  16964. /**
  16965. * Find the `t` value for a cubic bezier using Cardano's formula
  16966. */
  16967. const solveCubicBezier = (p0, p1, p2, p3, refPoint) => {
  16968. p0 -= refPoint;
  16969. p1 -= refPoint;
  16970. p2 -= refPoint;
  16971. p3 -= refPoint;
  16972. const roots = solveCubicEquation(p3 - 3 * p2 + 3 * p1 - p0, 3 * p2 - 6 * p1 + 3 * p0, 3 * p1 - 3 * p0, p0);
  16973. return roots.filter((root) => root >= 0 && root <= 1);
  16974. };
  16975. const solveQuadraticEquation = (a, b, c) => {
  16976. const discriminant = b * b - 4 * a * c;
  16977. if (discriminant < 0) {
  16978. return [];
  16979. }
  16980. else {
  16981. return [(-b + Math.sqrt(discriminant)) / (2 * a), (-b - Math.sqrt(discriminant)) / (2 * a)];
  16982. }
  16983. };
  16984. const solveCubicEquation = (a, b, c, d) => {
  16985. if (a === 0) {
  16986. return solveQuadraticEquation(b, c, d);
  16987. }
  16988. b /= a;
  16989. c /= a;
  16990. d /= a;
  16991. const p = (3 * c - b * b) / 3;
  16992. const q = (2 * b * b * b - 9 * b * c + 27 * d) / 27;
  16993. if (p === 0) {
  16994. return [Math.pow(-q, 1 / 3)];
  16995. }
  16996. else if (q === 0) {
  16997. return [Math.sqrt(-p), -Math.sqrt(-p)];
  16998. }
  16999. const discriminant = Math.pow(q / 2, 2) + Math.pow(p / 3, 3);
  17000. if (discriminant === 0) {
  17001. return [Math.pow(q / 2, 1 / 2) - b / 3];
  17002. }
  17003. else if (discriminant > 0) {
  17004. return [
  17005. Math.pow(-(q / 2) + Math.sqrt(discriminant), 1 / 3) - Math.pow(q / 2 + Math.sqrt(discriminant), 1 / 3) - b / 3,
  17006. ];
  17007. }
  17008. const r = Math.sqrt(Math.pow(-(p / 3), 3));
  17009. const phi = Math.acos(-(q / (2 * Math.sqrt(Math.pow(-(p / 3), 3)))));
  17010. const s = 2 * Math.pow(r, 1 / 3);
  17011. return [
  17012. s * Math.cos(phi / 3) - b / 3,
  17013. s * Math.cos((phi + 2 * Math.PI) / 3) - b / 3,
  17014. s * Math.cos((phi + 4 * Math.PI) / 3) - b / 3,
  17015. ];
  17016. };
  17017. /**
  17018. * baseAnimation
  17019. * Base class which is extended by the various types. Each
  17020. * type will provide their own animations for open and close
  17021. * and registers itself with Menu.
  17022. */
  17023. const baseAnimation = (isIos) => {
  17024. // https://material.io/guidelines/motion/movement.html#movement-movement-in-out-of-screen-bounds
  17025. // https://material.io/guidelines/motion/duration-easing.html#duration-easing-natural-easing-curves
  17026. /**
  17027. * "Apply the sharp curve to items temporarily leaving the screen that may return
  17028. * from the same exit point. When they return, use the deceleration curve. On mobile,
  17029. * this transition typically occurs over 300ms" -- MD Motion Guide
  17030. */
  17031. return createAnimation().duration(isIos ? 400 : 300);
  17032. };
  17033. /**
  17034. * Menu Overlay Type
  17035. * The menu slides over the content. The content
  17036. * itself, which is under the menu, does not move.
  17037. */
  17038. const menuOverlayAnimation = (menu) => {
  17039. let closedX;
  17040. let openedX;
  17041. const width = menu.width + 8;
  17042. const menuAnimation = createAnimation();
  17043. const backdropAnimation = createAnimation();
  17044. if (menu.isEndSide) {
  17045. // right side
  17046. closedX = width + 'px';
  17047. openedX = '0px';
  17048. }
  17049. else {
  17050. // left side
  17051. closedX = -width + 'px';
  17052. openedX = '0px';
  17053. }
  17054. menuAnimation.addElement(menu.menuInnerEl).fromTo('transform', `translateX(${closedX})`, `translateX(${openedX})`);
  17055. const mode = getIonMode$1(menu);
  17056. const isIos = mode === 'ios';
  17057. const opacity = isIos ? 0.2 : 0.25;
  17058. backdropAnimation.addElement(menu.backdropEl).fromTo('opacity', 0.01, opacity);
  17059. return baseAnimation(isIos).addAnimation([menuAnimation, backdropAnimation]);
  17060. };
  17061. /**
  17062. * Menu Push Type
  17063. * The content slides over to reveal the menu underneath.
  17064. * The menu itself also slides over to reveal its bad self.
  17065. */
  17066. const menuPushAnimation = (menu) => {
  17067. let contentOpenedX;
  17068. let menuClosedX;
  17069. const mode = getIonMode$1(menu);
  17070. const width = menu.width;
  17071. if (menu.isEndSide) {
  17072. contentOpenedX = -width + 'px';
  17073. menuClosedX = width + 'px';
  17074. }
  17075. else {
  17076. contentOpenedX = width + 'px';
  17077. menuClosedX = -width + 'px';
  17078. }
  17079. const menuAnimation = createAnimation()
  17080. .addElement(menu.menuInnerEl)
  17081. .fromTo('transform', `translateX(${menuClosedX})`, 'translateX(0px)');
  17082. const contentAnimation = createAnimation()
  17083. .addElement(menu.contentEl)
  17084. .fromTo('transform', 'translateX(0px)', `translateX(${contentOpenedX})`);
  17085. const backdropAnimation = createAnimation().addElement(menu.backdropEl).fromTo('opacity', 0.01, 0.32);
  17086. return baseAnimation(mode === 'ios').addAnimation([menuAnimation, contentAnimation, backdropAnimation]);
  17087. };
  17088. /**
  17089. * Menu Reveal Type
  17090. * The content slides over to reveal the menu underneath.
  17091. * The menu itself, which is under the content, does not move.
  17092. */
  17093. const menuRevealAnimation = (menu) => {
  17094. const mode = getIonMode$1(menu);
  17095. const openedX = menu.width * (menu.isEndSide ? -1 : 1) + 'px';
  17096. const contentOpen = createAnimation()
  17097. .addElement(menu.contentEl) // REVIEW
  17098. .fromTo('transform', 'translateX(0px)', `translateX(${openedX})`);
  17099. return baseAnimation(mode === 'ios').addAnimation(contentOpen);
  17100. };
  17101. const createMenuController = () => {
  17102. const menuAnimations = new Map();
  17103. const menus = [];
  17104. const open = async (menu) => {
  17105. const menuEl = await get(menu, true);
  17106. if (menuEl) {
  17107. return menuEl.open();
  17108. }
  17109. return false;
  17110. };
  17111. const close = async (menu) => {
  17112. const menuEl = await (menu !== undefined ? get(menu, true) : getOpen());
  17113. if (menuEl !== undefined) {
  17114. return menuEl.close();
  17115. }
  17116. return false;
  17117. };
  17118. const toggle = async (menu) => {
  17119. const menuEl = await get(menu, true);
  17120. if (menuEl) {
  17121. return menuEl.toggle();
  17122. }
  17123. return false;
  17124. };
  17125. const enable = async (shouldEnable, menu) => {
  17126. const menuEl = await get(menu);
  17127. if (menuEl) {
  17128. menuEl.disabled = !shouldEnable;
  17129. }
  17130. return menuEl;
  17131. };
  17132. const swipeGesture = async (shouldEnable, menu) => {
  17133. const menuEl = await get(menu);
  17134. if (menuEl) {
  17135. menuEl.swipeGesture = shouldEnable;
  17136. }
  17137. return menuEl;
  17138. };
  17139. const isOpen = async (menu) => {
  17140. if (menu != null) {
  17141. const menuEl = await get(menu);
  17142. // eslint-disable-next-line @typescript-eslint/prefer-optional-chain
  17143. return menuEl !== undefined && menuEl.isOpen();
  17144. }
  17145. else {
  17146. const menuEl = await getOpen();
  17147. return menuEl !== undefined;
  17148. }
  17149. };
  17150. const isEnabled = async (menu) => {
  17151. const menuEl = await get(menu);
  17152. if (menuEl) {
  17153. return !menuEl.disabled;
  17154. }
  17155. return false;
  17156. };
  17157. /**
  17158. * Finds and returns the menu specified by "menu" if registered.
  17159. * @param menu - The side or ID of the desired menu
  17160. * @param logOnMultipleSideMenus - If true, this function will log a warning
  17161. * if "menu" is a side but multiple menus on the same side were found. Since this function
  17162. * is used in multiple places, we default this log to false so that the calling
  17163. * functions can choose whether or not it is appropriate to log this warning.
  17164. */
  17165. const get = async (menu, logOnMultipleSideMenus = false) => {
  17166. await waitUntilReady();
  17167. if (menu === 'start' || menu === 'end') {
  17168. // there could be more than one menu on the same side
  17169. // so first try to get the enabled one
  17170. const menuRefs = menus.filter((m) => m.side === menu && !m.disabled);
  17171. if (menuRefs.length >= 1) {
  17172. if (menuRefs.length > 1 && logOnMultipleSideMenus) {
  17173. printIonWarning(`menuController queried for a menu on the "${menu}" side, but ${menuRefs.length} menus were found. The first menu reference will be used. If this is not the behavior you want then pass the ID of the menu instead of its side.`, menuRefs.map((m) => m.el));
  17174. }
  17175. return menuRefs[0].el;
  17176. }
  17177. // didn't find a menu side that is enabled
  17178. // so try to get the first menu side found
  17179. const sideMenuRefs = menus.filter((m) => m.side === menu);
  17180. if (sideMenuRefs.length >= 1) {
  17181. if (sideMenuRefs.length > 1 && logOnMultipleSideMenus) {
  17182. printIonWarning(`menuController queried for a menu on the "${menu}" side, but ${sideMenuRefs.length} menus were found. The first menu reference will be used. If this is not the behavior you want then pass the ID of the menu instead of its side.`, sideMenuRefs.map((m) => m.el));
  17183. }
  17184. return sideMenuRefs[0].el;
  17185. }
  17186. }
  17187. else if (menu != null) {
  17188. // the menuId was not left or right
  17189. // so try to get the menu by its "id"
  17190. return find((m) => m.menuId === menu);
  17191. }
  17192. // return the first enabled menu
  17193. const menuEl = find((m) => !m.disabled);
  17194. if (menuEl) {
  17195. return menuEl;
  17196. }
  17197. // get the first menu in the array, if one exists
  17198. return menus.length > 0 ? menus[0].el : undefined;
  17199. };
  17200. /**
  17201. * Get the instance of the opened menu. Returns `null` if a menu is not found.
  17202. */
  17203. const getOpen = async () => {
  17204. await waitUntilReady();
  17205. return _getOpenSync();
  17206. };
  17207. /**
  17208. * Get all menu instances.
  17209. */
  17210. const getMenus = async () => {
  17211. await waitUntilReady();
  17212. return getMenusSync();
  17213. };
  17214. /**
  17215. * Get whether or not a menu is animating. Returns `true` if any
  17216. * menu is currently animating.
  17217. */
  17218. const isAnimating = async () => {
  17219. await waitUntilReady();
  17220. return isAnimatingSync();
  17221. };
  17222. const registerAnimation = (name, animation) => {
  17223. menuAnimations.set(name, animation);
  17224. };
  17225. const _register = (menu) => {
  17226. if (menus.indexOf(menu) < 0) {
  17227. menus.push(menu);
  17228. }
  17229. };
  17230. const _unregister = (menu) => {
  17231. const index = menus.indexOf(menu);
  17232. if (index > -1) {
  17233. menus.splice(index, 1);
  17234. }
  17235. };
  17236. const _setOpen = async (menu, shouldOpen, animated, role) => {
  17237. if (isAnimatingSync()) {
  17238. return false;
  17239. }
  17240. if (shouldOpen) {
  17241. const openedMenu = await getOpen();
  17242. if (openedMenu && menu.el !== openedMenu) {
  17243. await openedMenu.setOpen(false, false);
  17244. }
  17245. }
  17246. return menu._setOpen(shouldOpen, animated, role);
  17247. };
  17248. const _createAnimation = (type, menuCmp) => {
  17249. const animationBuilder = menuAnimations.get(type); // TODO(FW-2832): type
  17250. if (!animationBuilder) {
  17251. throw new Error('animation not registered');
  17252. }
  17253. const animation = animationBuilder(menuCmp);
  17254. return animation;
  17255. };
  17256. const _getOpenSync = () => {
  17257. return find((m) => m._isOpen);
  17258. };
  17259. const getMenusSync = () => {
  17260. return menus.map((menu) => menu.el);
  17261. };
  17262. const isAnimatingSync = () => {
  17263. return menus.some((menu) => menu.isAnimating);
  17264. };
  17265. const find = (predicate) => {
  17266. const instance = menus.find(predicate);
  17267. if (instance !== undefined) {
  17268. return instance.el;
  17269. }
  17270. return undefined;
  17271. };
  17272. const waitUntilReady = () => {
  17273. return Promise.all(Array.from(document.querySelectorAll('ion-menu')).map((menu) => new Promise((resolve) => componentOnReady(menu, resolve))));
  17274. };
  17275. registerAnimation('reveal', menuRevealAnimation);
  17276. registerAnimation('push', menuPushAnimation);
  17277. registerAnimation('overlay', menuOverlayAnimation);
  17278. doc === null || doc === void 0 ? void 0 : doc.addEventListener('ionBackButton', (ev) => {
  17279. const openMenu = _getOpenSync();
  17280. if (openMenu) {
  17281. ev.detail.register(MENU_BACK_BUTTON_PRIORITY, () => {
  17282. return openMenu.close();
  17283. });
  17284. }
  17285. });
  17286. return {
  17287. registerAnimation,
  17288. get,
  17289. getMenus,
  17290. getOpen,
  17291. isEnabled,
  17292. swipeGesture,
  17293. isAnimating,
  17294. isOpen,
  17295. enable,
  17296. toggle,
  17297. close,
  17298. open,
  17299. _getOpenSync,
  17300. _createAnimation,
  17301. _register,
  17302. _unregister,
  17303. _setOpen,
  17304. };
  17305. };
  17306. const menuController = /*@__PURE__*/ createMenuController();
  17307. const menuIosCss = ":host{--width:304px;--min-width:auto;--max-width:auto;--height:100%;--min-height:auto;--max-height:auto;--background:var(--ion-background-color, #fff);left:0;right:0;top:0;bottom:0;display:none;position:absolute;contain:strict}:host(.show-menu){display:block}.menu-inner{-webkit-transform:translateX(-9999px);transform:translateX(-9999px);display:-ms-flexbox;display:flex;position:absolute;-ms-flex-direction:column;flex-direction:column;-ms-flex-pack:justify;justify-content:space-between;width:var(--width);min-width:var(--min-width);max-width:var(--max-width);height:var(--height);min-height:var(--min-height);max-height:var(--max-height);background:var(--background);contain:strict}:host(.menu-side-start) .menu-inner{--ion-safe-area-right:0px;top:0;bottom:0}:host(.menu-side-start) .menu-inner{inset-inline-start:0;inset-inline-end:auto}:host-context([dir=rtl]):host(.menu-side-start) .menu-inner,:host-context([dir=rtl]).menu-side-start .menu-inner{--ion-safe-area-right:unset;--ion-safe-area-left:0px}@supports selector(:dir(rtl)){:host(.menu-side-start:dir(rtl)) .menu-inner{--ion-safe-area-right:unset;--ion-safe-area-left:0px}}:host(.menu-side-end) .menu-inner{--ion-safe-area-left:0px;top:0;bottom:0}:host(.menu-side-end) .menu-inner{inset-inline-start:auto;inset-inline-end:0}:host-context([dir=rtl]):host(.menu-side-end) .menu-inner,:host-context([dir=rtl]).menu-side-end .menu-inner{--ion-safe-area-left:unset;--ion-safe-area-right:0px}@supports selector(:dir(rtl)){:host(.menu-side-end:dir(rtl)) .menu-inner{--ion-safe-area-left:unset;--ion-safe-area-right:0px}}ion-backdrop{display:none;opacity:0.01;z-index:-1}@media (max-width: 340px){.menu-inner{--width:264px}}:host(.menu-type-reveal){z-index:0}:host(.menu-type-reveal.show-menu) .menu-inner{-webkit-transform:translate3d(0, 0, 0);transform:translate3d(0, 0, 0)}:host(.menu-type-overlay){z-index:1000}:host(.menu-type-overlay) .show-backdrop{display:block;cursor:pointer}:host(.menu-pane-visible){-ms-flex:0 1 auto;flex:0 1 auto;width:var(--side-width, var(--width));min-width:var(--side-min-width, var(--min-width));max-width:var(--side-max-width, var(--max-width))}:host(.menu-pane-visible.split-pane-side){left:0;right:0;top:0;bottom:0;position:relative;-webkit-box-shadow:none;box-shadow:none;z-index:0}:host(.menu-pane-visible.split-pane-side.menu-enabled){display:-ms-flexbox;display:flex;-ms-flex-negative:0;flex-shrink:0}:host(.menu-pane-visible.split-pane-side){-ms-flex-order:-1;order:-1}:host(.menu-pane-visible.split-pane-side[side=end]){-ms-flex-order:1;order:1}:host(.menu-pane-visible) .menu-inner{left:0;right:0;width:auto;-webkit-transform:none;transform:none;-webkit-box-shadow:none;box-shadow:none}:host(.menu-pane-visible) ion-backdrop{display:hidden !important}:host(.menu-pane-visible.split-pane-side){-webkit-border-start:0;border-inline-start:0;-webkit-border-end:var(--border);border-inline-end:var(--border);border-top:0;border-bottom:0;min-width:var(--side-min-width);max-width:var(--side-max-width)}:host(.menu-pane-visible.split-pane-side[side=end]){-webkit-border-start:var(--border);border-inline-start:var(--border);-webkit-border-end:0;border-inline-end:0;border-top:0;border-bottom:0;min-width:var(--side-min-width);max-width:var(--side-max-width)}:host(.menu-type-push){z-index:1000}:host(.menu-type-push) .show-backdrop{display:block}";
  17308. var IonMenuIosStyle0 = menuIosCss;
  17309. const menuMdCss = ":host{--width:304px;--min-width:auto;--max-width:auto;--height:100%;--min-height:auto;--max-height:auto;--background:var(--ion-background-color, #fff);left:0;right:0;top:0;bottom:0;display:none;position:absolute;contain:strict}:host(.show-menu){display:block}.menu-inner{-webkit-transform:translateX(-9999px);transform:translateX(-9999px);display:-ms-flexbox;display:flex;position:absolute;-ms-flex-direction:column;flex-direction:column;-ms-flex-pack:justify;justify-content:space-between;width:var(--width);min-width:var(--min-width);max-width:var(--max-width);height:var(--height);min-height:var(--min-height);max-height:var(--max-height);background:var(--background);contain:strict}:host(.menu-side-start) .menu-inner{--ion-safe-area-right:0px;top:0;bottom:0}:host(.menu-side-start) .menu-inner{inset-inline-start:0;inset-inline-end:auto}:host-context([dir=rtl]):host(.menu-side-start) .menu-inner,:host-context([dir=rtl]).menu-side-start .menu-inner{--ion-safe-area-right:unset;--ion-safe-area-left:0px}@supports selector(:dir(rtl)){:host(.menu-side-start:dir(rtl)) .menu-inner{--ion-safe-area-right:unset;--ion-safe-area-left:0px}}:host(.menu-side-end) .menu-inner{--ion-safe-area-left:0px;top:0;bottom:0}:host(.menu-side-end) .menu-inner{inset-inline-start:auto;inset-inline-end:0}:host-context([dir=rtl]):host(.menu-side-end) .menu-inner,:host-context([dir=rtl]).menu-side-end .menu-inner{--ion-safe-area-left:unset;--ion-safe-area-right:0px}@supports selector(:dir(rtl)){:host(.menu-side-end:dir(rtl)) .menu-inner{--ion-safe-area-left:unset;--ion-safe-area-right:0px}}ion-backdrop{display:none;opacity:0.01;z-index:-1}@media (max-width: 340px){.menu-inner{--width:264px}}:host(.menu-type-reveal){z-index:0}:host(.menu-type-reveal.show-menu) .menu-inner{-webkit-transform:translate3d(0, 0, 0);transform:translate3d(0, 0, 0)}:host(.menu-type-overlay){z-index:1000}:host(.menu-type-overlay) .show-backdrop{display:block;cursor:pointer}:host(.menu-pane-visible){-ms-flex:0 1 auto;flex:0 1 auto;width:var(--side-width, var(--width));min-width:var(--side-min-width, var(--min-width));max-width:var(--side-max-width, var(--max-width))}:host(.menu-pane-visible.split-pane-side){left:0;right:0;top:0;bottom:0;position:relative;-webkit-box-shadow:none;box-shadow:none;z-index:0}:host(.menu-pane-visible.split-pane-side.menu-enabled){display:-ms-flexbox;display:flex;-ms-flex-negative:0;flex-shrink:0}:host(.menu-pane-visible.split-pane-side){-ms-flex-order:-1;order:-1}:host(.menu-pane-visible.split-pane-side[side=end]){-ms-flex-order:1;order:1}:host(.menu-pane-visible) .menu-inner{left:0;right:0;width:auto;-webkit-transform:none;transform:none;-webkit-box-shadow:none;box-shadow:none}:host(.menu-pane-visible) ion-backdrop{display:hidden !important}:host(.menu-pane-visible.split-pane-side){-webkit-border-start:0;border-inline-start:0;-webkit-border-end:var(--border);border-inline-end:var(--border);border-top:0;border-bottom:0;min-width:var(--side-min-width);max-width:var(--side-max-width)}:host(.menu-pane-visible.split-pane-side[side=end]){-webkit-border-start:var(--border);border-inline-start:var(--border);-webkit-border-end:0;border-inline-end:0;border-top:0;border-bottom:0;min-width:var(--side-min-width);max-width:var(--side-max-width)}:host(.menu-type-overlay) .menu-inner{-webkit-box-shadow:4px 0px 16px rgba(0, 0, 0, 0.18);box-shadow:4px 0px 16px rgba(0, 0, 0, 0.18)}";
  17310. var IonMenuMdStyle0 = menuMdCss;
  17311. const iosEasing = 'cubic-bezier(0.32,0.72,0,1)';
  17312. const mdEasing = 'cubic-bezier(0.0,0.0,0.2,1)';
  17313. const iosEasingReverse = 'cubic-bezier(1, 0, 0.68, 0.28)';
  17314. const mdEasingReverse = 'cubic-bezier(0.4, 0, 0.6, 1)';
  17315. /**
  17316. * @part container - The container for the menu content.
  17317. * @part backdrop - The backdrop that appears over the main content when the menu is open.
  17318. */
  17319. class Menu {
  17320. constructor(hostRef) {
  17321. registerInstance(this, hostRef);
  17322. this.ionWillOpen = createEvent(this, "ionWillOpen", 7);
  17323. this.ionWillClose = createEvent(this, "ionWillClose", 7);
  17324. this.ionDidOpen = createEvent(this, "ionDidOpen", 7);
  17325. this.ionDidClose = createEvent(this, "ionDidClose", 7);
  17326. this.ionMenuChange = createEvent(this, "ionMenuChange", 7);
  17327. this.lastOnEnd = 0;
  17328. this.blocker = GESTURE_CONTROLLER.createBlocker({ disableScroll: true });
  17329. this.didLoad = false;
  17330. /**
  17331. * Flag used to determine if an open/close
  17332. * operation was cancelled. For example, if
  17333. * an app calls "menu.open" then disables the menu
  17334. * part way through the animation, then this would
  17335. * be considered a cancelled operation.
  17336. */
  17337. this.operationCancelled = false;
  17338. this.isAnimating = false;
  17339. this._isOpen = false;
  17340. this.inheritedAttributes = {};
  17341. this.handleFocus = (ev) => {
  17342. /**
  17343. * Overlays have their own focus trapping listener
  17344. * so we do not want the two listeners to conflict
  17345. * with each other. If the top-most overlay that is
  17346. * open does not contain this ion-menu, then ion-menu's
  17347. * focus trapping should not run.
  17348. */
  17349. const lastOverlay = getPresentedOverlay(document);
  17350. if (lastOverlay && !lastOverlay.contains(this.el)) {
  17351. return;
  17352. }
  17353. this.trapKeyboardFocus(ev, document);
  17354. };
  17355. this.isPaneVisible = false;
  17356. this.isEndSide = false;
  17357. this.contentId = undefined;
  17358. this.menuId = undefined;
  17359. this.type = undefined;
  17360. this.disabled = false;
  17361. this.side = 'start';
  17362. this.swipeGesture = true;
  17363. this.maxEdgeStart = 50;
  17364. }
  17365. typeChanged(type, oldType) {
  17366. const contentEl = this.contentEl;
  17367. if (contentEl) {
  17368. if (oldType !== undefined) {
  17369. contentEl.classList.remove(`menu-content-${oldType}`);
  17370. }
  17371. contentEl.classList.add(`menu-content-${type}`);
  17372. contentEl.removeAttribute('style');
  17373. }
  17374. if (this.menuInnerEl) {
  17375. // Remove effects of previous animations
  17376. this.menuInnerEl.removeAttribute('style');
  17377. }
  17378. this.animation = undefined;
  17379. }
  17380. disabledChanged() {
  17381. this.updateState();
  17382. this.ionMenuChange.emit({
  17383. disabled: this.disabled,
  17384. open: this._isOpen,
  17385. });
  17386. }
  17387. sideChanged() {
  17388. this.isEndSide = isEndSide(this.side);
  17389. /**
  17390. * Menu direction animation is calculated based on the document direction.
  17391. * If the document direction changes, we need to create a new animation.
  17392. */
  17393. this.animation = undefined;
  17394. }
  17395. swipeGestureChanged() {
  17396. this.updateState();
  17397. }
  17398. async connectedCallback() {
  17399. // TODO: connectedCallback is fired in CE build
  17400. // before WC is defined. This needs to be fixed in Stencil.
  17401. if (typeof customElements !== 'undefined' && customElements != null) {
  17402. await customElements.whenDefined('ion-menu');
  17403. }
  17404. if (this.type === undefined) {
  17405. this.type = config.get('menuType', 'overlay');
  17406. }
  17407. {
  17408. return;
  17409. }
  17410. }
  17411. componentWillLoad() {
  17412. this.inheritedAttributes = inheritAriaAttributes(this.el);
  17413. }
  17414. async componentDidLoad() {
  17415. this.didLoad = true;
  17416. /**
  17417. * A menu inside of a split pane is assumed
  17418. * to be a side pane.
  17419. *
  17420. * When the menu is loaded it needs to
  17421. * see if it should be considered visible inside
  17422. * of the split pane. If the split pane is
  17423. * hidden then the menu should be too.
  17424. */
  17425. const splitPane = this.el.closest('ion-split-pane');
  17426. if (splitPane !== null) {
  17427. this.isPaneVisible = await splitPane.isVisible();
  17428. }
  17429. this.menuChanged();
  17430. this.updateState();
  17431. }
  17432. menuChanged() {
  17433. /**
  17434. * Inform dependent components such as ion-menu-button
  17435. * that the menu is ready. Note that we only want to do this
  17436. * once the menu has been rendered which is why we check for didLoad.
  17437. */
  17438. if (this.didLoad) {
  17439. this.ionMenuChange.emit({ disabled: this.disabled, open: this._isOpen });
  17440. }
  17441. }
  17442. async disconnectedCallback() {
  17443. /**
  17444. * The menu should be closed when it is
  17445. * unmounted from the DOM.
  17446. * This is an async call, so we need to wait for
  17447. * this to finish otherwise contentEl
  17448. * will not have MENU_CONTENT_OPEN removed.
  17449. */
  17450. await this.close(false);
  17451. this.blocker.destroy();
  17452. menuController._unregister(this);
  17453. if (this.animation) {
  17454. this.animation.destroy();
  17455. }
  17456. if (this.gesture) {
  17457. this.gesture.destroy();
  17458. this.gesture = undefined;
  17459. }
  17460. this.animation = undefined;
  17461. this.contentEl = undefined;
  17462. }
  17463. onSplitPaneChanged(ev) {
  17464. const closestSplitPane = this.el.closest('ion-split-pane');
  17465. if (closestSplitPane !== null && closestSplitPane === ev.target) {
  17466. this.isPaneVisible = ev.detail.visible;
  17467. this.updateState();
  17468. }
  17469. }
  17470. onBackdropClick(ev) {
  17471. // TODO(FW-2832): type (CustomEvent triggers errors which should be sorted)
  17472. if (this._isOpen && this.lastOnEnd < ev.timeStamp - 100) {
  17473. const shouldClose = ev.composedPath ? !ev.composedPath().includes(this.menuInnerEl) : false;
  17474. if (shouldClose) {
  17475. ev.preventDefault();
  17476. ev.stopPropagation();
  17477. this.close(undefined, BACKDROP);
  17478. }
  17479. }
  17480. }
  17481. onKeydown(ev) {
  17482. if (ev.key === 'Escape') {
  17483. this.close(undefined, BACKDROP);
  17484. }
  17485. }
  17486. /**
  17487. * Returns `true` is the menu is open.
  17488. */
  17489. isOpen() {
  17490. return Promise.resolve(this._isOpen);
  17491. }
  17492. /**
  17493. * Returns `true` is the menu is active.
  17494. *
  17495. * A menu is active when it can be opened or closed, meaning it's enabled
  17496. * and it's not part of a `ion-split-pane`.
  17497. */
  17498. isActive() {
  17499. return Promise.resolve(this._isActive());
  17500. }
  17501. /**
  17502. * Opens the menu. If the menu is already open or it can't be opened,
  17503. * it returns `false`.
  17504. */
  17505. open(animated = true) {
  17506. return this.setOpen(true, animated);
  17507. }
  17508. /**
  17509. * Closes the menu. If the menu is already closed or it can't be closed,
  17510. * it returns `false`.
  17511. */
  17512. close(animated = true, role) {
  17513. return this.setOpen(false, animated, role);
  17514. }
  17515. /**
  17516. * Toggles the menu. If the menu is already open, it will try to close, otherwise it will try to open it.
  17517. * If the operation can't be completed successfully, it returns `false`.
  17518. */
  17519. toggle(animated = true) {
  17520. return this.setOpen(!this._isOpen, animated);
  17521. }
  17522. /**
  17523. * Opens or closes the button.
  17524. * If the operation can't be completed successfully, it returns `false`.
  17525. */
  17526. setOpen(shouldOpen, animated = true, role) {
  17527. return menuController._setOpen(this, shouldOpen, animated, role);
  17528. }
  17529. trapKeyboardFocus(ev, doc) {
  17530. const target = ev.target;
  17531. if (!target) {
  17532. return;
  17533. }
  17534. /**
  17535. * If the target is inside the menu contents, let the browser
  17536. * focus as normal and keep a log of the last focused element.
  17537. */
  17538. if (this.el.contains(target)) {
  17539. this.lastFocus = target;
  17540. }
  17541. else {
  17542. /**
  17543. * Otherwise, we are about to have focus go out of the menu.
  17544. * Wrap the focus to either the first or last element.
  17545. */
  17546. const { el } = this;
  17547. /**
  17548. * Once we call `focusFirstDescendant`, another focus event
  17549. * will fire, which will cause `lastFocus` to be updated
  17550. * before we can run the code after that. We cache the value
  17551. * here to avoid that.
  17552. */
  17553. focusFirstDescendant(el);
  17554. /**
  17555. * If the cached last focused element is the same as the now-
  17556. * active element, that means the user was on the first element
  17557. * already and pressed Shift + Tab, so we need to wrap to the
  17558. * last descendant.
  17559. */
  17560. if (this.lastFocus === doc.activeElement) {
  17561. focusLastDescendant(el);
  17562. }
  17563. }
  17564. }
  17565. async _setOpen(shouldOpen, animated = true, role) {
  17566. // If the menu is disabled or it is currently being animated, let's do nothing
  17567. if (!this._isActive() || this.isAnimating || shouldOpen === this._isOpen) {
  17568. return false;
  17569. }
  17570. this.beforeAnimation(shouldOpen, role);
  17571. await this.loadAnimation();
  17572. await this.startAnimation(shouldOpen, animated);
  17573. /**
  17574. * If the animation was cancelled then
  17575. * return false because the operation
  17576. * did not succeed.
  17577. */
  17578. if (this.operationCancelled) {
  17579. this.operationCancelled = false;
  17580. return false;
  17581. }
  17582. this.afterAnimation(shouldOpen, role);
  17583. return true;
  17584. }
  17585. async loadAnimation() {
  17586. // Menu swipe animation takes the menu's inner width as parameter,
  17587. // If `offsetWidth` changes, we need to create a new animation.
  17588. const width = this.menuInnerEl.offsetWidth;
  17589. /**
  17590. * Menu direction animation is calculated based on the document direction.
  17591. * If the document direction changes, we need to create a new animation.
  17592. */
  17593. const isEndSide$1 = isEndSide(this.side);
  17594. if (width === this.width && this.animation !== undefined && isEndSide$1 === this.isEndSide) {
  17595. return;
  17596. }
  17597. this.width = width;
  17598. this.isEndSide = isEndSide$1;
  17599. // Destroy existing animation
  17600. if (this.animation) {
  17601. this.animation.destroy();
  17602. this.animation = undefined;
  17603. }
  17604. // Create new animation
  17605. const animation = (this.animation = await menuController._createAnimation(this.type, this));
  17606. if (!config.getBoolean('animated', true)) {
  17607. animation.duration(0);
  17608. }
  17609. animation.fill('both');
  17610. }
  17611. async startAnimation(shouldOpen, animated) {
  17612. const isReversed = !shouldOpen;
  17613. const mode = getIonMode$1(this);
  17614. const easing = mode === 'ios' ? iosEasing : mdEasing;
  17615. const easingReverse = mode === 'ios' ? iosEasingReverse : mdEasingReverse;
  17616. const ani = this.animation
  17617. .direction(isReversed ? 'reverse' : 'normal')
  17618. .easing(isReversed ? easingReverse : easing);
  17619. if (animated) {
  17620. await ani.play();
  17621. }
  17622. else {
  17623. ani.play({ sync: true });
  17624. }
  17625. /**
  17626. * We run this after the play invocation
  17627. * instead of using ani.onFinish so that
  17628. * multiple onFinish callbacks do not get
  17629. * run if an animation is played, stopped,
  17630. * and then played again.
  17631. */
  17632. if (ani.getDirection() === 'reverse') {
  17633. ani.direction('normal');
  17634. }
  17635. }
  17636. _isActive() {
  17637. return !this.disabled && !this.isPaneVisible;
  17638. }
  17639. canSwipe() {
  17640. return this.swipeGesture && !this.isAnimating && this._isActive();
  17641. }
  17642. canStart(detail) {
  17643. // Do not allow swipe gesture if a modal is open
  17644. const isModalPresented = !!document.querySelector('ion-modal.show-modal');
  17645. if (isModalPresented || !this.canSwipe()) {
  17646. return false;
  17647. }
  17648. if (this._isOpen) {
  17649. return true;
  17650. }
  17651. else if (menuController._getOpenSync()) {
  17652. return false;
  17653. }
  17654. return checkEdgeSide(window, detail.currentX, this.isEndSide, this.maxEdgeStart);
  17655. }
  17656. onWillStart() {
  17657. this.beforeAnimation(!this._isOpen, GESTURE);
  17658. return this.loadAnimation();
  17659. }
  17660. onStart() {
  17661. if (!this.isAnimating || !this.animation) {
  17662. assert(false, 'isAnimating has to be true');
  17663. return;
  17664. }
  17665. // the cloned animation should not use an easing curve during seek
  17666. this.animation.progressStart(true, this._isOpen ? 1 : 0);
  17667. }
  17668. onMove(detail) {
  17669. if (!this.isAnimating || !this.animation) {
  17670. assert(false, 'isAnimating has to be true');
  17671. return;
  17672. }
  17673. const delta = computeDelta(detail.deltaX, this._isOpen, this.isEndSide);
  17674. const stepValue = delta / this.width;
  17675. this.animation.progressStep(this._isOpen ? 1 - stepValue : stepValue);
  17676. }
  17677. onEnd(detail) {
  17678. if (!this.isAnimating || !this.animation) {
  17679. assert(false, 'isAnimating has to be true');
  17680. return;
  17681. }
  17682. const isOpen = this._isOpen;
  17683. const isEndSide = this.isEndSide;
  17684. const delta = computeDelta(detail.deltaX, isOpen, isEndSide);
  17685. const width = this.width;
  17686. const stepValue = delta / width;
  17687. const velocity = detail.velocityX;
  17688. const z = width / 2.0;
  17689. const shouldCompleteRight = velocity >= 0 && (velocity > 0.2 || detail.deltaX > z);
  17690. const shouldCompleteLeft = velocity <= 0 && (velocity < -0.2 || detail.deltaX < -z);
  17691. const shouldComplete = isOpen
  17692. ? isEndSide
  17693. ? shouldCompleteRight
  17694. : shouldCompleteLeft
  17695. : isEndSide
  17696. ? shouldCompleteLeft
  17697. : shouldCompleteRight;
  17698. let shouldOpen = !isOpen && shouldComplete;
  17699. if (isOpen && !shouldComplete) {
  17700. shouldOpen = true;
  17701. }
  17702. this.lastOnEnd = detail.currentTime;
  17703. // Account for rounding errors in JS
  17704. let newStepValue = shouldComplete ? 0.001 : -0.001;
  17705. /**
  17706. * stepValue can sometimes return a negative
  17707. * value, but you can't have a negative time value
  17708. * for the cubic bezier curve (at least with web animations)
  17709. */
  17710. const adjustedStepValue = stepValue < 0 ? 0.01 : stepValue;
  17711. /**
  17712. * Animation will be reversed here, so need to
  17713. * reverse the easing curve as well
  17714. *
  17715. * Additionally, we need to account for the time relative
  17716. * to the new easing curve, as `stepValue` is going to be given
  17717. * in terms of a linear curve.
  17718. */
  17719. newStepValue +=
  17720. getTimeGivenProgression([0, 0], [0.4, 0], [0.6, 1], [1, 1], clamp(0, adjustedStepValue, 0.9999))[0] || 0;
  17721. const playTo = this._isOpen ? !shouldComplete : shouldComplete;
  17722. this.animation
  17723. .easing('cubic-bezier(0.4, 0.0, 0.6, 1)')
  17724. .onFinish(() => this.afterAnimation(shouldOpen, GESTURE), { oneTimeCallback: true })
  17725. .progressEnd(playTo ? 1 : 0, this._isOpen ? 1 - newStepValue : newStepValue, 300);
  17726. }
  17727. beforeAnimation(shouldOpen, role) {
  17728. assert(!this.isAnimating, '_before() should not be called while animating');
  17729. /**
  17730. * When the menu is presented on an Android device, TalkBack's focus rings
  17731. * may appear in the wrong position due to the transition (specifically
  17732. * `transform` styles). This occurs because the focus rings are initially
  17733. * displayed at the starting position of the elements before the transition
  17734. * begins. This workaround ensures the focus rings do not appear in the
  17735. * incorrect location.
  17736. *
  17737. * If this solution is applied to iOS devices, then it leads to a bug where
  17738. * the overlays cannot be accessed by screen readers. This is due to
  17739. * VoiceOver not being able to update the accessibility tree when the
  17740. * `aria-hidden` is removed.
  17741. */
  17742. if (isPlatform('android')) {
  17743. this.el.setAttribute('aria-hidden', 'true');
  17744. }
  17745. // this places the menu into the correct location before it animates in
  17746. // this css class doesn't actually kick off any animations
  17747. this.el.classList.add(SHOW_MENU);
  17748. /**
  17749. * We add a tabindex here so that focus trapping
  17750. * still works even if the menu does not have
  17751. * any focusable elements slotted inside. The
  17752. * focus trapping utility will fallback to focusing
  17753. * the menu so focus does not leave when the menu
  17754. * is open.
  17755. */
  17756. this.el.setAttribute('tabindex', '0');
  17757. if (this.backdropEl) {
  17758. this.backdropEl.classList.add(SHOW_BACKDROP);
  17759. }
  17760. // add css class and hide content behind menu from screen readers
  17761. if (this.contentEl) {
  17762. this.contentEl.classList.add(MENU_CONTENT_OPEN);
  17763. /**
  17764. * When the menu is open and overlaying the main
  17765. * content, the main content should not be announced
  17766. * by the screenreader as the menu is the main
  17767. * focus. This is useful with screenreaders that have
  17768. * "read from top" gestures that read the entire
  17769. * page from top to bottom when activated.
  17770. * This should be done before the animation starts
  17771. * so that users cannot accidentally scroll
  17772. * the content while dragging a menu open.
  17773. */
  17774. this.contentEl.setAttribute('aria-hidden', 'true');
  17775. }
  17776. this.blocker.block();
  17777. this.isAnimating = true;
  17778. if (shouldOpen) {
  17779. this.ionWillOpen.emit();
  17780. }
  17781. else {
  17782. this.ionWillClose.emit({ role });
  17783. }
  17784. }
  17785. afterAnimation(isOpen, role) {
  17786. var _a;
  17787. // keep opening/closing the menu disabled for a touch more yet
  17788. // only add listeners/css if it's enabled and isOpen
  17789. // and only remove listeners/css if it's not open
  17790. // emit opened/closed events
  17791. this._isOpen = isOpen;
  17792. this.isAnimating = false;
  17793. if (!this._isOpen) {
  17794. this.blocker.unblock();
  17795. }
  17796. if (isOpen) {
  17797. /**
  17798. * When the menu is presented on an Android device, TalkBack's focus rings
  17799. * may appear in the wrong position due to the transition (specifically
  17800. * `transform` styles). The menu is hidden from screen readers during the
  17801. * transition to prevent this. Once the transition is complete, the menu
  17802. * is shown again.
  17803. */
  17804. if (isPlatform('android')) {
  17805. this.el.removeAttribute('aria-hidden');
  17806. }
  17807. // emit open event
  17808. this.ionDidOpen.emit();
  17809. /**
  17810. * Move focus to the menu to prepare focus trapping, as long as
  17811. * it isn't already focused. Use the host element instead of the
  17812. * first descendant to avoid the scroll position jumping around.
  17813. */
  17814. const focusedMenu = (_a = document.activeElement) === null || _a === void 0 ? void 0 : _a.closest('ion-menu');
  17815. if (focusedMenu !== this.el) {
  17816. this.el.focus();
  17817. }
  17818. // start focus trapping
  17819. document.addEventListener('focus', this.handleFocus, true);
  17820. }
  17821. else {
  17822. this.el.removeAttribute('aria-hidden');
  17823. // remove css classes and unhide content from screen readers
  17824. this.el.classList.remove(SHOW_MENU);
  17825. /**
  17826. * Remove tabindex from the menu component
  17827. * so that is cannot be tabbed to.
  17828. */
  17829. this.el.removeAttribute('tabindex');
  17830. if (this.contentEl) {
  17831. this.contentEl.classList.remove(MENU_CONTENT_OPEN);
  17832. /**
  17833. * Remove aria-hidden so screen readers
  17834. * can announce the main content again
  17835. * now that the menu is not the main focus.
  17836. */
  17837. this.contentEl.removeAttribute('aria-hidden');
  17838. }
  17839. if (this.backdropEl) {
  17840. this.backdropEl.classList.remove(SHOW_BACKDROP);
  17841. }
  17842. if (this.animation) {
  17843. this.animation.stop();
  17844. }
  17845. // emit close event
  17846. this.ionDidClose.emit({ role });
  17847. // undo focus trapping so multiple menus don't collide
  17848. document.removeEventListener('focus', this.handleFocus, true);
  17849. }
  17850. }
  17851. updateState() {
  17852. const isActive = this._isActive();
  17853. if (this.gesture) {
  17854. this.gesture.enable(isActive && this.swipeGesture);
  17855. }
  17856. /**
  17857. * If the menu is disabled but it is still open
  17858. * then we should close the menu immediately.
  17859. * Additionally, if the menu is in the process
  17860. * of animating {open, close} and the menu is disabled
  17861. * then it should still be closed immediately.
  17862. */
  17863. if (!isActive) {
  17864. /**
  17865. * It is possible to disable the menu while
  17866. * it is mid-animation. When this happens, we
  17867. * need to set the operationCancelled flag
  17868. * so that this._setOpen knows to return false
  17869. * and not run the "afterAnimation" callback.
  17870. */
  17871. if (this.isAnimating) {
  17872. this.operationCancelled = true;
  17873. }
  17874. /**
  17875. * If the menu is disabled then we should
  17876. * forcibly close the menu even if it is open.
  17877. */
  17878. this.afterAnimation(false, GESTURE);
  17879. }
  17880. }
  17881. render() {
  17882. const { type, disabled, el, isPaneVisible, inheritedAttributes, side } = this;
  17883. const mode = getIonMode$1(this);
  17884. /**
  17885. * If the Close Watcher is enabled then
  17886. * the ionBackButton listener in the menu controller
  17887. * will handle closing the menu when Escape is pressed.
  17888. */
  17889. return (hAsync(Host, { key: '0a2ba4ff5600b80b54d1b5b45124779c6aa0d2f2', onKeyDown: shouldUseCloseWatcher() ? null : this.onKeydown, role: "navigation", "aria-label": inheritedAttributes['aria-label'] || 'menu', class: {
  17890. [mode]: true,
  17891. [`menu-type-${type}`]: true,
  17892. 'menu-enabled': !disabled,
  17893. [`menu-side-${side}`]: true,
  17894. 'menu-pane-visible': isPaneVisible,
  17895. 'split-pane-side': hostContext('ion-split-pane', el),
  17896. } }, hAsync("div", { key: '40a222bcde4b959abc9939c44e89ea0cf8967aba', class: "menu-inner", part: "container", ref: (el) => (this.menuInnerEl = el) }, hAsync("slot", { key: '6a7ec5583294bb314990ff4ce6f25045652c07cb' })), hAsync("ion-backdrop", { key: '95f1e87237f3cc24845d91b744f935bad6bb460d', ref: (el) => (this.backdropEl = el), class: "menu-backdrop", tappable: false, stopPropagation: false, part: "backdrop" })));
  17897. }
  17898. get el() { return getElement(this); }
  17899. static get watchers() { return {
  17900. "type": ["typeChanged"],
  17901. "disabled": ["disabledChanged"],
  17902. "side": ["sideChanged"],
  17903. "swipeGesture": ["swipeGestureChanged"]
  17904. }; }
  17905. static get style() { return {
  17906. ios: IonMenuIosStyle0,
  17907. md: IonMenuMdStyle0
  17908. }; }
  17909. static get cmpMeta() { return {
  17910. "$flags$": 41,
  17911. "$tagName$": "ion-menu",
  17912. "$members$": {
  17913. "contentId": [513, "content-id"],
  17914. "menuId": [513, "menu-id"],
  17915. "type": [1025],
  17916. "disabled": [1028],
  17917. "side": [513],
  17918. "swipeGesture": [4, "swipe-gesture"],
  17919. "maxEdgeStart": [2, "max-edge-start"],
  17920. "isPaneVisible": [32],
  17921. "isEndSide": [32],
  17922. "isOpen": [64],
  17923. "isActive": [64],
  17924. "open": [64],
  17925. "close": [64],
  17926. "toggle": [64],
  17927. "setOpen": [64]
  17928. },
  17929. "$listeners$": [[16, "ionSplitPaneVisible", "onSplitPaneChanged"], [2, "click", "onBackdropClick"]],
  17930. "$lazyBundleId$": "-",
  17931. "$attrsToReflect$": [["contentId", "content-id"], ["menuId", "menu-id"], ["side", "side"]]
  17932. }; }
  17933. }
  17934. const computeDelta = (deltaX, isOpen, isEndSide) => {
  17935. return Math.max(0, isOpen !== isEndSide ? -deltaX : deltaX);
  17936. };
  17937. const checkEdgeSide = (win, posX, isEndSide, maxEdgeStart) => {
  17938. if (isEndSide) {
  17939. return posX >= win.innerWidth - maxEdgeStart;
  17940. }
  17941. else {
  17942. return posX <= maxEdgeStart;
  17943. }
  17944. };
  17945. const SHOW_MENU = 'show-menu';
  17946. const SHOW_BACKDROP = 'show-backdrop';
  17947. const MENU_CONTENT_OPEN = 'menu-content-open';
  17948. // Given a menu, return whether or not the menu toggle should be visible
  17949. const updateVisibility = async (menu) => {
  17950. const menuEl = await menuController.get(menu);
  17951. return !!(menuEl && (await menuEl.isActive()));
  17952. };
  17953. const menuButtonIosCss = ":host{--background:transparent;--color-focused:currentColor;--border-radius:initial;--padding-top:0;--padding-bottom:0;color:var(--color);text-align:center;text-decoration:none;text-overflow:ellipsis;text-transform:none;white-space:nowrap;-webkit-font-kerning:none;font-kerning:none}.button-native{border-radius:var(--border-radius);font-family:inherit;font-size:inherit;font-style:inherit;font-weight:inherit;letter-spacing:inherit;text-decoration:inherit;text-indent:inherit;text-overflow:inherit;text-transform:inherit;text-align:inherit;white-space:inherit;color:inherit;margin-left:0;margin-right:0;margin-top:0;margin-bottom:0;-webkit-padding-start:var(--padding-start);padding-inline-start:var(--padding-start);-webkit-padding-end:var(--padding-end);padding-inline-end:var(--padding-end);padding-top:var(--padding-top);padding-bottom:var(--padding-bottom);-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;display:-ms-flexbox;display:flex;position:relative;-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-negative:0;flex-shrink:0;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;width:100%;height:100%;min-height:inherit;border:0;outline:none;background:var(--background);line-height:1;cursor:pointer;overflow:hidden;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;z-index:0;-webkit-appearance:none;-moz-appearance:none;appearance:none}.button-inner{display:-ms-flexbox;display:flex;position:relative;-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-negative:0;flex-shrink:0;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;width:100%;height:100%;min-height:inherit;z-index:1}ion-icon{margin-left:0;margin-right:0;margin-top:0;margin-bottom:0;padding-left:0;padding-right:0;padding-top:0;padding-bottom:0;pointer-events:none}:host(.menu-button-hidden){display:none}:host(.menu-button-disabled){cursor:default;opacity:0.5;pointer-events:none}:host(.ion-focused) .button-native{color:var(--color-focused)}:host(.ion-focused) .button-native::after{background:var(--background-focused);opacity:var(--background-focused-opacity)}.button-native::after{left:0;right:0;top:0;bottom:0;position:absolute;content:\"\";opacity:0}@media (any-hover: hover){:host(:hover) .button-native{color:var(--color-hover)}:host(:hover) .button-native::after{background:var(--background-hover);opacity:var(--background-hover-opacity, 0)}}:host(.ion-color) .button-native{color:var(--ion-color-base)}:host(.in-toolbar:not(.in-toolbar-color)){color:var(--ion-toolbar-color, var(--color))}:host{--background-focused:currentColor;--background-focused-opacity:.1;--border-radius:4px;--color:var(--ion-color-primary, #0054e9);--padding-start:5px;--padding-end:5px;min-height:32px;font-size:clamp(31px, 1.9375rem, 38.13px)}:host(.ion-activated){opacity:0.4}@media (any-hover: hover){:host(:hover){opacity:0.6}}";
  17954. var IonMenuButtonIosStyle0 = menuButtonIosCss;
  17955. const menuButtonMdCss = ":host{--background:transparent;--color-focused:currentColor;--border-radius:initial;--padding-top:0;--padding-bottom:0;color:var(--color);text-align:center;text-decoration:none;text-overflow:ellipsis;text-transform:none;white-space:nowrap;-webkit-font-kerning:none;font-kerning:none}.button-native{border-radius:var(--border-radius);font-family:inherit;font-size:inherit;font-style:inherit;font-weight:inherit;letter-spacing:inherit;text-decoration:inherit;text-indent:inherit;text-overflow:inherit;text-transform:inherit;text-align:inherit;white-space:inherit;color:inherit;margin-left:0;margin-right:0;margin-top:0;margin-bottom:0;-webkit-padding-start:var(--padding-start);padding-inline-start:var(--padding-start);-webkit-padding-end:var(--padding-end);padding-inline-end:var(--padding-end);padding-top:var(--padding-top);padding-bottom:var(--padding-bottom);-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;display:-ms-flexbox;display:flex;position:relative;-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-negative:0;flex-shrink:0;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;width:100%;height:100%;min-height:inherit;border:0;outline:none;background:var(--background);line-height:1;cursor:pointer;overflow:hidden;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;z-index:0;-webkit-appearance:none;-moz-appearance:none;appearance:none}.button-inner{display:-ms-flexbox;display:flex;position:relative;-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-negative:0;flex-shrink:0;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;width:100%;height:100%;min-height:inherit;z-index:1}ion-icon{margin-left:0;margin-right:0;margin-top:0;margin-bottom:0;padding-left:0;padding-right:0;padding-top:0;padding-bottom:0;pointer-events:none}:host(.menu-button-hidden){display:none}:host(.menu-button-disabled){cursor:default;opacity:0.5;pointer-events:none}:host(.ion-focused) .button-native{color:var(--color-focused)}:host(.ion-focused) .button-native::after{background:var(--background-focused);opacity:var(--background-focused-opacity)}.button-native::after{left:0;right:0;top:0;bottom:0;position:absolute;content:\"\";opacity:0}@media (any-hover: hover){:host(:hover) .button-native{color:var(--color-hover)}:host(:hover) .button-native::after{background:var(--background-hover);opacity:var(--background-hover-opacity, 0)}}:host(.ion-color) .button-native{color:var(--ion-color-base)}:host(.in-toolbar:not(.in-toolbar-color)){color:var(--ion-toolbar-color, var(--color))}:host{--background-focused:currentColor;--background-focused-opacity:.12;--background-hover:currentColor;--background-hover-opacity:.04;--border-radius:50%;--color:initial;--padding-start:8px;--padding-end:8px;width:3rem;height:3rem;font-size:1.5rem}:host(.ion-color.ion-focused)::after{background:var(--ion-color-base)}@media (any-hover: hover){:host(.ion-color:hover) .button-native::after{background:var(--ion-color-base)}}";
  17956. var IonMenuButtonMdStyle0 = menuButtonMdCss;
  17957. /**
  17958. * @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
  17959. *
  17960. * @part native - The native HTML button element that wraps all child elements.
  17961. * @part icon - The menu button icon (uses ion-icon).
  17962. */
  17963. class MenuButton {
  17964. constructor(hostRef) {
  17965. registerInstance(this, hostRef);
  17966. this.inheritedAttributes = {};
  17967. this.onClick = async () => {
  17968. return menuController.toggle(this.menu);
  17969. };
  17970. this.visible = false;
  17971. this.color = undefined;
  17972. this.disabled = false;
  17973. this.menu = undefined;
  17974. this.autoHide = true;
  17975. this.type = 'button';
  17976. }
  17977. componentWillLoad() {
  17978. this.inheritedAttributes = inheritAriaAttributes(this.el);
  17979. }
  17980. componentDidLoad() {
  17981. this.visibilityChanged();
  17982. }
  17983. async visibilityChanged() {
  17984. this.visible = await updateVisibility(this.menu);
  17985. }
  17986. render() {
  17987. const { color, disabled, inheritedAttributes } = this;
  17988. const mode = getIonMode$1(this);
  17989. const menuIcon = config.get('menuIcon', mode === 'ios' ? menuOutline : menuSharp);
  17990. const hidden = this.autoHide && !this.visible;
  17991. const attrs = {
  17992. type: this.type,
  17993. };
  17994. const ariaLabel = inheritedAttributes['aria-label'] || 'menu';
  17995. return (hAsync(Host, { key: '3cde3704f28eb275f4a5ff2985bbb68c1024e79c', onClick: this.onClick, "aria-disabled": disabled ? 'true' : null, "aria-hidden": hidden ? 'true' : null, class: createColorClasses$1(color, {
  17996. [mode]: true,
  17997. button: true, // ion-buttons target .button
  17998. 'menu-button-hidden': hidden,
  17999. 'menu-button-disabled': disabled,
  18000. 'in-toolbar': hostContext('ion-toolbar', this.el),
  18001. 'in-toolbar-color': hostContext('ion-toolbar[color]', this.el),
  18002. 'ion-activatable': true,
  18003. 'ion-focusable': true,
  18004. }) }, hAsync("button", Object.assign({ key: 'a02a3374288bd1759b6e352ada8eab0d45c6422f' }, attrs, { disabled: disabled, class: "button-native", part: "native", "aria-label": ariaLabel }), hAsync("span", { key: 'ba699f2277a4e7b27ce5e42faeefc53d8805bb43', class: "button-inner" }, hAsync("slot", { key: '829fe6cbdeb173f50d1a670389d1565baa6273e4' }, hAsync("ion-icon", { key: 'a9a9f7b8dcffc648a8429fe0adbe766869de72fd', part: "icon", icon: menuIcon, mode: mode, lazy: false, "aria-hidden": "true" }))), mode === 'md' && hAsync("ion-ripple-effect", { key: '48deca9a771a249f2fc76eaa8b9741c8d66d8355', type: "unbounded" }))));
  18005. }
  18006. get el() { return getElement(this); }
  18007. static get style() { return {
  18008. ios: IonMenuButtonIosStyle0,
  18009. md: IonMenuButtonMdStyle0
  18010. }; }
  18011. static get cmpMeta() { return {
  18012. "$flags$": 41,
  18013. "$tagName$": "ion-menu-button",
  18014. "$members$": {
  18015. "color": [513],
  18016. "disabled": [4],
  18017. "menu": [1],
  18018. "autoHide": [4, "auto-hide"],
  18019. "type": [1],
  18020. "visible": [32]
  18021. },
  18022. "$listeners$": [[16, "ionMenuChange", "visibilityChanged"], [16, "ionSplitPaneVisible", "visibilityChanged"]],
  18023. "$lazyBundleId$": "-",
  18024. "$attrsToReflect$": [["color", "color"]]
  18025. }; }
  18026. }
  18027. const menuToggleCss = ":host(.menu-toggle-hidden){display:none}";
  18028. var IonMenuToggleStyle0 = menuToggleCss;
  18029. /**
  18030. * @slot - Content is placed inside the toggle to act as the click target.
  18031. */
  18032. class MenuToggle {
  18033. constructor(hostRef) {
  18034. registerInstance(this, hostRef);
  18035. this.onClick = () => {
  18036. return menuController.toggle(this.menu);
  18037. };
  18038. this.visible = false;
  18039. this.menu = undefined;
  18040. this.autoHide = true;
  18041. }
  18042. connectedCallback() {
  18043. this.visibilityChanged();
  18044. }
  18045. async visibilityChanged() {
  18046. this.visible = await updateVisibility(this.menu);
  18047. }
  18048. render() {
  18049. const mode = getIonMode$1(this);
  18050. const hidden = this.autoHide && !this.visible;
  18051. return (hAsync(Host, { key: '88e88fa13ac7f10ba3acfe378bd11cda0c7e2749', onClick: this.onClick, "aria-hidden": hidden ? 'true' : null, class: {
  18052. [mode]: true,
  18053. 'menu-toggle-hidden': hidden,
  18054. } }, hAsync("slot", { key: '0a14c7b63eda64702d2fd1b4bc7db4809892842d' })));
  18055. }
  18056. static get style() { return IonMenuToggleStyle0; }
  18057. static get cmpMeta() { return {
  18058. "$flags$": 9,
  18059. "$tagName$": "ion-menu-toggle",
  18060. "$members$": {
  18061. "menu": [1],
  18062. "autoHide": [4, "auto-hide"],
  18063. "visible": [32]
  18064. },
  18065. "$listeners$": [[16, "ionMenuChange", "visibilityChanged"], [16, "ionSplitPaneVisible", "visibilityChanged"]],
  18066. "$lazyBundleId$": "-",
  18067. "$attrsToReflect$": []
  18068. }; }
  18069. }
  18070. var Style;
  18071. (function (Style) {
  18072. Style["Dark"] = "DARK";
  18073. Style["Light"] = "LIGHT";
  18074. Style["Default"] = "DEFAULT";
  18075. })(Style || (Style = {}));
  18076. const StatusBar = {
  18077. getEngine() {
  18078. const capacitor = getCapacitor();
  18079. if (capacitor === null || capacitor === void 0 ? void 0 : capacitor.isPluginAvailable('StatusBar')) {
  18080. return capacitor.Plugins.StatusBar;
  18081. }
  18082. return undefined;
  18083. },
  18084. setStyle(options) {
  18085. const engine = this.getEngine();
  18086. if (!engine) {
  18087. return;
  18088. }
  18089. engine.setStyle(options);
  18090. },
  18091. getStyle: async function () {
  18092. const engine = this.getEngine();
  18093. if (!engine) {
  18094. return Style.Default;
  18095. }
  18096. const { style } = await engine.getInfo();
  18097. return style;
  18098. },
  18099. };
  18100. const LIFECYCLE_WILL_ENTER = 'ionViewWillEnter';
  18101. const LIFECYCLE_DID_ENTER = 'ionViewDidEnter';
  18102. const LIFECYCLE_WILL_LEAVE = 'ionViewWillLeave';
  18103. const LIFECYCLE_DID_LEAVE = 'ionViewDidLeave';
  18104. const LIFECYCLE_WILL_UNLOAD = 'ionViewWillUnload';
  18105. /**
  18106. * Moves focus to a specified element. Note that we do not remove the tabindex
  18107. * because that can result in an unintentional blur. Non-focusables can't be
  18108. * focused, so the body will get focused again.
  18109. */
  18110. const moveFocus = (el) => {
  18111. el.tabIndex = -1;
  18112. el.focus();
  18113. };
  18114. /**
  18115. * Elements that are hidden using `display: none` should not be focused even if
  18116. * they are present in the DOM.
  18117. */
  18118. const isVisible = (el) => {
  18119. return el.offsetParent !== null;
  18120. };
  18121. /**
  18122. * The focus controller allows us to manage focus within a view so assistive
  18123. * technologies can inform users of changes to the navigation state. Traditional
  18124. * native apps have a way of informing assistive technology about a navigation
  18125. * state change. Mobile browsers have this too, but only when doing a full page
  18126. * load. In a single page app we do not do that, so we need to build this
  18127. * integration ourselves.
  18128. */
  18129. const createFocusController = () => {
  18130. const saveViewFocus = (referenceEl) => {
  18131. const focusManagerEnabled = config.get('focusManagerPriority', false);
  18132. /**
  18133. * When going back to a previously visited page focus should typically be moved
  18134. * back to the element that was last focused when the user was on this view.
  18135. */
  18136. if (focusManagerEnabled) {
  18137. const activeEl = document.activeElement;
  18138. if (activeEl !== null && (referenceEl === null || referenceEl === void 0 ? void 0 : referenceEl.contains(activeEl))) {
  18139. activeEl.setAttribute(LAST_FOCUS, 'true');
  18140. }
  18141. }
  18142. };
  18143. const setViewFocus = (referenceEl) => {
  18144. const focusManagerPriorities = config.get('focusManagerPriority', false);
  18145. /**
  18146. * If the focused element is a descendant of the referenceEl then it's possible
  18147. * that the app developer manually moved focus, so we do not want to override that.
  18148. * This can happen with inputs the are focused when a view transitions in.
  18149. */
  18150. if (Array.isArray(focusManagerPriorities) && !referenceEl.contains(document.activeElement)) {
  18151. /**
  18152. * When going back to a previously visited view focus should always be moved back
  18153. * to the element that the user was last focused on when they were on this view.
  18154. */
  18155. const lastFocus = referenceEl.querySelector(`[${LAST_FOCUS}]`);
  18156. if (lastFocus && isVisible(lastFocus)) {
  18157. moveFocus(lastFocus);
  18158. return;
  18159. }
  18160. for (const priority of focusManagerPriorities) {
  18161. /**
  18162. * For each recognized case (excluding the default case) make sure to return
  18163. * so that the fallback focus behavior does not run.
  18164. *
  18165. * We intentionally query for specific roles/semantic elements so that the
  18166. * transition manager can work with both Ionic and non-Ionic UI components.
  18167. *
  18168. * If new selectors are added, be sure to remove the outline ring by adding
  18169. * new selectors to rule in core.scss.
  18170. */
  18171. switch (priority) {
  18172. case 'content':
  18173. const content = referenceEl.querySelector('main, [role="main"]');
  18174. if (content && isVisible(content)) {
  18175. moveFocus(content);
  18176. return;
  18177. }
  18178. break;
  18179. case 'heading':
  18180. const headingOne = referenceEl.querySelector('h1, [role="heading"][aria-level="1"]');
  18181. if (headingOne && isVisible(headingOne)) {
  18182. moveFocus(headingOne);
  18183. return;
  18184. }
  18185. break;
  18186. case 'banner':
  18187. const header = referenceEl.querySelector('header, [role="banner"]');
  18188. if (header && isVisible(header)) {
  18189. moveFocus(header);
  18190. return;
  18191. }
  18192. break;
  18193. default:
  18194. printIonWarning(`Unrecognized focus manager priority value ${priority}`);
  18195. break;
  18196. }
  18197. }
  18198. /**
  18199. * If there is nothing to focus then focus the page so focus at least moves to
  18200. * the correct view. The browser will then determine where within the page to
  18201. * move focus to.
  18202. */
  18203. moveFocus(referenceEl);
  18204. }
  18205. };
  18206. return {
  18207. saveViewFocus,
  18208. setViewFocus,
  18209. };
  18210. };
  18211. const LAST_FOCUS = 'ion-last-focus';
  18212. const iosTransitionAnimation$1 = () => Promise.resolve().then(function () { return ios_transition; });
  18213. const mdTransitionAnimation$1 = () => Promise.resolve().then(function () { return md_transition; });
  18214. const focusController = createFocusController();
  18215. // TODO(FW-2832): types
  18216. const transition = (opts) => {
  18217. return new Promise((resolve, reject) => {
  18218. writeTask(() => {
  18219. beforeTransition(opts);
  18220. runTransition(opts).then((result) => {
  18221. if (result.animation) {
  18222. result.animation.destroy();
  18223. }
  18224. afterTransition(opts);
  18225. resolve(result);
  18226. }, (error) => {
  18227. afterTransition(opts);
  18228. reject(error);
  18229. });
  18230. });
  18231. });
  18232. };
  18233. const beforeTransition = (opts) => {
  18234. const enteringEl = opts.enteringEl;
  18235. const leavingEl = opts.leavingEl;
  18236. focusController.saveViewFocus(leavingEl);
  18237. setZIndex(enteringEl, leavingEl, opts.direction);
  18238. if (opts.showGoBack) {
  18239. enteringEl.classList.add('can-go-back');
  18240. }
  18241. else {
  18242. enteringEl.classList.remove('can-go-back');
  18243. }
  18244. setPageHidden(enteringEl, false);
  18245. /**
  18246. * When transitioning, the page should not
  18247. * respond to click events. This resolves small
  18248. * issues like users double tapping the ion-back-button.
  18249. * These pointer events are removed in `afterTransition`.
  18250. */
  18251. enteringEl.style.setProperty('pointer-events', 'none');
  18252. if (leavingEl) {
  18253. setPageHidden(leavingEl, false);
  18254. leavingEl.style.setProperty('pointer-events', 'none');
  18255. }
  18256. };
  18257. const runTransition = async (opts) => {
  18258. const animationBuilder = await getAnimationBuilder(opts);
  18259. const ani = animationBuilder && Build.isBrowser ? animation(animationBuilder, opts) : noAnimation(opts); // fast path for no animation
  18260. return ani;
  18261. };
  18262. const afterTransition = (opts) => {
  18263. const enteringEl = opts.enteringEl;
  18264. const leavingEl = opts.leavingEl;
  18265. enteringEl.classList.remove('ion-page-invisible');
  18266. enteringEl.style.removeProperty('pointer-events');
  18267. if (leavingEl !== undefined) {
  18268. leavingEl.classList.remove('ion-page-invisible');
  18269. leavingEl.style.removeProperty('pointer-events');
  18270. }
  18271. focusController.setViewFocus(enteringEl);
  18272. };
  18273. const getAnimationBuilder = async (opts) => {
  18274. if (!opts.leavingEl || !opts.animated || opts.duration === 0) {
  18275. return undefined;
  18276. }
  18277. if (opts.animationBuilder) {
  18278. return opts.animationBuilder;
  18279. }
  18280. const getAnimation = opts.mode === 'ios'
  18281. ? (await iosTransitionAnimation$1()).iosTransitionAnimation
  18282. : (await mdTransitionAnimation$1()).mdTransitionAnimation;
  18283. return getAnimation;
  18284. };
  18285. const animation = async (animationBuilder, opts) => {
  18286. await waitForReady(opts, true);
  18287. const trans = animationBuilder(opts.baseEl, opts);
  18288. fireWillEvents(opts.enteringEl, opts.leavingEl);
  18289. const didComplete = await playTransition(trans, opts);
  18290. if (opts.progressCallback) {
  18291. opts.progressCallback(undefined);
  18292. }
  18293. if (didComplete) {
  18294. fireDidEvents(opts.enteringEl, opts.leavingEl);
  18295. }
  18296. return {
  18297. hasCompleted: didComplete,
  18298. animation: trans,
  18299. };
  18300. };
  18301. const noAnimation = async (opts) => {
  18302. const enteringEl = opts.enteringEl;
  18303. const leavingEl = opts.leavingEl;
  18304. const focusManagerEnabled = config.get('focusManagerPriority', false);
  18305. /**
  18306. * If the focus manager is enabled then we need to wait for Ionic components to be
  18307. * rendered otherwise the component to focus may not be focused because it is hidden.
  18308. */
  18309. await waitForReady(opts, focusManagerEnabled);
  18310. fireWillEvents(enteringEl, leavingEl);
  18311. fireDidEvents(enteringEl, leavingEl);
  18312. return {
  18313. hasCompleted: true,
  18314. };
  18315. };
  18316. const waitForReady = async (opts, defaultDeep) => {
  18317. const deep = opts.deepWait !== undefined ? opts.deepWait : defaultDeep;
  18318. if (deep) {
  18319. await Promise.all([deepReady(opts.enteringEl), deepReady(opts.leavingEl)]);
  18320. }
  18321. await notifyViewReady(opts.viewIsReady, opts.enteringEl);
  18322. };
  18323. const notifyViewReady = async (viewIsReady, enteringEl) => {
  18324. if (viewIsReady) {
  18325. await viewIsReady(enteringEl);
  18326. }
  18327. };
  18328. const playTransition = (trans, opts) => {
  18329. const progressCallback = opts.progressCallback;
  18330. const promise = new Promise((resolve) => {
  18331. trans.onFinish((currentStep) => resolve(currentStep === 1));
  18332. });
  18333. // cool, let's do this, start the transition
  18334. if (progressCallback) {
  18335. // this is a swipe to go back, just get the transition progress ready
  18336. // kick off the swipe animation start
  18337. trans.progressStart(true);
  18338. progressCallback(trans);
  18339. }
  18340. else {
  18341. // only the top level transition should actually start "play"
  18342. // kick it off and let it play through
  18343. // ******** DOM WRITE ****************
  18344. trans.play();
  18345. }
  18346. // create a callback for when the animation is done
  18347. return promise;
  18348. };
  18349. const fireWillEvents = (enteringEl, leavingEl) => {
  18350. lifecycle(leavingEl, LIFECYCLE_WILL_LEAVE);
  18351. lifecycle(enteringEl, LIFECYCLE_WILL_ENTER);
  18352. };
  18353. const fireDidEvents = (enteringEl, leavingEl) => {
  18354. lifecycle(enteringEl, LIFECYCLE_DID_ENTER);
  18355. lifecycle(leavingEl, LIFECYCLE_DID_LEAVE);
  18356. };
  18357. const lifecycle = (el, eventName) => {
  18358. if (el) {
  18359. const ev = new CustomEvent(eventName, {
  18360. bubbles: false,
  18361. cancelable: false,
  18362. });
  18363. el.dispatchEvent(ev);
  18364. }
  18365. };
  18366. /**
  18367. * Wait two request animation frame loops.
  18368. * This allows the framework implementations enough time to mount
  18369. * the user-defined contents. This is often needed when using inline
  18370. * modals and popovers that accept user components. For popover,
  18371. * the contents must be mounted for the popover to be sized correctly.
  18372. * For modals, the contents must be mounted for iOS to run the
  18373. * transition correctly.
  18374. *
  18375. * On Angular and React, a single raf is enough time, but for Vue
  18376. * we need to wait two rafs. As a result we are using two rafs for
  18377. * all frameworks to ensure contents are mounted.
  18378. */
  18379. const waitForMount = () => {
  18380. return new Promise((resolve) => raf(() => raf(() => resolve())));
  18381. };
  18382. const deepReady = async (el) => {
  18383. const element = el;
  18384. if (element) {
  18385. if (element.componentOnReady != null) {
  18386. // eslint-disable-next-line custom-rules/no-component-on-ready-method
  18387. const stencilEl = await element.componentOnReady();
  18388. if (stencilEl != null) {
  18389. return;
  18390. }
  18391. /**
  18392. * Custom elements in Stencil will have __registerHost.
  18393. */
  18394. }
  18395. else if (element.__registerHost != null) {
  18396. /**
  18397. * Non-lazy loaded custom elements need to wait
  18398. * one frame for component to be loaded.
  18399. */
  18400. const waitForCustomElement = new Promise((resolve) => raf(resolve));
  18401. await waitForCustomElement;
  18402. return;
  18403. }
  18404. await Promise.all(Array.from(element.children).map(deepReady));
  18405. }
  18406. };
  18407. const setPageHidden = (el, hidden) => {
  18408. if (hidden) {
  18409. el.setAttribute('aria-hidden', 'true');
  18410. el.classList.add('ion-page-hidden');
  18411. }
  18412. else {
  18413. el.hidden = false;
  18414. el.removeAttribute('aria-hidden');
  18415. el.classList.remove('ion-page-hidden');
  18416. }
  18417. };
  18418. const setZIndex = (enteringEl, leavingEl, direction) => {
  18419. if (enteringEl !== undefined) {
  18420. enteringEl.style.zIndex = direction === 'back' ? '99' : '101';
  18421. }
  18422. if (leavingEl !== undefined) {
  18423. leavingEl.style.zIndex = '100';
  18424. }
  18425. };
  18426. const getIonPageElement = (element) => {
  18427. if (element.classList.contains('ion-page')) {
  18428. return element;
  18429. }
  18430. const ionPage = element.querySelector(':scope > .ion-page, :scope > ion-nav, :scope > ion-tabs');
  18431. if (ionPage) {
  18432. return ionPage;
  18433. }
  18434. // idk, return the original element so at least something animates and we don't have a null pointer
  18435. return element;
  18436. };
  18437. const KEYBOARD_DID_OPEN = 'ionKeyboardDidShow';
  18438. /**
  18439. * Use y = mx + b to
  18440. * figure out the backdrop value
  18441. * at a particular x coordinate. This
  18442. * is useful when the backdrop does
  18443. * not begin to fade in until after
  18444. * the 0 breakpoint.
  18445. */
  18446. const getBackdropValueForSheet = (x, backdropBreakpoint) => {
  18447. /**
  18448. * We will use these points:
  18449. * (backdropBreakpoint, 0)
  18450. * (maxBreakpoint, 1)
  18451. * We know that at the beginning breakpoint,
  18452. * the backdrop will be hidden. We also
  18453. * know that at the maxBreakpoint, the backdrop
  18454. * must be fully visible. maxBreakpoint should
  18455. * always be 1 even if the maximum value
  18456. * of the breakpoints array is not 1 since
  18457. * the animation runs from a progress of 0
  18458. * to a progress of 1.
  18459. * m = (y2 - y1) / (x2 - x1)
  18460. *
  18461. * This is simplified from:
  18462. * m = (1 - 0) / (maxBreakpoint - backdropBreakpoint)
  18463. *
  18464. * If the backdropBreakpoint is 1, we return 0 as the
  18465. * backdrop is completely hidden.
  18466. *
  18467. */
  18468. if (backdropBreakpoint === 1) {
  18469. return 0;
  18470. }
  18471. const slope = 1 / (1 - backdropBreakpoint);
  18472. /**
  18473. * From here, compute b which is
  18474. * the backdrop opacity if the offset
  18475. * is 0. If the backdrop does not
  18476. * begin to fade in until after the
  18477. * 0 breakpoint, this b value will be
  18478. * negative. This is fine as we never pass
  18479. * b directly into the animation keyframes.
  18480. * b = y - mx
  18481. * Use a known point: (backdropBreakpoint, 0)
  18482. * This is simplified from:
  18483. * b = 0 - (backdropBreakpoint * slope)
  18484. */
  18485. const b = -(backdropBreakpoint * slope);
  18486. /**
  18487. * Finally, we can now determine the
  18488. * backdrop offset given an arbitrary
  18489. * gesture offset.
  18490. */
  18491. return x * slope + b;
  18492. };
  18493. /**
  18494. * The tablet/desktop card modal activates
  18495. * when the window width is >= 768.
  18496. * At that point, the presenting element
  18497. * is not transformed, so we do not need to
  18498. * adjust the status bar color.
  18499. *
  18500. */
  18501. const setCardStatusBarDark = () => {
  18502. if (!win$1 || win$1.innerWidth >= 768) {
  18503. return;
  18504. }
  18505. StatusBar.setStyle({ style: Style.Dark });
  18506. };
  18507. const setCardStatusBarDefault = (defaultStyle = Style.Default) => {
  18508. if (!win$1 || win$1.innerWidth >= 768) {
  18509. return;
  18510. }
  18511. StatusBar.setStyle({ style: defaultStyle });
  18512. };
  18513. const handleCanDismiss = async (el, animation) => {
  18514. /**
  18515. * If canDismiss is not a function
  18516. * then we can return early. If canDismiss is `true`,
  18517. * then canDismissBlocksGesture is `false` as canDismiss
  18518. * will never interrupt the gesture. As a result,
  18519. * this code block is never reached. If canDismiss is `false`,
  18520. * then we never dismiss.
  18521. */
  18522. if (typeof el.canDismiss !== 'function') {
  18523. return;
  18524. }
  18525. /**
  18526. * Run the canDismiss callback.
  18527. * If the function returns `true`,
  18528. * then we can proceed with dismiss.
  18529. */
  18530. const shouldDismiss = await el.canDismiss(undefined, GESTURE);
  18531. if (!shouldDismiss) {
  18532. return;
  18533. }
  18534. /**
  18535. * If canDismiss resolved after the snap
  18536. * back animation finished, we can
  18537. * dismiss immediately.
  18538. *
  18539. * If canDismiss resolved before the snap
  18540. * back animation finished, we need to
  18541. * wait until the snap back animation is
  18542. * done before dismissing.
  18543. */
  18544. if (animation.isRunning()) {
  18545. animation.onFinish(() => {
  18546. el.dismiss(undefined, 'handler');
  18547. }, { oneTimeCallback: true });
  18548. }
  18549. else {
  18550. el.dismiss(undefined, 'handler');
  18551. }
  18552. };
  18553. /**
  18554. * This function lets us simulate a realistic spring-like animation
  18555. * when swiping down on the modal.
  18556. * There are two forces that we need to use to compute the spring physics:
  18557. *
  18558. * 1. Stiffness, k: This is a measure of resistance applied a spring.
  18559. * 2. Dampening, c: This value has the effect of reducing or preventing oscillation.
  18560. *
  18561. * Using these two values, we can calculate the Spring Force and the Dampening Force
  18562. * to compute the total force applied to a spring.
  18563. *
  18564. * Spring Force: This force pulls a spring back into its equilibrium position.
  18565. * Hooke's Law tells us that that spring force (FS) = kX.
  18566. * k is the stiffness of a spring, and X is the displacement of the spring from its
  18567. * equilibrium position. In this case, it is the amount by which the free end
  18568. * of a spring was displaced (stretched/pushed) from its "relaxed" position.
  18569. *
  18570. * Dampening Force: This force slows down motion. Without it, a spring would oscillate forever.
  18571. * The dampening force, FD, can be found via this formula: FD = -cv
  18572. * where c the dampening value and v is velocity.
  18573. *
  18574. * Therefore, the resulting force that is exerted on the block is:
  18575. * F = FS + FD = -kX - cv
  18576. *
  18577. * Newton's 2nd Law tells us that F = ma:
  18578. * ma = -kX - cv.
  18579. *
  18580. * For Ionic's purposes, we can assume that m = 1:
  18581. * a = -kX - cv
  18582. *
  18583. * Imagine a block attached to the end of a spring. At equilibrium
  18584. * the block is at position x = 1.
  18585. * Pressing on the block moves it to position x = 0;
  18586. * So, to calculate the displacement, we need to take the
  18587. * current position and subtract the previous position from it.
  18588. * X = x - x0 = 0 - 1 = -1.
  18589. *
  18590. * For Ionic's purposes, we are only pushing on the spring modal
  18591. * so we have a max position of 1.
  18592. * As a result, we can expand displacement to this formula:
  18593. * X = x - 1
  18594. *
  18595. * a = -k(x - 1) - cv
  18596. *
  18597. * We can represent the motion of something as a function of time: f(t) = x.
  18598. * The derivative of position gives us the velocity: f'(t)
  18599. * The derivative of the velocity gives us the acceleration: f''(t)
  18600. *
  18601. * We can substitute the formula above with these values:
  18602. *
  18603. * f"(t) = -k * (f(t) - 1) - c * f'(t)
  18604. *
  18605. * This is called a differential equation.
  18606. *
  18607. * We know that at t = 0, we are at x = 0 because the modal does not move: f(0) = 0
  18608. * This means our velocity is also zero: f'(0) = 0.
  18609. *
  18610. * We can cheat a bit and plug the formula into Wolfram Alpha.
  18611. * However, we need to pick stiffness and dampening values:
  18612. * k = 0.57
  18613. * c = 15
  18614. *
  18615. * I picked these as they are fairly close to native iOS's spring effect
  18616. * with the modal.
  18617. *
  18618. * What we plug in is this: f(0) = 0; f'(0) = 0; f''(t) = -0.57(f(t) - 1) - 15f'(t)
  18619. *
  18620. * The result is a formula that lets us calculate the acceleration
  18621. * for a given time t.
  18622. * Note: This is the approximate form of the solution. Wolfram Alpha will
  18623. * give you a complex differential equation too.
  18624. */
  18625. const calculateSpringStep = (t) => {
  18626. return 0.00255275 * 2.71828 ** (-14.9619 * t) - 1.00255 * 2.71828 ** (-0.0380968 * t) + 1;
  18627. };
  18628. // Defaults for the card swipe animation
  18629. const SwipeToCloseDefaults = {
  18630. MIN_PRESENTING_SCALE: 0.915,
  18631. };
  18632. const createSwipeToCloseGesture = (el, animation, statusBarStyle, onDismiss) => {
  18633. /**
  18634. * The step value at which a card modal
  18635. * is eligible for dismissing via gesture.
  18636. */
  18637. const DISMISS_THRESHOLD = 0.5;
  18638. const height = el.offsetHeight;
  18639. let isOpen = false;
  18640. let canDismissBlocksGesture = false;
  18641. let contentEl = null;
  18642. let scrollEl = null;
  18643. const canDismissMaxStep = 0.2;
  18644. let initialScrollY = true;
  18645. let lastStep = 0;
  18646. const getScrollY = () => {
  18647. if (contentEl && isIonContent(contentEl)) {
  18648. return contentEl.scrollY;
  18649. /**
  18650. * Custom scroll containers are intended to be
  18651. * used with virtual scrolling, so we assume
  18652. * there is scrolling in this case.
  18653. */
  18654. }
  18655. else {
  18656. return true;
  18657. }
  18658. };
  18659. const canStart = (detail) => {
  18660. const target = detail.event.target;
  18661. if (target === null || !target.closest) {
  18662. return true;
  18663. }
  18664. /**
  18665. * If we are swiping on the content,
  18666. * swiping should only be possible if
  18667. * the content is scrolled all the way
  18668. * to the top so that we do not interfere
  18669. * with scrolling.
  18670. *
  18671. * We cannot assume that the `ion-content`
  18672. * target will remain consistent between
  18673. * swipes. For example, when using
  18674. * ion-nav within a card modal it is
  18675. * possible to swipe, push a view, and then
  18676. * swipe again. The target content will not
  18677. * be the same between swipes.
  18678. */
  18679. contentEl = findClosestIonContent(target);
  18680. if (contentEl) {
  18681. /**
  18682. * The card should never swipe to close
  18683. * on the content with a refresher.
  18684. * Note: We cannot solve this by making the
  18685. * swipeToClose gesture have a higher priority
  18686. * than the refresher gesture as the iOS native
  18687. * refresh gesture uses a scroll listener in
  18688. * addition to a gesture.
  18689. *
  18690. * Note: Do not use getScrollElement here
  18691. * because we need this to be a synchronous
  18692. * operation, and getScrollElement is
  18693. * asynchronous.
  18694. */
  18695. if (isIonContent(contentEl)) {
  18696. const root = getElementRoot(contentEl);
  18697. scrollEl = root.querySelector('.inner-scroll');
  18698. }
  18699. else {
  18700. scrollEl = contentEl;
  18701. }
  18702. const hasRefresherInContent = !!contentEl.querySelector('ion-refresher');
  18703. return !hasRefresherInContent && scrollEl.scrollTop === 0;
  18704. }
  18705. /**
  18706. * Card should be swipeable on all
  18707. * parts of the modal except for the footer.
  18708. */
  18709. const footer = target.closest('ion-footer');
  18710. if (footer === null) {
  18711. return true;
  18712. }
  18713. return false;
  18714. };
  18715. const onStart = (detail) => {
  18716. const { deltaY } = detail;
  18717. /**
  18718. * Get the initial scrollY value so
  18719. * that we can correctly reset the scrollY
  18720. * prop when the gesture ends.
  18721. */
  18722. initialScrollY = getScrollY();
  18723. /**
  18724. * If canDismiss is anything other than `true`
  18725. * then users should be able to swipe down
  18726. * until a threshold is hit. At that point,
  18727. * the card modal should not proceed any further.
  18728. * TODO (FW-937)
  18729. * Remove undefined check
  18730. */
  18731. canDismissBlocksGesture = el.canDismiss !== undefined && el.canDismiss !== true;
  18732. /**
  18733. * If we are pulling down, then
  18734. * it is possible we are pulling on the
  18735. * content. We do not want scrolling to
  18736. * happen at the same time as the gesture.
  18737. */
  18738. if (deltaY > 0 && contentEl) {
  18739. disableContentScrollY(contentEl);
  18740. }
  18741. animation.progressStart(true, isOpen ? 1 : 0);
  18742. };
  18743. const onMove = (detail) => {
  18744. const { deltaY } = detail;
  18745. /**
  18746. * If we are pulling down, then
  18747. * it is possible we are pulling on the
  18748. * content. We do not want scrolling to
  18749. * happen at the same time as the gesture.
  18750. */
  18751. if (deltaY > 0 && contentEl) {
  18752. disableContentScrollY(contentEl);
  18753. }
  18754. /**
  18755. * If we are swiping on the content
  18756. * then the swipe gesture should only
  18757. * happen if we are pulling down.
  18758. *
  18759. * However, if we pull up and
  18760. * then down such that the scroll position
  18761. * returns to 0, we should be able to swipe
  18762. * the card.
  18763. */
  18764. const step = detail.deltaY / height;
  18765. /**
  18766. * Check if user is swiping down and
  18767. * if we have a canDismiss value that
  18768. * should block the gesture from
  18769. * proceeding,
  18770. */
  18771. const isAttemptingDismissWithCanDismiss = step >= 0 && canDismissBlocksGesture;
  18772. /**
  18773. * If we are blocking the gesture from dismissing,
  18774. * set the max step value so that the sheet cannot be
  18775. * completely hidden.
  18776. */
  18777. const maxStep = isAttemptingDismissWithCanDismiss ? canDismissMaxStep : 0.9999;
  18778. /**
  18779. * If we are blocking the gesture from
  18780. * dismissing, calculate the spring modifier value
  18781. * this will be added to the starting breakpoint
  18782. * value to give the gesture a spring-like feeling.
  18783. * Note that the starting breakpoint is always 0,
  18784. * so we omit adding 0 to the result.
  18785. */
  18786. const processedStep = isAttemptingDismissWithCanDismiss ? calculateSpringStep(step / maxStep) : step;
  18787. const clampedStep = clamp(0.0001, processedStep, maxStep);
  18788. animation.progressStep(clampedStep);
  18789. /**
  18790. * When swiping down half way, the status bar style
  18791. * should be reset to its default value.
  18792. *
  18793. * We track lastStep so that we do not fire these
  18794. * functions on every onMove, only when the user has
  18795. * crossed a certain threshold.
  18796. */
  18797. if (clampedStep >= DISMISS_THRESHOLD && lastStep < DISMISS_THRESHOLD) {
  18798. setCardStatusBarDefault(statusBarStyle);
  18799. /**
  18800. * However, if we swipe back up, then the
  18801. * status bar style should be set to have light
  18802. * text on a dark background.
  18803. */
  18804. }
  18805. else if (clampedStep < DISMISS_THRESHOLD && lastStep >= DISMISS_THRESHOLD) {
  18806. setCardStatusBarDark();
  18807. }
  18808. lastStep = clampedStep;
  18809. };
  18810. const onEnd = (detail) => {
  18811. const velocity = detail.velocityY;
  18812. const step = detail.deltaY / height;
  18813. const isAttemptingDismissWithCanDismiss = step >= 0 && canDismissBlocksGesture;
  18814. const maxStep = isAttemptingDismissWithCanDismiss ? canDismissMaxStep : 0.9999;
  18815. const processedStep = isAttemptingDismissWithCanDismiss ? calculateSpringStep(step / maxStep) : step;
  18816. const clampedStep = clamp(0.0001, processedStep, maxStep);
  18817. const threshold = (detail.deltaY + velocity * 1000) / height;
  18818. /**
  18819. * If canDismiss blocks
  18820. * the swipe gesture, then the
  18821. * animation can never complete until
  18822. * canDismiss is checked.
  18823. */
  18824. const shouldComplete = !isAttemptingDismissWithCanDismiss && threshold >= DISMISS_THRESHOLD;
  18825. let newStepValue = shouldComplete ? -0.001 : 0.001;
  18826. if (!shouldComplete) {
  18827. animation.easing('cubic-bezier(1, 0, 0.68, 0.28)');
  18828. newStepValue += getTimeGivenProgression([0, 0], [1, 0], [0.68, 0.28], [1, 1], clampedStep)[0];
  18829. }
  18830. else {
  18831. animation.easing('cubic-bezier(0.32, 0.72, 0, 1)');
  18832. newStepValue += getTimeGivenProgression([0, 0], [0.32, 0.72], [0, 1], [1, 1], clampedStep)[0];
  18833. }
  18834. const duration = shouldComplete
  18835. ? computeDuration(step * height, velocity)
  18836. : computeDuration((1 - clampedStep) * height, velocity);
  18837. isOpen = shouldComplete;
  18838. gesture.enable(false);
  18839. if (contentEl) {
  18840. resetContentScrollY(contentEl, initialScrollY);
  18841. }
  18842. animation
  18843. .onFinish(() => {
  18844. if (!shouldComplete) {
  18845. gesture.enable(true);
  18846. }
  18847. })
  18848. .progressEnd(shouldComplete ? 1 : 0, newStepValue, duration);
  18849. /**
  18850. * If the canDismiss value blocked the gesture
  18851. * from proceeding, then we should ignore whatever
  18852. * shouldComplete is. Whether or not the modal
  18853. * animation should complete is now determined by
  18854. * canDismiss.
  18855. *
  18856. * If the user swiped >25% of the way
  18857. * to the max step, then we should
  18858. * check canDismiss. 25% was chosen
  18859. * to avoid accidental swipes.
  18860. */
  18861. if (isAttemptingDismissWithCanDismiss && clampedStep > maxStep / 4) {
  18862. handleCanDismiss(el, animation);
  18863. }
  18864. else if (shouldComplete) {
  18865. onDismiss();
  18866. }
  18867. };
  18868. const gesture = createGesture({
  18869. el,
  18870. gestureName: 'modalSwipeToClose',
  18871. gesturePriority: OVERLAY_GESTURE_PRIORITY,
  18872. direction: 'y',
  18873. threshold: 10,
  18874. canStart,
  18875. onStart,
  18876. onMove,
  18877. onEnd,
  18878. });
  18879. return gesture;
  18880. };
  18881. const computeDuration = (remaining, velocity) => {
  18882. return clamp(400, remaining / Math.abs(velocity * 1.1), 500);
  18883. };
  18884. const createSheetEnterAnimation = (opts) => {
  18885. const { currentBreakpoint, backdropBreakpoint, expandToScroll } = opts;
  18886. /**
  18887. * If the backdropBreakpoint is undefined, then the backdrop
  18888. * should always fade in. If the backdropBreakpoint came before the
  18889. * current breakpoint, then the backdrop should be fading in.
  18890. */
  18891. const shouldShowBackdrop = backdropBreakpoint === undefined || backdropBreakpoint < currentBreakpoint;
  18892. const initialBackdrop = shouldShowBackdrop ? `calc(var(--backdrop-opacity) * ${currentBreakpoint})` : '0';
  18893. const backdropAnimation = createAnimation('backdropAnimation').fromTo('opacity', 0, initialBackdrop);
  18894. if (shouldShowBackdrop) {
  18895. backdropAnimation
  18896. .beforeStyles({
  18897. 'pointer-events': 'none',
  18898. })
  18899. .afterClearStyles(['pointer-events']);
  18900. }
  18901. const wrapperAnimation = createAnimation('wrapperAnimation').keyframes([
  18902. { offset: 0, opacity: 1, transform: 'translateY(100%)' },
  18903. { offset: 1, opacity: 1, transform: `translateY(${100 - currentBreakpoint * 100}%)` },
  18904. ]);
  18905. /**
  18906. * This allows the content to be scrollable at any breakpoint.
  18907. */
  18908. const contentAnimation = !expandToScroll
  18909. ? createAnimation('contentAnimation').keyframes([
  18910. { offset: 0, opacity: 1, maxHeight: `${(1 - currentBreakpoint) * 100}%` },
  18911. { offset: 1, opacity: 1, maxHeight: `${currentBreakpoint * 100}%` },
  18912. ])
  18913. : undefined;
  18914. return { wrapperAnimation, backdropAnimation, contentAnimation };
  18915. };
  18916. const createSheetLeaveAnimation = (opts) => {
  18917. const { currentBreakpoint, backdropBreakpoint } = opts;
  18918. /**
  18919. * Backdrop does not always fade in from 0 to 1 if backdropBreakpoint
  18920. * is defined, so we need to account for that offset by figuring out
  18921. * what the current backdrop value should be.
  18922. */
  18923. const backdropValue = `calc(var(--backdrop-opacity) * ${getBackdropValueForSheet(currentBreakpoint, backdropBreakpoint)})`;
  18924. const defaultBackdrop = [
  18925. { offset: 0, opacity: backdropValue },
  18926. { offset: 1, opacity: 0 },
  18927. ];
  18928. const customBackdrop = [
  18929. { offset: 0, opacity: backdropValue },
  18930. { offset: backdropBreakpoint, opacity: 0 },
  18931. { offset: 1, opacity: 0 },
  18932. ];
  18933. const backdropAnimation = createAnimation('backdropAnimation').keyframes(backdropBreakpoint !== 0 ? customBackdrop : defaultBackdrop);
  18934. const wrapperAnimation = createAnimation('wrapperAnimation').keyframes([
  18935. { offset: 0, opacity: 1, transform: `translateY(${100 - currentBreakpoint * 100}%)` },
  18936. { offset: 1, opacity: 1, transform: `translateY(100%)` },
  18937. ]);
  18938. return { wrapperAnimation, backdropAnimation };
  18939. };
  18940. const createEnterAnimation$1 = () => {
  18941. const backdropAnimation = createAnimation()
  18942. .fromTo('opacity', 0.01, 'var(--backdrop-opacity)')
  18943. .beforeStyles({
  18944. 'pointer-events': 'none',
  18945. })
  18946. .afterClearStyles(['pointer-events']);
  18947. const wrapperAnimation = createAnimation().fromTo('transform', 'translateY(100vh)', 'translateY(0vh)');
  18948. return { backdropAnimation, wrapperAnimation, contentAnimation: undefined };
  18949. };
  18950. /**
  18951. * iOS Modal Enter Animation for the Card presentation style
  18952. */
  18953. const iosEnterAnimation$3 = (baseEl, opts) => {
  18954. const { presentingEl, currentBreakpoint, expandToScroll } = opts;
  18955. const root = getElementRoot(baseEl);
  18956. const { wrapperAnimation, backdropAnimation, contentAnimation } = currentBreakpoint !== undefined ? createSheetEnterAnimation(opts) : createEnterAnimation$1();
  18957. backdropAnimation.addElement(root.querySelector('ion-backdrop'));
  18958. wrapperAnimation.addElement(root.querySelectorAll('.modal-wrapper, .modal-shadow')).beforeStyles({ opacity: 1 });
  18959. // The content animation is only added if scrolling is enabled for
  18960. // all the breakpoints.
  18961. !expandToScroll && (contentAnimation === null || contentAnimation === void 0 ? void 0 : contentAnimation.addElement(baseEl.querySelector('.ion-page')));
  18962. const baseAnimation = createAnimation('entering-base')
  18963. .addElement(baseEl)
  18964. .easing('cubic-bezier(0.32,0.72,0,1)')
  18965. .duration(500)
  18966. .addAnimation([wrapperAnimation])
  18967. .beforeAddWrite(() => {
  18968. if (expandToScroll) {
  18969. // Scroll can only be done when the modal is fully expanded.
  18970. return;
  18971. }
  18972. /**
  18973. * There are some browsers that causes flickering when
  18974. * dragging the content when scroll is enabled at every
  18975. * breakpoint. This is due to the wrapper element being
  18976. * transformed off the screen and having a snap animation.
  18977. *
  18978. * A workaround is to clone the footer element and append
  18979. * it outside of the wrapper element. This way, the footer
  18980. * is still visible and the drag can be done without
  18981. * flickering. The original footer is hidden until the modal
  18982. * is dismissed. This maintains the animation of the footer
  18983. * when the modal is dismissed.
  18984. *
  18985. * The workaround needs to be done before the animation starts
  18986. * so there are no flickering issues.
  18987. */
  18988. const ionFooter = baseEl.querySelector('ion-footer');
  18989. /**
  18990. * This check is needed to prevent more than one footer
  18991. * from being appended to the shadow root.
  18992. * Otherwise, iOS and MD enter animations would append
  18993. * the footer twice.
  18994. */
  18995. const ionFooterAlreadyAppended = baseEl.shadowRoot.querySelector('ion-footer');
  18996. if (ionFooter && !ionFooterAlreadyAppended) {
  18997. const footerHeight = ionFooter.clientHeight;
  18998. const clonedFooter = ionFooter.cloneNode(true);
  18999. baseEl.shadowRoot.appendChild(clonedFooter);
  19000. ionFooter.style.setProperty('display', 'none');
  19001. ionFooter.setAttribute('aria-hidden', 'true');
  19002. // Padding is added to prevent some content from being hidden.
  19003. const page = baseEl.querySelector('.ion-page');
  19004. page.style.setProperty('padding-bottom', `${footerHeight}px`);
  19005. }
  19006. });
  19007. if (contentAnimation) {
  19008. baseAnimation.addAnimation(contentAnimation);
  19009. }
  19010. if (presentingEl) {
  19011. const isMobile = window.innerWidth < 768;
  19012. const hasCardModal = presentingEl.tagName === 'ION-MODAL' && presentingEl.presentingElement !== undefined;
  19013. const presentingElRoot = getElementRoot(presentingEl);
  19014. const presentingAnimation = createAnimation().beforeStyles({
  19015. transform: 'translateY(0)',
  19016. 'transform-origin': 'top center',
  19017. overflow: 'hidden',
  19018. });
  19019. const bodyEl = document.body;
  19020. if (isMobile) {
  19021. /**
  19022. * Fallback for browsers that does not support `max()` (ex: Firefox)
  19023. * No need to worry about statusbar padding since engines like Gecko
  19024. * are not used as the engine for standalone Cordova/Capacitor apps
  19025. */
  19026. const transformOffset = !CSS.supports('width', 'max(0px, 1px)') ? '30px' : 'max(30px, var(--ion-safe-area-top))';
  19027. const modalTransform = hasCardModal ? '-10px' : transformOffset;
  19028. const toPresentingScale = SwipeToCloseDefaults.MIN_PRESENTING_SCALE;
  19029. const finalTransform = `translateY(${modalTransform}) scale(${toPresentingScale})`;
  19030. presentingAnimation
  19031. .afterStyles({
  19032. transform: finalTransform,
  19033. })
  19034. .beforeAddWrite(() => bodyEl.style.setProperty('background-color', 'black'))
  19035. .addElement(presentingEl)
  19036. .keyframes([
  19037. { offset: 0, filter: 'contrast(1)', transform: 'translateY(0px) scale(1)', borderRadius: '0px' },
  19038. { offset: 1, filter: 'contrast(0.85)', transform: finalTransform, borderRadius: '10px 10px 0 0' },
  19039. ]);
  19040. baseAnimation.addAnimation(presentingAnimation);
  19041. }
  19042. else {
  19043. baseAnimation.addAnimation(backdropAnimation);
  19044. if (!hasCardModal) {
  19045. wrapperAnimation.fromTo('opacity', '0', '1');
  19046. }
  19047. else {
  19048. const toPresentingScale = hasCardModal ? SwipeToCloseDefaults.MIN_PRESENTING_SCALE : 1;
  19049. const finalTransform = `translateY(-10px) scale(${toPresentingScale})`;
  19050. presentingAnimation
  19051. .afterStyles({
  19052. transform: finalTransform,
  19053. })
  19054. .addElement(presentingElRoot.querySelector('.modal-wrapper'))
  19055. .keyframes([
  19056. { offset: 0, filter: 'contrast(1)', transform: 'translateY(0) scale(1)' },
  19057. { offset: 1, filter: 'contrast(0.85)', transform: finalTransform },
  19058. ]);
  19059. const shadowAnimation = createAnimation()
  19060. .afterStyles({
  19061. transform: finalTransform,
  19062. })
  19063. .addElement(presentingElRoot.querySelector('.modal-shadow'))
  19064. .keyframes([
  19065. { offset: 0, opacity: '1', transform: 'translateY(0) scale(1)' },
  19066. { offset: 1, opacity: '0', transform: finalTransform },
  19067. ]);
  19068. baseAnimation.addAnimation([presentingAnimation, shadowAnimation]);
  19069. }
  19070. }
  19071. }
  19072. else {
  19073. baseAnimation.addAnimation(backdropAnimation);
  19074. }
  19075. return baseAnimation;
  19076. };
  19077. const createLeaveAnimation$1 = () => {
  19078. const backdropAnimation = createAnimation().fromTo('opacity', 'var(--backdrop-opacity)', 0);
  19079. const wrapperAnimation = createAnimation().fromTo('transform', 'translateY(0vh)', 'translateY(100vh)');
  19080. return { backdropAnimation, wrapperAnimation };
  19081. };
  19082. /**
  19083. * iOS Modal Leave Animation
  19084. */
  19085. const iosLeaveAnimation$3 = (baseEl, opts, duration = 500) => {
  19086. const { presentingEl, currentBreakpoint, expandToScroll } = opts;
  19087. const root = getElementRoot(baseEl);
  19088. const { wrapperAnimation, backdropAnimation } = currentBreakpoint !== undefined ? createSheetLeaveAnimation(opts) : createLeaveAnimation$1();
  19089. backdropAnimation.addElement(root.querySelector('ion-backdrop'));
  19090. wrapperAnimation.addElement(root.querySelectorAll('.modal-wrapper, .modal-shadow')).beforeStyles({ opacity: 1 });
  19091. const baseAnimation = createAnimation('leaving-base')
  19092. .addElement(baseEl)
  19093. .easing('cubic-bezier(0.32,0.72,0,1)')
  19094. .duration(duration)
  19095. .addAnimation(wrapperAnimation)
  19096. .beforeAddWrite(() => {
  19097. if (expandToScroll) {
  19098. // Scroll can only be done when the modal is fully expanded.
  19099. return;
  19100. }
  19101. /**
  19102. * If expandToScroll is disabled, we need to swap
  19103. * the visibility to the original, so the footer
  19104. * dismisses with the modal and doesn't stay
  19105. * until the modal is removed from the DOM.
  19106. */
  19107. const ionFooter = baseEl.querySelector('ion-footer');
  19108. if (ionFooter) {
  19109. const clonedFooter = baseEl.shadowRoot.querySelector('ion-footer');
  19110. ionFooter.style.removeProperty('display');
  19111. ionFooter.removeAttribute('aria-hidden');
  19112. clonedFooter.style.setProperty('display', 'none');
  19113. clonedFooter.setAttribute('aria-hidden', 'true');
  19114. const page = baseEl.querySelector('.ion-page');
  19115. page.style.removeProperty('padding-bottom');
  19116. }
  19117. });
  19118. if (presentingEl) {
  19119. const isMobile = window.innerWidth < 768;
  19120. const hasCardModal = presentingEl.tagName === 'ION-MODAL' && presentingEl.presentingElement !== undefined;
  19121. const presentingElRoot = getElementRoot(presentingEl);
  19122. const presentingAnimation = createAnimation()
  19123. .beforeClearStyles(['transform'])
  19124. .afterClearStyles(['transform'])
  19125. .onFinish((currentStep) => {
  19126. // only reset background color if this is the last card-style modal
  19127. if (currentStep !== 1) {
  19128. return;
  19129. }
  19130. presentingEl.style.setProperty('overflow', '');
  19131. const numModals = Array.from(bodyEl.querySelectorAll('ion-modal:not(.overlay-hidden)')).filter((m) => m.presentingElement !== undefined).length;
  19132. if (numModals <= 1) {
  19133. bodyEl.style.setProperty('background-color', '');
  19134. }
  19135. });
  19136. const bodyEl = document.body;
  19137. if (isMobile) {
  19138. const transformOffset = !CSS.supports('width', 'max(0px, 1px)') ? '30px' : 'max(30px, var(--ion-safe-area-top))';
  19139. const modalTransform = hasCardModal ? '-10px' : transformOffset;
  19140. const toPresentingScale = SwipeToCloseDefaults.MIN_PRESENTING_SCALE;
  19141. const finalTransform = `translateY(${modalTransform}) scale(${toPresentingScale})`;
  19142. presentingAnimation.addElement(presentingEl).keyframes([
  19143. { offset: 0, filter: 'contrast(0.85)', transform: finalTransform, borderRadius: '10px 10px 0 0' },
  19144. { offset: 1, filter: 'contrast(1)', transform: 'translateY(0px) scale(1)', borderRadius: '0px' },
  19145. ]);
  19146. baseAnimation.addAnimation(presentingAnimation);
  19147. }
  19148. else {
  19149. baseAnimation.addAnimation(backdropAnimation);
  19150. if (!hasCardModal) {
  19151. wrapperAnimation.fromTo('opacity', '1', '0');
  19152. }
  19153. else {
  19154. const toPresentingScale = hasCardModal ? SwipeToCloseDefaults.MIN_PRESENTING_SCALE : 1;
  19155. const finalTransform = `translateY(-10px) scale(${toPresentingScale})`;
  19156. presentingAnimation
  19157. .addElement(presentingElRoot.querySelector('.modal-wrapper'))
  19158. .afterStyles({
  19159. transform: 'translate3d(0, 0, 0)',
  19160. })
  19161. .keyframes([
  19162. { offset: 0, filter: 'contrast(0.85)', transform: finalTransform },
  19163. { offset: 1, filter: 'contrast(1)', transform: 'translateY(0) scale(1)' },
  19164. ]);
  19165. const shadowAnimation = createAnimation()
  19166. .addElement(presentingElRoot.querySelector('.modal-shadow'))
  19167. .afterStyles({
  19168. transform: 'translateY(0) scale(1)',
  19169. })
  19170. .keyframes([
  19171. { offset: 0, opacity: '0', transform: finalTransform },
  19172. { offset: 1, opacity: '1', transform: 'translateY(0) scale(1)' },
  19173. ]);
  19174. baseAnimation.addAnimation([presentingAnimation, shadowAnimation]);
  19175. }
  19176. }
  19177. }
  19178. else {
  19179. baseAnimation.addAnimation(backdropAnimation);
  19180. }
  19181. return baseAnimation;
  19182. };
  19183. const createEnterAnimation = () => {
  19184. const backdropAnimation = createAnimation()
  19185. .fromTo('opacity', 0.01, 'var(--backdrop-opacity)')
  19186. .beforeStyles({
  19187. 'pointer-events': 'none',
  19188. })
  19189. .afterClearStyles(['pointer-events']);
  19190. const wrapperAnimation = createAnimation().keyframes([
  19191. { offset: 0, opacity: 0.01, transform: 'translateY(40px)' },
  19192. { offset: 1, opacity: 1, transform: `translateY(0px)` },
  19193. ]);
  19194. return { backdropAnimation, wrapperAnimation, contentAnimation: undefined };
  19195. };
  19196. /**
  19197. * Md Modal Enter Animation
  19198. */
  19199. const mdEnterAnimation$2 = (baseEl, opts) => {
  19200. const { currentBreakpoint, expandToScroll } = opts;
  19201. const root = getElementRoot(baseEl);
  19202. const { wrapperAnimation, backdropAnimation, contentAnimation } = currentBreakpoint !== undefined ? createSheetEnterAnimation(opts) : createEnterAnimation();
  19203. backdropAnimation.addElement(root.querySelector('ion-backdrop'));
  19204. wrapperAnimation.addElement(root.querySelector('.modal-wrapper'));
  19205. // The content animation is only added if scrolling is enabled for
  19206. // all the breakpoints.
  19207. expandToScroll && (contentAnimation === null || contentAnimation === void 0 ? void 0 : contentAnimation.addElement(baseEl.querySelector('.ion-page')));
  19208. const baseAnimation = createAnimation()
  19209. .addElement(baseEl)
  19210. .easing('cubic-bezier(0.36,0.66,0.04,1)')
  19211. .duration(280)
  19212. .addAnimation([backdropAnimation, wrapperAnimation])
  19213. .beforeAddWrite(() => {
  19214. if (expandToScroll) {
  19215. // Scroll can only be done when the modal is fully expanded.
  19216. return;
  19217. }
  19218. /**
  19219. * There are some browsers that causes flickering when
  19220. * dragging the content when scroll is enabled at every
  19221. * breakpoint. This is due to the wrapper element being
  19222. * transformed off the screen and having a snap animation.
  19223. *
  19224. * A workaround is to clone the footer element and append
  19225. * it outside of the wrapper element. This way, the footer
  19226. * is still visible and the drag can be done without
  19227. * flickering. The original footer is hidden until the modal
  19228. * is dismissed. This maintains the animation of the footer
  19229. * when the modal is dismissed.
  19230. *
  19231. * The workaround needs to be done before the animation starts
  19232. * so there are no flickering issues.
  19233. */
  19234. const ionFooter = baseEl.querySelector('ion-footer');
  19235. /**
  19236. * This check is needed to prevent more than one footer
  19237. * from being appended to the shadow root.
  19238. * Otherwise, iOS and MD enter animations would append
  19239. * the footer twice.
  19240. */
  19241. const ionFooterAlreadyAppended = baseEl.shadowRoot.querySelector('ion-footer');
  19242. if (ionFooter && !ionFooterAlreadyAppended) {
  19243. const footerHeight = ionFooter.clientHeight;
  19244. const clonedFooter = ionFooter.cloneNode(true);
  19245. baseEl.shadowRoot.appendChild(clonedFooter);
  19246. ionFooter.style.setProperty('display', 'none');
  19247. ionFooter.setAttribute('aria-hidden', 'true');
  19248. // Padding is added to prevent some content from being hidden.
  19249. const page = baseEl.querySelector('.ion-page');
  19250. page.style.setProperty('padding-bottom', `${footerHeight}px`);
  19251. }
  19252. });
  19253. if (contentAnimation) {
  19254. baseAnimation.addAnimation(contentAnimation);
  19255. }
  19256. return baseAnimation;
  19257. };
  19258. const createLeaveAnimation = () => {
  19259. const backdropAnimation = createAnimation().fromTo('opacity', 'var(--backdrop-opacity)', 0);
  19260. const wrapperAnimation = createAnimation().keyframes([
  19261. { offset: 0, opacity: 0.99, transform: `translateY(0px)` },
  19262. { offset: 1, opacity: 0, transform: 'translateY(40px)' },
  19263. ]);
  19264. return { backdropAnimation, wrapperAnimation };
  19265. };
  19266. /**
  19267. * Md Modal Leave Animation
  19268. */
  19269. const mdLeaveAnimation$2 = (baseEl, opts) => {
  19270. const { currentBreakpoint, expandToScroll } = opts;
  19271. const root = getElementRoot(baseEl);
  19272. const { wrapperAnimation, backdropAnimation } = currentBreakpoint !== undefined ? createSheetLeaveAnimation(opts) : createLeaveAnimation();
  19273. backdropAnimation.addElement(root.querySelector('ion-backdrop'));
  19274. wrapperAnimation.addElement(root.querySelector('.modal-wrapper'));
  19275. const baseAnimation = createAnimation()
  19276. .easing('cubic-bezier(0.47,0,0.745,0.715)')
  19277. .duration(200)
  19278. .addAnimation([backdropAnimation, wrapperAnimation])
  19279. .beforeAddWrite(() => {
  19280. if (expandToScroll) {
  19281. // Scroll can only be done when the modal is fully expanded.
  19282. return;
  19283. }
  19284. /**
  19285. * If expandToScroll is disabled, we need to swap
  19286. * the visibility to the original, so the footer
  19287. * dismisses with the modal and doesn't stay
  19288. * until the modal is removed from the DOM.
  19289. */
  19290. const ionFooter = baseEl.querySelector('ion-footer');
  19291. if (ionFooter) {
  19292. const clonedFooter = baseEl.shadowRoot.querySelector('ion-footer');
  19293. ionFooter.style.removeProperty('display');
  19294. ionFooter.removeAttribute('aria-hidden');
  19295. clonedFooter.style.setProperty('display', 'none');
  19296. clonedFooter.setAttribute('aria-hidden', 'true');
  19297. const page = baseEl.querySelector('.ion-page');
  19298. page.style.removeProperty('padding-bottom');
  19299. }
  19300. });
  19301. return baseAnimation;
  19302. };
  19303. const createSheetGesture = (baseEl, backdropEl, wrapperEl, initialBreakpoint, backdropBreakpoint, animation, breakpoints = [], expandToScroll, getCurrentBreakpoint, onDismiss, onBreakpointChange) => {
  19304. // Defaults for the sheet swipe animation
  19305. const defaultBackdrop = [
  19306. { offset: 0, opacity: 'var(--backdrop-opacity)' },
  19307. { offset: 1, opacity: 0.01 },
  19308. ];
  19309. const customBackdrop = [
  19310. { offset: 0, opacity: 'var(--backdrop-opacity)' },
  19311. { offset: 1 - backdropBreakpoint, opacity: 0 },
  19312. { offset: 1, opacity: 0 },
  19313. ];
  19314. const SheetDefaults = {
  19315. WRAPPER_KEYFRAMES: [
  19316. { offset: 0, transform: 'translateY(0%)' },
  19317. { offset: 1, transform: 'translateY(100%)' },
  19318. ],
  19319. BACKDROP_KEYFRAMES: backdropBreakpoint !== 0 ? customBackdrop : defaultBackdrop,
  19320. CONTENT_KEYFRAMES: [
  19321. { offset: 0, maxHeight: '100%' },
  19322. { offset: 1, maxHeight: '0%' },
  19323. ],
  19324. };
  19325. const contentEl = baseEl.querySelector('ion-content');
  19326. const height = wrapperEl.clientHeight;
  19327. let currentBreakpoint = initialBreakpoint;
  19328. let offset = 0;
  19329. let canDismissBlocksGesture = false;
  19330. let cachedScrollEl = null;
  19331. const canDismissMaxStep = 0.95;
  19332. const maxBreakpoint = breakpoints[breakpoints.length - 1];
  19333. const minBreakpoint = breakpoints[0];
  19334. const wrapperAnimation = animation.childAnimations.find((ani) => ani.id === 'wrapperAnimation');
  19335. const backdropAnimation = animation.childAnimations.find((ani) => ani.id === 'backdropAnimation');
  19336. const contentAnimation = animation.childAnimations.find((ani) => ani.id === 'contentAnimation');
  19337. const enableBackdrop = () => {
  19338. baseEl.style.setProperty('pointer-events', 'auto');
  19339. backdropEl.style.setProperty('pointer-events', 'auto');
  19340. /**
  19341. * When the backdrop is enabled, elements such
  19342. * as inputs should not be focusable outside
  19343. * the sheet.
  19344. */
  19345. baseEl.classList.remove(FOCUS_TRAP_DISABLE_CLASS);
  19346. };
  19347. const disableBackdrop = () => {
  19348. baseEl.style.setProperty('pointer-events', 'none');
  19349. backdropEl.style.setProperty('pointer-events', 'none');
  19350. /**
  19351. * When the backdrop is enabled, elements such
  19352. * as inputs should not be focusable outside
  19353. * the sheet.
  19354. * Adding this class disables focus trapping
  19355. * for the sheet temporarily.
  19356. */
  19357. baseEl.classList.add(FOCUS_TRAP_DISABLE_CLASS);
  19358. };
  19359. /**
  19360. * Toggles the visible modal footer when `expandToScroll` is disabled.
  19361. * @param footer The footer to show.
  19362. */
  19363. const swapFooterVisibility = (footer) => {
  19364. const originalFooter = baseEl.querySelector('ion-footer');
  19365. if (!originalFooter) {
  19366. return;
  19367. }
  19368. const clonedFooter = wrapperEl.nextElementSibling;
  19369. const footerToHide = footer === 'original' ? clonedFooter : originalFooter;
  19370. const footerToShow = footer === 'original' ? originalFooter : clonedFooter;
  19371. footerToShow.style.removeProperty('display');
  19372. footerToShow.removeAttribute('aria-hidden');
  19373. const page = baseEl.querySelector('.ion-page');
  19374. if (footer === 'original') {
  19375. page.style.removeProperty('padding-bottom');
  19376. }
  19377. else {
  19378. const pagePadding = footerToShow.clientHeight;
  19379. page.style.setProperty('padding-bottom', `${pagePadding}px`);
  19380. }
  19381. footerToHide.style.setProperty('display', 'none');
  19382. footerToHide.setAttribute('aria-hidden', 'true');
  19383. };
  19384. /**
  19385. * After the entering animation completes,
  19386. * we need to set the animation to go from
  19387. * offset 0 to offset 1 so that users can
  19388. * swipe in any direction. We then set the
  19389. * animation offset to the current breakpoint
  19390. * so there is no flickering.
  19391. */
  19392. if (wrapperAnimation && backdropAnimation) {
  19393. wrapperAnimation.keyframes([...SheetDefaults.WRAPPER_KEYFRAMES]);
  19394. backdropAnimation.keyframes([...SheetDefaults.BACKDROP_KEYFRAMES]);
  19395. contentAnimation === null || contentAnimation === void 0 ? void 0 : contentAnimation.keyframes([...SheetDefaults.CONTENT_KEYFRAMES]);
  19396. animation.progressStart(true, 1 - currentBreakpoint);
  19397. /**
  19398. * If backdrop is not enabled, then content
  19399. * behind modal should be clickable. To do this, we need
  19400. * to remove pointer-events from ion-modal as a whole.
  19401. * ion-backdrop and .modal-wrapper always have pointer-events: auto
  19402. * applied, so the modal content can still be interacted with.
  19403. */
  19404. const shouldEnableBackdrop = currentBreakpoint > backdropBreakpoint;
  19405. if (shouldEnableBackdrop) {
  19406. enableBackdrop();
  19407. }
  19408. else {
  19409. disableBackdrop();
  19410. }
  19411. }
  19412. if (contentEl && currentBreakpoint !== maxBreakpoint && expandToScroll) {
  19413. contentEl.scrollY = false;
  19414. }
  19415. const canStart = (detail) => {
  19416. /**
  19417. * If we are swiping on the content, swiping should only be possible if the content
  19418. * is scrolled all the way to the top so that we do not interfere with scrolling.
  19419. *
  19420. * We cannot assume that the `ion-content` target will remain consistent between swipes.
  19421. * For example, when using ion-nav within a modal it is possible to swipe, push a view,
  19422. * and then swipe again. The target content will not be the same between swipes.
  19423. */
  19424. const contentEl = findClosestIonContent(detail.event.target);
  19425. currentBreakpoint = getCurrentBreakpoint();
  19426. /**
  19427. * If `expandToScroll` is disabled, we should not allow the swipe gesture
  19428. * to start if the content is not scrolled to the top.
  19429. */
  19430. if (!expandToScroll && contentEl) {
  19431. const scrollEl = isIonContent(contentEl) ? getElementRoot(contentEl).querySelector('.inner-scroll') : contentEl;
  19432. return scrollEl.scrollTop === 0;
  19433. }
  19434. if (currentBreakpoint === 1 && contentEl) {
  19435. /**
  19436. * The modal should never swipe to close on the content with a refresher.
  19437. * Note 1: We cannot solve this by making this gesture have a higher priority than
  19438. * the refresher gesture as the iOS native refresh gesture uses a scroll listener in
  19439. * addition to a gesture.
  19440. *
  19441. * Note 2: Do not use getScrollElement here because we need this to be a synchronous
  19442. * operation, and getScrollElement is asynchronous.
  19443. */
  19444. const scrollEl = isIonContent(contentEl) ? getElementRoot(contentEl).querySelector('.inner-scroll') : contentEl;
  19445. const hasRefresherInContent = !!contentEl.querySelector('ion-refresher');
  19446. return !hasRefresherInContent && scrollEl.scrollTop === 0;
  19447. }
  19448. return true;
  19449. };
  19450. const onStart = (detail) => {
  19451. /**
  19452. * If canDismiss is anything other than `true`
  19453. * then users should be able to swipe down
  19454. * until a threshold is hit. At that point,
  19455. * the card modal should not proceed any further.
  19456. *
  19457. * canDismiss is never fired via gesture if there is
  19458. * no 0 breakpoint. However, it can be fired if the user
  19459. * presses Esc or the hardware back button.
  19460. * TODO (FW-937)
  19461. * Remove undefined check
  19462. */
  19463. canDismissBlocksGesture = baseEl.canDismiss !== undefined && baseEl.canDismiss !== true && minBreakpoint === 0;
  19464. /**
  19465. * Cache the scroll element reference when the gesture starts,
  19466. * this allows us to avoid querying the DOM for the target in onMove,
  19467. * which would impact performance significantly.
  19468. */
  19469. if (!expandToScroll) {
  19470. const targetEl = findClosestIonContent(detail.event.target);
  19471. cachedScrollEl =
  19472. targetEl && isIonContent(targetEl) ? getElementRoot(targetEl).querySelector('.inner-scroll') : targetEl;
  19473. }
  19474. /**
  19475. * If expandToScroll is disabled, we need to swap
  19476. * the footer visibility to the original, so if the modal
  19477. * is dismissed, the footer dismisses with the modal
  19478. * and doesn't stay on the screen after the modal is gone.
  19479. */
  19480. if (!expandToScroll) {
  19481. swapFooterVisibility('original');
  19482. }
  19483. /**
  19484. * If we are pulling down, then it is possible we are pulling on the content.
  19485. * We do not want scrolling to happen at the same time as the gesture.
  19486. */
  19487. if (detail.deltaY > 0 && contentEl) {
  19488. contentEl.scrollY = false;
  19489. }
  19490. raf(() => {
  19491. /**
  19492. * Dismisses the open keyboard when the sheet drag gesture is started.
  19493. * Sets the focus onto the modal element.
  19494. */
  19495. baseEl.focus();
  19496. });
  19497. animation.progressStart(true, 1 - currentBreakpoint);
  19498. };
  19499. const onMove = (detail) => {
  19500. /**
  19501. * If `expandToScroll` is disabled, and an upwards swipe gesture is done within
  19502. * the scrollable content, we should not allow the swipe gesture to continue.
  19503. */
  19504. if (!expandToScroll && detail.deltaY <= 0 && cachedScrollEl) {
  19505. return;
  19506. }
  19507. /**
  19508. * If we are pulling down, then it is possible we are pulling on the content.
  19509. * We do not want scrolling to happen at the same time as the gesture.
  19510. * This accounts for when the user scrolls down, scrolls all the way up, and then
  19511. * pulls down again such that the modal should start to move.
  19512. */
  19513. if (detail.deltaY > 0 && contentEl) {
  19514. contentEl.scrollY = false;
  19515. }
  19516. /**
  19517. * Given the change in gesture position on the Y axis,
  19518. * compute where the offset of the animation should be
  19519. * relative to where the user dragged.
  19520. */
  19521. const initialStep = 1 - currentBreakpoint;
  19522. const secondToLastBreakpoint = breakpoints.length > 1 ? 1 - breakpoints[1] : undefined;
  19523. const step = initialStep + detail.deltaY / height;
  19524. const isAttemptingDismissWithCanDismiss = secondToLastBreakpoint !== undefined && step >= secondToLastBreakpoint && canDismissBlocksGesture;
  19525. /**
  19526. * If we are blocking the gesture from dismissing,
  19527. * set the max step value so that the sheet cannot be
  19528. * completely hidden.
  19529. */
  19530. const maxStep = isAttemptingDismissWithCanDismiss ? canDismissMaxStep : 0.9999;
  19531. /**
  19532. * If we are blocking the gesture from
  19533. * dismissing, calculate the spring modifier value
  19534. * this will be added to the starting breakpoint
  19535. * value to give the gesture a spring-like feeling.
  19536. * Note that when isAttemptingDismissWithCanDismiss is true,
  19537. * the modifier is always added to the breakpoint that
  19538. * appears right after the 0 breakpoint.
  19539. *
  19540. * Note that this modifier is essentially the progression
  19541. * between secondToLastBreakpoint and maxStep which is
  19542. * why we subtract secondToLastBreakpoint. This lets us get
  19543. * the result as a value from 0 to 1.
  19544. */
  19545. const processedStep = isAttemptingDismissWithCanDismiss && secondToLastBreakpoint !== undefined
  19546. ? secondToLastBreakpoint +
  19547. calculateSpringStep((step - secondToLastBreakpoint) / (maxStep - secondToLastBreakpoint))
  19548. : step;
  19549. offset = clamp(0.0001, processedStep, maxStep);
  19550. animation.progressStep(offset);
  19551. };
  19552. const onEnd = (detail) => {
  19553. /**
  19554. * If expandToScroll is disabled, we should not allow the moveSheetToBreakpoint
  19555. * function to be called if the user is trying to swipe content upwards and the content
  19556. * is not scrolled to the top.
  19557. */
  19558. if (!expandToScroll && detail.deltaY <= 0 && cachedScrollEl && cachedScrollEl.scrollTop > 0) {
  19559. return;
  19560. }
  19561. /**
  19562. * When the gesture releases, we need to determine
  19563. * the closest breakpoint to snap to.
  19564. */
  19565. const velocity = detail.velocityY;
  19566. const threshold = (detail.deltaY + velocity * 350) / height;
  19567. const diff = currentBreakpoint - threshold;
  19568. const closest = breakpoints.reduce((a, b) => {
  19569. return Math.abs(b - diff) < Math.abs(a - diff) ? b : a;
  19570. });
  19571. moveSheetToBreakpoint({
  19572. breakpoint: closest,
  19573. breakpointOffset: offset,
  19574. canDismiss: canDismissBlocksGesture,
  19575. /**
  19576. * The swipe is user-driven, so we should
  19577. * always animate when the gesture ends.
  19578. */
  19579. animated: true,
  19580. });
  19581. };
  19582. const moveSheetToBreakpoint = (options) => {
  19583. const { breakpoint, canDismiss, breakpointOffset, animated } = options;
  19584. /**
  19585. * canDismiss should only prevent snapping
  19586. * when users are trying to dismiss. If canDismiss
  19587. * is present but the user is trying to swipe upwards,
  19588. * we should allow that to happen,
  19589. */
  19590. const shouldPreventDismiss = canDismiss && breakpoint === 0;
  19591. const snapToBreakpoint = shouldPreventDismiss ? currentBreakpoint : breakpoint;
  19592. const shouldRemainOpen = snapToBreakpoint !== 0;
  19593. currentBreakpoint = 0;
  19594. /**
  19595. * Update the animation so that it plays from
  19596. * the last offset to the closest snap point.
  19597. */
  19598. if (wrapperAnimation && backdropAnimation) {
  19599. wrapperAnimation.keyframes([
  19600. { offset: 0, transform: `translateY(${breakpointOffset * 100}%)` },
  19601. { offset: 1, transform: `translateY(${(1 - snapToBreakpoint) * 100}%)` },
  19602. ]);
  19603. backdropAnimation.keyframes([
  19604. {
  19605. offset: 0,
  19606. opacity: `calc(var(--backdrop-opacity) * ${getBackdropValueForSheet(1 - breakpointOffset, backdropBreakpoint)})`,
  19607. },
  19608. {
  19609. offset: 1,
  19610. opacity: `calc(var(--backdrop-opacity) * ${getBackdropValueForSheet(snapToBreakpoint, backdropBreakpoint)})`,
  19611. },
  19612. ]);
  19613. if (contentAnimation) {
  19614. /**
  19615. * The modal content should scroll at any breakpoint when expandToScroll
  19616. * is disabled. In order to do this, the content needs to be completely
  19617. * viewable so scrolling can access everything. Otherwise, the default
  19618. * behavior would show the content off the screen and only allow
  19619. * scrolling when the sheet is fully expanded.
  19620. */
  19621. contentAnimation.keyframes([
  19622. { offset: 0, maxHeight: `${(1 - breakpointOffset) * 100}%` },
  19623. { offset: 1, maxHeight: `${snapToBreakpoint * 100}%` },
  19624. ]);
  19625. }
  19626. animation.progressStep(0);
  19627. }
  19628. /**
  19629. * Gesture should remain disabled until the
  19630. * snapping animation completes.
  19631. */
  19632. gesture.enable(false);
  19633. /**
  19634. * If expandToScroll is disabled, we need to swap
  19635. * the footer visibility to the cloned one so the footer
  19636. * doesn't flicker when the sheet's height is animated.
  19637. */
  19638. if (!expandToScroll && shouldRemainOpen) {
  19639. swapFooterVisibility('cloned');
  19640. }
  19641. if (shouldPreventDismiss) {
  19642. handleCanDismiss(baseEl, animation);
  19643. }
  19644. else if (!shouldRemainOpen) {
  19645. onDismiss();
  19646. }
  19647. /**
  19648. * Enables scrolling immediately if the sheet is about to fully expand
  19649. * or if it allows scrolling at any breakpoint. Without this, there would
  19650. * be a ~500ms delay while the modal animation completes, causing a
  19651. * noticeable lag. Native iOS allows scrolling as soon as the gesture is
  19652. * released, so we align with that behavior.
  19653. */
  19654. if (contentEl && (snapToBreakpoint === breakpoints[breakpoints.length - 1] || !expandToScroll)) {
  19655. contentEl.scrollY = true;
  19656. }
  19657. return new Promise((resolve) => {
  19658. animation
  19659. .onFinish(() => {
  19660. if (shouldRemainOpen) {
  19661. /**
  19662. * Once the snapping animation completes,
  19663. * we need to reset the animation to go
  19664. * from 0 to 1 so users can swipe in any direction.
  19665. * We then set the animation offset to the current
  19666. * breakpoint so that it starts at the snapped position.
  19667. */
  19668. if (wrapperAnimation && backdropAnimation) {
  19669. raf(() => {
  19670. wrapperAnimation.keyframes([...SheetDefaults.WRAPPER_KEYFRAMES]);
  19671. backdropAnimation.keyframes([...SheetDefaults.BACKDROP_KEYFRAMES]);
  19672. contentAnimation === null || contentAnimation === void 0 ? void 0 : contentAnimation.keyframes([...SheetDefaults.CONTENT_KEYFRAMES]);
  19673. animation.progressStart(true, 1 - snapToBreakpoint);
  19674. currentBreakpoint = snapToBreakpoint;
  19675. onBreakpointChange(currentBreakpoint);
  19676. /**
  19677. * Backdrop should become enabled
  19678. * after the backdropBreakpoint value
  19679. */
  19680. const shouldEnableBackdrop = currentBreakpoint > backdropBreakpoint;
  19681. if (shouldEnableBackdrop) {
  19682. enableBackdrop();
  19683. }
  19684. else {
  19685. disableBackdrop();
  19686. }
  19687. gesture.enable(true);
  19688. resolve();
  19689. });
  19690. }
  19691. else {
  19692. gesture.enable(true);
  19693. resolve();
  19694. }
  19695. }
  19696. else {
  19697. resolve();
  19698. }
  19699. /**
  19700. * This must be a one time callback
  19701. * otherwise a new callback will
  19702. * be added every time onEnd runs.
  19703. */
  19704. }, { oneTimeCallback: true })
  19705. .progressEnd(1, 0, animated ? 500 : 0);
  19706. });
  19707. };
  19708. const gesture = createGesture({
  19709. el: wrapperEl,
  19710. gestureName: 'modalSheet',
  19711. gesturePriority: 40,
  19712. direction: 'y',
  19713. threshold: 10,
  19714. canStart,
  19715. onStart,
  19716. onMove,
  19717. onEnd,
  19718. });
  19719. return {
  19720. gesture,
  19721. moveSheetToBreakpoint,
  19722. };
  19723. };
  19724. const modalIosCss = ":host{--width:100%;--min-width:auto;--max-width:auto;--height:100%;--min-height:auto;--max-height:auto;--overflow:hidden;--border-radius:0;--border-width:0;--border-style:none;--border-color:transparent;--background:var(--ion-background-color, #fff);--box-shadow:none;--backdrop-opacity:0;left:0;right:0;top:0;bottom:0;display:-ms-flexbox;display:flex;position:absolute;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;outline:none;color:var(--ion-text-color, #000);contain:strict}.modal-wrapper,ion-backdrop{pointer-events:auto}:host(.overlay-hidden){display:none}.modal-wrapper,.modal-shadow{border-radius:var(--border-radius);width:var(--width);min-width:var(--min-width);max-width:var(--max-width);height:var(--height);min-height:var(--min-height);max-height:var(--max-height);border-width:var(--border-width);border-style:var(--border-style);border-color:var(--border-color);background:var(--background);-webkit-box-shadow:var(--box-shadow);box-shadow:var(--box-shadow);overflow:var(--overflow);z-index:10}.modal-shadow{position:absolute;background:transparent}@media only screen and (min-width: 768px) and (min-height: 600px){:host{--width:600px;--height:500px;--ion-safe-area-top:0px;--ion-safe-area-bottom:0px;--ion-safe-area-right:0px;--ion-safe-area-left:0px}}@media only screen and (min-width: 768px) and (min-height: 768px){:host{--width:600px;--height:600px}}.modal-handle{left:0px;right:0px;top:5px;border-radius:8px;-webkit-margin-start:auto;margin-inline-start:auto;-webkit-margin-end:auto;margin-inline-end:auto;position:absolute;width:36px;height:5px;-webkit-transform:translateZ(0);transform:translateZ(0);border:0;background:var(--ion-color-step-350, var(--ion-background-color-step-350, #c0c0be));cursor:pointer;z-index:11}.modal-handle::before{-webkit-padding-start:4px;padding-inline-start:4px;-webkit-padding-end:4px;padding-inline-end:4px;padding-top:4px;padding-bottom:4px;position:absolute;width:36px;height:5px;-webkit-transform:translate(-50%, -50%);transform:translate(-50%, -50%);content:\"\"}:host(.modal-sheet){--height:calc(100% - (var(--ion-safe-area-top) + 10px))}:host(.modal-sheet) .modal-wrapper,:host(.modal-sheet) .modal-shadow{position:absolute;bottom:0}:host(.modal-sheet.modal-no-expand-scroll) ion-footer{position:absolute;bottom:0;width:var(--width)}:host{--backdrop-opacity:var(--ion-backdrop-opacity, 0.4)}:host(.modal-card),:host(.modal-sheet){--border-radius:10px}@media only screen and (min-width: 768px) and (min-height: 600px){:host{--border-radius:10px}}.modal-wrapper{-webkit-transform:translate3d(0, 100%, 0);transform:translate3d(0, 100%, 0)}@media screen and (max-width: 767px){@supports (width: max(0px, 1px)){:host(.modal-card){--height:calc(100% - max(30px, var(--ion-safe-area-top)) - 10px)}}@supports not (width: max(0px, 1px)){:host(.modal-card){--height:calc(100% - 40px)}}:host(.modal-card) .modal-wrapper{border-start-start-radius:var(--border-radius);border-start-end-radius:var(--border-radius);border-end-end-radius:0;border-end-start-radius:0}:host(.modal-card){--backdrop-opacity:0;--width:100%;-ms-flex-align:end;align-items:flex-end}:host(.modal-card) .modal-shadow{display:none}:host(.modal-card) ion-backdrop{pointer-events:none}}@media screen and (min-width: 768px){:host(.modal-card){--width:calc(100% - 120px);--height:calc(100% - (120px + var(--ion-safe-area-top) + var(--ion-safe-area-bottom)));--max-width:720px;--max-height:1000px;--backdrop-opacity:0;--box-shadow:0px 0px 30px 10px rgba(0, 0, 0, 0.1);-webkit-transition:all 0.5s ease-in-out;transition:all 0.5s ease-in-out}:host(.modal-card) .modal-wrapper{-webkit-box-shadow:none;box-shadow:none}:host(.modal-card) .modal-shadow{-webkit-box-shadow:var(--box-shadow);box-shadow:var(--box-shadow)}}:host(.modal-sheet) .modal-wrapper{border-start-start-radius:var(--border-radius);border-start-end-radius:var(--border-radius);border-end-end-radius:0;border-end-start-radius:0}:host(.modal-sheet.modal-no-expand-scroll) ion-footer ion-toolbar:first-of-type{padding-top:6px}";
  19725. var IonModalIosStyle0 = modalIosCss;
  19726. const modalMdCss = ":host{--width:100%;--min-width:auto;--max-width:auto;--height:100%;--min-height:auto;--max-height:auto;--overflow:hidden;--border-radius:0;--border-width:0;--border-style:none;--border-color:transparent;--background:var(--ion-background-color, #fff);--box-shadow:none;--backdrop-opacity:0;left:0;right:0;top:0;bottom:0;display:-ms-flexbox;display:flex;position:absolute;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;outline:none;color:var(--ion-text-color, #000);contain:strict}.modal-wrapper,ion-backdrop{pointer-events:auto}:host(.overlay-hidden){display:none}.modal-wrapper,.modal-shadow{border-radius:var(--border-radius);width:var(--width);min-width:var(--min-width);max-width:var(--max-width);height:var(--height);min-height:var(--min-height);max-height:var(--max-height);border-width:var(--border-width);border-style:var(--border-style);border-color:var(--border-color);background:var(--background);-webkit-box-shadow:var(--box-shadow);box-shadow:var(--box-shadow);overflow:var(--overflow);z-index:10}.modal-shadow{position:absolute;background:transparent}@media only screen and (min-width: 768px) and (min-height: 600px){:host{--width:600px;--height:500px;--ion-safe-area-top:0px;--ion-safe-area-bottom:0px;--ion-safe-area-right:0px;--ion-safe-area-left:0px}}@media only screen and (min-width: 768px) and (min-height: 768px){:host{--width:600px;--height:600px}}.modal-handle{left:0px;right:0px;top:5px;border-radius:8px;-webkit-margin-start:auto;margin-inline-start:auto;-webkit-margin-end:auto;margin-inline-end:auto;position:absolute;width:36px;height:5px;-webkit-transform:translateZ(0);transform:translateZ(0);border:0;background:var(--ion-color-step-350, var(--ion-background-color-step-350, #c0c0be));cursor:pointer;z-index:11}.modal-handle::before{-webkit-padding-start:4px;padding-inline-start:4px;-webkit-padding-end:4px;padding-inline-end:4px;padding-top:4px;padding-bottom:4px;position:absolute;width:36px;height:5px;-webkit-transform:translate(-50%, -50%);transform:translate(-50%, -50%);content:\"\"}:host(.modal-sheet){--height:calc(100% - (var(--ion-safe-area-top) + 10px))}:host(.modal-sheet) .modal-wrapper,:host(.modal-sheet) .modal-shadow{position:absolute;bottom:0}:host(.modal-sheet.modal-no-expand-scroll) ion-footer{position:absolute;bottom:0;width:var(--width)}:host{--backdrop-opacity:var(--ion-backdrop-opacity, 0.32)}@media only screen and (min-width: 768px) and (min-height: 600px){:host{--border-radius:2px;--box-shadow:0 28px 48px rgba(0, 0, 0, 0.4)}}.modal-wrapper{-webkit-transform:translate3d(0, 40px, 0);transform:translate3d(0, 40px, 0);opacity:0.01}";
  19727. var IonModalMdStyle0 = modalMdCss;
  19728. // TODO(FW-2832): types
  19729. /**
  19730. * @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
  19731. *
  19732. * @slot - Content is placed inside of the `.modal-content` element.
  19733. *
  19734. * @part backdrop - The `ion-backdrop` element.
  19735. * @part content - The wrapper element for the default slot.
  19736. * @part handle - The handle that is displayed at the top of the sheet modal when `handle="true"`.
  19737. */
  19738. class Modal {
  19739. constructor(hostRef) {
  19740. registerInstance(this, hostRef);
  19741. this.didPresent = createEvent(this, "ionModalDidPresent", 7);
  19742. this.willPresent = createEvent(this, "ionModalWillPresent", 7);
  19743. this.willDismiss = createEvent(this, "ionModalWillDismiss", 7);
  19744. this.didDismiss = createEvent(this, "ionModalDidDismiss", 7);
  19745. this.ionBreakpointDidChange = createEvent(this, "ionBreakpointDidChange", 7);
  19746. this.didPresentShorthand = createEvent(this, "didPresent", 7);
  19747. this.willPresentShorthand = createEvent(this, "willPresent", 7);
  19748. this.willDismissShorthand = createEvent(this, "willDismiss", 7);
  19749. this.didDismissShorthand = createEvent(this, "didDismiss", 7);
  19750. this.ionMount = createEvent(this, "ionMount", 7);
  19751. this.lockController = createLockController();
  19752. this.triggerController = createTriggerController();
  19753. this.coreDelegate = CoreDelegate();
  19754. this.isSheetModal = false;
  19755. this.inheritedAttributes = {};
  19756. this.inline = false;
  19757. // Whether or not modal is being dismissed via gesture
  19758. this.gestureAnimationDismissing = false;
  19759. this.onHandleClick = () => {
  19760. const { sheetTransition, handleBehavior } = this;
  19761. if (handleBehavior !== 'cycle' || sheetTransition !== undefined) {
  19762. /**
  19763. * The sheet modal should not advance to the next breakpoint
  19764. * if the handle behavior is not `cycle` or if the handle
  19765. * is clicked while the sheet is moving to a breakpoint.
  19766. */
  19767. return;
  19768. }
  19769. this.moveToNextBreakpoint();
  19770. };
  19771. this.onBackdropTap = () => {
  19772. const { sheetTransition } = this;
  19773. if (sheetTransition !== undefined) {
  19774. /**
  19775. * When the handle is double clicked at the largest breakpoint,
  19776. * it will start to move to the first breakpoint. While transitioning,
  19777. * the backdrop will often receive the second click. We prevent the
  19778. * backdrop from dismissing the modal while moving between breakpoints.
  19779. */
  19780. return;
  19781. }
  19782. this.dismiss(undefined, BACKDROP);
  19783. };
  19784. this.onLifecycle = (modalEvent) => {
  19785. const el = this.usersElement;
  19786. const name = LIFECYCLE_MAP$1[modalEvent.type];
  19787. if (el && name) {
  19788. const ev = new CustomEvent(name, {
  19789. bubbles: false,
  19790. cancelable: false,
  19791. detail: modalEvent.detail,
  19792. });
  19793. el.dispatchEvent(ev);
  19794. }
  19795. };
  19796. this.presented = false;
  19797. this.hasController = false;
  19798. this.overlayIndex = undefined;
  19799. this.delegate = undefined;
  19800. this.keyboardClose = true;
  19801. this.enterAnimation = undefined;
  19802. this.leaveAnimation = undefined;
  19803. this.breakpoints = undefined;
  19804. this.expandToScroll = true;
  19805. this.initialBreakpoint = undefined;
  19806. this.backdropBreakpoint = 0;
  19807. this.handle = undefined;
  19808. this.handleBehavior = 'none';
  19809. this.component = undefined;
  19810. this.componentProps = undefined;
  19811. this.cssClass = undefined;
  19812. this.backdropDismiss = true;
  19813. this.showBackdrop = true;
  19814. this.animated = true;
  19815. this.presentingElement = undefined;
  19816. this.htmlAttributes = undefined;
  19817. this.isOpen = false;
  19818. this.trigger = undefined;
  19819. this.keepContentsMounted = false;
  19820. this.focusTrap = true;
  19821. this.canDismiss = true;
  19822. }
  19823. onIsOpenChange(newValue, oldValue) {
  19824. if (newValue === true && oldValue === false) {
  19825. this.present();
  19826. }
  19827. else if (newValue === false && oldValue === true) {
  19828. this.dismiss();
  19829. }
  19830. }
  19831. triggerChanged() {
  19832. const { trigger, el, triggerController } = this;
  19833. if (trigger) {
  19834. triggerController.addClickListener(el, trigger);
  19835. }
  19836. }
  19837. breakpointsChanged(breakpoints) {
  19838. if (breakpoints !== undefined) {
  19839. this.sortedBreakpoints = breakpoints.sort((a, b) => a - b);
  19840. }
  19841. }
  19842. connectedCallback() {
  19843. const { el } = this;
  19844. prepareOverlay(el);
  19845. this.triggerChanged();
  19846. }
  19847. disconnectedCallback() {
  19848. this.triggerController.removeClickListener();
  19849. }
  19850. componentWillLoad() {
  19851. var _a;
  19852. const { breakpoints, initialBreakpoint, el, htmlAttributes } = this;
  19853. const isSheetModal = (this.isSheetModal = breakpoints !== undefined && initialBreakpoint !== undefined);
  19854. const attributesToInherit = ['aria-label', 'role'];
  19855. this.inheritedAttributes = inheritAttributes$1(el, attributesToInherit);
  19856. /**
  19857. * When using a controller modal you can set attributes
  19858. * using the htmlAttributes property. Since the above attributes
  19859. * need to be inherited inside of the modal, we need to look
  19860. * and see if these attributes are being set via htmlAttributes.
  19861. *
  19862. * We could alternatively move this to componentDidLoad to simplify the work
  19863. * here, but we'd then need to make inheritedAttributes a State variable,
  19864. * thus causing another render to always happen after the first render.
  19865. */
  19866. if (htmlAttributes !== undefined) {
  19867. attributesToInherit.forEach((attribute) => {
  19868. const attributeValue = htmlAttributes[attribute];
  19869. if (attributeValue) {
  19870. /**
  19871. * If an attribute we need to inherit was
  19872. * set using htmlAttributes then add it to
  19873. * inheritedAttributes and remove it from htmlAttributes.
  19874. * This ensures the attribute is inherited and not
  19875. * set on the host.
  19876. *
  19877. * In this case, if an inherited attribute is set
  19878. * on the host element and using htmlAttributes then
  19879. * htmlAttributes wins, but that's not a pattern that we recommend.
  19880. * The only time you'd need htmlAttributes is when using modalController.
  19881. */
  19882. this.inheritedAttributes = Object.assign(Object.assign({}, this.inheritedAttributes), { [attribute]: htmlAttributes[attribute] });
  19883. delete htmlAttributes[attribute];
  19884. }
  19885. });
  19886. }
  19887. if (isSheetModal) {
  19888. this.currentBreakpoint = this.initialBreakpoint;
  19889. }
  19890. if (breakpoints !== undefined && initialBreakpoint !== undefined && !breakpoints.includes(initialBreakpoint)) {
  19891. printIonWarning('[ion-modal] - Your breakpoints array must include the initialBreakpoint value.');
  19892. }
  19893. if (!((_a = this.htmlAttributes) === null || _a === void 0 ? void 0 : _a.id)) {
  19894. setOverlayId(this.el);
  19895. }
  19896. }
  19897. componentDidLoad() {
  19898. /**
  19899. * If modal was rendered with isOpen="true"
  19900. * then we should open modal immediately.
  19901. */
  19902. if (this.isOpen === true) {
  19903. raf(() => this.present());
  19904. }
  19905. this.breakpointsChanged(this.breakpoints);
  19906. /**
  19907. * When binding values in frameworks such as Angular
  19908. * it is possible for the value to be set after the Web Component
  19909. * initializes but before the value watcher is set up in Stencil.
  19910. * As a result, the watcher callback may not be fired.
  19911. * We work around this by manually calling the watcher
  19912. * callback when the component has loaded and the watcher
  19913. * is configured.
  19914. */
  19915. this.triggerChanged();
  19916. }
  19917. /**
  19918. * Determines whether or not an overlay
  19919. * is being used inline or via a controller/JS
  19920. * and returns the correct delegate.
  19921. * By default, subsequent calls to getDelegate
  19922. * will use a cached version of the delegate.
  19923. * This is useful for calling dismiss after
  19924. * present so that the correct delegate is given.
  19925. */
  19926. getDelegate(force = false) {
  19927. if (this.workingDelegate && !force) {
  19928. return {
  19929. delegate: this.workingDelegate,
  19930. inline: this.inline,
  19931. };
  19932. }
  19933. /**
  19934. * If using overlay inline
  19935. * we potentially need to use the coreDelegate
  19936. * so that this works in vanilla JS apps.
  19937. * If a developer has presented this component
  19938. * via a controller, then we can assume
  19939. * the component is already in the
  19940. * correct place.
  19941. */
  19942. const parentEl = this.el.parentNode;
  19943. const inline = (this.inline = parentEl !== null && !this.hasController);
  19944. const delegate = (this.workingDelegate = inline ? this.delegate || this.coreDelegate : this.delegate);
  19945. return { inline, delegate };
  19946. }
  19947. /**
  19948. * Determines whether or not the
  19949. * modal is allowed to dismiss based
  19950. * on the state of the canDismiss prop.
  19951. */
  19952. async checkCanDismiss(data, role) {
  19953. const { canDismiss } = this;
  19954. if (typeof canDismiss === 'function') {
  19955. return canDismiss(data, role);
  19956. }
  19957. return canDismiss;
  19958. }
  19959. /**
  19960. * Present the modal overlay after it has been created.
  19961. */
  19962. async present() {
  19963. const unlock = await this.lockController.lock();
  19964. if (this.presented) {
  19965. unlock();
  19966. return;
  19967. }
  19968. const { presentingElement, el } = this;
  19969. /**
  19970. * If the modal is presented multiple times (inline modals), we
  19971. * need to reset the current breakpoint to the initial breakpoint.
  19972. */
  19973. this.currentBreakpoint = this.initialBreakpoint;
  19974. const { inline, delegate } = this.getDelegate(true);
  19975. /**
  19976. * Emit ionMount so JS Frameworks have an opportunity
  19977. * to add the child component to the DOM. The child
  19978. * component will be assigned to this.usersElement below.
  19979. */
  19980. this.ionMount.emit();
  19981. this.usersElement = await attachComponent(delegate, el, this.component, ['ion-page'], this.componentProps, inline);
  19982. /**
  19983. * When using the lazy loaded build of Stencil, we need to wait
  19984. * for every Stencil component instance to be ready before presenting
  19985. * otherwise there can be a flash of unstyled content. With the
  19986. * custom elements bundle we need to wait for the JS framework
  19987. * mount the inner contents of the overlay otherwise WebKit may
  19988. * get the transition incorrect.
  19989. */
  19990. if (hasLazyBuild(el)) {
  19991. await deepReady(this.usersElement);
  19992. /**
  19993. * If keepContentsMounted="true" then the
  19994. * JS Framework has already mounted the inner
  19995. * contents so there is no need to wait.
  19996. * Otherwise, we need to wait for the JS
  19997. * Framework to mount the inner contents
  19998. * of this component.
  19999. */
  20000. }
  20001. else if (!this.keepContentsMounted) {
  20002. await waitForMount();
  20003. }
  20004. writeTask(() => this.el.classList.add('show-modal'));
  20005. const hasCardModal = presentingElement !== undefined;
  20006. /**
  20007. * We need to change the status bar at the
  20008. * start of the animation so that it completes
  20009. * by the time the card animation is done.
  20010. */
  20011. if (hasCardModal && getIonMode$1(this) === 'ios') {
  20012. // Cache the original status bar color before the modal is presented
  20013. this.statusBarStyle = await StatusBar.getStyle();
  20014. setCardStatusBarDark();
  20015. }
  20016. await present(this, 'modalEnter', iosEnterAnimation$3, mdEnterAnimation$2, {
  20017. presentingEl: presentingElement,
  20018. currentBreakpoint: this.initialBreakpoint,
  20019. backdropBreakpoint: this.backdropBreakpoint,
  20020. expandToScroll: this.expandToScroll,
  20021. });
  20022. /* tslint:disable-next-line */
  20023. if (typeof window !== 'undefined') {
  20024. /**
  20025. * This needs to be setup before any
  20026. * non-transition async work so it can be dereferenced
  20027. * in the dismiss method. The dismiss method
  20028. * only waits for the entering transition
  20029. * to finish. It does not wait for all of the `present`
  20030. * method to resolve.
  20031. */
  20032. this.keyboardOpenCallback = () => {
  20033. if (this.gesture) {
  20034. /**
  20035. * When the native keyboard is opened and the webview
  20036. * is resized, the gesture implementation will become unresponsive
  20037. * and enter a free-scroll mode.
  20038. *
  20039. * When the keyboard is opened, we disable the gesture for
  20040. * a single frame and re-enable once the contents have repositioned
  20041. * from the keyboard placement.
  20042. */
  20043. this.gesture.enable(false);
  20044. raf(() => {
  20045. if (this.gesture) {
  20046. this.gesture.enable(true);
  20047. }
  20048. });
  20049. }
  20050. };
  20051. window.addEventListener(KEYBOARD_DID_OPEN, this.keyboardOpenCallback);
  20052. }
  20053. if (this.isSheetModal) {
  20054. this.initSheetGesture();
  20055. }
  20056. else if (hasCardModal) {
  20057. this.initSwipeToClose();
  20058. }
  20059. unlock();
  20060. }
  20061. initSwipeToClose() {
  20062. var _a;
  20063. if (getIonMode$1(this) !== 'ios') {
  20064. return;
  20065. }
  20066. const { el } = this;
  20067. // All of the elements needed for the swipe gesture
  20068. // should be in the DOM and referenced by now, except
  20069. // for the presenting el
  20070. const animationBuilder = this.leaveAnimation || config.get('modalLeave', iosLeaveAnimation$3);
  20071. const ani = (this.animation = animationBuilder(el, {
  20072. presentingEl: this.presentingElement,
  20073. expandToScroll: this.expandToScroll,
  20074. }));
  20075. const contentEl = findIonContent(el);
  20076. if (!contentEl) {
  20077. printIonContentErrorMsg(el);
  20078. return;
  20079. }
  20080. const statusBarStyle = (_a = this.statusBarStyle) !== null && _a !== void 0 ? _a : Style.Default;
  20081. this.gesture = createSwipeToCloseGesture(el, ani, statusBarStyle, () => {
  20082. /**
  20083. * While the gesture animation is finishing
  20084. * it is possible for a user to tap the backdrop.
  20085. * This would result in the dismiss animation
  20086. * being played again. Typically this is avoided
  20087. * by setting `presented = false` on the overlay
  20088. * component; however, we cannot do that here as
  20089. * that would prevent the element from being
  20090. * removed from the DOM.
  20091. */
  20092. this.gestureAnimationDismissing = true;
  20093. /**
  20094. * Reset the status bar style as the dismiss animation
  20095. * starts otherwise the status bar will be the wrong
  20096. * color for the duration of the dismiss animation.
  20097. * The dismiss method does this as well, but
  20098. * in this case it's only called once the animation
  20099. * has finished.
  20100. */
  20101. setCardStatusBarDefault(this.statusBarStyle);
  20102. this.animation.onFinish(async () => {
  20103. await this.dismiss(undefined, GESTURE);
  20104. this.gestureAnimationDismissing = false;
  20105. });
  20106. });
  20107. this.gesture.enable(true);
  20108. }
  20109. initSheetGesture() {
  20110. const { wrapperEl, initialBreakpoint, backdropBreakpoint } = this;
  20111. if (!wrapperEl || initialBreakpoint === undefined) {
  20112. return;
  20113. }
  20114. const animationBuilder = this.enterAnimation || config.get('modalEnter', iosEnterAnimation$3);
  20115. const ani = (this.animation = animationBuilder(this.el, {
  20116. presentingEl: this.presentingElement,
  20117. currentBreakpoint: initialBreakpoint,
  20118. backdropBreakpoint,
  20119. expandToScroll: this.expandToScroll,
  20120. }));
  20121. ani.progressStart(true, 1);
  20122. const { gesture, moveSheetToBreakpoint } = createSheetGesture(this.el, this.backdropEl, wrapperEl, initialBreakpoint, backdropBreakpoint, ani, this.sortedBreakpoints, this.expandToScroll, () => { var _a; return (_a = this.currentBreakpoint) !== null && _a !== void 0 ? _a : 0; }, () => this.sheetOnDismiss(), (breakpoint) => {
  20123. if (this.currentBreakpoint !== breakpoint) {
  20124. this.currentBreakpoint = breakpoint;
  20125. this.ionBreakpointDidChange.emit({ breakpoint });
  20126. }
  20127. });
  20128. this.gesture = gesture;
  20129. this.moveSheetToBreakpoint = moveSheetToBreakpoint;
  20130. this.gesture.enable(true);
  20131. }
  20132. sheetOnDismiss() {
  20133. /**
  20134. * While the gesture animation is finishing
  20135. * it is possible for a user to tap the backdrop.
  20136. * This would result in the dismiss animation
  20137. * being played again. Typically this is avoided
  20138. * by setting `presented = false` on the overlay
  20139. * component; however, we cannot do that here as
  20140. * that would prevent the element from being
  20141. * removed from the DOM.
  20142. */
  20143. this.gestureAnimationDismissing = true;
  20144. this.animation.onFinish(async () => {
  20145. this.currentBreakpoint = 0;
  20146. this.ionBreakpointDidChange.emit({ breakpoint: this.currentBreakpoint });
  20147. await this.dismiss(undefined, GESTURE);
  20148. this.gestureAnimationDismissing = false;
  20149. });
  20150. }
  20151. /**
  20152. * Dismiss the modal overlay after it has been presented.
  20153. *
  20154. * @param data Any data to emit in the dismiss events.
  20155. * @param role The role of the element that is dismissing the modal. For example, 'cancel' or 'backdrop'.
  20156. *
  20157. * This is a no-op if the overlay has not been presented yet. If you want
  20158. * to remove an overlay from the DOM that was never presented, use the
  20159. * [remove](https://developer.mozilla.org/en-US/docs/Web/API/Element/remove) method.
  20160. */
  20161. async dismiss(data, role) {
  20162. var _a;
  20163. if (this.gestureAnimationDismissing && role !== GESTURE) {
  20164. return false;
  20165. }
  20166. /**
  20167. * Because the canDismiss check below is async,
  20168. * we need to claim a lock before the check happens,
  20169. * in case the dismiss transition does run.
  20170. */
  20171. const unlock = await this.lockController.lock();
  20172. /**
  20173. * If a canDismiss handler is responsible
  20174. * for calling the dismiss method, we should
  20175. * not run the canDismiss check again.
  20176. */
  20177. if (role !== 'handler' && !(await this.checkCanDismiss(data, role))) {
  20178. unlock();
  20179. return false;
  20180. }
  20181. const { presentingElement } = this;
  20182. /**
  20183. * We need to start the status bar change
  20184. * before the animation so that the change
  20185. * finishes when the dismiss animation does.
  20186. */
  20187. const hasCardModal = presentingElement !== undefined;
  20188. if (hasCardModal && getIonMode$1(this) === 'ios') {
  20189. setCardStatusBarDefault(this.statusBarStyle);
  20190. }
  20191. /* tslint:disable-next-line */
  20192. if (typeof window !== 'undefined' && this.keyboardOpenCallback) {
  20193. window.removeEventListener(KEYBOARD_DID_OPEN, this.keyboardOpenCallback);
  20194. this.keyboardOpenCallback = undefined;
  20195. }
  20196. const dismissed = await dismiss(this, data, role, 'modalLeave', iosLeaveAnimation$3, mdLeaveAnimation$2, {
  20197. presentingEl: presentingElement,
  20198. currentBreakpoint: (_a = this.currentBreakpoint) !== null && _a !== void 0 ? _a : this.initialBreakpoint,
  20199. backdropBreakpoint: this.backdropBreakpoint,
  20200. expandToScroll: this.expandToScroll,
  20201. });
  20202. if (dismissed) {
  20203. const { delegate } = this.getDelegate();
  20204. await detachComponent(delegate, this.usersElement);
  20205. writeTask(() => this.el.classList.remove('show-modal'));
  20206. if (this.animation) {
  20207. this.animation.destroy();
  20208. }
  20209. if (this.gesture) {
  20210. this.gesture.destroy();
  20211. }
  20212. }
  20213. this.currentBreakpoint = undefined;
  20214. this.animation = undefined;
  20215. unlock();
  20216. return dismissed;
  20217. }
  20218. /**
  20219. * Returns a promise that resolves when the modal did dismiss.
  20220. */
  20221. onDidDismiss() {
  20222. return eventMethod(this.el, 'ionModalDidDismiss');
  20223. }
  20224. /**
  20225. * Returns a promise that resolves when the modal will dismiss.
  20226. */
  20227. onWillDismiss() {
  20228. return eventMethod(this.el, 'ionModalWillDismiss');
  20229. }
  20230. /**
  20231. * Move a sheet style modal to a specific breakpoint. The breakpoint value must
  20232. * be a value defined in your `breakpoints` array.
  20233. */
  20234. async setCurrentBreakpoint(breakpoint) {
  20235. if (!this.isSheetModal) {
  20236. printIonWarning('[ion-modal] - setCurrentBreakpoint is only supported on sheet modals.');
  20237. return;
  20238. }
  20239. if (!this.breakpoints.includes(breakpoint)) {
  20240. printIonWarning(`[ion-modal] - Attempted to set invalid breakpoint value ${breakpoint}. Please double check that the breakpoint value is part of your defined breakpoints.`);
  20241. return;
  20242. }
  20243. const { currentBreakpoint, moveSheetToBreakpoint, canDismiss, breakpoints, animated } = this;
  20244. if (currentBreakpoint === breakpoint) {
  20245. return;
  20246. }
  20247. if (moveSheetToBreakpoint) {
  20248. this.sheetTransition = moveSheetToBreakpoint({
  20249. breakpoint,
  20250. breakpointOffset: 1 - currentBreakpoint,
  20251. canDismiss: canDismiss !== undefined && canDismiss !== true && breakpoints[0] === 0,
  20252. animated,
  20253. });
  20254. await this.sheetTransition;
  20255. this.sheetTransition = undefined;
  20256. }
  20257. }
  20258. /**
  20259. * Returns the current breakpoint of a sheet style modal
  20260. */
  20261. async getCurrentBreakpoint() {
  20262. return this.currentBreakpoint;
  20263. }
  20264. async moveToNextBreakpoint() {
  20265. const { breakpoints, currentBreakpoint } = this;
  20266. if (!breakpoints || currentBreakpoint == null) {
  20267. /**
  20268. * If the modal does not have breakpoints and/or the current
  20269. * breakpoint is not set, we can't move to the next breakpoint.
  20270. */
  20271. return false;
  20272. }
  20273. const allowedBreakpoints = breakpoints.filter((b) => b !== 0);
  20274. const currentBreakpointIndex = allowedBreakpoints.indexOf(currentBreakpoint);
  20275. const nextBreakpointIndex = (currentBreakpointIndex + 1) % allowedBreakpoints.length;
  20276. const nextBreakpoint = allowedBreakpoints[nextBreakpointIndex];
  20277. /**
  20278. * Sets the current breakpoint to the next available breakpoint.
  20279. * If the current breakpoint is the last breakpoint, we set the current
  20280. * breakpoint to the first non-zero breakpoint to avoid dismissing the sheet.
  20281. */
  20282. await this.setCurrentBreakpoint(nextBreakpoint);
  20283. return true;
  20284. }
  20285. render() {
  20286. const { handle, isSheetModal, presentingElement, htmlAttributes, handleBehavior, inheritedAttributes, focusTrap, expandToScroll, } = this;
  20287. const showHandle = handle !== false && isSheetModal;
  20288. const mode = getIonMode$1(this);
  20289. const isCardModal = presentingElement !== undefined && mode === 'ios';
  20290. const isHandleCycle = handleBehavior === 'cycle';
  20291. return (hAsync(Host, Object.assign({ key: '0991b2e4e32da511e59fb1463b47e4ac1b86d1ca', "no-router": true, tabindex: "-1" }, htmlAttributes, { style: {
  20292. zIndex: `${20000 + this.overlayIndex}`,
  20293. }, class: Object.assign({ [mode]: true, ['modal-default']: !isCardModal && !isSheetModal, [`modal-card`]: isCardModal, [`modal-sheet`]: isSheetModal, [`modal-no-expand-scroll`]: isSheetModal && !expandToScroll, 'overlay-hidden': true, [FOCUS_TRAP_DISABLE_CLASS]: focusTrap === false }, getClassMap(this.cssClass)), onIonBackdropTap: this.onBackdropTap, onIonModalDidPresent: this.onLifecycle, onIonModalWillPresent: this.onLifecycle, onIonModalWillDismiss: this.onLifecycle, onIonModalDidDismiss: this.onLifecycle }), hAsync("ion-backdrop", { key: 'ca9453ffe1021fb252ad9460676cfabb5633f00f', ref: (el) => (this.backdropEl = el), visible: this.showBackdrop, tappable: this.backdropDismiss, part: "backdrop" }), mode === 'ios' && hAsync("div", { key: '9f8da446a7b0f3b26aec856e13f6d6d131a7e37b', class: "modal-shadow" }), hAsync("div", Object.assign({ key: '9d08bf600571849c97b58f66df40b496a358d1e1',
  20294. /*
  20295. role and aria-modal must be used on the
  20296. same element. They must also be set inside the
  20297. shadow DOM otherwise ion-button will not be highlighted
  20298. when using VoiceOver: https://bugs.webkit.org/show_bug.cgi?id=247134
  20299. */
  20300. role: "dialog" }, inheritedAttributes, { "aria-modal": "true", class: "modal-wrapper ion-overlay-wrapper", part: "content", ref: (el) => (this.wrapperEl = el) }), showHandle && (hAsync("button", { key: 'f8bf0d1126e5376519101225d9965727121ee042', class: "modal-handle",
  20301. // Prevents the handle from receiving keyboard focus when it does not cycle
  20302. tabIndex: !isHandleCycle ? -1 : 0, "aria-label": "Activate to adjust the size of the dialog overlaying the screen", onClick: isHandleCycle ? this.onHandleClick : undefined, part: "handle" })), hAsync("slot", { key: '6d52849df98f2c6c8fbc03996a931ea6a39a512b' }))));
  20303. }
  20304. get el() { return getElement(this); }
  20305. static get watchers() { return {
  20306. "isOpen": ["onIsOpenChange"],
  20307. "trigger": ["triggerChanged"]
  20308. }; }
  20309. static get style() { return {
  20310. ios: IonModalIosStyle0,
  20311. md: IonModalMdStyle0
  20312. }; }
  20313. static get cmpMeta() { return {
  20314. "$flags$": 41,
  20315. "$tagName$": "ion-modal",
  20316. "$members$": {
  20317. "hasController": [4, "has-controller"],
  20318. "overlayIndex": [2, "overlay-index"],
  20319. "delegate": [16],
  20320. "keyboardClose": [4, "keyboard-close"],
  20321. "enterAnimation": [16],
  20322. "leaveAnimation": [16],
  20323. "breakpoints": [16],
  20324. "expandToScroll": [4, "expand-to-scroll"],
  20325. "initialBreakpoint": [2, "initial-breakpoint"],
  20326. "backdropBreakpoint": [2, "backdrop-breakpoint"],
  20327. "handle": [4],
  20328. "handleBehavior": [1, "handle-behavior"],
  20329. "component": [1],
  20330. "componentProps": [16],
  20331. "cssClass": [1, "css-class"],
  20332. "backdropDismiss": [4, "backdrop-dismiss"],
  20333. "showBackdrop": [4, "show-backdrop"],
  20334. "animated": [4],
  20335. "presentingElement": [16],
  20336. "htmlAttributes": [16],
  20337. "isOpen": [4, "is-open"],
  20338. "trigger": [1],
  20339. "keepContentsMounted": [4, "keep-contents-mounted"],
  20340. "focusTrap": [4, "focus-trap"],
  20341. "canDismiss": [4, "can-dismiss"],
  20342. "presented": [32],
  20343. "present": [64],
  20344. "dismiss": [64],
  20345. "onDidDismiss": [64],
  20346. "onWillDismiss": [64],
  20347. "setCurrentBreakpoint": [64],
  20348. "getCurrentBreakpoint": [64]
  20349. },
  20350. "$listeners$": undefined,
  20351. "$lazyBundleId$": "-",
  20352. "$attrsToReflect$": []
  20353. }; }
  20354. }
  20355. const LIFECYCLE_MAP$1 = {
  20356. ionModalDidPresent: 'ionViewDidEnter',
  20357. ionModalWillPresent: 'ionViewWillEnter',
  20358. ionModalWillDismiss: 'ionViewWillLeave',
  20359. ionModalDidDismiss: 'ionViewDidLeave',
  20360. };
  20361. const VIEW_STATE_NEW = 1;
  20362. const VIEW_STATE_ATTACHED = 2;
  20363. const VIEW_STATE_DESTROYED = 3;
  20364. // TODO(FW-2832): types
  20365. class ViewController {
  20366. constructor(component, params) {
  20367. this.component = component;
  20368. this.params = params;
  20369. this.state = VIEW_STATE_NEW;
  20370. }
  20371. async init(container) {
  20372. this.state = VIEW_STATE_ATTACHED;
  20373. if (!this.element) {
  20374. const component = this.component;
  20375. this.element = await attachComponent(this.delegate, container, component, ['ion-page', 'ion-page-invisible'], this.params);
  20376. }
  20377. }
  20378. /**
  20379. * DOM WRITE
  20380. */
  20381. _destroy() {
  20382. assert(this.state !== VIEW_STATE_DESTROYED, 'view state must be ATTACHED');
  20383. const element = this.element;
  20384. if (element) {
  20385. if (this.delegate) {
  20386. this.delegate.removeViewFromDom(element.parentElement, element);
  20387. }
  20388. else {
  20389. element.remove();
  20390. }
  20391. }
  20392. this.nav = undefined;
  20393. this.state = VIEW_STATE_DESTROYED;
  20394. }
  20395. }
  20396. const matches = (view, id, params) => {
  20397. if (!view) {
  20398. return false;
  20399. }
  20400. if (view.component !== id) {
  20401. return false;
  20402. }
  20403. return shallowEqualStringMap(view.params, params);
  20404. };
  20405. const convertToView = (page, params) => {
  20406. if (!page) {
  20407. return null;
  20408. }
  20409. if (page instanceof ViewController) {
  20410. return page;
  20411. }
  20412. return new ViewController(page, params);
  20413. };
  20414. const convertToViews = (pages) => {
  20415. return pages
  20416. .map((page) => {
  20417. if (page instanceof ViewController) {
  20418. return page;
  20419. }
  20420. if ('component' in page) {
  20421. return convertToView(page.component, page.componentProps === null ? undefined : page.componentProps);
  20422. }
  20423. return convertToView(page, undefined);
  20424. })
  20425. .filter((v) => v !== null);
  20426. };
  20427. const navCss = ":host{left:0;right:0;top:0;bottom:0;position:absolute;contain:layout size style;z-index:0}";
  20428. var IonNavStyle0 = navCss;
  20429. class Nav {
  20430. constructor(hostRef) {
  20431. registerInstance(this, hostRef);
  20432. this.ionNavWillLoad = createEvent(this, "ionNavWillLoad", 7);
  20433. this.ionNavWillChange = createEvent(this, "ionNavWillChange", 3);
  20434. this.ionNavDidChange = createEvent(this, "ionNavDidChange", 3);
  20435. this.transInstr = [];
  20436. this.gestureOrAnimationInProgress = false;
  20437. this.useRouter = false;
  20438. this.isTransitioning = false;
  20439. this.destroyed = false;
  20440. this.views = [];
  20441. this.didLoad = false;
  20442. this.delegate = undefined;
  20443. this.swipeGesture = undefined;
  20444. this.animated = true;
  20445. this.animation = undefined;
  20446. this.rootParams = undefined;
  20447. this.root = undefined;
  20448. }
  20449. swipeGestureChanged() {
  20450. if (this.gesture) {
  20451. this.gesture.enable(this.swipeGesture === true);
  20452. }
  20453. }
  20454. rootChanged() {
  20455. if (this.root === undefined) {
  20456. return;
  20457. }
  20458. if (this.didLoad === false) {
  20459. /**
  20460. * If the component has not loaded yet, we can skip setting up the root component.
  20461. * It will be called when `componentDidLoad` fires.
  20462. */
  20463. return;
  20464. }
  20465. if (!this.useRouter) {
  20466. if (this.root !== undefined) {
  20467. this.setRoot(this.root, this.rootParams);
  20468. }
  20469. }
  20470. }
  20471. componentWillLoad() {
  20472. this.useRouter = document.querySelector('ion-router') !== null && this.el.closest('[no-router]') === null;
  20473. if (this.swipeGesture === undefined) {
  20474. const mode = getIonMode$1(this);
  20475. this.swipeGesture = config.getBoolean('swipeBackEnabled', mode === 'ios');
  20476. }
  20477. this.ionNavWillLoad.emit();
  20478. }
  20479. async componentDidLoad() {
  20480. // We want to set this flag before any watch callbacks are manually called
  20481. this.didLoad = true;
  20482. this.rootChanged();
  20483. this.gesture = (await Promise.resolve().then(function () { return swipeBack; })).createSwipeBackGesture(this.el, this.canStart.bind(this), this.onStart.bind(this), this.onMove.bind(this), this.onEnd.bind(this));
  20484. this.swipeGestureChanged();
  20485. }
  20486. connectedCallback() {
  20487. this.destroyed = false;
  20488. }
  20489. disconnectedCallback() {
  20490. for (const view of this.views) {
  20491. lifecycle(view.element, LIFECYCLE_WILL_UNLOAD);
  20492. view._destroy();
  20493. }
  20494. // Release swipe back gesture and transition.
  20495. if (this.gesture) {
  20496. this.gesture.destroy();
  20497. this.gesture = undefined;
  20498. }
  20499. this.transInstr.length = 0;
  20500. this.views.length = 0;
  20501. this.destroyed = true;
  20502. }
  20503. /**
  20504. * Push a new component onto the current navigation stack. Pass any additional
  20505. * information along as an object. This additional information is accessible
  20506. * through NavParams.
  20507. *
  20508. * @param component The component to push onto the navigation stack.
  20509. * @param componentProps Any properties of the component.
  20510. * @param opts The navigation options.
  20511. * @param done The transition complete function.
  20512. */
  20513. push(component, componentProps, opts, done) {
  20514. return this.insert(-1, component, componentProps, opts, done);
  20515. }
  20516. /**
  20517. * Inserts a component into the navigation stack at the specified index.
  20518. * This is useful to add a component at any point in the navigation stack.
  20519. *
  20520. * @param insertIndex The index to insert the component at in the stack.
  20521. * @param component The component to insert into the navigation stack.
  20522. * @param componentProps Any properties of the component.
  20523. * @param opts The navigation options.
  20524. * @param done The transition complete function.
  20525. */
  20526. insert(insertIndex, component, componentProps, opts, done) {
  20527. return this.insertPages(insertIndex, [{ component, componentProps }], opts, done);
  20528. }
  20529. /**
  20530. * Inserts an array of components into the navigation stack at the specified index.
  20531. * The last component in the array will become instantiated as a view, and animate
  20532. * in to become the active view.
  20533. *
  20534. * @param insertIndex The index to insert the components at in the stack.
  20535. * @param insertComponents The components to insert into the navigation stack.
  20536. * @param opts The navigation options.
  20537. * @param done The transition complete function.
  20538. */
  20539. insertPages(insertIndex, insertComponents, opts, done) {
  20540. return this.queueTrns({
  20541. insertStart: insertIndex,
  20542. insertViews: insertComponents,
  20543. opts,
  20544. }, done);
  20545. }
  20546. /**
  20547. * Pop a component off of the navigation stack. Navigates back from the current
  20548. * component.
  20549. *
  20550. * @param opts The navigation options.
  20551. * @param done The transition complete function.
  20552. */
  20553. pop(opts, done) {
  20554. return this.removeIndex(-1, 1, opts, done);
  20555. }
  20556. /**
  20557. * Pop to a specific index in the navigation stack.
  20558. *
  20559. * @param indexOrViewCtrl The index or view controller to pop to.
  20560. * @param opts The navigation options.
  20561. * @param done The transition complete function.
  20562. */
  20563. popTo(indexOrViewCtrl, opts, done) {
  20564. const ti = {
  20565. removeStart: -1,
  20566. removeCount: -1,
  20567. opts,
  20568. };
  20569. if (typeof indexOrViewCtrl === 'object' && indexOrViewCtrl.component) {
  20570. ti.removeView = indexOrViewCtrl;
  20571. ti.removeStart = 1;
  20572. }
  20573. else if (typeof indexOrViewCtrl === 'number') {
  20574. ti.removeStart = indexOrViewCtrl + 1;
  20575. }
  20576. return this.queueTrns(ti, done);
  20577. }
  20578. /**
  20579. * Navigate back to the root of the stack, no matter how far back that is.
  20580. *
  20581. * @param opts The navigation options.
  20582. * @param done The transition complete function.
  20583. */
  20584. popToRoot(opts, done) {
  20585. return this.removeIndex(1, -1, opts, done);
  20586. }
  20587. /**
  20588. * Removes a component from the navigation stack at the specified index.
  20589. *
  20590. * @param startIndex The number to begin removal at.
  20591. * @param removeCount The number of components to remove.
  20592. * @param opts The navigation options.
  20593. * @param done The transition complete function.
  20594. */
  20595. removeIndex(startIndex, removeCount = 1, opts, done) {
  20596. return this.queueTrns({
  20597. removeStart: startIndex,
  20598. removeCount,
  20599. opts,
  20600. }, done);
  20601. }
  20602. /**
  20603. * Set the root for the current navigation stack to a component.
  20604. *
  20605. * @param component The component to set as the root of the navigation stack.
  20606. * @param componentProps Any properties of the component.
  20607. * @param opts The navigation options.
  20608. * @param done The transition complete function.
  20609. */
  20610. setRoot(component, componentProps, opts, done) {
  20611. return this.setPages([{ component, componentProps }], opts, done);
  20612. }
  20613. /**
  20614. * Set the views of the current navigation stack and navigate to the last view.
  20615. * By default animations are disabled, but they can be enabled by passing options
  20616. * to the navigation controller. Navigation parameters can also be passed to the
  20617. * individual pages in the array.
  20618. *
  20619. * @param views The list of views to set as the navigation stack.
  20620. * @param opts The navigation options.
  20621. * @param done The transition complete function.
  20622. */
  20623. setPages(views, opts, done) {
  20624. opts !== null && opts !== void 0 ? opts : (opts = {});
  20625. // if animation wasn't set to true then default it to NOT animate
  20626. if (opts.animated !== true) {
  20627. opts.animated = false;
  20628. }
  20629. return this.queueTrns({
  20630. insertStart: 0,
  20631. insertViews: views,
  20632. removeStart: 0,
  20633. removeCount: -1,
  20634. opts,
  20635. }, done);
  20636. }
  20637. /**
  20638. * Called by the router to update the view.
  20639. *
  20640. * @param id The component tag.
  20641. * @param params The component params.
  20642. * @param direction A direction hint.
  20643. * @param animation an AnimationBuilder.
  20644. *
  20645. * @return the status.
  20646. * @internal
  20647. */
  20648. setRouteId(id, params, direction, animation) {
  20649. const active = this.getActiveSync();
  20650. if (matches(active, id, params)) {
  20651. return Promise.resolve({
  20652. changed: false,
  20653. element: active.element,
  20654. });
  20655. }
  20656. let resolve;
  20657. const promise = new Promise((r) => (resolve = r));
  20658. let finish;
  20659. const commonOpts = {
  20660. updateURL: false,
  20661. viewIsReady: (enteringEl) => {
  20662. let mark;
  20663. const p = new Promise((r) => (mark = r));
  20664. resolve({
  20665. changed: true,
  20666. element: enteringEl,
  20667. markVisible: async () => {
  20668. mark();
  20669. await finish;
  20670. },
  20671. });
  20672. return p;
  20673. },
  20674. };
  20675. if (direction === 'root') {
  20676. finish = this.setRoot(id, params, commonOpts);
  20677. }
  20678. else {
  20679. // Look for a view matching the target in the view stack.
  20680. const viewController = this.views.find((v) => matches(v, id, params));
  20681. if (viewController) {
  20682. finish = this.popTo(viewController, Object.assign(Object.assign({}, commonOpts), { direction: 'back', animationBuilder: animation }));
  20683. }
  20684. else if (direction === 'forward') {
  20685. finish = this.push(id, params, Object.assign(Object.assign({}, commonOpts), { animationBuilder: animation }));
  20686. }
  20687. else if (direction === 'back') {
  20688. finish = this.setRoot(id, params, Object.assign(Object.assign({}, commonOpts), { direction: 'back', animated: true, animationBuilder: animation }));
  20689. }
  20690. }
  20691. return promise;
  20692. }
  20693. /**
  20694. * Called by <ion-router> to retrieve the current component.
  20695. *
  20696. * @internal
  20697. */
  20698. async getRouteId() {
  20699. const active = this.getActiveSync();
  20700. if (active) {
  20701. return {
  20702. id: active.element.tagName,
  20703. params: active.params,
  20704. element: active.element,
  20705. };
  20706. }
  20707. return undefined;
  20708. }
  20709. /**
  20710. * Get the active view.
  20711. */
  20712. async getActive() {
  20713. return this.getActiveSync();
  20714. }
  20715. /**
  20716. * Get the view at the specified index.
  20717. *
  20718. * @param index The index of the view.
  20719. */
  20720. async getByIndex(index) {
  20721. return this.views[index];
  20722. }
  20723. /**
  20724. * Returns `true` if the current view can go back.
  20725. *
  20726. * @param view The view to check.
  20727. */
  20728. async canGoBack(view) {
  20729. return this.canGoBackSync(view);
  20730. }
  20731. /**
  20732. * Get the previous view.
  20733. *
  20734. * @param view The view to get.
  20735. */
  20736. async getPrevious(view) {
  20737. return this.getPreviousSync(view);
  20738. }
  20739. /**
  20740. * Returns the number of views in the stack.
  20741. */
  20742. async getLength() {
  20743. return Promise.resolve(this.views.length);
  20744. }
  20745. getActiveSync() {
  20746. return this.views[this.views.length - 1];
  20747. }
  20748. canGoBackSync(view = this.getActiveSync()) {
  20749. return !!(view && this.getPreviousSync(view));
  20750. }
  20751. getPreviousSync(view = this.getActiveSync()) {
  20752. if (!view) {
  20753. return undefined;
  20754. }
  20755. const views = this.views;
  20756. const index = views.indexOf(view);
  20757. return index > 0 ? views[index - 1] : undefined;
  20758. }
  20759. /**
  20760. * Adds a navigation stack change to the queue and schedules it to run.
  20761. *
  20762. * @returns Whether the transition succeeds.
  20763. */
  20764. async queueTrns(ti, done) {
  20765. var _a, _b;
  20766. if (this.isTransitioning && ((_a = ti.opts) === null || _a === void 0 ? void 0 : _a.skipIfBusy)) {
  20767. return false;
  20768. }
  20769. const promise = new Promise((resolve, reject) => {
  20770. ti.resolve = resolve;
  20771. ti.reject = reject;
  20772. });
  20773. ti.done = done;
  20774. /**
  20775. * If using router, check to see if navigation hooks
  20776. * will allow us to perform this transition. This
  20777. * is required in order for hooks to work with
  20778. * the ion-back-button or swipe to go back.
  20779. */
  20780. if (ti.opts && ti.opts.updateURL !== false && this.useRouter) {
  20781. const router = document.querySelector('ion-router');
  20782. if (router) {
  20783. const canTransition = await router.canTransition();
  20784. if (canTransition === false) {
  20785. return false;
  20786. }
  20787. if (typeof canTransition === 'string') {
  20788. router.push(canTransition, ti.opts.direction || 'back');
  20789. return false;
  20790. }
  20791. }
  20792. }
  20793. // Normalize empty
  20794. if (((_b = ti.insertViews) === null || _b === void 0 ? void 0 : _b.length) === 0) {
  20795. ti.insertViews = undefined;
  20796. }
  20797. // Enqueue transition instruction
  20798. this.transInstr.push(ti);
  20799. // if there isn't a transition already happening
  20800. // then this will kick off this transition
  20801. this.nextTrns();
  20802. return promise;
  20803. }
  20804. success(result, ti) {
  20805. if (this.destroyed) {
  20806. this.fireError('nav controller was destroyed', ti);
  20807. return;
  20808. }
  20809. if (ti.done) {
  20810. ti.done(result.hasCompleted, result.requiresTransition, result.enteringView, result.leavingView, result.direction);
  20811. }
  20812. ti.resolve(result.hasCompleted);
  20813. if (ti.opts.updateURL !== false && this.useRouter) {
  20814. const router = document.querySelector('ion-router');
  20815. if (router) {
  20816. const direction = result.direction === 'back' ? 'back' : 'forward';
  20817. router.navChanged(direction);
  20818. }
  20819. }
  20820. }
  20821. failed(rejectReason, ti) {
  20822. if (this.destroyed) {
  20823. this.fireError('nav controller was destroyed', ti);
  20824. return;
  20825. }
  20826. this.transInstr.length = 0;
  20827. this.fireError(rejectReason, ti);
  20828. }
  20829. fireError(rejectReason, ti) {
  20830. if (ti.done) {
  20831. ti.done(false, false, rejectReason);
  20832. }
  20833. if (ti.reject && !this.destroyed) {
  20834. ti.reject(rejectReason);
  20835. }
  20836. else {
  20837. ti.resolve(false);
  20838. }
  20839. }
  20840. /**
  20841. * Consumes the next transition in the queue.
  20842. *
  20843. * @returns whether the transition is executed.
  20844. */
  20845. nextTrns() {
  20846. // this is the framework's bread 'n butta function
  20847. // only one transition is allowed at any given time
  20848. if (this.isTransitioning) {
  20849. return false;
  20850. }
  20851. // there is no transition happening right now, executes the next instructions.
  20852. const ti = this.transInstr.shift();
  20853. if (!ti) {
  20854. return false;
  20855. }
  20856. this.runTransition(ti);
  20857. return true;
  20858. }
  20859. /** Executes all the transition instruction from the queue. */
  20860. async runTransition(ti) {
  20861. try {
  20862. // set that this nav is actively transitioning
  20863. this.ionNavWillChange.emit();
  20864. this.isTransitioning = true;
  20865. this.prepareTI(ti);
  20866. const leavingView = this.getActiveSync();
  20867. const enteringView = this.getEnteringView(ti, leavingView);
  20868. if (!leavingView && !enteringView) {
  20869. throw new Error('no views in the stack to be removed');
  20870. }
  20871. if (enteringView && enteringView.state === VIEW_STATE_NEW) {
  20872. await enteringView.init(this.el);
  20873. }
  20874. this.postViewInit(enteringView, leavingView, ti);
  20875. // Needs transition?
  20876. const requiresTransition = (ti.enteringRequiresTransition || ti.leavingRequiresTransition) && enteringView !== leavingView;
  20877. if (requiresTransition && ti.opts && leavingView) {
  20878. const isBackDirection = ti.opts.direction === 'back';
  20879. /**
  20880. * If heading back, use the entering page's animation
  20881. * unless otherwise specified by the developer.
  20882. */
  20883. if (isBackDirection) {
  20884. ti.opts.animationBuilder = ti.opts.animationBuilder || (enteringView === null || enteringView === void 0 ? void 0 : enteringView.animationBuilder);
  20885. }
  20886. leavingView.animationBuilder = ti.opts.animationBuilder;
  20887. }
  20888. let result;
  20889. if (requiresTransition) {
  20890. result = await this.transition(enteringView, leavingView, ti);
  20891. }
  20892. else {
  20893. // transition is not required, so we are already done!
  20894. // they're inserting/removing the views somewhere in the middle or
  20895. // beginning, so visually nothing needs to animate/transition
  20896. // resolve immediately because there's no animation that's happening
  20897. result = {
  20898. hasCompleted: true,
  20899. requiresTransition: false,
  20900. };
  20901. }
  20902. this.success(result, ti);
  20903. this.ionNavDidChange.emit();
  20904. }
  20905. catch (rejectReason) {
  20906. this.failed(rejectReason, ti);
  20907. }
  20908. this.isTransitioning = false;
  20909. this.nextTrns();
  20910. }
  20911. prepareTI(ti) {
  20912. var _a, _b;
  20913. var _c;
  20914. const viewsLength = this.views.length;
  20915. (_a = ti.opts) !== null && _a !== void 0 ? _a : (ti.opts = {});
  20916. (_b = (_c = ti.opts).delegate) !== null && _b !== void 0 ? _b : (_c.delegate = this.delegate);
  20917. if (ti.removeView !== undefined) {
  20918. assert(ti.removeStart !== undefined, 'removeView needs removeStart');
  20919. assert(ti.removeCount !== undefined, 'removeView needs removeCount');
  20920. const index = this.views.indexOf(ti.removeView);
  20921. if (index < 0) {
  20922. throw new Error('removeView was not found');
  20923. }
  20924. ti.removeStart += index;
  20925. }
  20926. if (ti.removeStart !== undefined) {
  20927. if (ti.removeStart < 0) {
  20928. ti.removeStart = viewsLength - 1;
  20929. }
  20930. if (ti.removeCount < 0) {
  20931. ti.removeCount = viewsLength - ti.removeStart;
  20932. }
  20933. ti.leavingRequiresTransition = ti.removeCount > 0 && ti.removeStart + ti.removeCount === viewsLength;
  20934. }
  20935. if (ti.insertViews) {
  20936. // allow -1 to be passed in to auto push it on the end
  20937. // and clean up the index if it's larger then the size of the stack
  20938. if (ti.insertStart < 0 || ti.insertStart > viewsLength) {
  20939. ti.insertStart = viewsLength;
  20940. }
  20941. ti.enteringRequiresTransition = ti.insertStart === viewsLength;
  20942. }
  20943. const insertViews = ti.insertViews;
  20944. if (!insertViews) {
  20945. return;
  20946. }
  20947. assert(insertViews.length > 0, 'length can not be zero');
  20948. const viewControllers = convertToViews(insertViews);
  20949. if (viewControllers.length === 0) {
  20950. throw new Error('invalid views to insert');
  20951. }
  20952. // Check all the inserted view are correct
  20953. for (const view of viewControllers) {
  20954. view.delegate = ti.opts.delegate;
  20955. const nav = view.nav;
  20956. if (nav && nav !== this) {
  20957. throw new Error('inserted view was already inserted');
  20958. }
  20959. if (view.state === VIEW_STATE_DESTROYED) {
  20960. throw new Error('inserted view was already destroyed');
  20961. }
  20962. }
  20963. ti.insertViews = viewControllers;
  20964. }
  20965. /**
  20966. * Returns the view that will be entered considering the transition instructions.
  20967. *
  20968. * @param ti The instructions.
  20969. * @param leavingView The view being left or undefined if none.
  20970. *
  20971. * @returns The view that will be entered, undefined if none.
  20972. */
  20973. getEnteringView(ti, leavingView) {
  20974. // The last inserted view will be entered when view are inserted.
  20975. const insertViews = ti.insertViews;
  20976. if (insertViews !== undefined) {
  20977. return insertViews[insertViews.length - 1];
  20978. }
  20979. // When views are deleted, we will enter the last view that is not removed and not the view being left.
  20980. const removeStart = ti.removeStart;
  20981. if (removeStart !== undefined) {
  20982. const views = this.views;
  20983. const removeEnd = removeStart + ti.removeCount;
  20984. for (let i = views.length - 1; i >= 0; i--) {
  20985. const view = views[i];
  20986. if ((i < removeStart || i >= removeEnd) && view !== leavingView) {
  20987. return view;
  20988. }
  20989. }
  20990. }
  20991. return undefined;
  20992. }
  20993. /**
  20994. * Adds and Removes the views from the navigation stack.
  20995. *
  20996. * @param enteringView The view being entered.
  20997. * @param leavingView The view being left.
  20998. * @param ti The instructions.
  20999. */
  21000. postViewInit(enteringView, leavingView, ti) {
  21001. var _a, _b, _c;
  21002. assert(leavingView || enteringView, 'Both leavingView and enteringView are null');
  21003. assert(ti.resolve, 'resolve must be valid');
  21004. assert(ti.reject, 'reject must be valid');
  21005. // Compute the views to remove.
  21006. const opts = ti.opts;
  21007. const { insertViews, removeStart, removeCount } = ti;
  21008. /** Records the view to destroy */
  21009. let destroyQueue;
  21010. // there are views to remove
  21011. if (removeStart !== undefined && removeCount !== undefined) {
  21012. assert(removeStart >= 0, 'removeStart can not be negative');
  21013. assert(removeCount >= 0, 'removeCount can not be negative');
  21014. destroyQueue = [];
  21015. for (let i = removeStart; i < removeStart + removeCount; i++) {
  21016. const view = this.views[i];
  21017. if (view !== undefined && view !== enteringView && view !== leavingView) {
  21018. destroyQueue.push(view);
  21019. }
  21020. }
  21021. // default the direction to "back"
  21022. (_a = opts.direction) !== null && _a !== void 0 ? _a : (opts.direction = 'back');
  21023. }
  21024. const finalNumViews = this.views.length + ((_b = insertViews === null || insertViews === void 0 ? void 0 : insertViews.length) !== null && _b !== void 0 ? _b : 0) - (removeCount !== null && removeCount !== void 0 ? removeCount : 0);
  21025. assert(finalNumViews >= 0, 'final balance can not be negative');
  21026. if (finalNumViews === 0) {
  21027. printIonWarning(`[ion-nav] - You can't remove all the pages in the navigation stack. nav.pop() is probably called too many times.`, this, this.el);
  21028. throw new Error('navigation stack needs at least one root page');
  21029. }
  21030. // At this point the transition can not be rejected, any throw should be an error
  21031. // Insert the new views in the stack.
  21032. if (insertViews) {
  21033. // add the views to the
  21034. let insertIndex = ti.insertStart;
  21035. for (const view of insertViews) {
  21036. this.insertViewAt(view, insertIndex);
  21037. insertIndex++;
  21038. }
  21039. if (ti.enteringRequiresTransition) {
  21040. // default to forward if not already set
  21041. (_c = opts.direction) !== null && _c !== void 0 ? _c : (opts.direction = 'forward');
  21042. }
  21043. }
  21044. // if the views to be removed are in the beginning or middle
  21045. // and there is not a view that needs to visually transition out
  21046. // then just destroy them and don't transition anything
  21047. // batch all of lifecycles together
  21048. // let's make sure, callbacks are zoned
  21049. if (destroyQueue && destroyQueue.length > 0) {
  21050. for (const view of destroyQueue) {
  21051. lifecycle(view.element, LIFECYCLE_WILL_LEAVE);
  21052. lifecycle(view.element, LIFECYCLE_DID_LEAVE);
  21053. lifecycle(view.element, LIFECYCLE_WILL_UNLOAD);
  21054. }
  21055. // once all lifecycle events has been delivered, we can safely detroy the views
  21056. for (const view of destroyQueue) {
  21057. this.destroyView(view);
  21058. }
  21059. }
  21060. }
  21061. async transition(enteringView, leavingView, ti) {
  21062. // we should animate (duration > 0) if the pushed page is not the first one (startup)
  21063. // or if it is a portal (modal, actionsheet, etc.)
  21064. const opts = ti.opts;
  21065. const progressCallback = opts.progressAnimation
  21066. ? (ani) => {
  21067. /**
  21068. * Because this progress callback is called asynchronously
  21069. * it is possible for the gesture to start and end before
  21070. * the animation is ever set. In that scenario, we should
  21071. * immediately call progressEnd so that the transition promise
  21072. * resolves and the gesture does not get locked up.
  21073. */
  21074. if (ani !== undefined && !this.gestureOrAnimationInProgress) {
  21075. this.gestureOrAnimationInProgress = true;
  21076. ani.onFinish(() => {
  21077. this.gestureOrAnimationInProgress = false;
  21078. }, { oneTimeCallback: true });
  21079. /**
  21080. * Playing animation to beginning
  21081. * with a duration of 0 prevents
  21082. * any flickering when the animation
  21083. * is later cleaned up.
  21084. */
  21085. ani.progressEnd(0, 0, 0);
  21086. }
  21087. else {
  21088. this.sbAni = ani;
  21089. }
  21090. }
  21091. : undefined;
  21092. const mode = getIonMode$1(this);
  21093. const enteringEl = enteringView.element;
  21094. // eslint-disable-next-line @typescript-eslint/prefer-optional-chain
  21095. const leavingEl = leavingView && leavingView.element;
  21096. const animationOpts = Object.assign(Object.assign({ mode, showGoBack: this.canGoBackSync(enteringView), baseEl: this.el, progressCallback, animated: this.animated && config.getBoolean('animated', true), enteringEl,
  21097. leavingEl }, opts), { animationBuilder: opts.animationBuilder || this.animation || config.get('navAnimation') });
  21098. const { hasCompleted } = await transition(animationOpts);
  21099. return this.transitionFinish(hasCompleted, enteringView, leavingView, opts);
  21100. }
  21101. transitionFinish(hasCompleted, enteringView, leavingView, opts) {
  21102. /**
  21103. * If the transition did not complete, the leavingView will still be the active
  21104. * view on the stack. Otherwise unmount all the views after the enteringView.
  21105. */
  21106. const activeView = hasCompleted ? enteringView : leavingView;
  21107. if (activeView) {
  21108. this.unmountInactiveViews(activeView);
  21109. }
  21110. return {
  21111. hasCompleted,
  21112. requiresTransition: true,
  21113. enteringView,
  21114. leavingView,
  21115. direction: opts.direction,
  21116. };
  21117. }
  21118. /**
  21119. * Inserts a view at the specified index.
  21120. *
  21121. * When the view already is in the stack it will be moved to the new position.
  21122. *
  21123. * @param view The view to insert.
  21124. * @param index The index where to insert the view.
  21125. */
  21126. insertViewAt(view, index) {
  21127. const views = this.views;
  21128. const existingIndex = views.indexOf(view);
  21129. if (existingIndex > -1) {
  21130. assert(view.nav === this, 'view is not part of the nav');
  21131. // The view already in the stack, removes it.
  21132. views.splice(existingIndex, 1);
  21133. // and add it back at the requested index.
  21134. views.splice(index, 0, view);
  21135. }
  21136. else {
  21137. assert(!view.nav, 'nav is used');
  21138. // this is a new view to add to the stack
  21139. // create the new entering view
  21140. view.nav = this;
  21141. views.splice(index, 0, view);
  21142. }
  21143. }
  21144. /**
  21145. * Removes a view from the stack.
  21146. *
  21147. * @param view The view to remove.
  21148. */
  21149. removeView(view) {
  21150. assert(view.state === VIEW_STATE_ATTACHED || view.state === VIEW_STATE_DESTROYED, 'view state should be loaded or destroyed');
  21151. const views = this.views;
  21152. const index = views.indexOf(view);
  21153. assert(index > -1, 'view must be part of the stack');
  21154. if (index >= 0) {
  21155. views.splice(index, 1);
  21156. }
  21157. }
  21158. destroyView(view) {
  21159. view._destroy();
  21160. this.removeView(view);
  21161. }
  21162. /**
  21163. * Unmounts all inactive views after the specified active view.
  21164. *
  21165. * DOM WRITE
  21166. *
  21167. * @param activeView The view that is actively visible in the stack. Used to calculate which views to unmount.
  21168. */
  21169. unmountInactiveViews(activeView) {
  21170. // ok, cleanup time!! Destroy all of the views that are
  21171. // INACTIVE and come after the active view
  21172. // only do this if the views exist, though
  21173. if (this.destroyed) {
  21174. return;
  21175. }
  21176. const views = this.views;
  21177. const activeViewIndex = views.indexOf(activeView);
  21178. for (let i = views.length - 1; i >= 0; i--) {
  21179. const view = views[i];
  21180. /**
  21181. * When inserting multiple views via insertPages
  21182. * the last page will be transitioned to, but the
  21183. * others will not be. As a result, a DOM element
  21184. * will only be created for the last page inserted.
  21185. * As a result, it is possible to have views in the
  21186. * stack that do not have `view.element` yet.
  21187. */
  21188. const element = view.element;
  21189. if (element) {
  21190. if (i > activeViewIndex) {
  21191. // this view comes after the active view
  21192. // let's unload it
  21193. lifecycle(element, LIFECYCLE_WILL_UNLOAD);
  21194. this.destroyView(view);
  21195. }
  21196. else if (i < activeViewIndex) {
  21197. // this view comes before the active view
  21198. // and it is not a portal then ensure it is hidden
  21199. setPageHidden(element, true);
  21200. }
  21201. }
  21202. }
  21203. }
  21204. canStart() {
  21205. return (!this.gestureOrAnimationInProgress &&
  21206. !!this.swipeGesture &&
  21207. !this.isTransitioning &&
  21208. this.transInstr.length === 0 &&
  21209. this.canGoBackSync());
  21210. }
  21211. onStart() {
  21212. this.gestureOrAnimationInProgress = true;
  21213. this.pop({ direction: 'back', progressAnimation: true });
  21214. }
  21215. onMove(stepValue) {
  21216. if (this.sbAni) {
  21217. this.sbAni.progressStep(stepValue);
  21218. }
  21219. }
  21220. onEnd(shouldComplete, stepValue, dur) {
  21221. if (this.sbAni) {
  21222. this.sbAni.onFinish(() => {
  21223. this.gestureOrAnimationInProgress = false;
  21224. }, { oneTimeCallback: true });
  21225. // Account for rounding errors in JS
  21226. let newStepValue = shouldComplete ? -0.001 : 0.001;
  21227. /**
  21228. * Animation will be reversed here, so need to
  21229. * reverse the easing curve as well
  21230. *
  21231. * Additionally, we need to account for the time relative
  21232. * to the new easing curve, as `stepValue` is going to be given
  21233. * in terms of a linear curve.
  21234. */
  21235. if (!shouldComplete) {
  21236. this.sbAni.easing('cubic-bezier(1, 0, 0.68, 0.28)');
  21237. newStepValue += getTimeGivenProgression([0, 0], [1, 0], [0.68, 0.28], [1, 1], stepValue)[0];
  21238. }
  21239. else {
  21240. newStepValue += getTimeGivenProgression([0, 0], [0.32, 0.72], [0, 1], [1, 1], stepValue)[0];
  21241. }
  21242. this.sbAni.progressEnd(shouldComplete ? 1 : 0, newStepValue, dur);
  21243. }
  21244. else {
  21245. this.gestureOrAnimationInProgress = false;
  21246. }
  21247. }
  21248. render() {
  21249. return hAsync("slot", { key: '188d0abd6c047d235380f07aac81223b757010e8' });
  21250. }
  21251. get el() { return getElement(this); }
  21252. static get watchers() { return {
  21253. "swipeGesture": ["swipeGestureChanged"],
  21254. "root": ["rootChanged"]
  21255. }; }
  21256. static get style() { return IonNavStyle0; }
  21257. static get cmpMeta() { return {
  21258. "$flags$": 9,
  21259. "$tagName$": "ion-nav",
  21260. "$members$": {
  21261. "delegate": [16],
  21262. "swipeGesture": [1028, "swipe-gesture"],
  21263. "animated": [4],
  21264. "animation": [16],
  21265. "rootParams": [16],
  21266. "root": [1],
  21267. "push": [64],
  21268. "insert": [64],
  21269. "insertPages": [64],
  21270. "pop": [64],
  21271. "popTo": [64],
  21272. "popToRoot": [64],
  21273. "removeIndex": [64],
  21274. "setRoot": [64],
  21275. "setPages": [64],
  21276. "setRouteId": [64],
  21277. "getRouteId": [64],
  21278. "getActive": [64],
  21279. "getByIndex": [64],
  21280. "canGoBack": [64],
  21281. "getPrevious": [64],
  21282. "getLength": [64]
  21283. },
  21284. "$listeners$": undefined,
  21285. "$lazyBundleId$": "-",
  21286. "$attrsToReflect$": []
  21287. }; }
  21288. }
  21289. const navLink = (el, routerDirection, component, componentProps, routerAnimation) => {
  21290. const nav = el.closest('ion-nav');
  21291. if (nav) {
  21292. if (routerDirection === 'forward') {
  21293. if (component !== undefined) {
  21294. return nav.push(component, componentProps, { skipIfBusy: true, animationBuilder: routerAnimation });
  21295. }
  21296. }
  21297. else if (routerDirection === 'root') {
  21298. if (component !== undefined) {
  21299. return nav.setRoot(component, componentProps, { skipIfBusy: true, animationBuilder: routerAnimation });
  21300. }
  21301. }
  21302. else if (routerDirection === 'back') {
  21303. return nav.pop({ skipIfBusy: true, animationBuilder: routerAnimation });
  21304. }
  21305. }
  21306. return Promise.resolve(false);
  21307. };
  21308. class NavLink {
  21309. constructor(hostRef) {
  21310. registerInstance(this, hostRef);
  21311. this.onClick = () => {
  21312. return navLink(this.el, this.routerDirection, this.component, this.componentProps, this.routerAnimation);
  21313. };
  21314. this.component = undefined;
  21315. this.componentProps = undefined;
  21316. this.routerDirection = 'forward';
  21317. this.routerAnimation = undefined;
  21318. }
  21319. render() {
  21320. return hAsync(Host, { key: '9ba170d1b10e08e8a6b5e6a30d363871d455a0a9', onClick: this.onClick });
  21321. }
  21322. get el() { return getElement(this); }
  21323. static get cmpMeta() { return {
  21324. "$flags$": 0,
  21325. "$tagName$": "ion-nav-link",
  21326. "$members$": {
  21327. "component": [1],
  21328. "componentProps": [16],
  21329. "routerDirection": [1, "router-direction"],
  21330. "routerAnimation": [16]
  21331. },
  21332. "$listeners$": undefined,
  21333. "$lazyBundleId$": "-",
  21334. "$attrsToReflect$": []
  21335. }; }
  21336. }
  21337. const noteIosCss = ":host{color:var(--color);font-family:var(--ion-font-family, inherit);-webkit-box-sizing:border-box;box-sizing:border-box}:host(.ion-color){color:var(--ion-color-base)}:host{--color:var(--ion-color-step-350, var(--ion-text-color-step-650, #a6a6a6));font-size:max(14px, 1rem)}";
  21338. var IonNoteIosStyle0 = noteIosCss;
  21339. const noteMdCss = ":host{color:var(--color);font-family:var(--ion-font-family, inherit);-webkit-box-sizing:border-box;box-sizing:border-box}:host(.ion-color){color:var(--ion-color-base)}:host{--color:var(--ion-color-step-600, var(--ion-text-color-step-400, #666666));font-size:0.875rem}";
  21340. var IonNoteMdStyle0 = noteMdCss;
  21341. /**
  21342. * @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
  21343. */
  21344. class Note {
  21345. constructor(hostRef) {
  21346. registerInstance(this, hostRef);
  21347. this.color = undefined;
  21348. }
  21349. render() {
  21350. const mode = getIonMode$1(this);
  21351. return (hAsync(Host, { key: '3c3d9b2aa805c0bc1fdc6270a2bbf4dcc1b96c5b', class: createColorClasses$1(this.color, {
  21352. [mode]: true,
  21353. }) }, hAsync("slot", { key: '39e34682009fcb705ecafe51825162734bdf14d3' })));
  21354. }
  21355. static get style() { return {
  21356. ios: IonNoteIosStyle0,
  21357. md: IonNoteMdStyle0
  21358. }; }
  21359. static get cmpMeta() { return {
  21360. "$flags$": 41,
  21361. "$tagName$": "ion-note",
  21362. "$members$": {
  21363. "color": [513]
  21364. },
  21365. "$listeners$": undefined,
  21366. "$lazyBundleId$": "-",
  21367. "$attrsToReflect$": [["color", "color"]]
  21368. }; }
  21369. }
  21370. const pickerIosCss$1 = ":host{display:-ms-flexbox;display:flex;position:relative;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;width:100%;height:200px;direction:ltr;z-index:0}:host .picker-before,:host .picker-after{position:absolute;width:100%;-webkit-transform:translateZ(0);transform:translateZ(0);z-index:1;pointer-events:none}:host .picker-before{top:0;height:83px}:host .picker-before{inset-inline-start:0}:host .picker-after{top:116px;height:84px}:host .picker-after{inset-inline-start:0}:host .picker-highlight{border-radius:var(--highlight-border-radius, 8px);left:0;right:0;top:50%;bottom:0;-webkit-margin-start:auto;margin-inline-start:auto;-webkit-margin-end:auto;margin-inline-end:auto;margin-top:0;margin-bottom:0;position:absolute;width:calc(100% - 16px);height:34px;-webkit-transform:translateY(-50%);transform:translateY(-50%);background:var(--highlight-background);z-index:-1}:host input{position:absolute;top:0;left:0;right:0;bottom:0;width:100%;height:100%;margin:0;padding:0;border:0;outline:0;clip:rect(0 0 0 0);opacity:0;overflow:hidden;-webkit-appearance:none;-moz-appearance:none}:host ::slotted(ion-picker-column:first-of-type){text-align:start}:host ::slotted(ion-picker-column:last-of-type){text-align:end}:host ::slotted(ion-picker-column:only-child){text-align:center}:host .picker-before{background:-webkit-gradient(linear, left top, left bottom, color-stop(20%, rgba(var(--fade-background-rgb, var(--background-rgb, var(--ion-background-color-rgb, 255, 255, 255))), 1)), to(rgba(var(--fade-background-rgb, var(--background-rgb, var(--ion-background-color-rgb, 255, 255, 255))), 0.8)));background:linear-gradient(to bottom, rgba(var(--fade-background-rgb, var(--background-rgb, var(--ion-background-color-rgb, 255, 255, 255))), 1) 20%, rgba(var(--fade-background-rgb, var(--background-rgb, var(--ion-background-color-rgb, 255, 255, 255))), 0.8) 100%)}:host .picker-after{background:-webkit-gradient(linear, left bottom, left top, color-stop(20%, rgba(var(--fade-background-rgb, var(--background-rgb, var(--ion-background-color-rgb, 255, 255, 255))), 1)), to(rgba(var(--fade-background-rgb, var(--background-rgb, var(--ion-background-color-rgb, 255, 255, 255))), 0.8)));background:linear-gradient(to top, rgba(var(--fade-background-rgb, var(--background-rgb, var(--ion-background-color-rgb, 255, 255, 255))), 1) 20%, rgba(var(--fade-background-rgb, var(--background-rgb, var(--ion-background-color-rgb, 255, 255, 255))), 0.8) 100%)}:host .picker-highlight{background:var(--highlight-background, var(--ion-color-step-150, var(--ion-background-color-step-150, #eeeeef)))}";
  21371. var IonPickerIosStyle0 = pickerIosCss$1;
  21372. const pickerMdCss$1 = ":host{display:-ms-flexbox;display:flex;position:relative;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;width:100%;height:200px;direction:ltr;z-index:0}:host .picker-before,:host .picker-after{position:absolute;width:100%;-webkit-transform:translateZ(0);transform:translateZ(0);z-index:1;pointer-events:none}:host .picker-before{top:0;height:83px}:host .picker-before{inset-inline-start:0}:host .picker-after{top:116px;height:84px}:host .picker-after{inset-inline-start:0}:host .picker-highlight{border-radius:var(--highlight-border-radius, 8px);left:0;right:0;top:50%;bottom:0;-webkit-margin-start:auto;margin-inline-start:auto;-webkit-margin-end:auto;margin-inline-end:auto;margin-top:0;margin-bottom:0;position:absolute;width:calc(100% - 16px);height:34px;-webkit-transform:translateY(-50%);transform:translateY(-50%);background:var(--highlight-background);z-index:-1}:host input{position:absolute;top:0;left:0;right:0;bottom:0;width:100%;height:100%;margin:0;padding:0;border:0;outline:0;clip:rect(0 0 0 0);opacity:0;overflow:hidden;-webkit-appearance:none;-moz-appearance:none}:host ::slotted(ion-picker-column:first-of-type){text-align:start}:host ::slotted(ion-picker-column:last-of-type){text-align:end}:host ::slotted(ion-picker-column:only-child){text-align:center}:host .picker-before{background:-webkit-gradient(linear, left top, left bottom, color-stop(20%, rgba(var(--fade-background-rgb, var(--background-rgb, var(--ion-background-color-rgb, 255, 255, 255))), 1)), color-stop(90%, rgba(var(--fade-background-rgb, var(--background-rgb, var(--ion-background-color-rgb, 255, 255, 255))), 0)));background:linear-gradient(to bottom, rgba(var(--fade-background-rgb, var(--background-rgb, var(--ion-background-color-rgb, 255, 255, 255))), 1) 20%, rgba(var(--fade-background-rgb, var(--background-rgb, var(--ion-background-color-rgb, 255, 255, 255))), 0) 90%)}:host .picker-after{background:-webkit-gradient(linear, left bottom, left top, color-stop(30%, rgba(var(--fade-background-rgb, var(--background-rgb, var(--ion-background-color-rgb, 255, 255, 255))), 1)), color-stop(90%, rgba(var(--fade-background-rgb, var(--background-rgb, var(--ion-background-color-rgb, 255, 255, 255))), 0)));background:linear-gradient(to top, rgba(var(--fade-background-rgb, var(--background-rgb, var(--ion-background-color-rgb, 255, 255, 255))), 1) 30%, rgba(var(--fade-background-rgb, var(--background-rgb, var(--ion-background-color-rgb, 255, 255, 255))), 0) 90%)}";
  21373. var IonPickerMdStyle0 = pickerMdCss$1;
  21374. /**
  21375. * @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
  21376. */
  21377. class Picker$1 {
  21378. constructor(hostRef) {
  21379. registerInstance(this, hostRef);
  21380. this.ionInputModeChange = createEvent(this, "ionInputModeChange", 7);
  21381. this.useInputMode = false;
  21382. this.isInHighlightBounds = (ev) => {
  21383. const { highlightEl } = this;
  21384. if (!highlightEl) {
  21385. return false;
  21386. }
  21387. const bbox = highlightEl.getBoundingClientRect();
  21388. /**
  21389. * Check to see if the user clicked
  21390. * outside the bounds of the highlight.
  21391. */
  21392. const outsideX = ev.clientX < bbox.left || ev.clientX > bbox.right;
  21393. const outsideY = ev.clientY < bbox.top || ev.clientY > bbox.bottom;
  21394. if (outsideX || outsideY) {
  21395. return false;
  21396. }
  21397. return true;
  21398. };
  21399. /**
  21400. * If we are no longer focused
  21401. * on a picker column, then we should
  21402. * exit input mode. An exception is made
  21403. * for the input in the picker since having
  21404. * that focused means we are still in input mode.
  21405. */
  21406. this.onFocusOut = (ev) => {
  21407. // TODO(FW-2832): type
  21408. const { relatedTarget } = ev;
  21409. if (!relatedTarget || (relatedTarget.tagName !== 'ION-PICKER-COLUMN' && relatedTarget !== this.inputEl)) {
  21410. this.exitInputMode();
  21411. }
  21412. };
  21413. /**
  21414. * When picker columns receive focus
  21415. * the parent picker needs to determine
  21416. * whether to enter/exit input mode.
  21417. */
  21418. this.onFocusIn = (ev) => {
  21419. // TODO(FW-2832): type
  21420. const { target } = ev;
  21421. /**
  21422. * Due to browser differences in how/when focus
  21423. * is dispatched on certain elements, we need to
  21424. * make sure that this function only ever runs when
  21425. * focusing a picker column.
  21426. */
  21427. if (target.tagName !== 'ION-PICKER-COLUMN') {
  21428. return;
  21429. }
  21430. /**
  21431. * If we have actionOnClick
  21432. * then this means the user focused
  21433. * a picker column via mouse or
  21434. * touch (i.e. a PointerEvent). As a result,
  21435. * we should not enter/exit input mode
  21436. * until the click event has fired, which happens
  21437. * after the `focusin` event.
  21438. *
  21439. * Otherwise, the user likely focused
  21440. * the column using their keyboard and
  21441. * we should enter/exit input mode automatically.
  21442. */
  21443. if (!this.actionOnClick) {
  21444. const columnEl = target;
  21445. const allowInput = columnEl.numericInput;
  21446. if (allowInput) {
  21447. this.enterInputMode(columnEl, false);
  21448. }
  21449. else {
  21450. this.exitInputMode();
  21451. }
  21452. }
  21453. };
  21454. /**
  21455. * On click we need to run an actionOnClick
  21456. * function that has been set in onPointerDown
  21457. * so that we enter/exit input mode correctly.
  21458. */
  21459. this.onClick = () => {
  21460. const { actionOnClick } = this;
  21461. if (actionOnClick) {
  21462. actionOnClick();
  21463. this.actionOnClick = undefined;
  21464. }
  21465. };
  21466. /**
  21467. * Clicking a column also focuses the column on
  21468. * certain browsers, so we use onPointerDown
  21469. * to tell the onFocusIn function that users
  21470. * are trying to click the column rather than
  21471. * focus the column using the keyboard. When the
  21472. * user completes the click, the onClick function
  21473. * runs and runs the actionOnClick callback.
  21474. */
  21475. this.onPointerDown = (ev) => {
  21476. const { useInputMode, inputModeColumn, el } = this;
  21477. if (this.isInHighlightBounds(ev)) {
  21478. /**
  21479. * If we were already in
  21480. * input mode, then we should determine
  21481. * if we tapped a particular column and
  21482. * should switch to input mode for
  21483. * that specific column.
  21484. */
  21485. if (useInputMode) {
  21486. /**
  21487. * If we tapped a picker column
  21488. * then we should either switch to input
  21489. * mode for that column or all columns.
  21490. * Otherwise we should exit input mode
  21491. * since we just tapped the highlight and
  21492. * not a column.
  21493. */
  21494. if (ev.target.tagName === 'ION-PICKER-COLUMN') {
  21495. /**
  21496. * If user taps 2 different columns
  21497. * then we should just switch to input mode
  21498. * for the new column rather than switching to
  21499. * input mode for all columns.
  21500. */
  21501. if (inputModeColumn && inputModeColumn === ev.target) {
  21502. this.actionOnClick = () => {
  21503. this.enterInputMode();
  21504. };
  21505. }
  21506. else {
  21507. this.actionOnClick = () => {
  21508. this.enterInputMode(ev.target);
  21509. };
  21510. }
  21511. }
  21512. else {
  21513. this.actionOnClick = () => {
  21514. this.exitInputMode();
  21515. };
  21516. }
  21517. /**
  21518. * If we were not already in
  21519. * input mode, then we should
  21520. * enter input mode for all columns.
  21521. */
  21522. }
  21523. else {
  21524. /**
  21525. * If there is only 1 numeric input column
  21526. * then we should skip multi column input.
  21527. */
  21528. const columns = el.querySelectorAll('ion-picker-column.picker-column-numeric-input');
  21529. const columnEl = columns.length === 1 ? ev.target : undefined;
  21530. this.actionOnClick = () => {
  21531. this.enterInputMode(columnEl);
  21532. };
  21533. }
  21534. return;
  21535. }
  21536. this.actionOnClick = () => {
  21537. this.exitInputMode();
  21538. };
  21539. };
  21540. /**
  21541. * Enters input mode to allow
  21542. * for text entry of numeric values.
  21543. * If on mobile, we focus a hidden input
  21544. * field so that the on screen keyboard
  21545. * is brought up. When tabbing using a
  21546. * keyboard, picker columns receive an outline
  21547. * to indicate they are focused. As a result,
  21548. * we should not focus the hidden input as it
  21549. * would cause the outline to go away, preventing
  21550. * users from having any visual indication of which
  21551. * column is focused.
  21552. */
  21553. this.enterInputMode = (columnEl, focusInput = true) => {
  21554. const { inputEl, el } = this;
  21555. if (!inputEl) {
  21556. return;
  21557. }
  21558. /**
  21559. * Only active input mode if there is at
  21560. * least one column that accepts numeric input.
  21561. */
  21562. const hasInputColumn = el.querySelector('ion-picker-column.picker-column-numeric-input');
  21563. if (!hasInputColumn) {
  21564. return;
  21565. }
  21566. /**
  21567. * If columnEl is undefined then
  21568. * it is assumed that all numeric pickers
  21569. * are eligible for text entry.
  21570. * (i.e. hour and minute columns)
  21571. */
  21572. this.useInputMode = true;
  21573. this.inputModeColumn = columnEl;
  21574. /**
  21575. * Users with a keyboard and mouse can
  21576. * activate input mode where the input is
  21577. * focused as well as when it is not focused,
  21578. * so we need to make sure we clean up any
  21579. * old listeners.
  21580. */
  21581. if (focusInput) {
  21582. if (this.destroyKeypressListener) {
  21583. this.destroyKeypressListener();
  21584. this.destroyKeypressListener = undefined;
  21585. }
  21586. inputEl.focus();
  21587. }
  21588. else {
  21589. // TODO FW-5900 Use keydown instead
  21590. el.addEventListener('keypress', this.onKeyPress);
  21591. this.destroyKeypressListener = () => {
  21592. el.removeEventListener('keypress', this.onKeyPress);
  21593. };
  21594. }
  21595. this.emitInputModeChange();
  21596. };
  21597. this.onKeyPress = (ev) => {
  21598. const { inputEl } = this;
  21599. if (!inputEl) {
  21600. return;
  21601. }
  21602. const parsedValue = parseInt(ev.key, 10);
  21603. /**
  21604. * Only numbers should be allowed
  21605. */
  21606. if (!Number.isNaN(parsedValue)) {
  21607. inputEl.value += ev.key;
  21608. this.onInputChange();
  21609. }
  21610. };
  21611. this.selectSingleColumn = () => {
  21612. const { inputEl, inputModeColumn, singleColumnSearchTimeout } = this;
  21613. if (!inputEl || !inputModeColumn) {
  21614. return;
  21615. }
  21616. const options = Array.from(inputModeColumn.querySelectorAll('ion-picker-column-option')).filter((el) => el.disabled !== true);
  21617. /**
  21618. * If users pause for a bit, the search
  21619. * value should be reset similar to how a
  21620. * <select> behaves. So typing "34", waiting,
  21621. * then typing "5" should select "05".
  21622. */
  21623. if (singleColumnSearchTimeout) {
  21624. clearTimeout(singleColumnSearchTimeout);
  21625. }
  21626. this.singleColumnSearchTimeout = setTimeout(() => {
  21627. inputEl.value = '';
  21628. this.singleColumnSearchTimeout = undefined;
  21629. }, 1000);
  21630. /**
  21631. * For values that are longer than 2 digits long
  21632. * we should shift the value over 1 character
  21633. * to the left. So typing "456" would result in "56".
  21634. * TODO: If we want to support more than just
  21635. * time entry, we should update this value to be
  21636. * the max length of all of the picker items.
  21637. */
  21638. if (inputEl.value.length >= 3) {
  21639. const startIndex = inputEl.value.length - 2;
  21640. const newString = inputEl.value.substring(startIndex);
  21641. inputEl.value = newString;
  21642. this.selectSingleColumn();
  21643. return;
  21644. }
  21645. /**
  21646. * Checking the value of the input gets priority
  21647. * first. For example, if the value of the input
  21648. * is "1" and we entered "2", then the complete value
  21649. * is "12" and we should select hour 12.
  21650. *
  21651. * Regex removes any leading zeros from values like "02",
  21652. * but it keeps a single zero if there are only zeros in the string.
  21653. * 0+(?=[1-9]) --> Match 1 or more zeros that are followed by 1-9
  21654. * 0+(?=0$) --> Match 1 or more zeros that must be followed by one 0 and end.
  21655. */
  21656. const findItemFromCompleteValue = options.find(({ textContent }) => {
  21657. /**
  21658. * Keyboard entry is currently only used inside of Datetime
  21659. * where we guarantee textContent is set.
  21660. * If we end up exposing this feature publicly we should revisit this assumption.
  21661. */
  21662. const parsedText = textContent.replace(/^0+(?=[1-9])|0+(?=0$)/, '');
  21663. return parsedText === inputEl.value;
  21664. });
  21665. if (findItemFromCompleteValue) {
  21666. inputModeColumn.setValue(findItemFromCompleteValue.value);
  21667. return;
  21668. }
  21669. /**
  21670. * If we typed "56" to get minute 56, then typed "7",
  21671. * we should select "07" as "567" is not a valid minute.
  21672. */
  21673. if (inputEl.value.length === 2) {
  21674. const changedCharacter = inputEl.value.substring(inputEl.value.length - 1);
  21675. inputEl.value = changedCharacter;
  21676. this.selectSingleColumn();
  21677. }
  21678. };
  21679. /**
  21680. * Searches a list of column items for a particular
  21681. * value. This is currently used for numeric values.
  21682. * The zeroBehavior can be set to account for leading
  21683. * or trailing zeros when looking at the item text.
  21684. */
  21685. this.searchColumn = (colEl, value, zeroBehavior = 'start') => {
  21686. if (!value) {
  21687. return false;
  21688. }
  21689. const behavior = zeroBehavior === 'start' ? /^0+/ : /0$/;
  21690. value = value.replace(behavior, '');
  21691. const option = Array.from(colEl.querySelectorAll('ion-picker-column-option')).find((el) => {
  21692. return el.disabled !== true && el.textContent.replace(behavior, '') === value;
  21693. });
  21694. if (option) {
  21695. colEl.setValue(option.value);
  21696. }
  21697. return !!option;
  21698. };
  21699. /**
  21700. * Attempts to intelligently search the first and second
  21701. * column as if they're number columns for the provided numbers
  21702. * where the first two numbers are the first column
  21703. * and the last 2 are the last column. Tries to allow for the first
  21704. * number to be ignored for situations where typos occurred.
  21705. */
  21706. this.multiColumnSearch = (firstColumn, secondColumn, input) => {
  21707. if (input.length === 0) {
  21708. return;
  21709. }
  21710. const inputArray = input.split('');
  21711. const hourValue = inputArray.slice(0, 2).join('');
  21712. // Try to find a match for the first two digits in the first column
  21713. const foundHour = this.searchColumn(firstColumn, hourValue);
  21714. // If we have more than 2 digits and found a match for hours,
  21715. // use the remaining digits for the second column (minutes)
  21716. if (inputArray.length > 2 && foundHour) {
  21717. const minuteValue = inputArray.slice(2, 4).join('');
  21718. this.searchColumn(secondColumn, minuteValue);
  21719. }
  21720. // If we couldn't find a match for the two-digit hour, try single digit approaches
  21721. else if (!foundHour && inputArray.length >= 1) {
  21722. // First try the first digit as a single-digit hour
  21723. let singleDigitHour = inputArray[0];
  21724. let singleDigitFound = this.searchColumn(firstColumn, singleDigitHour);
  21725. // If that didn't work, try the second digit as a single-digit hour
  21726. // (handles case where user made a typo in the first digit, or they typed over themselves)
  21727. if (!singleDigitFound) {
  21728. inputArray.shift();
  21729. singleDigitHour = inputArray[0];
  21730. singleDigitFound = this.searchColumn(firstColumn, singleDigitHour);
  21731. }
  21732. // If we found a single-digit hour and have remaining digits,
  21733. // use up to 2 of the remaining digits for the second column
  21734. if (singleDigitFound && inputArray.length > 1) {
  21735. const remainingDigits = inputArray.slice(1, 3).join('');
  21736. this.searchColumn(secondColumn, remainingDigits);
  21737. }
  21738. }
  21739. };
  21740. this.selectMultiColumn = () => {
  21741. const { inputEl, el } = this;
  21742. if (!inputEl) {
  21743. return;
  21744. }
  21745. const numericPickers = Array.from(el.querySelectorAll('ion-picker-column')).filter((col) => col.numericInput);
  21746. const firstColumn = numericPickers[0];
  21747. const lastColumn = numericPickers[1];
  21748. let value = inputEl.value;
  21749. if (value.length > 4) {
  21750. const startIndex = inputEl.value.length - 4;
  21751. const newString = inputEl.value.substring(startIndex);
  21752. inputEl.value = newString;
  21753. value = newString;
  21754. }
  21755. this.multiColumnSearch(firstColumn, lastColumn, value);
  21756. };
  21757. /**
  21758. * Searches the value of the active column
  21759. * to determine which value users are trying
  21760. * to select
  21761. */
  21762. this.onInputChange = () => {
  21763. const { useInputMode, inputEl, inputModeColumn } = this;
  21764. if (!useInputMode || !inputEl) {
  21765. return;
  21766. }
  21767. if (inputModeColumn) {
  21768. this.selectSingleColumn();
  21769. }
  21770. else {
  21771. this.selectMultiColumn();
  21772. }
  21773. };
  21774. /**
  21775. * Emit ionInputModeChange. Picker columns
  21776. * listen for this event to determine whether
  21777. * or not their column is "active" for text input.
  21778. */
  21779. this.emitInputModeChange = () => {
  21780. const { useInputMode, inputModeColumn } = this;
  21781. this.ionInputModeChange.emit({
  21782. useInputMode,
  21783. inputModeColumn,
  21784. });
  21785. };
  21786. }
  21787. /**
  21788. * When the picker is interacted with
  21789. * we need to prevent touchstart so other
  21790. * gestures do not fire. For example,
  21791. * scrolling on the wheel picker
  21792. * in ion-datetime should not cause
  21793. * a card modal to swipe to close.
  21794. */
  21795. preventTouchStartPropagation(ev) {
  21796. ev.stopPropagation();
  21797. }
  21798. componentWillLoad() {
  21799. getElementRoot(this.el).addEventListener('focusin', this.onFocusIn);
  21800. getElementRoot(this.el).addEventListener('focusout', this.onFocusOut);
  21801. }
  21802. /**
  21803. * @internal
  21804. * Exits text entry mode for the picker
  21805. * This method blurs the hidden input
  21806. * and cause the keyboard to dismiss.
  21807. */
  21808. async exitInputMode() {
  21809. const { inputEl, useInputMode } = this;
  21810. if (!useInputMode || !inputEl) {
  21811. return;
  21812. }
  21813. this.useInputMode = false;
  21814. this.inputModeColumn = undefined;
  21815. inputEl.blur();
  21816. inputEl.value = '';
  21817. if (this.destroyKeypressListener) {
  21818. this.destroyKeypressListener();
  21819. this.destroyKeypressListener = undefined;
  21820. }
  21821. this.emitInputModeChange();
  21822. }
  21823. render() {
  21824. return (hAsync(Host, { key: '28f81e4ed44a633178561757c5199c2c98f94b74', onPointerDown: (ev) => this.onPointerDown(ev), onClick: () => this.onClick() }, hAsync("input", { key: 'abb3d1ad25ef63856af7804111175a4d50008bc0', "aria-hidden": "true", tabindex: -1, inputmode: "numeric", type: "number", onKeyDown: (ev) => {
  21825. var _a;
  21826. /**
  21827. * The "Enter" key represents
  21828. * the user submitting their time
  21829. * selection, so we should blur the
  21830. * input (and therefore close the keyboard)
  21831. *
  21832. * Updating the picker's state to no longer
  21833. * be in input mode is handled in the onBlur
  21834. * callback below.
  21835. */
  21836. if (ev.key === 'Enter') {
  21837. (_a = this.inputEl) === null || _a === void 0 ? void 0 : _a.blur();
  21838. }
  21839. }, ref: (el) => (this.inputEl = el), onInput: () => this.onInputChange(), onBlur: () => this.exitInputMode() }), hAsync("div", { key: '334a5abdc02e6b127c57177f626d7e4ff5526183', class: "picker-before" }), hAsync("div", { key: 'ffd6271931129e88fc7c820e919d684899e420c5', class: "picker-after" }), hAsync("div", { key: '78d1d95fd09e04f154ea59f24a1cece72c47ed7b', class: "picker-highlight", ref: (el) => (this.highlightEl = el) }), hAsync("slot", { key: '0bd5b9f875d3c71f6cbbde2054baeb1b0a2e8cd5' })));
  21840. }
  21841. get el() { return getElement(this); }
  21842. static get style() { return {
  21843. ios: IonPickerIosStyle0,
  21844. md: IonPickerMdStyle0
  21845. }; }
  21846. static get cmpMeta() { return {
  21847. "$flags$": 41,
  21848. "$tagName$": "ion-picker",
  21849. "$members$": {
  21850. "exitInputMode": [64]
  21851. },
  21852. "$listeners$": [[1, "touchstart", "preventTouchStartPropagation"]],
  21853. "$lazyBundleId$": "-",
  21854. "$attrsToReflect$": []
  21855. }; }
  21856. }
  21857. /**
  21858. * iOS Picker Enter Animation
  21859. */
  21860. const iosEnterAnimation$2 = (baseEl) => {
  21861. const baseAnimation = createAnimation();
  21862. const backdropAnimation = createAnimation();
  21863. const wrapperAnimation = createAnimation();
  21864. backdropAnimation
  21865. .addElement(baseEl.querySelector('ion-backdrop'))
  21866. .fromTo('opacity', 0.01, 'var(--backdrop-opacity)')
  21867. .beforeStyles({
  21868. 'pointer-events': 'none',
  21869. })
  21870. .afterClearStyles(['pointer-events']);
  21871. wrapperAnimation
  21872. .addElement(baseEl.querySelector('.picker-wrapper'))
  21873. .fromTo('transform', 'translateY(100%)', 'translateY(0%)');
  21874. return baseAnimation
  21875. .addElement(baseEl)
  21876. .easing('cubic-bezier(.36,.66,.04,1)')
  21877. .duration(400)
  21878. .addAnimation([backdropAnimation, wrapperAnimation]);
  21879. };
  21880. /**
  21881. * iOS Picker Leave Animation
  21882. */
  21883. const iosLeaveAnimation$2 = (baseEl) => {
  21884. const baseAnimation = createAnimation();
  21885. const backdropAnimation = createAnimation();
  21886. const wrapperAnimation = createAnimation();
  21887. backdropAnimation
  21888. .addElement(baseEl.querySelector('ion-backdrop'))
  21889. .fromTo('opacity', 'var(--backdrop-opacity)', 0.01);
  21890. wrapperAnimation
  21891. .addElement(baseEl.querySelector('.picker-wrapper'))
  21892. .fromTo('transform', 'translateY(0%)', 'translateY(100%)');
  21893. return baseAnimation
  21894. .addElement(baseEl)
  21895. .easing('cubic-bezier(.36,.66,.04,1)')
  21896. .duration(400)
  21897. .addAnimation([backdropAnimation, wrapperAnimation]);
  21898. };
  21899. const pickerIosCss = ".sc-ion-picker-legacy-ios-h{--border-radius:0;--border-style:solid;--min-width:auto;--width:100%;--max-width:500px;--min-height:auto;--max-height:auto;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;top:0;display:block;position:absolute;width:100%;height:100%;outline:none;font-family:var(--ion-font-family, inherit);contain:strict;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;z-index:1001}.sc-ion-picker-legacy-ios-h{inset-inline-start:0}.overlay-hidden.sc-ion-picker-legacy-ios-h{display:none}.picker-wrapper.sc-ion-picker-legacy-ios{border-radius:var(--border-radius);left:0;right:0;bottom:0;-webkit-margin-start:auto;margin-inline-start:auto;-webkit-margin-end:auto;margin-inline-end:auto;margin-top:auto;margin-bottom:auto;-webkit-transform:translate3d(0, 100%, 0);transform:translate3d(0, 100%, 0);display:-ms-flexbox;display:flex;position:absolute;-ms-flex-direction:column;flex-direction:column;width:var(--width);min-width:var(--min-width);max-width:var(--max-width);height:var(--height);min-height:var(--min-height);max-height:var(--max-height);border-width:var(--border-width);border-style:var(--border-style);border-color:var(--border-color);background:var(--background);contain:strict;overflow:hidden;z-index:10}.picker-toolbar.sc-ion-picker-legacy-ios{width:100%;background:transparent;contain:strict;z-index:1}.picker-button.sc-ion-picker-legacy-ios{border:0;font-family:inherit}.picker-button.sc-ion-picker-legacy-ios:active,.picker-button.sc-ion-picker-legacy-ios:focus{outline:none}.picker-columns.sc-ion-picker-legacy-ios{display:-ms-flexbox;display:flex;position:relative;-ms-flex-pack:center;justify-content:center;margin-bottom:var(--ion-safe-area-bottom, 0);contain:strict;overflow:hidden}.picker-above-highlight.sc-ion-picker-legacy-ios,.picker-below-highlight.sc-ion-picker-legacy-ios{display:none;pointer-events:none}.sc-ion-picker-legacy-ios-h{--background:var(--ion-background-color, #fff);--border-width:1px 0 0;--border-color:var(--ion-item-border-color, var(--ion-border-color, var(--ion-color-step-250, var(--ion-background-color-step-250, #c8c7cc))));--height:260px;--backdrop-opacity:var(--ion-backdrop-opacity, 0.26);color:var(--ion-item-color, var(--ion-text-color, #000))}.picker-toolbar.sc-ion-picker-legacy-ios{display:-ms-flexbox;display:flex;height:44px;border-bottom:0.55px solid var(--border-color)}.picker-toolbar-button.sc-ion-picker-legacy-ios{-ms-flex:1;flex:1;text-align:end}.picker-toolbar-button.sc-ion-picker-legacy-ios:last-child .picker-button.sc-ion-picker-legacy-ios{font-weight:600}.picker-toolbar-button.sc-ion-picker-legacy-ios:first-child{font-weight:normal;text-align:start}.picker-button.sc-ion-picker-legacy-ios,.picker-button.ion-activated.sc-ion-picker-legacy-ios{margin-left:0;margin-right:0;margin-top:0;margin-bottom:0;-webkit-padding-start:1em;padding-inline-start:1em;-webkit-padding-end:1em;padding-inline-end:1em;padding-top:0;padding-bottom:0;height:44px;background:transparent;color:var(--ion-color-primary, #0054e9);font-size:16px}.picker-columns.sc-ion-picker-legacy-ios{height:215px;-webkit-perspective:1000px;perspective:1000px}.picker-above-highlight.sc-ion-picker-legacy-ios{top:0;-webkit-transform:translate3d(0, 0, 90px);transform:translate3d(0, 0, 90px);display:block;position:absolute;width:100%;height:81px;border-bottom:1px solid var(--border-color);background:-webkit-gradient(linear, left top, left bottom, color-stop(20%, var(--background, var(--ion-background-color, #fff))), to(rgba(var(--background-rgb, var(--ion-background-color-rgb, 255, 255, 255)), 0.8)));background:linear-gradient(to bottom, var(--background, var(--ion-background-color, #fff)) 20%, rgba(var(--background-rgb, var(--ion-background-color-rgb, 255, 255, 255)), 0.8) 100%);z-index:10}.picker-above-highlight.sc-ion-picker-legacy-ios{inset-inline-start:0}.picker-below-highlight.sc-ion-picker-legacy-ios{top:115px;-webkit-transform:translate3d(0, 0, 90px);transform:translate3d(0, 0, 90px);display:block;position:absolute;width:100%;height:119px;border-top:1px solid var(--border-color);background:-webkit-gradient(linear, left bottom, left top, color-stop(30%, var(--background, var(--ion-background-color, #fff))), to(rgba(var(--background-rgb, var(--ion-background-color-rgb, 255, 255, 255)), 0.8)));background:linear-gradient(to top, var(--background, var(--ion-background-color, #fff)) 30%, rgba(var(--background-rgb, var(--ion-background-color-rgb, 255, 255, 255)), 0.8) 100%);z-index:11}.picker-below-highlight.sc-ion-picker-legacy-ios{inset-inline-start:0}";
  21900. var IonPickerLegacyIosStyle0 = pickerIosCss;
  21901. const pickerMdCss = ".sc-ion-picker-legacy-md-h{--border-radius:0;--border-style:solid;--min-width:auto;--width:100%;--max-width:500px;--min-height:auto;--max-height:auto;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;top:0;display:block;position:absolute;width:100%;height:100%;outline:none;font-family:var(--ion-font-family, inherit);contain:strict;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;z-index:1001}.sc-ion-picker-legacy-md-h{inset-inline-start:0}.overlay-hidden.sc-ion-picker-legacy-md-h{display:none}.picker-wrapper.sc-ion-picker-legacy-md{border-radius:var(--border-radius);left:0;right:0;bottom:0;-webkit-margin-start:auto;margin-inline-start:auto;-webkit-margin-end:auto;margin-inline-end:auto;margin-top:auto;margin-bottom:auto;-webkit-transform:translate3d(0, 100%, 0);transform:translate3d(0, 100%, 0);display:-ms-flexbox;display:flex;position:absolute;-ms-flex-direction:column;flex-direction:column;width:var(--width);min-width:var(--min-width);max-width:var(--max-width);height:var(--height);min-height:var(--min-height);max-height:var(--max-height);border-width:var(--border-width);border-style:var(--border-style);border-color:var(--border-color);background:var(--background);contain:strict;overflow:hidden;z-index:10}.picker-toolbar.sc-ion-picker-legacy-md{width:100%;background:transparent;contain:strict;z-index:1}.picker-button.sc-ion-picker-legacy-md{border:0;font-family:inherit}.picker-button.sc-ion-picker-legacy-md:active,.picker-button.sc-ion-picker-legacy-md:focus{outline:none}.picker-columns.sc-ion-picker-legacy-md{display:-ms-flexbox;display:flex;position:relative;-ms-flex-pack:center;justify-content:center;margin-bottom:var(--ion-safe-area-bottom, 0);contain:strict;overflow:hidden}.picker-above-highlight.sc-ion-picker-legacy-md,.picker-below-highlight.sc-ion-picker-legacy-md{display:none;pointer-events:none}.sc-ion-picker-legacy-md-h{--background:var(--ion-background-color, #fff);--border-width:0.55px 0 0;--border-color:var(--ion-item-border-color, var(--ion-border-color, var(--ion-color-step-150, var(--ion-background-color-step-150, rgba(0, 0, 0, 0.13)))));--height:260px;--backdrop-opacity:var(--ion-backdrop-opacity, 0.26);color:var(--ion-item-color, var(--ion-text-color, #000))}.picker-toolbar.sc-ion-picker-legacy-md{display:-ms-flexbox;display:flex;-ms-flex-pack:end;justify-content:flex-end;height:44px}.picker-button.sc-ion-picker-legacy-md,.picker-button.ion-activated.sc-ion-picker-legacy-md{margin-left:0;margin-right:0;margin-top:0;margin-bottom:0;-webkit-padding-start:1.1em;padding-inline-start:1.1em;-webkit-padding-end:1.1em;padding-inline-end:1.1em;padding-top:0;padding-bottom:0;height:44px;background:transparent;color:var(--ion-color-primary, #0054e9);font-size:14px;font-weight:500;text-transform:uppercase;-webkit-box-shadow:none;box-shadow:none}.picker-columns.sc-ion-picker-legacy-md{height:216px;-webkit-perspective:1800px;perspective:1800px}.picker-above-highlight.sc-ion-picker-legacy-md{top:0;-webkit-transform:translate3d(0, 0, 90px);transform:translate3d(0, 0, 90px);position:absolute;width:100%;height:81px;border-bottom:1px solid var(--ion-item-border-color, var(--ion-border-color, var(--ion-color-step-150, var(--ion-background-color-step-150, rgba(0, 0, 0, 0.13)))));background:-webkit-gradient(linear, left top, left bottom, color-stop(20%, var(--ion-background-color, #fff)), to(rgba(var(--ion-background-color-rgb, 255, 255, 255), 0.8)));background:linear-gradient(to bottom, var(--ion-background-color, #fff) 20%, rgba(var(--ion-background-color-rgb, 255, 255, 255), 0.8) 100%);z-index:10}.picker-above-highlight.sc-ion-picker-legacy-md{inset-inline-start:0}.picker-below-highlight.sc-ion-picker-legacy-md{top:115px;-webkit-transform:translate3d(0, 0, 90px);transform:translate3d(0, 0, 90px);position:absolute;width:100%;height:119px;border-top:1px solid var(--ion-item-border-color, var(--ion-border-color, var(--ion-color-step-150, var(--ion-background-color-step-150, rgba(0, 0, 0, 0.13)))));background:-webkit-gradient(linear, left bottom, left top, color-stop(30%, var(--ion-background-color, #fff)), to(rgba(var(--ion-background-color-rgb, 255, 255, 255), 0.8)));background:linear-gradient(to top, var(--ion-background-color, #fff) 30%, rgba(var(--ion-background-color-rgb, 255, 255, 255), 0.8) 100%);z-index:11}.picker-below-highlight.sc-ion-picker-legacy-md{inset-inline-start:0}";
  21902. var IonPickerLegacyMdStyle0 = pickerMdCss;
  21903. // TODO(FW-2832): types
  21904. /**
  21905. * @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
  21906. */
  21907. class Picker {
  21908. constructor(hostRef) {
  21909. registerInstance(this, hostRef);
  21910. this.didPresent = createEvent(this, "ionPickerDidPresent", 7);
  21911. this.willPresent = createEvent(this, "ionPickerWillPresent", 7);
  21912. this.willDismiss = createEvent(this, "ionPickerWillDismiss", 7);
  21913. this.didDismiss = createEvent(this, "ionPickerDidDismiss", 7);
  21914. this.didPresentShorthand = createEvent(this, "didPresent", 7);
  21915. this.willPresentShorthand = createEvent(this, "willPresent", 7);
  21916. this.willDismissShorthand = createEvent(this, "willDismiss", 7);
  21917. this.didDismissShorthand = createEvent(this, "didDismiss", 7);
  21918. this.delegateController = createDelegateController(this);
  21919. this.lockController = createLockController();
  21920. this.triggerController = createTriggerController();
  21921. this.onBackdropTap = () => {
  21922. this.dismiss(undefined, BACKDROP);
  21923. };
  21924. this.dispatchCancelHandler = (ev) => {
  21925. const role = ev.detail.role;
  21926. if (isCancel(role)) {
  21927. const cancelButton = this.buttons.find((b) => b.role === 'cancel');
  21928. this.callButtonHandler(cancelButton);
  21929. }
  21930. };
  21931. this.presented = false;
  21932. this.overlayIndex = undefined;
  21933. this.delegate = undefined;
  21934. this.hasController = false;
  21935. this.keyboardClose = true;
  21936. this.enterAnimation = undefined;
  21937. this.leaveAnimation = undefined;
  21938. this.buttons = [];
  21939. this.columns = [];
  21940. this.cssClass = undefined;
  21941. this.duration = 0;
  21942. this.showBackdrop = true;
  21943. this.backdropDismiss = true;
  21944. this.animated = true;
  21945. this.htmlAttributes = undefined;
  21946. this.isOpen = false;
  21947. this.trigger = undefined;
  21948. }
  21949. onIsOpenChange(newValue, oldValue) {
  21950. if (newValue === true && oldValue === false) {
  21951. this.present();
  21952. }
  21953. else if (newValue === false && oldValue === true) {
  21954. this.dismiss();
  21955. }
  21956. }
  21957. triggerChanged() {
  21958. const { trigger, el, triggerController } = this;
  21959. if (trigger) {
  21960. triggerController.addClickListener(el, trigger);
  21961. }
  21962. }
  21963. connectedCallback() {
  21964. prepareOverlay(this.el);
  21965. this.triggerChanged();
  21966. }
  21967. disconnectedCallback() {
  21968. this.triggerController.removeClickListener();
  21969. }
  21970. componentWillLoad() {
  21971. var _a;
  21972. if (!((_a = this.htmlAttributes) === null || _a === void 0 ? void 0 : _a.id)) {
  21973. setOverlayId(this.el);
  21974. }
  21975. }
  21976. componentDidLoad() {
  21977. printIonWarning('[ion-picker-legacy] - ion-picker-legacy and ion-picker-legacy-column have been deprecated in favor of new versions of the ion-picker and ion-picker-column components. These new components display inline with your page content allowing for more presentation flexibility than before.', this.el);
  21978. /**
  21979. * If picker was rendered with isOpen="true"
  21980. * then we should open picker immediately.
  21981. */
  21982. if (this.isOpen === true) {
  21983. raf(() => this.present());
  21984. }
  21985. /**
  21986. * When binding values in frameworks such as Angular
  21987. * it is possible for the value to be set after the Web Component
  21988. * initializes but before the value watcher is set up in Stencil.
  21989. * As a result, the watcher callback may not be fired.
  21990. * We work around this by manually calling the watcher
  21991. * callback when the component has loaded and the watcher
  21992. * is configured.
  21993. */
  21994. this.triggerChanged();
  21995. }
  21996. /**
  21997. * Present the picker overlay after it has been created.
  21998. */
  21999. async present() {
  22000. const unlock = await this.lockController.lock();
  22001. await this.delegateController.attachViewToDom();
  22002. await present(this, 'pickerEnter', iosEnterAnimation$2, iosEnterAnimation$2, undefined);
  22003. if (this.duration > 0) {
  22004. this.durationTimeout = setTimeout(() => this.dismiss(), this.duration);
  22005. }
  22006. unlock();
  22007. }
  22008. /**
  22009. * Dismiss the picker overlay after it has been presented.
  22010. *
  22011. * @param data Any data to emit in the dismiss events.
  22012. * @param role The role of the element that is dismissing the picker.
  22013. * This can be useful in a button handler for determining which button was
  22014. * clicked to dismiss the picker.
  22015. * Some examples include: ``"cancel"`, `"destructive"`, "selected"`, and `"backdrop"`.
  22016. */
  22017. async dismiss(data, role) {
  22018. const unlock = await this.lockController.lock();
  22019. if (this.durationTimeout) {
  22020. clearTimeout(this.durationTimeout);
  22021. }
  22022. const dismissed = await dismiss(this, data, role, 'pickerLeave', iosLeaveAnimation$2, iosLeaveAnimation$2);
  22023. if (dismissed) {
  22024. this.delegateController.removeViewFromDom();
  22025. }
  22026. unlock();
  22027. return dismissed;
  22028. }
  22029. /**
  22030. * Returns a promise that resolves when the picker did dismiss.
  22031. */
  22032. onDidDismiss() {
  22033. return eventMethod(this.el, 'ionPickerDidDismiss');
  22034. }
  22035. /**
  22036. * Returns a promise that resolves when the picker will dismiss.
  22037. */
  22038. onWillDismiss() {
  22039. return eventMethod(this.el, 'ionPickerWillDismiss');
  22040. }
  22041. /**
  22042. * Get the column that matches the specified name.
  22043. *
  22044. * @param name The name of the column.
  22045. */
  22046. getColumn(name) {
  22047. return Promise.resolve(this.columns.find((column) => column.name === name));
  22048. }
  22049. async buttonClick(button) {
  22050. const role = button.role;
  22051. if (isCancel(role)) {
  22052. return this.dismiss(undefined, role);
  22053. }
  22054. const shouldDismiss = await this.callButtonHandler(button);
  22055. if (shouldDismiss) {
  22056. return this.dismiss(this.getSelected(), button.role);
  22057. }
  22058. return Promise.resolve();
  22059. }
  22060. async callButtonHandler(button) {
  22061. if (button) {
  22062. // a handler has been provided, execute it
  22063. // pass the handler the values from the inputs
  22064. const rtn = await safeCall(button.handler, this.getSelected());
  22065. if (rtn === false) {
  22066. // if the return value of the handler is false then do not dismiss
  22067. return false;
  22068. }
  22069. }
  22070. return true;
  22071. }
  22072. getSelected() {
  22073. const selected = {};
  22074. this.columns.forEach((col, index) => {
  22075. const selectedColumn = col.selectedIndex !== undefined ? col.options[col.selectedIndex] : undefined;
  22076. selected[col.name] = {
  22077. text: selectedColumn ? selectedColumn.text : undefined,
  22078. value: selectedColumn ? selectedColumn.value : undefined,
  22079. columnIndex: index,
  22080. };
  22081. });
  22082. return selected;
  22083. }
  22084. render() {
  22085. const { htmlAttributes } = this;
  22086. const mode = getIonMode$1(this);
  22087. return (hAsync(Host, Object.assign({ key: 'b6b6ca6f9aa74681e6d67f64b366f5965fec2a6d', "aria-modal": "true", tabindex: "-1" }, htmlAttributes, { style: {
  22088. zIndex: `${20000 + this.overlayIndex}`,
  22089. }, class: Object.assign({ [mode]: true,
  22090. // Used internally for styling
  22091. [`picker-${mode}`]: true, 'overlay-hidden': true }, getClassMap(this.cssClass)), onIonBackdropTap: this.onBackdropTap, onIonPickerWillDismiss: this.dispatchCancelHandler }), hAsync("ion-backdrop", { key: '20202ca1d7b6cd5f517a802879b39efb79033cb1', visible: this.showBackdrop, tappable: this.backdropDismiss }), hAsync("div", { key: '72fe76a1e1748593cdf38deab5100087bfa75983', tabindex: "0", "aria-hidden": "true" }), hAsync("div", { key: '921954cfc716f3774aab66677563754ff479a44a', class: "picker-wrapper ion-overlay-wrapper", role: "dialog" }, hAsync("div", { key: '224413950bfcf2a948e58c2554c2a37a4e6d0319', class: "picker-toolbar" }, this.buttons.map((b) => (hAsync("div", { class: buttonWrapperClass(b) }, hAsync("button", { type: "button", onClick: () => this.buttonClick(b), class: buttonClass$1(b) }, b.text))))), hAsync("div", { key: '7e688c2d0705940ec8a9ace493b679e6a9b68860', class: "picker-columns" }, hAsync("div", { key: '0ec2db79a9ca9e2a0b324b6c4b90176a0eb33df3', class: "picker-above-highlight" }), this.presented && this.columns.map((c) => hAsync("ion-picker-legacy-column", { col: c })), hAsync("div", { key: 'b8344f4f342fddc3f773435515567ef8f3accbb0', class: "picker-below-highlight" }))), hAsync("div", { key: '374c7a6b31b0a00ab3913faeea0ec3d6c02274b9', tabindex: "0", "aria-hidden": "true" })));
  22092. }
  22093. get el() { return getElement(this); }
  22094. static get watchers() { return {
  22095. "isOpen": ["onIsOpenChange"],
  22096. "trigger": ["triggerChanged"]
  22097. }; }
  22098. static get style() { return {
  22099. ios: IonPickerLegacyIosStyle0,
  22100. md: IonPickerLegacyMdStyle0
  22101. }; }
  22102. static get cmpMeta() { return {
  22103. "$flags$": 34,
  22104. "$tagName$": "ion-picker-legacy",
  22105. "$members$": {
  22106. "overlayIndex": [2, "overlay-index"],
  22107. "delegate": [16],
  22108. "hasController": [4, "has-controller"],
  22109. "keyboardClose": [4, "keyboard-close"],
  22110. "enterAnimation": [16],
  22111. "leaveAnimation": [16],
  22112. "buttons": [16],
  22113. "columns": [16],
  22114. "cssClass": [1, "css-class"],
  22115. "duration": [2],
  22116. "showBackdrop": [4, "show-backdrop"],
  22117. "backdropDismiss": [4, "backdrop-dismiss"],
  22118. "animated": [4],
  22119. "htmlAttributes": [16],
  22120. "isOpen": [4, "is-open"],
  22121. "trigger": [1],
  22122. "presented": [32],
  22123. "present": [64],
  22124. "dismiss": [64],
  22125. "onDidDismiss": [64],
  22126. "onWillDismiss": [64],
  22127. "getColumn": [64]
  22128. },
  22129. "$listeners$": undefined,
  22130. "$lazyBundleId$": "-",
  22131. "$attrsToReflect$": []
  22132. }; }
  22133. }
  22134. const buttonWrapperClass = (button) => {
  22135. return {
  22136. [`picker-toolbar-${button.role}`]: button.role !== undefined,
  22137. 'picker-toolbar-button': true,
  22138. };
  22139. };
  22140. const buttonClass$1 = (button) => {
  22141. return Object.assign({ 'picker-button': true, 'ion-activatable': true }, getClassMap(button.cssClass));
  22142. };
  22143. const pickerColumnCss = ":host{display:-ms-flexbox;display:flex;position:relative;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;max-width:100%;height:200px;font-size:22px;text-align:center}.assistive-focusable{left:0;right:0;top:0;bottom:0;position:absolute;z-index:1;pointer-events:none}.assistive-focusable:focus{outline:none}.picker-opts{-webkit-padding-start:16px;padding-inline-start:16px;-webkit-padding-end:16px;padding-inline-end:16px;padding-top:0px;padding-bottom:0px;min-width:26px;max-height:200px;outline:none;text-align:inherit;-webkit-scroll-snap-type:y mandatory;-ms-scroll-snap-type:y mandatory;scroll-snap-type:y mandatory;overflow-x:hidden;overflow-y:scroll;scrollbar-width:none}.picker-item-empty{padding-left:0;padding-right:0;padding-top:0;padding-bottom:0;margin-left:0;margin-right:0;margin-top:0;margin-bottom:0;display:block;width:100%;height:34px;border:0px;outline:none;background:transparent;color:inherit;font-family:var(--ion-font-family, inherit);font-size:inherit;line-height:34px;text-align:inherit;text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.picker-opts::-webkit-scrollbar{display:none}::slotted(ion-picker-column-option){display:block;scroll-snap-align:center}.picker-item-empty,:host(:not([disabled])) ::slotted(ion-picker-column-option.option-disabled){scroll-snap-align:none}::slotted([slot=prefix]),::slotted([slot=suffix]){max-width:200px;text-overflow:ellipsis;white-space:nowrap;overflow:hidden}::slotted([slot=prefix]){-webkit-padding-start:16px;padding-inline-start:16px;-webkit-padding-end:16px;padding-inline-end:16px;padding-top:0;padding-bottom:0;-ms-flex-pack:end;justify-content:end}::slotted([slot=suffix]){-webkit-padding-start:16px;padding-inline-start:16px;-webkit-padding-end:16px;padding-inline-end:16px;padding-top:0;padding-bottom:0;-ms-flex-pack:start;justify-content:start}:host(.picker-column-disabled) .picker-opts{overflow-y:hidden}:host(.picker-column-disabled) ::slotted(ion-picker-column-option){cursor:default;opacity:0.4;pointer-events:none}@media (any-hover: hover){:host(:focus) .picker-opts{outline:none;background:rgba(var(--ion-color-base-rgb), 0.2)}}";
  22144. var IonPickerColumnStyle0 = pickerColumnCss;
  22145. /**
  22146. * @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
  22147. *
  22148. * @slot prefix - Content to show on the left side of the picker options.
  22149. * @slot suffix - Content to show on the right side of the picker options.
  22150. */
  22151. class PickerColumn {
  22152. constructor(hostRef) {
  22153. registerInstance(this, hostRef);
  22154. this.ionChange = createEvent(this, "ionChange", 7);
  22155. this.isScrolling = false;
  22156. this.isColumnVisible = false;
  22157. this.canExitInputMode = true;
  22158. this.updateValueTextOnScroll = false;
  22159. this.centerPickerItemInView = (target, smooth = true, canExitInputMode = true) => {
  22160. const { isColumnVisible, scrollEl } = this;
  22161. if (isColumnVisible && scrollEl) {
  22162. // (Vertical offset from parent) - (three empty picker rows) + (half the height of the target to ensure the scroll triggers)
  22163. const top = target.offsetTop - 3 * target.clientHeight + target.clientHeight / 2;
  22164. if (scrollEl.scrollTop !== top) {
  22165. /**
  22166. * Setting this flag prevents input
  22167. * mode from exiting in the picker column's
  22168. * scroll callback. This is useful when the user manually
  22169. * taps an item or types on the keyboard as both
  22170. * of these can cause a scroll to occur.
  22171. */
  22172. this.canExitInputMode = canExitInputMode;
  22173. this.updateValueTextOnScroll = false;
  22174. scrollEl.scroll({
  22175. top,
  22176. left: 0,
  22177. behavior: smooth ? 'smooth' : undefined,
  22178. });
  22179. }
  22180. }
  22181. };
  22182. this.setPickerItemActiveState = (item, isActive) => {
  22183. if (isActive) {
  22184. item.classList.add(PICKER_ITEM_ACTIVE_CLASS);
  22185. }
  22186. else {
  22187. item.classList.remove(PICKER_ITEM_ACTIVE_CLASS);
  22188. }
  22189. };
  22190. /**
  22191. * When ionInputModeChange is emitted, each column
  22192. * needs to check if it is the one being made available
  22193. * for text entry.
  22194. */
  22195. this.inputModeChange = (ev) => {
  22196. if (!this.numericInput) {
  22197. return;
  22198. }
  22199. const { useInputMode, inputModeColumn } = ev.detail;
  22200. /**
  22201. * If inputModeColumn is undefined then this means
  22202. * all numericInput columns are being selected.
  22203. */
  22204. const isColumnActive = inputModeColumn === undefined || inputModeColumn === this.el;
  22205. if (!useInputMode || !isColumnActive) {
  22206. this.setInputModeActive(false);
  22207. return;
  22208. }
  22209. this.setInputModeActive(true);
  22210. };
  22211. /**
  22212. * Setting isActive will cause a re-render.
  22213. * As a result, we do not want to cause the
  22214. * re-render mid scroll as this will cause
  22215. * the picker column to jump back to
  22216. * whatever value was selected at the
  22217. * start of the scroll interaction.
  22218. */
  22219. this.setInputModeActive = (state) => {
  22220. if (this.isScrolling) {
  22221. this.scrollEndCallback = () => {
  22222. this.isActive = state;
  22223. };
  22224. return;
  22225. }
  22226. this.isActive = state;
  22227. };
  22228. /**
  22229. * When the column scrolls, the component
  22230. * needs to determine which item is centered
  22231. * in the view and will emit an ionChange with
  22232. * the item object.
  22233. */
  22234. this.initializeScrollListener = () => {
  22235. /**
  22236. * The haptics for the wheel picker are
  22237. * an iOS-only feature. As a result, they should
  22238. * be disabled on Android.
  22239. */
  22240. const enableHaptics = isPlatform('ios');
  22241. const { el, scrollEl } = this;
  22242. let timeout;
  22243. let activeEl = this.activeItem;
  22244. const scrollCallback = () => {
  22245. raf(() => {
  22246. var _a;
  22247. if (!scrollEl)
  22248. return;
  22249. if (timeout) {
  22250. clearTimeout(timeout);
  22251. timeout = undefined;
  22252. }
  22253. if (!this.isScrolling) {
  22254. enableHaptics && hapticSelectionStart();
  22255. this.isScrolling = true;
  22256. }
  22257. /**
  22258. * Select item in the center of the column
  22259. * which is the month/year that we want to select
  22260. */
  22261. const bbox = scrollEl.getBoundingClientRect();
  22262. const centerX = bbox.x + bbox.width / 2;
  22263. const centerY = bbox.y + bbox.height / 2;
  22264. /**
  22265. * elementFromPoint returns the top-most element.
  22266. * This means that if an ion-backdrop is overlaying the
  22267. * picker then the appropriate picker column option will
  22268. * not be selected. To account for this, we use elementsFromPoint
  22269. * and use an Array.find to find the appropriate column option
  22270. * at that point.
  22271. *
  22272. * Additionally, the picker column could be used in the
  22273. * Shadow DOM (i.e. in ion-datetime) so we need to make
  22274. * sure we are choosing the correct host otherwise
  22275. * the elements returns by elementsFromPoint will be
  22276. * retargeted. To account for this, we check to see
  22277. * if the picker column has a parent shadow root. If
  22278. * so, we use that shadow root when doing elementsFromPoint.
  22279. * Otherwise, we just use the document.
  22280. */
  22281. const rootNode = el.getRootNode();
  22282. const hasParentShadow = rootNode instanceof ShadowRoot;
  22283. const referenceNode = hasParentShadow ? rootNode : doc;
  22284. /**
  22285. * If the reference node is undefined
  22286. * then it's likely that doc is undefined
  22287. * due to being in an SSR environment.
  22288. */
  22289. if (referenceNode === undefined) {
  22290. return;
  22291. }
  22292. const elementsAtPoint = referenceNode.elementsFromPoint(centerX, centerY);
  22293. /**
  22294. * elementsFromPoint can returns multiple elements
  22295. * so find the relevant picker column option if one exists.
  22296. */
  22297. const newActiveElement = elementsAtPoint.find((el) => el.tagName === 'ION-PICKER-COLUMN-OPTION');
  22298. if (activeEl !== undefined) {
  22299. this.setPickerItemActiveState(activeEl, false);
  22300. }
  22301. if (newActiveElement === undefined || newActiveElement.disabled) {
  22302. return;
  22303. }
  22304. /**
  22305. * If we are selecting a new value,
  22306. * we need to run haptics again.
  22307. */
  22308. if (newActiveElement !== activeEl) {
  22309. enableHaptics && hapticSelectionChanged();
  22310. if (this.canExitInputMode) {
  22311. /**
  22312. * The native iOS wheel picker
  22313. * only dismisses the keyboard
  22314. * once the selected item has changed
  22315. * as a result of a swipe
  22316. * from the user. If `canExitInputMode` is
  22317. * `false` then this means that the
  22318. * scroll is happening as a result of
  22319. * the `value` property programmatically changing
  22320. * either by an application or by the user via the keyboard.
  22321. */
  22322. this.exitInputMode();
  22323. }
  22324. }
  22325. activeEl = newActiveElement;
  22326. this.setPickerItemActiveState(newActiveElement, true);
  22327. /**
  22328. * Set the aria-valuetext even though the value prop has not been updated yet.
  22329. * This enables some screen readers to announce the value as the users drag
  22330. * as opposed to when their release their pointer from the screen.
  22331. *
  22332. * When the value is programmatically updated, we will smoothly scroll
  22333. * to the new option. However, we do not want to update aria-valuetext mid-scroll
  22334. * as that can cause the old value to be briefly set before being set to the
  22335. * correct option. This will cause some screen readers to announce the old value
  22336. * again before announcing the new value. The correct valuetext will be set on render.
  22337. */
  22338. if (this.updateValueTextOnScroll) {
  22339. (_a = this.assistiveFocusable) === null || _a === void 0 ? void 0 : _a.setAttribute('aria-valuetext', this.getOptionValueText(newActiveElement));
  22340. }
  22341. timeout = setTimeout(() => {
  22342. this.isScrolling = false;
  22343. this.updateValueTextOnScroll = true;
  22344. enableHaptics && hapticSelectionEnd();
  22345. /**
  22346. * Certain tasks (such as those that
  22347. * cause re-renders) should only be done
  22348. * once scrolling has finished, otherwise
  22349. * flickering may occur.
  22350. */
  22351. const { scrollEndCallback } = this;
  22352. if (scrollEndCallback) {
  22353. scrollEndCallback();
  22354. this.scrollEndCallback = undefined;
  22355. }
  22356. /**
  22357. * Reset this flag as the
  22358. * next scroll interaction could
  22359. * be a scroll from the user. In this
  22360. * case, we should exit input mode.
  22361. */
  22362. this.canExitInputMode = true;
  22363. this.setValue(newActiveElement.value);
  22364. }, 250);
  22365. });
  22366. };
  22367. /**
  22368. * Wrap this in an raf so that the scroll callback
  22369. * does not fire when component is initially shown.
  22370. */
  22371. raf(() => {
  22372. if (!scrollEl)
  22373. return;
  22374. scrollEl.addEventListener('scroll', scrollCallback);
  22375. this.destroyScrollListener = () => {
  22376. scrollEl.removeEventListener('scroll', scrollCallback);
  22377. };
  22378. });
  22379. };
  22380. /**
  22381. * Tells the parent picker to
  22382. * exit text entry mode. This is only called
  22383. * when the selected item changes during scroll, so
  22384. * we know that the user likely wants to scroll
  22385. * instead of type.
  22386. */
  22387. this.exitInputMode = () => {
  22388. const { parentEl } = this;
  22389. if (parentEl == null)
  22390. return;
  22391. parentEl.exitInputMode();
  22392. /**
  22393. * setInputModeActive only takes
  22394. * effect once scrolling stops to avoid
  22395. * a component re-render while scrolling.
  22396. * However, we want the visual active
  22397. * indicator to go away immediately, so
  22398. * we call classList.remove here.
  22399. */
  22400. this.el.classList.remove('picker-column-active');
  22401. };
  22402. /**
  22403. * Find the next enabled option after the active option.
  22404. * @param stride - How many options to "jump" over in order to select the next option.
  22405. * This can be used to implement PageUp/PageDown behaviors where pressing these keys
  22406. * scrolls the picker by more than 1 option. For example, a stride of 5 means select
  22407. * the enabled option 5 options after the active one. Note that the actual option selected
  22408. * may be past the stride if the option at the stride is disabled.
  22409. */
  22410. this.findNextOption = (stride = 1) => {
  22411. const { activeItem } = this;
  22412. if (!activeItem)
  22413. return null;
  22414. let prevNode = activeItem;
  22415. let node = activeItem.nextElementSibling;
  22416. while (node != null) {
  22417. if (stride > 0) {
  22418. stride--;
  22419. }
  22420. if (node.tagName === 'ION-PICKER-COLUMN-OPTION' && !node.disabled && stride === 0) {
  22421. return node;
  22422. }
  22423. prevNode = node;
  22424. // Use nextElementSibling instead of nextSibling to avoid text/comment nodes
  22425. node = node.nextElementSibling;
  22426. }
  22427. return prevNode;
  22428. };
  22429. /**
  22430. * Find the next enabled option after the active option.
  22431. * @param stride - How many options to "jump" over in order to select the next option.
  22432. * This can be used to implement PageUp/PageDown behaviors where pressing these keys
  22433. * scrolls the picker by more than 1 option. For example, a stride of 5 means select
  22434. * the enabled option 5 options before the active one. Note that the actual option selected
  22435. * may be past the stride if the option at the stride is disabled.
  22436. */
  22437. this.findPreviousOption = (stride = 1) => {
  22438. const { activeItem } = this;
  22439. if (!activeItem)
  22440. return null;
  22441. let nextNode = activeItem;
  22442. let node = activeItem.previousElementSibling;
  22443. while (node != null) {
  22444. if (stride > 0) {
  22445. stride--;
  22446. }
  22447. if (node.tagName === 'ION-PICKER-COLUMN-OPTION' && !node.disabled && stride === 0) {
  22448. return node;
  22449. }
  22450. nextNode = node;
  22451. // Use previousElementSibling instead of previousSibling to avoid text/comment nodes
  22452. node = node.previousElementSibling;
  22453. }
  22454. return nextNode;
  22455. };
  22456. this.onKeyDown = (ev) => {
  22457. /**
  22458. * The below operations should be inverted when running on a mobile device.
  22459. * For example, swiping up will dispatch an "ArrowUp" event. On desktop,
  22460. * this should cause the previous option to be selected. On mobile, swiping
  22461. * up causes a view to scroll down. As a result, swiping up on mobile should
  22462. * cause the next option to be selected. The Home/End operations remain
  22463. * unchanged because those always represent the first/last options, respectively.
  22464. */
  22465. const mobile = isPlatform('mobile');
  22466. let newOption = null;
  22467. switch (ev.key) {
  22468. case 'ArrowDown':
  22469. newOption = mobile ? this.findPreviousOption() : this.findNextOption();
  22470. break;
  22471. case 'ArrowUp':
  22472. newOption = mobile ? this.findNextOption() : this.findPreviousOption();
  22473. break;
  22474. case 'PageUp':
  22475. newOption = mobile ? this.findNextOption(5) : this.findPreviousOption(5);
  22476. break;
  22477. case 'PageDown':
  22478. newOption = mobile ? this.findPreviousOption(5) : this.findNextOption(5);
  22479. break;
  22480. case 'Home':
  22481. /**
  22482. * There is no guarantee that the first child will be an ion-picker-column-option,
  22483. * so we do not use firstElementChild.
  22484. */
  22485. newOption = this.el.querySelector('ion-picker-column-option:first-of-type');
  22486. break;
  22487. case 'End':
  22488. /**
  22489. * There is no guarantee that the last child will be an ion-picker-column-option,
  22490. * so we do not use lastElementChild.
  22491. */
  22492. newOption = this.el.querySelector('ion-picker-column-option:last-of-type');
  22493. break;
  22494. }
  22495. if (newOption !== null) {
  22496. this.setValue(newOption.value);
  22497. // This stops any default browser behavior such as scrolling
  22498. ev.preventDefault();
  22499. }
  22500. };
  22501. /**
  22502. * Utility to generate the correct text for aria-valuetext.
  22503. */
  22504. this.getOptionValueText = (el) => {
  22505. var _a;
  22506. return el ? (_a = el.getAttribute('aria-label')) !== null && _a !== void 0 ? _a : el.innerText : '';
  22507. };
  22508. /**
  22509. * Render an element that overlays the column. This element is for assistive
  22510. * tech to allow users to navigate the column up/down. This element should receive
  22511. * focus as it listens for synthesized keyboard events as required by the
  22512. * slider role: https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/slider_role
  22513. */
  22514. this.renderAssistiveFocusable = () => {
  22515. const { activeItem } = this;
  22516. const valueText = this.getOptionValueText(activeItem);
  22517. /**
  22518. * When using the picker, the valuetext provides important context that valuenow
  22519. * does not. Additionally, using non-zero valuemin/valuemax values can cause
  22520. * WebKit to incorrectly announce numeric valuetext values (such as a year
  22521. * like "2024") as percentages: https://bugs.webkit.org/show_bug.cgi?id=273126
  22522. */
  22523. return (hAsync("div", { ref: (el) => (this.assistiveFocusable = el), class: "assistive-focusable", role: "slider", tabindex: this.disabled ? undefined : 0, "aria-label": this.ariaLabel, "aria-valuemin": 0, "aria-valuemax": 0, "aria-valuenow": 0, "aria-valuetext": valueText, "aria-orientation": "vertical", onKeyDown: (ev) => this.onKeyDown(ev) }));
  22524. };
  22525. this.ariaLabel = null;
  22526. this.isActive = false;
  22527. this.disabled = false;
  22528. this.value = undefined;
  22529. this.color = 'primary';
  22530. this.numericInput = false;
  22531. }
  22532. ariaLabelChanged(newValue) {
  22533. this.ariaLabel = newValue;
  22534. }
  22535. valueChange() {
  22536. if (this.isColumnVisible) {
  22537. /**
  22538. * Only scroll the active item into view when the picker column
  22539. * is actively visible to the user.
  22540. */
  22541. this.scrollActiveItemIntoView(true);
  22542. }
  22543. }
  22544. /**
  22545. * Only setup scroll listeners
  22546. * when the picker is visible, otherwise
  22547. * the container will have a scroll
  22548. * height of 0px.
  22549. */
  22550. componentWillLoad() {
  22551. /**
  22552. * We cache parentEl in a local variable
  22553. * so we don't need to keep accessing
  22554. * the class variable (which comes with
  22555. * a small performance hit)
  22556. */
  22557. const parentEl = (this.parentEl = this.el.closest('ion-picker'));
  22558. const visibleCallback = (entries) => {
  22559. /**
  22560. * Browsers will sometimes group multiple IO events into a single callback.
  22561. * As a result, we want to grab the last/most recent event in case there are multiple events.
  22562. */
  22563. const ev = entries[entries.length - 1];
  22564. if (ev.isIntersecting) {
  22565. const { activeItem, el } = this;
  22566. this.isColumnVisible = true;
  22567. /**
  22568. * Because this initial call to scrollActiveItemIntoView has to fire before
  22569. * the scroll listener is set up, we need to manage the active class manually.
  22570. */
  22571. const oldActive = getElementRoot(el).querySelector(`.${PICKER_ITEM_ACTIVE_CLASS}`);
  22572. if (oldActive) {
  22573. this.setPickerItemActiveState(oldActive, false);
  22574. }
  22575. this.scrollActiveItemIntoView();
  22576. if (activeItem) {
  22577. this.setPickerItemActiveState(activeItem, true);
  22578. }
  22579. this.initializeScrollListener();
  22580. }
  22581. else {
  22582. this.isColumnVisible = false;
  22583. if (this.destroyScrollListener) {
  22584. this.destroyScrollListener();
  22585. this.destroyScrollListener = undefined;
  22586. }
  22587. }
  22588. };
  22589. /**
  22590. * Set the root to be the parent picker element
  22591. * This causes the IO callback
  22592. * to be fired in WebKit as soon as the element
  22593. * is visible. If we used the default root value
  22594. * then WebKit would only fire the IO callback
  22595. * after any animations (such as a modal transition)
  22596. * finished, and there would potentially be a flicker.
  22597. */
  22598. new IntersectionObserver(visibleCallback, { threshold: 0.001, root: this.parentEl }).observe(this.el);
  22599. if (parentEl !== null) {
  22600. // TODO(FW-2832): type
  22601. parentEl.addEventListener('ionInputModeChange', (ev) => this.inputModeChange(ev));
  22602. }
  22603. }
  22604. componentDidRender() {
  22605. const { el, activeItem, isColumnVisible, value } = this;
  22606. if (isColumnVisible && !activeItem) {
  22607. const firstOption = el.querySelector('ion-picker-column-option');
  22608. /**
  22609. * If the picker column does not have an active item and the current value
  22610. * does not match the first item in the picker column, that means
  22611. * the value is out of bounds. In this case, we assign the value to the
  22612. * first item to match the scroll position of the column.
  22613. *
  22614. */
  22615. if (firstOption !== null && firstOption.value !== value) {
  22616. this.setValue(firstOption.value);
  22617. }
  22618. }
  22619. }
  22620. /** @internal */
  22621. async scrollActiveItemIntoView(smooth = false) {
  22622. const activeEl = this.activeItem;
  22623. if (activeEl) {
  22624. this.centerPickerItemInView(activeEl, smooth, false);
  22625. }
  22626. }
  22627. /**
  22628. * Sets the value prop and fires the ionChange event.
  22629. * This is used when we need to fire ionChange from
  22630. * user-generated events that cannot be caught with normal
  22631. * input/change event listeners.
  22632. * @internal
  22633. */
  22634. async setValue(value) {
  22635. if (this.disabled === true || this.value === value) {
  22636. return;
  22637. }
  22638. this.value = value;
  22639. this.ionChange.emit({ value });
  22640. }
  22641. /**
  22642. * Sets focus on the scrollable container within the picker column.
  22643. * Use this method instead of the global `pickerColumn.focus()`.
  22644. */
  22645. async setFocus() {
  22646. if (this.assistiveFocusable) {
  22647. this.assistiveFocusable.focus();
  22648. }
  22649. }
  22650. connectedCallback() {
  22651. var _a;
  22652. this.ariaLabel = (_a = this.el.getAttribute('aria-label')) !== null && _a !== void 0 ? _a : 'Select a value';
  22653. }
  22654. get activeItem() {
  22655. const { value } = this;
  22656. const options = Array.from(this.el.querySelectorAll('ion-picker-column-option'));
  22657. return options.find((option) => {
  22658. /**
  22659. * If the whole picker column is disabled, the current value should appear active
  22660. * If the current value item is specifically disabled, it should not appear active
  22661. */
  22662. if (!this.disabled && option.disabled) {
  22663. return false;
  22664. }
  22665. return option.value === value;
  22666. });
  22667. }
  22668. render() {
  22669. const { color, disabled, isActive, numericInput } = this;
  22670. const mode = getIonMode$1(this);
  22671. return (hAsync(Host, { key: 'a221dc10f1eb7c41637a16d2c7167c16939822fd', class: createColorClasses$1(color, {
  22672. [mode]: true,
  22673. ['picker-column-active']: isActive,
  22674. ['picker-column-numeric-input']: numericInput,
  22675. ['picker-column-disabled']: disabled,
  22676. }) }, this.renderAssistiveFocusable(), hAsync("slot", { key: '81b0656f606856f3dc0a657bf167d81a5011405e', name: "prefix" }), hAsync("div", { key: '71b9de67c04150255dd66592601c9d926db0c31c', "aria-hidden": "true", class: "picker-opts", ref: (el) => {
  22677. this.scrollEl = el;
  22678. },
  22679. /**
  22680. * When an element has an overlay scroll style and
  22681. * a fixed height, Firefox will focus the scrollable
  22682. * container if the content exceeds the container's
  22683. * dimensions.
  22684. *
  22685. * This causes keyboard navigation to focus to this
  22686. * element instead of going to the next element in
  22687. * the tab order.
  22688. *
  22689. * The desired behavior is for the user to be able to
  22690. * focus the assistive focusable element and tab to
  22691. * the next element in the tab order. Instead of tabbing
  22692. * to this element.
  22693. *
  22694. * To prevent this, we set the tabIndex to -1. This
  22695. * will match the behavior of the other browsers.
  22696. */
  22697. tabIndex: -1 }, hAsync("div", { key: 'ebdc2f08c83db0cf17b4be29f28fcb00f529601e', class: "picker-item-empty", "aria-hidden": "true" }, "\u00A0"), hAsync("div", { key: '04ab56fcb8e6a7d6af00204c4560feb99ff34a56', class: "picker-item-empty", "aria-hidden": "true" }, "\u00A0"), hAsync("div", { key: '6cf8f538903faf0fe1e4130f3eaf7b4e2e17cb52', class: "picker-item-empty", "aria-hidden": "true" }, "\u00A0"), hAsync("slot", { key: '1cc392307b70c576be5b81b5226ceba735957f0f' }), hAsync("div", { key: '23e3f28e2a99b9aa8b7c8f68ad9583e3ca63e9e2', class: "picker-item-empty", "aria-hidden": "true" }, "\u00A0"), hAsync("div", { key: '8a0563f09780c3116af0caebe4f40587ec1f041f', class: "picker-item-empty", "aria-hidden": "true" }, "\u00A0"), hAsync("div", { key: '13207e248fc0009f37e0c90a3ee2bac2f130b856', class: "picker-item-empty", "aria-hidden": "true" }, "\u00A0")), hAsync("slot", { key: '55ecf2ab5f214f936c2468cbdb7952daf89416b8', name: "suffix" })));
  22698. }
  22699. get el() { return getElement(this); }
  22700. static get watchers() { return {
  22701. "aria-label": ["ariaLabelChanged"],
  22702. "value": ["valueChange"]
  22703. }; }
  22704. static get style() { return IonPickerColumnStyle0; }
  22705. static get cmpMeta() { return {
  22706. "$flags$": 9,
  22707. "$tagName$": "ion-picker-column",
  22708. "$members$": {
  22709. "disabled": [4],
  22710. "value": [1032],
  22711. "color": [513],
  22712. "numericInput": [4, "numeric-input"],
  22713. "ariaLabel": [32],
  22714. "isActive": [32],
  22715. "scrollActiveItemIntoView": [64],
  22716. "setValue": [64],
  22717. "setFocus": [64]
  22718. },
  22719. "$listeners$": undefined,
  22720. "$lazyBundleId$": "-",
  22721. "$attrsToReflect$": [["color", "color"]]
  22722. }; }
  22723. }
  22724. const PICKER_ITEM_ACTIVE_CLASS = 'option-active';
  22725. const pickerColumnIosCss = ".picker-col{display:-ms-flexbox;display:flex;position:relative;-ms-flex:1;flex:1;-ms-flex-pack:center;justify-content:center;height:100%;-webkit-box-sizing:content-box;box-sizing:content-box;contain:content}.picker-opts{position:relative;-ms-flex:1;flex:1;max-width:100%}.picker-opt{top:0;display:block;position:absolute;width:100%;border:0;text-align:center;text-overflow:ellipsis;white-space:nowrap;contain:strict;overflow:hidden;will-change:transform}.picker-opt{inset-inline-start:0}.picker-opt.picker-opt-disabled{pointer-events:none}.picker-opt-disabled{opacity:0}.picker-opts-left{-ms-flex-pack:start;justify-content:flex-start}.picker-opts-right{-ms-flex-pack:end;justify-content:flex-end}.picker-opt:active,.picker-opt:focus{outline:none}.picker-prefix{position:relative;-ms-flex:1;flex:1;text-align:end;white-space:nowrap}.picker-suffix{position:relative;-ms-flex:1;flex:1;text-align:start;white-space:nowrap}.picker-col{-webkit-padding-start:4px;padding-inline-start:4px;-webkit-padding-end:4px;padding-inline-end:4px;padding-top:0;padding-bottom:0;-webkit-transform-style:preserve-3d;transform-style:preserve-3d}.picker-prefix,.picker-suffix,.picker-opts{top:77px;-webkit-transform-style:preserve-3d;transform-style:preserve-3d;color:inherit;font-size:20px;line-height:42px;pointer-events:none}.picker-opt{padding-left:0;padding-right:0;padding-top:0;padding-bottom:0;margin-left:0;margin-right:0;margin-top:0;margin-bottom:0;-webkit-transform-origin:center center;transform-origin:center center;height:46px;-webkit-transform-style:preserve-3d;transform-style:preserve-3d;-webkit-transition-timing-function:ease-out;transition-timing-function:ease-out;background:transparent;color:inherit;font-size:20px;line-height:42px;-webkit-backface-visibility:hidden;backface-visibility:hidden;pointer-events:auto}:host-context([dir=rtl]) .picker-opt{-webkit-transform-origin:calc(100% - center) center;transform-origin:calc(100% - center) center}[dir=rtl] .picker-opt{-webkit-transform-origin:calc(100% - center) center;transform-origin:calc(100% - center) center}@supports selector(:dir(rtl)){.picker-opt:dir(rtl){-webkit-transform-origin:calc(100% - center) center;transform-origin:calc(100% - center) center}}";
  22726. var IonPickerLegacyColumnIosStyle0 = pickerColumnIosCss;
  22727. const pickerColumnMdCss = ".picker-col{display:-ms-flexbox;display:flex;position:relative;-ms-flex:1;flex:1;-ms-flex-pack:center;justify-content:center;height:100%;-webkit-box-sizing:content-box;box-sizing:content-box;contain:content}.picker-opts{position:relative;-ms-flex:1;flex:1;max-width:100%}.picker-opt{top:0;display:block;position:absolute;width:100%;border:0;text-align:center;text-overflow:ellipsis;white-space:nowrap;contain:strict;overflow:hidden;will-change:transform}.picker-opt{inset-inline-start:0}.picker-opt.picker-opt-disabled{pointer-events:none}.picker-opt-disabled{opacity:0}.picker-opts-left{-ms-flex-pack:start;justify-content:flex-start}.picker-opts-right{-ms-flex-pack:end;justify-content:flex-end}.picker-opt:active,.picker-opt:focus{outline:none}.picker-prefix{position:relative;-ms-flex:1;flex:1;text-align:end;white-space:nowrap}.picker-suffix{position:relative;-ms-flex:1;flex:1;text-align:start;white-space:nowrap}.picker-col{-webkit-padding-start:8px;padding-inline-start:8px;-webkit-padding-end:8px;padding-inline-end:8px;padding-top:0;padding-bottom:0;-webkit-transform-style:preserve-3d;transform-style:preserve-3d}.picker-prefix,.picker-suffix,.picker-opts{top:77px;-webkit-transform-style:preserve-3d;transform-style:preserve-3d;color:inherit;font-size:22px;line-height:42px;pointer-events:none}.picker-opt{margin-left:0;margin-right:0;margin-top:0;margin-bottom:0;padding-left:0;padding-right:0;padding-top:0;padding-bottom:0;height:43px;-webkit-transition-timing-function:ease-out;transition-timing-function:ease-out;background:transparent;color:inherit;font-size:22px;line-height:42px;-webkit-backface-visibility:hidden;backface-visibility:hidden;pointer-events:auto}.picker-prefix,.picker-suffix,.picker-opt.picker-opt-selected{color:var(--ion-color-primary, #0054e9)}";
  22728. var IonPickerLegacyColumnMdStyle0 = pickerColumnMdCss;
  22729. /**
  22730. * @internal
  22731. */
  22732. class PickerColumnCmp {
  22733. constructor(hostRef) {
  22734. registerInstance(this, hostRef);
  22735. this.ionPickerColChange = createEvent(this, "ionPickerColChange", 7);
  22736. this.optHeight = 0;
  22737. this.rotateFactor = 0;
  22738. this.scaleFactor = 1;
  22739. this.velocity = 0;
  22740. this.y = 0;
  22741. this.noAnimate = true;
  22742. // `colDidChange` is a flag that gets set when the column is changed
  22743. // dynamically. When this flag is set, the column will refresh
  22744. // after the component re-renders to incorporate the new column data.
  22745. // This is necessary because `this.refresh` queries for the option elements,
  22746. // so it needs to wait for the latest elements to be available in the DOM.
  22747. // Ex: column is created with 3 options. User updates the column data
  22748. // to have 5 options. The column will still think it only has 3 options.
  22749. this.colDidChange = false;
  22750. this.col = undefined;
  22751. }
  22752. colChanged() {
  22753. this.colDidChange = true;
  22754. }
  22755. async connectedCallback() {
  22756. let pickerRotateFactor = 0;
  22757. let pickerScaleFactor = 0.81;
  22758. const mode = getIonMode$1(this);
  22759. if (mode === 'ios') {
  22760. pickerRotateFactor = -0.46;
  22761. pickerScaleFactor = 1;
  22762. }
  22763. this.rotateFactor = pickerRotateFactor;
  22764. this.scaleFactor = pickerScaleFactor;
  22765. this.gesture = (await Promise.resolve().then(function () { return index; })).createGesture({
  22766. el: this.el,
  22767. gestureName: 'picker-swipe',
  22768. gesturePriority: 100,
  22769. threshold: 0,
  22770. passive: false,
  22771. onStart: (ev) => this.onStart(ev),
  22772. onMove: (ev) => this.onMove(ev),
  22773. onEnd: (ev) => this.onEnd(ev),
  22774. });
  22775. this.gesture.enable();
  22776. // Options have not been initialized yet
  22777. // Animation must be disabled through the `noAnimate` flag
  22778. // Otherwise, the options will render
  22779. // at the top of the column and transition down
  22780. this.tmrId = setTimeout(() => {
  22781. this.noAnimate = false;
  22782. // After initialization, `refresh()` will be called
  22783. // At this point, animation will be enabled. The options will
  22784. // animate as they are being selected.
  22785. this.refresh(true);
  22786. }, 250);
  22787. }
  22788. componentDidLoad() {
  22789. this.onDomChange();
  22790. }
  22791. componentDidUpdate() {
  22792. // Options may have changed since last update.
  22793. if (this.colDidChange) {
  22794. // Animation must be disabled through the `onDomChange` parameter.
  22795. // Otherwise, the recently added options will render
  22796. // at the top of the column and transition down
  22797. this.onDomChange(true, false);
  22798. this.colDidChange = false;
  22799. }
  22800. }
  22801. disconnectedCallback() {
  22802. if (this.rafId !== undefined)
  22803. cancelAnimationFrame(this.rafId);
  22804. if (this.tmrId)
  22805. clearTimeout(this.tmrId);
  22806. if (this.gesture) {
  22807. this.gesture.destroy();
  22808. this.gesture = undefined;
  22809. }
  22810. }
  22811. emitColChange() {
  22812. this.ionPickerColChange.emit(this.col);
  22813. }
  22814. setSelected(selectedIndex, duration) {
  22815. // if there is a selected index, then figure out it's y position
  22816. // if there isn't a selected index, then just use the top y position
  22817. const y = selectedIndex > -1 ? -(selectedIndex * this.optHeight) : 0;
  22818. this.velocity = 0;
  22819. // set what y position we're at
  22820. if (this.rafId !== undefined)
  22821. cancelAnimationFrame(this.rafId);
  22822. this.update(y, duration, true);
  22823. this.emitColChange();
  22824. }
  22825. update(y, duration, saveY) {
  22826. if (!this.optsEl) {
  22827. return;
  22828. }
  22829. // ensure we've got a good round number :)
  22830. let translateY = 0;
  22831. let translateZ = 0;
  22832. const { col, rotateFactor } = this;
  22833. const prevSelected = col.selectedIndex;
  22834. const selectedIndex = (col.selectedIndex = this.indexForY(-y));
  22835. const durationStr = duration === 0 ? '' : duration + 'ms';
  22836. const scaleStr = `scale(${this.scaleFactor})`;
  22837. const children = this.optsEl.children;
  22838. for (let i = 0; i < children.length; i++) {
  22839. const button = children[i];
  22840. const opt = col.options[i];
  22841. const optOffset = i * this.optHeight + y;
  22842. let transform = '';
  22843. if (rotateFactor !== 0) {
  22844. const rotateX = optOffset * rotateFactor;
  22845. if (Math.abs(rotateX) <= 90) {
  22846. translateY = 0;
  22847. translateZ = 90;
  22848. transform = `rotateX(${rotateX}deg) `;
  22849. }
  22850. else {
  22851. translateY = -9999;
  22852. }
  22853. }
  22854. else {
  22855. translateZ = 0;
  22856. translateY = optOffset;
  22857. }
  22858. const selected = selectedIndex === i;
  22859. transform += `translate3d(0px,${translateY}px,${translateZ}px) `;
  22860. if (this.scaleFactor !== 1 && !selected) {
  22861. transform += scaleStr;
  22862. }
  22863. // Update transition duration
  22864. if (this.noAnimate) {
  22865. opt.duration = 0;
  22866. button.style.transitionDuration = '';
  22867. }
  22868. else if (duration !== opt.duration) {
  22869. opt.duration = duration;
  22870. button.style.transitionDuration = durationStr;
  22871. }
  22872. // Update transform
  22873. if (transform !== opt.transform) {
  22874. opt.transform = transform;
  22875. }
  22876. button.style.transform = transform;
  22877. /**
  22878. * Ensure that the select column
  22879. * item has the selected class
  22880. */
  22881. opt.selected = selected;
  22882. if (selected) {
  22883. button.classList.add(PICKER_OPT_SELECTED);
  22884. }
  22885. else {
  22886. button.classList.remove(PICKER_OPT_SELECTED);
  22887. }
  22888. }
  22889. this.col.prevSelected = prevSelected;
  22890. if (saveY) {
  22891. this.y = y;
  22892. }
  22893. if (this.lastIndex !== selectedIndex) {
  22894. // have not set a last index yet
  22895. hapticSelectionChanged();
  22896. this.lastIndex = selectedIndex;
  22897. }
  22898. }
  22899. decelerate() {
  22900. if (this.velocity !== 0) {
  22901. // still decelerating
  22902. this.velocity *= DECELERATION_FRICTION;
  22903. // do not let it go slower than a velocity of 1
  22904. this.velocity = this.velocity > 0 ? Math.max(this.velocity, 1) : Math.min(this.velocity, -1);
  22905. let y = this.y + this.velocity;
  22906. if (y > this.minY) {
  22907. // whoops, it's trying to scroll up farther than the options we have!
  22908. y = this.minY;
  22909. this.velocity = 0;
  22910. }
  22911. else if (y < this.maxY) {
  22912. // gahh, it's trying to scroll down farther than we can!
  22913. y = this.maxY;
  22914. this.velocity = 0;
  22915. }
  22916. this.update(y, 0, true);
  22917. const notLockedIn = Math.round(y) % this.optHeight !== 0 || Math.abs(this.velocity) > 1;
  22918. if (notLockedIn) {
  22919. // isn't locked in yet, keep decelerating until it is
  22920. this.rafId = requestAnimationFrame(() => this.decelerate());
  22921. }
  22922. else {
  22923. this.velocity = 0;
  22924. this.emitColChange();
  22925. hapticSelectionEnd();
  22926. }
  22927. }
  22928. else if (this.y % this.optHeight !== 0) {
  22929. // needs to still get locked into a position so options line up
  22930. const currentPos = Math.abs(this.y % this.optHeight);
  22931. // create a velocity in the direction it needs to scroll
  22932. this.velocity = currentPos > this.optHeight / 2 ? 1 : -1;
  22933. this.decelerate();
  22934. }
  22935. }
  22936. indexForY(y) {
  22937. return Math.min(Math.max(Math.abs(Math.round(y / this.optHeight)), 0), this.col.options.length - 1);
  22938. }
  22939. onStart(detail) {
  22940. // We have to prevent default in order to block scrolling under the picker
  22941. // but we DO NOT have to stop propagation, since we still want
  22942. // some "click" events to capture
  22943. if (detail.event.cancelable) {
  22944. detail.event.preventDefault();
  22945. }
  22946. detail.event.stopPropagation();
  22947. hapticSelectionStart();
  22948. // reset everything
  22949. if (this.rafId !== undefined)
  22950. cancelAnimationFrame(this.rafId);
  22951. const options = this.col.options;
  22952. let minY = options.length - 1;
  22953. let maxY = 0;
  22954. for (let i = 0; i < options.length; i++) {
  22955. if (!options[i].disabled) {
  22956. minY = Math.min(minY, i);
  22957. maxY = Math.max(maxY, i);
  22958. }
  22959. }
  22960. this.minY = -(minY * this.optHeight);
  22961. this.maxY = -(maxY * this.optHeight);
  22962. }
  22963. onMove(detail) {
  22964. if (detail.event.cancelable) {
  22965. detail.event.preventDefault();
  22966. }
  22967. detail.event.stopPropagation();
  22968. // update the scroll position relative to pointer start position
  22969. let y = this.y + detail.deltaY;
  22970. if (y > this.minY) {
  22971. // scrolling up higher than scroll area
  22972. y = Math.pow(y, 0.8);
  22973. this.bounceFrom = y;
  22974. }
  22975. else if (y < this.maxY) {
  22976. // scrolling down below scroll area
  22977. y += Math.pow(this.maxY - y, 0.9);
  22978. this.bounceFrom = y;
  22979. }
  22980. else {
  22981. this.bounceFrom = 0;
  22982. }
  22983. this.update(y, 0, false);
  22984. }
  22985. onEnd(detail) {
  22986. if (this.bounceFrom > 0) {
  22987. // bounce back up
  22988. this.update(this.minY, 100, true);
  22989. this.emitColChange();
  22990. return;
  22991. }
  22992. else if (this.bounceFrom < 0) {
  22993. // bounce back down
  22994. this.update(this.maxY, 100, true);
  22995. this.emitColChange();
  22996. return;
  22997. }
  22998. this.velocity = clamp(-MAX_PICKER_SPEED, detail.velocityY * 23, MAX_PICKER_SPEED);
  22999. if (this.velocity === 0 && detail.deltaY === 0) {
  23000. const opt = detail.event.target.closest('.picker-opt');
  23001. if (opt === null || opt === void 0 ? void 0 : opt.hasAttribute('opt-index')) {
  23002. this.setSelected(parseInt(opt.getAttribute('opt-index'), 10), TRANSITION_DURATION);
  23003. }
  23004. }
  23005. else {
  23006. this.y += detail.deltaY;
  23007. if (Math.abs(detail.velocityY) < 0.05) {
  23008. const isScrollingUp = detail.deltaY > 0;
  23009. const optHeightFraction = (Math.abs(this.y) % this.optHeight) / this.optHeight;
  23010. if (isScrollingUp && optHeightFraction > 0.5) {
  23011. this.velocity = Math.abs(this.velocity) * -1;
  23012. }
  23013. else if (!isScrollingUp && optHeightFraction <= 0.5) {
  23014. this.velocity = Math.abs(this.velocity);
  23015. }
  23016. }
  23017. this.decelerate();
  23018. }
  23019. }
  23020. refresh(forceRefresh, animated) {
  23021. var _a;
  23022. let min = this.col.options.length - 1;
  23023. let max = 0;
  23024. const options = this.col.options;
  23025. for (let i = 0; i < options.length; i++) {
  23026. if (!options[i].disabled) {
  23027. min = Math.min(min, i);
  23028. max = Math.max(max, i);
  23029. }
  23030. }
  23031. /**
  23032. * Only update selected value if column has a
  23033. * velocity of 0. If it does not, then the
  23034. * column is animating might land on
  23035. * a value different than the value at
  23036. * selectedIndex
  23037. */
  23038. if (this.velocity !== 0) {
  23039. return;
  23040. }
  23041. const selectedIndex = clamp(min, (_a = this.col.selectedIndex) !== null && _a !== void 0 ? _a : 0, max);
  23042. if (this.col.prevSelected !== selectedIndex || forceRefresh) {
  23043. const y = selectedIndex * this.optHeight * -1;
  23044. const duration = animated ? TRANSITION_DURATION : 0;
  23045. this.velocity = 0;
  23046. this.update(y, duration, true);
  23047. }
  23048. }
  23049. onDomChange(forceRefresh, animated) {
  23050. const colEl = this.optsEl;
  23051. if (colEl) {
  23052. // DOM READ
  23053. // We perfom a DOM read over a rendered item, this needs to happen after the first render or after the the column has changed
  23054. this.optHeight = colEl.firstElementChild ? colEl.firstElementChild.clientHeight : 0;
  23055. }
  23056. this.refresh(forceRefresh, animated);
  23057. }
  23058. render() {
  23059. const col = this.col;
  23060. const mode = getIonMode$1(this);
  23061. return (hAsync(Host, { key: '88a3c9397c9ac92dd814074c8ae6ecf8e3420a2c', class: Object.assign({ [mode]: true, 'picker-col': true, 'picker-opts-left': this.col.align === 'left', 'picker-opts-right': this.col.align === 'right' }, getClassMap(col.cssClass)), style: {
  23062. 'max-width': this.col.columnWidth,
  23063. } }, col.prefix && (hAsync("div", { key: '4491a705d15337e6f45f3cf6fd21af5242474729', class: "picker-prefix", style: { width: col.prefixWidth } }, col.prefix)), hAsync("div", { key: 'b0dd4b7a7a4c1edc4b73e7fb134ac85264072365', class: "picker-opts", style: { maxWidth: col.optionsWidth }, ref: (el) => (this.optsEl = el) }, col.options.map((o, index) => (hAsync("button", { "aria-label": o.ariaLabel, class: { 'picker-opt': true, 'picker-opt-disabled': !!o.disabled }, "opt-index": index }, o.text)))), col.suffix && (hAsync("div", { key: 'c16419ce6481d60fc3ba6b8d102a4edf0ede02aa', class: "picker-suffix", style: { width: col.suffixWidth } }, col.suffix))));
  23064. }
  23065. get el() { return getElement(this); }
  23066. static get watchers() { return {
  23067. "col": ["colChanged"]
  23068. }; }
  23069. static get style() { return {
  23070. ios: IonPickerLegacyColumnIosStyle0,
  23071. md: IonPickerLegacyColumnMdStyle0
  23072. }; }
  23073. static get cmpMeta() { return {
  23074. "$flags$": 32,
  23075. "$tagName$": "ion-picker-legacy-column",
  23076. "$members$": {
  23077. "col": [16]
  23078. },
  23079. "$listeners$": undefined,
  23080. "$lazyBundleId$": "-",
  23081. "$attrsToReflect$": []
  23082. }; }
  23083. }
  23084. const PICKER_OPT_SELECTED = 'picker-opt-selected';
  23085. const DECELERATION_FRICTION = 0.97;
  23086. const MAX_PICKER_SPEED = 90;
  23087. const TRANSITION_DURATION = 150;
  23088. const pickerColumnOptionIosCss = "button{padding-left:0;padding-right:0;padding-top:0;padding-bottom:0;margin-left:0;margin-right:0;margin-top:0;margin-bottom:0;width:100%;height:34px;border:0px;outline:none;background:transparent;color:inherit;font-family:var(--ion-font-family, inherit);font-size:inherit;line-height:34px;text-align:inherit;text-overflow:ellipsis;white-space:nowrap;cursor:pointer;overflow:hidden}:host(.option-disabled){opacity:0.4}:host(.option-disabled) button{cursor:default}";
  23089. var IonPickerColumnOptionIosStyle0 = pickerColumnOptionIosCss;
  23090. const pickerColumnOptionMdCss = "button{padding-left:0;padding-right:0;padding-top:0;padding-bottom:0;margin-left:0;margin-right:0;margin-top:0;margin-bottom:0;width:100%;height:34px;border:0px;outline:none;background:transparent;color:inherit;font-family:var(--ion-font-family, inherit);font-size:inherit;line-height:34px;text-align:inherit;text-overflow:ellipsis;white-space:nowrap;cursor:pointer;overflow:hidden}:host(.option-disabled){opacity:0.4}:host(.option-disabled) button{cursor:default}:host(.option-active){color:var(--ion-color-base)}";
  23091. var IonPickerColumnOptionMdStyle0 = pickerColumnOptionMdCss;
  23092. class PickerColumnOption {
  23093. constructor(hostRef) {
  23094. registerInstance(this, hostRef);
  23095. /**
  23096. * We keep track of the parent picker column
  23097. * so we can update the value of it when
  23098. * clicking an enable option.
  23099. */
  23100. this.pickerColumn = null;
  23101. this.ariaLabel = null;
  23102. this.disabled = false;
  23103. this.value = undefined;
  23104. this.color = 'primary';
  23105. }
  23106. /**
  23107. * The aria-label of the option has changed after the
  23108. * first render and needs to be updated within the component.
  23109. *
  23110. * @param ariaLbl The new aria-label value.
  23111. */
  23112. onAriaLabelChange(ariaLbl) {
  23113. this.ariaLabel = ariaLbl;
  23114. }
  23115. componentWillLoad() {
  23116. const inheritedAttributes = inheritAttributes$1(this.el, ['aria-label']);
  23117. /**
  23118. * The initial value of `aria-label` needs to be set for
  23119. * the first render.
  23120. */
  23121. this.ariaLabel = inheritedAttributes['aria-label'] || null;
  23122. }
  23123. connectedCallback() {
  23124. this.pickerColumn = this.el.closest('ion-picker-column');
  23125. }
  23126. disconnectedCallback() {
  23127. this.pickerColumn = null;
  23128. }
  23129. /**
  23130. * The column options can load at any time
  23131. * so the options needs to tell the
  23132. * parent picker column when it is loaded
  23133. * so the picker column can ensure it is
  23134. * centered in the view.
  23135. *
  23136. * We intentionally run this for every
  23137. * option. If we only ran this from
  23138. * the selected option then if the newly
  23139. * loaded options were not selected then
  23140. * scrollActiveItemIntoView would not be called.
  23141. */
  23142. componentDidLoad() {
  23143. const { pickerColumn } = this;
  23144. if (pickerColumn !== null) {
  23145. pickerColumn.scrollActiveItemIntoView();
  23146. }
  23147. }
  23148. /**
  23149. * When an option is clicked, update the
  23150. * parent picker column value. This
  23151. * component will handle centering the option
  23152. * in the column view.
  23153. */
  23154. onClick() {
  23155. const { pickerColumn } = this;
  23156. if (pickerColumn !== null) {
  23157. pickerColumn.setValue(this.value);
  23158. }
  23159. }
  23160. render() {
  23161. const { color, disabled, ariaLabel } = this;
  23162. const mode = getIonMode$1(this);
  23163. return (hAsync(Host, { key: 'c1353e99c2aa19c0e3ddbe433557ed18e72e1c66', class: createColorClasses$1(color, {
  23164. [mode]: true,
  23165. ['option-disabled']: disabled,
  23166. }) }, hAsync("button", { key: 'b4ee62ecf7458a07a56e8aa494485766a87a3fcb', tabindex: "-1", "aria-label": ariaLabel, disabled: disabled, onClick: () => this.onClick() }, hAsync("slot", { key: '9ab1e4700c27103b676670a4b3521c183c6ab83d' }))));
  23167. }
  23168. get el() { return getElement(this); }
  23169. static get watchers() { return {
  23170. "aria-label": ["onAriaLabelChange"]
  23171. }; }
  23172. static get style() { return {
  23173. ios: IonPickerColumnOptionIosStyle0,
  23174. md: IonPickerColumnOptionMdStyle0
  23175. }; }
  23176. static get cmpMeta() { return {
  23177. "$flags$": 41,
  23178. "$tagName$": "ion-picker-column-option",
  23179. "$members$": {
  23180. "disabled": [4],
  23181. "value": [8],
  23182. "color": [513],
  23183. "ariaLabel": [32]
  23184. },
  23185. "$listeners$": undefined,
  23186. "$lazyBundleId$": "-",
  23187. "$attrsToReflect$": [["color", "color"]]
  23188. }; }
  23189. }
  23190. /**
  23191. * Returns the dimensions of the popover
  23192. * arrow on `ios` mode. If arrow is disabled
  23193. * returns (0, 0).
  23194. */
  23195. const getArrowDimensions = (arrowEl) => {
  23196. if (!arrowEl) {
  23197. return { arrowWidth: 0, arrowHeight: 0 };
  23198. }
  23199. const { width, height } = arrowEl.getBoundingClientRect();
  23200. return { arrowWidth: width, arrowHeight: height };
  23201. };
  23202. /**
  23203. * Returns the recommended dimensions of the popover
  23204. * that takes into account whether or not the width
  23205. * should match the trigger width.
  23206. */
  23207. const getPopoverDimensions = (size, contentEl, triggerEl) => {
  23208. const contentDimentions = contentEl.getBoundingClientRect();
  23209. const contentHeight = contentDimentions.height;
  23210. let contentWidth = contentDimentions.width;
  23211. if (size === 'cover' && triggerEl) {
  23212. const triggerDimensions = triggerEl.getBoundingClientRect();
  23213. contentWidth = triggerDimensions.width;
  23214. }
  23215. return {
  23216. contentWidth,
  23217. contentHeight,
  23218. };
  23219. };
  23220. const configureDismissInteraction = (triggerEl, triggerAction, popoverEl, parentPopoverEl) => {
  23221. let dismissCallbacks = [];
  23222. const root = getElementRoot(parentPopoverEl);
  23223. const parentContentEl = root.querySelector('.popover-content');
  23224. switch (triggerAction) {
  23225. case 'hover':
  23226. dismissCallbacks = [
  23227. {
  23228. /**
  23229. * Do not use mouseover here
  23230. * as this will causes the event to
  23231. * be dispatched on each underlying
  23232. * element rather than on the popover
  23233. * content as a whole.
  23234. */
  23235. eventName: 'mouseenter',
  23236. callback: (ev) => {
  23237. /**
  23238. * Do not dismiss the popover is we
  23239. * are hovering over its trigger.
  23240. * This would be easier if we used mouseover
  23241. * but this would cause the event to be dispatched
  23242. * more often than we would like, potentially
  23243. * causing performance issues.
  23244. */
  23245. const element = document.elementFromPoint(ev.clientX, ev.clientY);
  23246. if (element === triggerEl) {
  23247. return;
  23248. }
  23249. popoverEl.dismiss(undefined, undefined, false);
  23250. },
  23251. },
  23252. ];
  23253. break;
  23254. case 'context-menu':
  23255. case 'click':
  23256. default:
  23257. dismissCallbacks = [
  23258. {
  23259. eventName: 'click',
  23260. callback: (ev) => {
  23261. /**
  23262. * Do not dismiss the popover is we
  23263. * are hovering over its trigger.
  23264. */
  23265. const target = ev.target;
  23266. const closestTrigger = target.closest('[data-ion-popover-trigger]');
  23267. if (closestTrigger === triggerEl) {
  23268. /**
  23269. * stopPropagation here so if the
  23270. * popover has dismissOnSelect="true"
  23271. * the popover does not dismiss since
  23272. * we just clicked a trigger element.
  23273. */
  23274. ev.stopPropagation();
  23275. return;
  23276. }
  23277. popoverEl.dismiss(undefined, undefined, false);
  23278. },
  23279. },
  23280. ];
  23281. break;
  23282. }
  23283. dismissCallbacks.forEach(({ eventName, callback }) => parentContentEl.addEventListener(eventName, callback));
  23284. return () => {
  23285. dismissCallbacks.forEach(({ eventName, callback }) => parentContentEl.removeEventListener(eventName, callback));
  23286. };
  23287. };
  23288. /**
  23289. * Configures the triggerEl to respond
  23290. * to user interaction based upon the triggerAction
  23291. * prop that devs have defined.
  23292. */
  23293. const configureTriggerInteraction = (triggerEl, triggerAction, popoverEl) => {
  23294. let triggerCallbacks = [];
  23295. /**
  23296. * Based upon the kind of trigger interaction
  23297. * the user wants, we setup the correct event
  23298. * listeners.
  23299. */
  23300. switch (triggerAction) {
  23301. case 'hover':
  23302. let hoverTimeout;
  23303. triggerCallbacks = [
  23304. {
  23305. eventName: 'mouseenter',
  23306. callback: async (ev) => {
  23307. ev.stopPropagation();
  23308. if (hoverTimeout) {
  23309. clearTimeout(hoverTimeout);
  23310. }
  23311. /**
  23312. * Hovering over a trigger should not
  23313. * immediately open the next popover.
  23314. */
  23315. hoverTimeout = setTimeout(() => {
  23316. raf(() => {
  23317. popoverEl.presentFromTrigger(ev);
  23318. hoverTimeout = undefined;
  23319. });
  23320. }, 100);
  23321. },
  23322. },
  23323. {
  23324. eventName: 'mouseleave',
  23325. callback: (ev) => {
  23326. if (hoverTimeout) {
  23327. clearTimeout(hoverTimeout);
  23328. }
  23329. /**
  23330. * If mouse is over another popover
  23331. * that is not this popover then we should
  23332. * close this popover.
  23333. */
  23334. const target = ev.relatedTarget;
  23335. if (!target) {
  23336. return;
  23337. }
  23338. if (target.closest('ion-popover') !== popoverEl) {
  23339. popoverEl.dismiss(undefined, undefined, false);
  23340. }
  23341. },
  23342. },
  23343. {
  23344. /**
  23345. * stopPropagation here prevents the popover
  23346. * from dismissing when dismiss-on-select="true".
  23347. */
  23348. eventName: 'click',
  23349. callback: (ev) => ev.stopPropagation(),
  23350. },
  23351. {
  23352. eventName: 'ionPopoverActivateTrigger',
  23353. callback: (ev) => popoverEl.presentFromTrigger(ev, true),
  23354. },
  23355. ];
  23356. break;
  23357. case 'context-menu':
  23358. triggerCallbacks = [
  23359. {
  23360. eventName: 'contextmenu',
  23361. callback: (ev) => {
  23362. /**
  23363. * Prevents the platform context
  23364. * menu from appearing.
  23365. */
  23366. ev.preventDefault();
  23367. popoverEl.presentFromTrigger(ev);
  23368. },
  23369. },
  23370. {
  23371. eventName: 'click',
  23372. callback: (ev) => ev.stopPropagation(),
  23373. },
  23374. {
  23375. eventName: 'ionPopoverActivateTrigger',
  23376. callback: (ev) => popoverEl.presentFromTrigger(ev, true),
  23377. },
  23378. ];
  23379. break;
  23380. case 'click':
  23381. default:
  23382. triggerCallbacks = [
  23383. {
  23384. /**
  23385. * Do not do a stopPropagation() here
  23386. * because if you had two click triggers
  23387. * then clicking the first trigger and then
  23388. * clicking the second trigger would not cause
  23389. * the first popover to dismiss.
  23390. */
  23391. eventName: 'click',
  23392. callback: (ev) => popoverEl.presentFromTrigger(ev),
  23393. },
  23394. {
  23395. eventName: 'ionPopoverActivateTrigger',
  23396. callback: (ev) => popoverEl.presentFromTrigger(ev, true),
  23397. },
  23398. ];
  23399. break;
  23400. }
  23401. triggerCallbacks.forEach(({ eventName, callback }) => triggerEl.addEventListener(eventName, callback));
  23402. triggerEl.setAttribute('data-ion-popover-trigger', 'true');
  23403. return () => {
  23404. triggerCallbacks.forEach(({ eventName, callback }) => triggerEl.removeEventListener(eventName, callback));
  23405. triggerEl.removeAttribute('data-ion-popover-trigger');
  23406. };
  23407. };
  23408. /**
  23409. * Returns the index of an ion-item in an array of ion-items.
  23410. */
  23411. const getIndexOfItem = (items, item) => {
  23412. if (!item || item.tagName !== 'ION-ITEM') {
  23413. return -1;
  23414. }
  23415. return items.findIndex((el) => el === item);
  23416. };
  23417. /**
  23418. * Given an array of elements and a currently focused ion-item
  23419. * returns the next ion-item relative to the focused one or
  23420. * undefined.
  23421. */
  23422. const getNextItem = (items, currentItem) => {
  23423. const currentItemIndex = getIndexOfItem(items, currentItem);
  23424. return items[currentItemIndex + 1];
  23425. };
  23426. /**
  23427. * Given an array of elements and a currently focused ion-item
  23428. * returns the previous ion-item relative to the focused one or
  23429. * undefined.
  23430. */
  23431. const getPrevItem = (items, currentItem) => {
  23432. const currentItemIndex = getIndexOfItem(items, currentItem);
  23433. return items[currentItemIndex - 1];
  23434. };
  23435. /** Focus the internal button of the ion-item */
  23436. const focusItem = (item) => {
  23437. const root = getElementRoot(item);
  23438. const button = root.querySelector('button');
  23439. if (button) {
  23440. raf(() => button.focus());
  23441. }
  23442. };
  23443. /**
  23444. * Returns `true` if `el` has been designated
  23445. * as a trigger element for an ion-popover.
  23446. */
  23447. const isTriggerElement = (el) => el.hasAttribute('data-ion-popover-trigger');
  23448. const configureKeyboardInteraction = (popoverEl) => {
  23449. const callback = async (ev) => {
  23450. var _a;
  23451. const activeElement = document.activeElement;
  23452. let items = [];
  23453. const targetTagName = (_a = ev.target) === null || _a === void 0 ? void 0 : _a.tagName;
  23454. /**
  23455. * Only handle custom keyboard interactions for the host popover element
  23456. * and children ion-item elements.
  23457. */
  23458. if (targetTagName !== 'ION-POPOVER' && targetTagName !== 'ION-ITEM') {
  23459. return;
  23460. }
  23461. /**
  23462. * Complex selectors with :not() are :not supported
  23463. * in older versions of Chromium so we need to do a
  23464. * try/catch here so errors are not thrown.
  23465. */
  23466. try {
  23467. /**
  23468. * Select all ion-items that are not children of child popovers.
  23469. * i.e. only select ion-item elements that are part of this popover
  23470. */
  23471. items = Array.from(popoverEl.querySelectorAll('ion-item:not(ion-popover ion-popover *):not([disabled])'));
  23472. /* eslint-disable-next-line */
  23473. }
  23474. catch (_b) { }
  23475. switch (ev.key) {
  23476. /**
  23477. * If we are in a child popover
  23478. * then pressing the left arrow key
  23479. * should close this popover and move
  23480. * focus to the popover that presented
  23481. * this one.
  23482. */
  23483. case 'ArrowLeft':
  23484. const parentPopover = await popoverEl.getParentPopover();
  23485. if (parentPopover) {
  23486. popoverEl.dismiss(undefined, undefined, false);
  23487. }
  23488. break;
  23489. /**
  23490. * ArrowDown should move focus to the next focusable ion-item.
  23491. */
  23492. case 'ArrowDown':
  23493. // Disable movement/scroll with keyboard
  23494. ev.preventDefault();
  23495. const nextItem = getNextItem(items, activeElement);
  23496. if (nextItem !== undefined) {
  23497. focusItem(nextItem);
  23498. }
  23499. break;
  23500. /**
  23501. * ArrowUp should move focus to the previous focusable ion-item.
  23502. */
  23503. case 'ArrowUp':
  23504. // Disable movement/scroll with keyboard
  23505. ev.preventDefault();
  23506. const prevItem = getPrevItem(items, activeElement);
  23507. if (prevItem !== undefined) {
  23508. focusItem(prevItem);
  23509. }
  23510. break;
  23511. /**
  23512. * Home should move focus to the first focusable ion-item.
  23513. */
  23514. case 'Home':
  23515. ev.preventDefault();
  23516. const firstItem = items[0];
  23517. if (firstItem !== undefined) {
  23518. focusItem(firstItem);
  23519. }
  23520. break;
  23521. /**
  23522. * End should move focus to the last focusable ion-item.
  23523. */
  23524. case 'End':
  23525. ev.preventDefault();
  23526. const lastItem = items[items.length - 1];
  23527. if (lastItem !== undefined) {
  23528. focusItem(lastItem);
  23529. }
  23530. break;
  23531. /**
  23532. * ArrowRight, Spacebar, or Enter should activate
  23533. * the currently focused trigger item to open a
  23534. * popover if the element is a trigger item.
  23535. */
  23536. case 'ArrowRight':
  23537. case ' ':
  23538. case 'Enter':
  23539. if (activeElement && isTriggerElement(activeElement)) {
  23540. const rightEvent = new CustomEvent('ionPopoverActivateTrigger');
  23541. activeElement.dispatchEvent(rightEvent);
  23542. }
  23543. break;
  23544. }
  23545. };
  23546. popoverEl.addEventListener('keydown', callback);
  23547. return () => popoverEl.removeEventListener('keydown', callback);
  23548. };
  23549. /**
  23550. * Positions a popover by taking into account
  23551. * the reference point, preferred side, alignment
  23552. * and viewport dimensions.
  23553. */
  23554. const getPopoverPosition = (isRTL, contentWidth, contentHeight, arrowWidth, arrowHeight, reference, side, align, defaultPosition, triggerEl, event) => {
  23555. var _a;
  23556. let referenceCoordinates = {
  23557. top: 0,
  23558. left: 0,
  23559. width: 0,
  23560. height: 0,
  23561. };
  23562. /**
  23563. * Calculate position relative to the
  23564. * x-y coordinates in the event that
  23565. * was passed in
  23566. */
  23567. switch (reference) {
  23568. case 'event':
  23569. if (!event) {
  23570. return defaultPosition;
  23571. }
  23572. const mouseEv = event;
  23573. referenceCoordinates = {
  23574. top: mouseEv.clientY,
  23575. left: mouseEv.clientX,
  23576. width: 1,
  23577. height: 1,
  23578. };
  23579. break;
  23580. /**
  23581. * Calculate position relative to the bounding
  23582. * box on either the trigger element
  23583. * specified via the `trigger` prop or
  23584. * the target specified on the event
  23585. * that was passed in.
  23586. */
  23587. case 'trigger':
  23588. default:
  23589. const customEv = event;
  23590. /**
  23591. * ionShadowTarget is used when we need to align the
  23592. * popover with an element inside of the shadow root
  23593. * of an Ionic component. Ex: Presenting a popover
  23594. * by clicking on the collapsed indicator inside
  23595. * of `ion-breadcrumb` and centering it relative
  23596. * to the indicator rather than `ion-breadcrumb`
  23597. * as a whole.
  23598. */
  23599. const actualTriggerEl = (triggerEl ||
  23600. ((_a = customEv === null || customEv === void 0 ? void 0 : customEv.detail) === null || _a === void 0 ? void 0 : _a.ionShadowTarget) ||
  23601. (customEv === null || customEv === void 0 ? void 0 : customEv.target));
  23602. if (!actualTriggerEl) {
  23603. return defaultPosition;
  23604. }
  23605. const triggerBoundingBox = actualTriggerEl.getBoundingClientRect();
  23606. referenceCoordinates = {
  23607. top: triggerBoundingBox.top,
  23608. left: triggerBoundingBox.left,
  23609. width: triggerBoundingBox.width,
  23610. height: triggerBoundingBox.height,
  23611. };
  23612. break;
  23613. }
  23614. /**
  23615. * Get top/left offset that would allow
  23616. * popover to be positioned on the
  23617. * preferred side of the reference.
  23618. */
  23619. const coordinates = calculatePopoverSide(side, referenceCoordinates, contentWidth, contentHeight, arrowWidth, arrowHeight, isRTL);
  23620. /**
  23621. * Get the top/left adjustments that
  23622. * would allow the popover content
  23623. * to have the correct alignment.
  23624. */
  23625. const alignedCoordinates = calculatePopoverAlign(align, side, referenceCoordinates, contentWidth, contentHeight);
  23626. const top = coordinates.top + alignedCoordinates.top;
  23627. const left = coordinates.left + alignedCoordinates.left;
  23628. const { arrowTop, arrowLeft } = calculateArrowPosition(side, arrowWidth, arrowHeight, top, left, contentWidth, contentHeight, isRTL);
  23629. const { originX, originY } = calculatePopoverOrigin(side, align, isRTL);
  23630. return { top, left, referenceCoordinates, arrowTop, arrowLeft, originX, originY };
  23631. };
  23632. /**
  23633. * Determines the transform-origin
  23634. * of the popover animation so that it
  23635. * is in line with what the side and alignment
  23636. * prop values are. Currently only used
  23637. * with the MD animation.
  23638. */
  23639. const calculatePopoverOrigin = (side, align, isRTL) => {
  23640. switch (side) {
  23641. case 'top':
  23642. return { originX: getOriginXAlignment(align), originY: 'bottom' };
  23643. case 'bottom':
  23644. return { originX: getOriginXAlignment(align), originY: 'top' };
  23645. case 'left':
  23646. return { originX: 'right', originY: getOriginYAlignment(align) };
  23647. case 'right':
  23648. return { originX: 'left', originY: getOriginYAlignment(align) };
  23649. case 'start':
  23650. return { originX: isRTL ? 'left' : 'right', originY: getOriginYAlignment(align) };
  23651. case 'end':
  23652. return { originX: isRTL ? 'right' : 'left', originY: getOriginYAlignment(align) };
  23653. }
  23654. };
  23655. const getOriginXAlignment = (align) => {
  23656. switch (align) {
  23657. case 'start':
  23658. return 'left';
  23659. case 'center':
  23660. return 'center';
  23661. case 'end':
  23662. return 'right';
  23663. }
  23664. };
  23665. const getOriginYAlignment = (align) => {
  23666. switch (align) {
  23667. case 'start':
  23668. return 'top';
  23669. case 'center':
  23670. return 'center';
  23671. case 'end':
  23672. return 'bottom';
  23673. }
  23674. };
  23675. /**
  23676. * Calculates where the arrow positioning
  23677. * should be relative to the popover content.
  23678. */
  23679. const calculateArrowPosition = (side, arrowWidth, arrowHeight, top, left, contentWidth, contentHeight, isRTL) => {
  23680. /**
  23681. * Note: When side is left, right, start, or end, the arrow is
  23682. * been rotated using a `transform`, so to move the arrow up or down
  23683. * by its dimension, you need to use `arrowWidth`.
  23684. */
  23685. const leftPosition = {
  23686. arrowTop: top + contentHeight / 2 - arrowWidth / 2,
  23687. arrowLeft: left + contentWidth - arrowWidth / 2,
  23688. };
  23689. /**
  23690. * Move the arrow to the left by arrowWidth and then
  23691. * again by half of its width because we have rotated
  23692. * the arrow using a transform.
  23693. */
  23694. const rightPosition = { arrowTop: top + contentHeight / 2 - arrowWidth / 2, arrowLeft: left - arrowWidth * 1.5 };
  23695. switch (side) {
  23696. case 'top':
  23697. return { arrowTop: top + contentHeight, arrowLeft: left + contentWidth / 2 - arrowWidth / 2 };
  23698. case 'bottom':
  23699. return { arrowTop: top - arrowHeight, arrowLeft: left + contentWidth / 2 - arrowWidth / 2 };
  23700. case 'left':
  23701. return leftPosition;
  23702. case 'right':
  23703. return rightPosition;
  23704. case 'start':
  23705. return isRTL ? rightPosition : leftPosition;
  23706. case 'end':
  23707. return isRTL ? leftPosition : rightPosition;
  23708. default:
  23709. return { arrowTop: 0, arrowLeft: 0 };
  23710. }
  23711. };
  23712. /**
  23713. * Calculates the required top/left
  23714. * values needed to position the popover
  23715. * content on the side specified in the
  23716. * `side` prop.
  23717. */
  23718. const calculatePopoverSide = (side, triggerBoundingBox, contentWidth, contentHeight, arrowWidth, arrowHeight, isRTL) => {
  23719. const sideLeft = {
  23720. top: triggerBoundingBox.top,
  23721. left: triggerBoundingBox.left - contentWidth - arrowWidth,
  23722. };
  23723. const sideRight = {
  23724. top: triggerBoundingBox.top,
  23725. left: triggerBoundingBox.left + triggerBoundingBox.width + arrowWidth,
  23726. };
  23727. switch (side) {
  23728. case 'top':
  23729. return {
  23730. top: triggerBoundingBox.top - contentHeight - arrowHeight,
  23731. left: triggerBoundingBox.left,
  23732. };
  23733. case 'right':
  23734. return sideRight;
  23735. case 'bottom':
  23736. return {
  23737. top: triggerBoundingBox.top + triggerBoundingBox.height + arrowHeight,
  23738. left: triggerBoundingBox.left,
  23739. };
  23740. case 'left':
  23741. return sideLeft;
  23742. case 'start':
  23743. return isRTL ? sideRight : sideLeft;
  23744. case 'end':
  23745. return isRTL ? sideLeft : sideRight;
  23746. }
  23747. };
  23748. /**
  23749. * Calculates the required top/left
  23750. * offset values needed to provide the
  23751. * correct alignment regardless while taking
  23752. * into account the side the popover is on.
  23753. */
  23754. const calculatePopoverAlign = (align, side, triggerBoundingBox, contentWidth, contentHeight) => {
  23755. switch (align) {
  23756. case 'center':
  23757. return calculatePopoverCenterAlign(side, triggerBoundingBox, contentWidth, contentHeight);
  23758. case 'end':
  23759. return calculatePopoverEndAlign(side, triggerBoundingBox, contentWidth, contentHeight);
  23760. case 'start':
  23761. default:
  23762. return { top: 0, left: 0 };
  23763. }
  23764. };
  23765. /**
  23766. * Calculate the end alignment for
  23767. * the popover. If side is on the x-axis
  23768. * then the align values refer to the top
  23769. * and bottom margins of the content.
  23770. * If side is on the y-axis then the
  23771. * align values refer to the left and right
  23772. * margins of the content.
  23773. */
  23774. const calculatePopoverEndAlign = (side, triggerBoundingBox, contentWidth, contentHeight) => {
  23775. switch (side) {
  23776. case 'start':
  23777. case 'end':
  23778. case 'left':
  23779. case 'right':
  23780. return {
  23781. top: -(contentHeight - triggerBoundingBox.height),
  23782. left: 0,
  23783. };
  23784. case 'top':
  23785. case 'bottom':
  23786. default:
  23787. return {
  23788. top: 0,
  23789. left: -(contentWidth - triggerBoundingBox.width),
  23790. };
  23791. }
  23792. };
  23793. /**
  23794. * Calculate the center alignment for
  23795. * the popover. If side is on the x-axis
  23796. * then the align values refer to the top
  23797. * and bottom margins of the content.
  23798. * If side is on the y-axis then the
  23799. * align values refer to the left and right
  23800. * margins of the content.
  23801. */
  23802. const calculatePopoverCenterAlign = (side, triggerBoundingBox, contentWidth, contentHeight) => {
  23803. switch (side) {
  23804. case 'start':
  23805. case 'end':
  23806. case 'left':
  23807. case 'right':
  23808. return {
  23809. top: -(contentHeight / 2 - triggerBoundingBox.height / 2),
  23810. left: 0,
  23811. };
  23812. case 'top':
  23813. case 'bottom':
  23814. default:
  23815. return {
  23816. top: 0,
  23817. left: -(contentWidth / 2 - triggerBoundingBox.width / 2),
  23818. };
  23819. }
  23820. };
  23821. /**
  23822. * Adjusts popover positioning coordinates
  23823. * such that popover does not appear offscreen
  23824. * or overlapping safe area bounds.
  23825. */
  23826. const calculateWindowAdjustment = (side, coordTop, coordLeft, bodyPadding, bodyWidth, bodyHeight, contentWidth, contentHeight, safeAreaMargin, contentOriginX, contentOriginY, triggerCoordinates, coordArrowTop = 0, coordArrowLeft = 0, arrowHeight = 0) => {
  23827. let arrowTop = coordArrowTop;
  23828. const arrowLeft = coordArrowLeft;
  23829. let left = coordLeft;
  23830. let top = coordTop;
  23831. let bottom;
  23832. let originX = contentOriginX;
  23833. let originY = contentOriginY;
  23834. let checkSafeAreaLeft = false;
  23835. let checkSafeAreaRight = false;
  23836. const triggerTop = triggerCoordinates
  23837. ? triggerCoordinates.top + triggerCoordinates.height
  23838. : bodyHeight / 2 - contentHeight / 2;
  23839. const triggerHeight = triggerCoordinates ? triggerCoordinates.height : 0;
  23840. let addPopoverBottomClass = false;
  23841. /**
  23842. * Adjust popover so it does not
  23843. * go off the left of the screen.
  23844. */
  23845. if (left < bodyPadding + safeAreaMargin) {
  23846. left = bodyPadding;
  23847. checkSafeAreaLeft = true;
  23848. originX = 'left';
  23849. /**
  23850. * Adjust popover so it does not
  23851. * go off the right of the screen.
  23852. */
  23853. }
  23854. else if (contentWidth + bodyPadding + left + safeAreaMargin > bodyWidth) {
  23855. checkSafeAreaRight = true;
  23856. left = bodyWidth - contentWidth - bodyPadding;
  23857. originX = 'right';
  23858. }
  23859. /**
  23860. * Adjust popover so it does not
  23861. * go off the top of the screen.
  23862. * If popover is on the left or the right of
  23863. * the trigger, then we should not adjust top
  23864. * margins.
  23865. */
  23866. if (triggerTop + triggerHeight + contentHeight > bodyHeight && (side === 'top' || side === 'bottom')) {
  23867. if (triggerTop - contentHeight > 0) {
  23868. /**
  23869. * While we strive to align the popover with the trigger
  23870. * on smaller screens this is not always possible. As a result,
  23871. * we adjust the popover up so that it does not hang
  23872. * off the bottom of the screen. However, we do not want to move
  23873. * the popover up so much that it goes off the top of the screen.
  23874. *
  23875. * We chose 12 here so that the popover position looks a bit nicer as
  23876. * it is not right up against the edge of the screen.
  23877. */
  23878. top = Math.max(12, triggerTop - contentHeight - triggerHeight - (arrowHeight - 1));
  23879. arrowTop = top + contentHeight;
  23880. originY = 'bottom';
  23881. addPopoverBottomClass = true;
  23882. /**
  23883. * If not enough room for popover to appear
  23884. * above trigger, then cut it off.
  23885. */
  23886. }
  23887. else {
  23888. bottom = bodyPadding;
  23889. }
  23890. }
  23891. return {
  23892. top,
  23893. left,
  23894. bottom,
  23895. originX,
  23896. originY,
  23897. checkSafeAreaLeft,
  23898. checkSafeAreaRight,
  23899. arrowTop,
  23900. arrowLeft,
  23901. addPopoverBottomClass,
  23902. };
  23903. };
  23904. const shouldShowArrow = (side, didAdjustBounds = false, ev, trigger) => {
  23905. /**
  23906. * If no event provided and
  23907. * we do not have a trigger,
  23908. * then this popover was likely
  23909. * presented via the popoverController
  23910. * or users called `present` manually.
  23911. * In this case, the arrow should not be
  23912. * shown as we do not have a reference.
  23913. */
  23914. if (!ev && !trigger) {
  23915. return false;
  23916. }
  23917. /**
  23918. * If popover is on the left or the right
  23919. * of a trigger, but we needed to adjust the
  23920. * popover due to screen bounds, then we should
  23921. * hide the arrow as it will never be pointing
  23922. * at the trigger.
  23923. */
  23924. if (side !== 'top' && side !== 'bottom' && didAdjustBounds) {
  23925. return false;
  23926. }
  23927. return true;
  23928. };
  23929. const POPOVER_IOS_BODY_PADDING = 5;
  23930. /**
  23931. * iOS Popover Enter Animation
  23932. */
  23933. // TODO(FW-2832): types
  23934. const iosEnterAnimation$1 = (baseEl, opts) => {
  23935. var _a;
  23936. const { event: ev, size, trigger, reference, side, align } = opts;
  23937. const doc = baseEl.ownerDocument;
  23938. const isRTL = doc.dir === 'rtl';
  23939. const bodyWidth = doc.defaultView.innerWidth;
  23940. const bodyHeight = doc.defaultView.innerHeight;
  23941. const root = getElementRoot(baseEl);
  23942. const contentEl = root.querySelector('.popover-content');
  23943. const arrowEl = root.querySelector('.popover-arrow');
  23944. const referenceSizeEl = trigger || ((_a = ev === null || ev === void 0 ? void 0 : ev.detail) === null || _a === void 0 ? void 0 : _a.ionShadowTarget) || (ev === null || ev === void 0 ? void 0 : ev.target);
  23945. const { contentWidth, contentHeight } = getPopoverDimensions(size, contentEl, referenceSizeEl);
  23946. const { arrowWidth, arrowHeight } = getArrowDimensions(arrowEl);
  23947. const defaultPosition = {
  23948. top: bodyHeight / 2 - contentHeight / 2,
  23949. left: bodyWidth / 2 - contentWidth / 2,
  23950. originX: isRTL ? 'right' : 'left',
  23951. originY: 'top',
  23952. };
  23953. const results = getPopoverPosition(isRTL, contentWidth, contentHeight, arrowWidth, arrowHeight, reference, side, align, defaultPosition, trigger, ev);
  23954. const padding = size === 'cover' ? 0 : POPOVER_IOS_BODY_PADDING;
  23955. const margin = size === 'cover' ? 0 : 25;
  23956. const { originX, originY, top, left, bottom, checkSafeAreaLeft, checkSafeAreaRight, arrowTop, arrowLeft, addPopoverBottomClass, } = calculateWindowAdjustment(side, results.top, results.left, padding, bodyWidth, bodyHeight, contentWidth, contentHeight, margin, results.originX, results.originY, results.referenceCoordinates, results.arrowTop, results.arrowLeft, arrowHeight);
  23957. const baseAnimation = createAnimation();
  23958. const backdropAnimation = createAnimation();
  23959. const contentAnimation = createAnimation();
  23960. backdropAnimation
  23961. .addElement(root.querySelector('ion-backdrop'))
  23962. .fromTo('opacity', 0.01, 'var(--backdrop-opacity)')
  23963. .beforeStyles({
  23964. 'pointer-events': 'none',
  23965. })
  23966. .afterClearStyles(['pointer-events']);
  23967. // In Chromium, if the wrapper animates, the backdrop filter doesn't work.
  23968. // The Chromium team stated that this behavior is expected and not a bug. The element animating opacity creates a backdrop root for the backdrop-filter.
  23969. // To get around this, instead of animating the wrapper, animate both the arrow and content.
  23970. // https://bugs.chromium.org/p/chromium/issues/detail?id=1148826
  23971. contentAnimation
  23972. .addElement(root.querySelector('.popover-arrow'))
  23973. .addElement(root.querySelector('.popover-content'))
  23974. .fromTo('opacity', 0.01, 1);
  23975. // TODO(FW-4376) Ensure that arrow also blurs when translucent
  23976. return baseAnimation
  23977. .easing('ease')
  23978. .duration(100)
  23979. .beforeAddWrite(() => {
  23980. if (size === 'cover') {
  23981. baseEl.style.setProperty('--width', `${contentWidth}px`);
  23982. }
  23983. if (addPopoverBottomClass) {
  23984. baseEl.classList.add('popover-bottom');
  23985. }
  23986. if (bottom !== undefined) {
  23987. contentEl.style.setProperty('bottom', `${bottom}px`);
  23988. }
  23989. const safeAreaLeft = ' + var(--ion-safe-area-left, 0)';
  23990. const safeAreaRight = ' - var(--ion-safe-area-right, 0)';
  23991. let leftValue = `${left}px`;
  23992. if (checkSafeAreaLeft) {
  23993. leftValue = `${left}px${safeAreaLeft}`;
  23994. }
  23995. if (checkSafeAreaRight) {
  23996. leftValue = `${left}px${safeAreaRight}`;
  23997. }
  23998. contentEl.style.setProperty('top', `calc(${top}px + var(--offset-y, 0))`);
  23999. contentEl.style.setProperty('left', `calc(${leftValue} + var(--offset-x, 0))`);
  24000. contentEl.style.setProperty('transform-origin', `${originY} ${originX}`);
  24001. if (arrowEl !== null) {
  24002. const didAdjustBounds = results.top !== top || results.left !== left;
  24003. const showArrow = shouldShowArrow(side, didAdjustBounds, ev, trigger);
  24004. if (showArrow) {
  24005. arrowEl.style.setProperty('top', `calc(${arrowTop}px + var(--offset-y, 0))`);
  24006. arrowEl.style.setProperty('left', `calc(${arrowLeft}px + var(--offset-x, 0))`);
  24007. }
  24008. else {
  24009. arrowEl.style.setProperty('display', 'none');
  24010. }
  24011. }
  24012. })
  24013. .addAnimation([backdropAnimation, contentAnimation]);
  24014. };
  24015. /**
  24016. * iOS Popover Leave Animation
  24017. */
  24018. const iosLeaveAnimation$1 = (baseEl) => {
  24019. const root = getElementRoot(baseEl);
  24020. const contentEl = root.querySelector('.popover-content');
  24021. const arrowEl = root.querySelector('.popover-arrow');
  24022. const baseAnimation = createAnimation();
  24023. const backdropAnimation = createAnimation();
  24024. const contentAnimation = createAnimation();
  24025. backdropAnimation.addElement(root.querySelector('ion-backdrop')).fromTo('opacity', 'var(--backdrop-opacity)', 0);
  24026. contentAnimation
  24027. .addElement(root.querySelector('.popover-arrow'))
  24028. .addElement(root.querySelector('.popover-content'))
  24029. .fromTo('opacity', 0.99, 0);
  24030. return baseAnimation
  24031. .easing('ease')
  24032. .afterAddWrite(() => {
  24033. baseEl.style.removeProperty('--width');
  24034. baseEl.classList.remove('popover-bottom');
  24035. contentEl.style.removeProperty('top');
  24036. contentEl.style.removeProperty('left');
  24037. contentEl.style.removeProperty('bottom');
  24038. contentEl.style.removeProperty('transform-origin');
  24039. if (arrowEl) {
  24040. arrowEl.style.removeProperty('top');
  24041. arrowEl.style.removeProperty('left');
  24042. arrowEl.style.removeProperty('display');
  24043. }
  24044. })
  24045. .duration(300)
  24046. .addAnimation([backdropAnimation, contentAnimation]);
  24047. };
  24048. const POPOVER_MD_BODY_PADDING = 12;
  24049. /**
  24050. * Md Popover Enter Animation
  24051. */
  24052. // TODO(FW-2832): types
  24053. const mdEnterAnimation$1 = (baseEl, opts) => {
  24054. var _a;
  24055. const { event: ev, size, trigger, reference, side, align } = opts;
  24056. const doc = baseEl.ownerDocument;
  24057. const isRTL = doc.dir === 'rtl';
  24058. const bodyWidth = doc.defaultView.innerWidth;
  24059. const bodyHeight = doc.defaultView.innerHeight;
  24060. const root = getElementRoot(baseEl);
  24061. const contentEl = root.querySelector('.popover-content');
  24062. const referenceSizeEl = trigger || ((_a = ev === null || ev === void 0 ? void 0 : ev.detail) === null || _a === void 0 ? void 0 : _a.ionShadowTarget) || (ev === null || ev === void 0 ? void 0 : ev.target);
  24063. const { contentWidth, contentHeight } = getPopoverDimensions(size, contentEl, referenceSizeEl);
  24064. const defaultPosition = {
  24065. top: bodyHeight / 2 - contentHeight / 2,
  24066. left: bodyWidth / 2 - contentWidth / 2,
  24067. originX: isRTL ? 'right' : 'left',
  24068. originY: 'top',
  24069. };
  24070. const results = getPopoverPosition(isRTL, contentWidth, contentHeight, 0, 0, reference, side, align, defaultPosition, trigger, ev);
  24071. const padding = size === 'cover' ? 0 : POPOVER_MD_BODY_PADDING;
  24072. const { originX, originY, top, left, bottom } = calculateWindowAdjustment(side, results.top, results.left, padding, bodyWidth, bodyHeight, contentWidth, contentHeight, 0, results.originX, results.originY, results.referenceCoordinates);
  24073. const baseAnimation = createAnimation();
  24074. const backdropAnimation = createAnimation();
  24075. const wrapperAnimation = createAnimation();
  24076. const contentAnimation = createAnimation();
  24077. const viewportAnimation = createAnimation();
  24078. backdropAnimation
  24079. .addElement(root.querySelector('ion-backdrop'))
  24080. .fromTo('opacity', 0.01, 'var(--backdrop-opacity)')
  24081. .beforeStyles({
  24082. 'pointer-events': 'none',
  24083. })
  24084. .afterClearStyles(['pointer-events']);
  24085. wrapperAnimation.addElement(root.querySelector('.popover-wrapper')).duration(150).fromTo('opacity', 0.01, 1);
  24086. contentAnimation
  24087. .addElement(contentEl)
  24088. .beforeStyles({
  24089. top: `calc(${top}px + var(--offset-y, 0px))`,
  24090. left: `calc(${left}px + var(--offset-x, 0px))`,
  24091. 'transform-origin': `${originY} ${originX}`,
  24092. })
  24093. .beforeAddWrite(() => {
  24094. if (bottom !== undefined) {
  24095. contentEl.style.setProperty('bottom', `${bottom}px`);
  24096. }
  24097. })
  24098. .fromTo('transform', 'scale(0.8)', 'scale(1)');
  24099. viewportAnimation.addElement(root.querySelector('.popover-viewport')).fromTo('opacity', 0.01, 1);
  24100. return baseAnimation
  24101. .easing('cubic-bezier(0.36,0.66,0.04,1)')
  24102. .duration(300)
  24103. .beforeAddWrite(() => {
  24104. if (size === 'cover') {
  24105. baseEl.style.setProperty('--width', `${contentWidth}px`);
  24106. }
  24107. if (originY === 'bottom') {
  24108. baseEl.classList.add('popover-bottom');
  24109. }
  24110. })
  24111. .addAnimation([backdropAnimation, wrapperAnimation, contentAnimation, viewportAnimation]);
  24112. };
  24113. /**
  24114. * Md Popover Leave Animation
  24115. */
  24116. const mdLeaveAnimation$1 = (baseEl) => {
  24117. const root = getElementRoot(baseEl);
  24118. const contentEl = root.querySelector('.popover-content');
  24119. const baseAnimation = createAnimation();
  24120. const backdropAnimation = createAnimation();
  24121. const wrapperAnimation = createAnimation();
  24122. backdropAnimation.addElement(root.querySelector('ion-backdrop')).fromTo('opacity', 'var(--backdrop-opacity)', 0);
  24123. wrapperAnimation.addElement(root.querySelector('.popover-wrapper')).fromTo('opacity', 0.99, 0);
  24124. return baseAnimation
  24125. .easing('ease')
  24126. .afterAddWrite(() => {
  24127. baseEl.style.removeProperty('--width');
  24128. baseEl.classList.remove('popover-bottom');
  24129. contentEl.style.removeProperty('top');
  24130. contentEl.style.removeProperty('left');
  24131. contentEl.style.removeProperty('bottom');
  24132. contentEl.style.removeProperty('transform-origin');
  24133. })
  24134. .duration(150)
  24135. .addAnimation([backdropAnimation, wrapperAnimation]);
  24136. };
  24137. const popoverIosCss = ":host{--background:var(--ion-background-color, #fff);--min-width:0;--min-height:0;--max-width:auto;--height:auto;--offset-x:0px;--offset-y:0px;left:0;right:0;top:0;bottom:0;display:-ms-flexbox;display:flex;position:fixed;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;outline:none;color:var(--ion-text-color, #000);z-index:1001}:host(.popover-nested){pointer-events:none}:host(.popover-nested) .popover-wrapper{pointer-events:auto}:host(.overlay-hidden){display:none}.popover-wrapper{z-index:10}.popover-content{display:-ms-flexbox;display:flex;position:absolute;-ms-flex-direction:column;flex-direction:column;width:var(--width);min-width:var(--min-width);max-width:var(--max-width);height:var(--height);min-height:var(--min-height);max-height:var(--max-height);background:var(--background);-webkit-box-shadow:var(--box-shadow);box-shadow:var(--box-shadow);overflow:auto;z-index:10}::slotted(.popover-viewport){--ion-safe-area-top:0px;--ion-safe-area-right:0px;--ion-safe-area-bottom:0px;--ion-safe-area-left:0px;display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column}:host(.popover-nested.popover-side-left){--offset-x:5px}:host(.popover-nested.popover-side-right){--offset-x:-5px}:host(.popover-nested.popover-side-start){--offset-x:5px}:host-context([dir=rtl]):host(.popover-nested.popover-side-start),:host-context([dir=rtl]).popover-nested.popover-side-start{--offset-x:-5px}@supports selector(:dir(rtl)){:host(.popover-nested.popover-side-start:dir(rtl)){--offset-x:-5px}}:host(.popover-nested.popover-side-end){--offset-x:-5px}:host-context([dir=rtl]):host(.popover-nested.popover-side-end),:host-context([dir=rtl]).popover-nested.popover-side-end{--offset-x:5px}@supports selector(:dir(rtl)){:host(.popover-nested.popover-side-end:dir(rtl)){--offset-x:5px}}:host{--width:200px;--max-height:90%;--box-shadow:none;--backdrop-opacity:var(--ion-backdrop-opacity, 0.08)}:host(.popover-desktop){--box-shadow:0px 4px 16px 0px rgba(0, 0, 0, 0.12)}.popover-content{border-radius:10px}:host(.popover-desktop) .popover-content{border:0.5px solid var(--ion-color-step-100, var(--ion-background-color-step-100, #e6e6e6))}.popover-arrow{display:block;position:absolute;width:20px;height:10px;overflow:hidden;z-index:11}.popover-arrow::after{top:3px;border-radius:3px;position:absolute;width:14px;height:14px;-webkit-transform:rotate(45deg);transform:rotate(45deg);background:var(--background);content:\"\";z-index:10}.popover-arrow::after{inset-inline-start:3px}:host(.popover-bottom) .popover-arrow{top:auto;bottom:-10px}:host(.popover-bottom) .popover-arrow::after{top:-6px}:host(.popover-side-left) .popover-arrow{-webkit-transform:rotate(90deg);transform:rotate(90deg)}:host(.popover-side-right) .popover-arrow{-webkit-transform:rotate(-90deg);transform:rotate(-90deg)}:host(.popover-side-top) .popover-arrow{-webkit-transform:rotate(180deg);transform:rotate(180deg)}:host(.popover-side-start) .popover-arrow{-webkit-transform:rotate(90deg);transform:rotate(90deg)}:host-context([dir=rtl]):host(.popover-side-start) .popover-arrow,:host-context([dir=rtl]).popover-side-start .popover-arrow{-webkit-transform:rotate(-90deg);transform:rotate(-90deg)}@supports selector(:dir(rtl)){:host(.popover-side-start:dir(rtl)) .popover-arrow{-webkit-transform:rotate(-90deg);transform:rotate(-90deg)}}:host(.popover-side-end) .popover-arrow{-webkit-transform:rotate(-90deg);transform:rotate(-90deg)}:host-context([dir=rtl]):host(.popover-side-end) .popover-arrow,:host-context([dir=rtl]).popover-side-end .popover-arrow{-webkit-transform:rotate(90deg);transform:rotate(90deg)}@supports selector(:dir(rtl)){:host(.popover-side-end:dir(rtl)) .popover-arrow{-webkit-transform:rotate(90deg);transform:rotate(90deg)}}.popover-arrow,.popover-content{opacity:0}@supports ((-webkit-backdrop-filter: blur(0)) or (backdrop-filter: blur(0))){:host(.popover-translucent) .popover-content,:host(.popover-translucent) .popover-arrow::after{background:rgba(var(--ion-background-color-rgb, 255, 255, 255), 0.8);-webkit-backdrop-filter:saturate(180%) blur(20px);backdrop-filter:saturate(180%) blur(20px)}}";
  24138. var IonPopoverIosStyle0 = popoverIosCss;
  24139. const popoverMdCss = ":host{--background:var(--ion-background-color, #fff);--min-width:0;--min-height:0;--max-width:auto;--height:auto;--offset-x:0px;--offset-y:0px;left:0;right:0;top:0;bottom:0;display:-ms-flexbox;display:flex;position:fixed;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;outline:none;color:var(--ion-text-color, #000);z-index:1001}:host(.popover-nested){pointer-events:none}:host(.popover-nested) .popover-wrapper{pointer-events:auto}:host(.overlay-hidden){display:none}.popover-wrapper{z-index:10}.popover-content{display:-ms-flexbox;display:flex;position:absolute;-ms-flex-direction:column;flex-direction:column;width:var(--width);min-width:var(--min-width);max-width:var(--max-width);height:var(--height);min-height:var(--min-height);max-height:var(--max-height);background:var(--background);-webkit-box-shadow:var(--box-shadow);box-shadow:var(--box-shadow);overflow:auto;z-index:10}::slotted(.popover-viewport){--ion-safe-area-top:0px;--ion-safe-area-right:0px;--ion-safe-area-bottom:0px;--ion-safe-area-left:0px;display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column}:host(.popover-nested.popover-side-left){--offset-x:5px}:host(.popover-nested.popover-side-right){--offset-x:-5px}:host(.popover-nested.popover-side-start){--offset-x:5px}:host-context([dir=rtl]):host(.popover-nested.popover-side-start),:host-context([dir=rtl]).popover-nested.popover-side-start{--offset-x:-5px}@supports selector(:dir(rtl)){:host(.popover-nested.popover-side-start:dir(rtl)){--offset-x:-5px}}:host(.popover-nested.popover-side-end){--offset-x:-5px}:host-context([dir=rtl]):host(.popover-nested.popover-side-end),:host-context([dir=rtl]).popover-nested.popover-side-end{--offset-x:5px}@supports selector(:dir(rtl)){:host(.popover-nested.popover-side-end:dir(rtl)){--offset-x:5px}}:host{--width:250px;--max-height:90%;--box-shadow:0 5px 5px -3px rgba(0, 0, 0, 0.2), 0 8px 10px 1px rgba(0, 0, 0, 0.14), 0 3px 14px 2px rgba(0, 0, 0, 0.12);--backdrop-opacity:var(--ion-backdrop-opacity, 0.32)}.popover-content{border-radius:4px;-webkit-transform-origin:left top;transform-origin:left top}:host-context([dir=rtl]) .popover-content{-webkit-transform-origin:right top;transform-origin:right top}[dir=rtl] .popover-content{-webkit-transform-origin:right top;transform-origin:right top}@supports selector(:dir(rtl)){.popover-content:dir(rtl){-webkit-transform-origin:right top;transform-origin:right top}}.popover-viewport{-webkit-transition-delay:100ms;transition-delay:100ms}.popover-wrapper{opacity:0}";
  24140. var IonPopoverMdStyle0 = popoverMdCss;
  24141. // TODO(FW-2832): types
  24142. /**
  24143. * @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
  24144. *
  24145. * @slot - Content is placed inside of the `.popover-content` element.
  24146. *
  24147. * @part backdrop - The `ion-backdrop` element.
  24148. * @part arrow - The arrow that points to the reference element. Only applies on `ios` mode.
  24149. * @part content - The wrapper element for the default slot.
  24150. */
  24151. class Popover {
  24152. constructor(hostRef) {
  24153. registerInstance(this, hostRef);
  24154. this.didPresent = createEvent(this, "ionPopoverDidPresent", 7);
  24155. this.willPresent = createEvent(this, "ionPopoverWillPresent", 7);
  24156. this.willDismiss = createEvent(this, "ionPopoverWillDismiss", 7);
  24157. this.didDismiss = createEvent(this, "ionPopoverDidDismiss", 7);
  24158. this.didPresentShorthand = createEvent(this, "didPresent", 7);
  24159. this.willPresentShorthand = createEvent(this, "willPresent", 7);
  24160. this.willDismissShorthand = createEvent(this, "willDismiss", 7);
  24161. this.didDismissShorthand = createEvent(this, "didDismiss", 7);
  24162. this.ionMount = createEvent(this, "ionMount", 7);
  24163. this.parentPopover = null;
  24164. this.coreDelegate = CoreDelegate();
  24165. this.lockController = createLockController();
  24166. this.inline = false;
  24167. this.focusDescendantOnPresent = false;
  24168. this.onBackdropTap = () => {
  24169. this.dismiss(undefined, BACKDROP);
  24170. };
  24171. this.onLifecycle = (modalEvent) => {
  24172. const el = this.usersElement;
  24173. const name = LIFECYCLE_MAP[modalEvent.type];
  24174. if (el && name) {
  24175. const event = new CustomEvent(name, {
  24176. bubbles: false,
  24177. cancelable: false,
  24178. detail: modalEvent.detail,
  24179. });
  24180. el.dispatchEvent(event);
  24181. }
  24182. };
  24183. this.configureTriggerInteraction = () => {
  24184. const { trigger, triggerAction, el, destroyTriggerInteraction } = this;
  24185. if (destroyTriggerInteraction) {
  24186. destroyTriggerInteraction();
  24187. }
  24188. if (trigger === undefined) {
  24189. return;
  24190. }
  24191. const triggerEl = (this.triggerEl = trigger !== undefined ? document.getElementById(trigger) : null);
  24192. if (!triggerEl) {
  24193. printIonWarning(`[ion-popover] - A trigger element with the ID "${trigger}" was not found in the DOM. The trigger element must be in the DOM when the "trigger" property is set on ion-popover.`, this.el);
  24194. return;
  24195. }
  24196. this.destroyTriggerInteraction = configureTriggerInteraction(triggerEl, triggerAction, el);
  24197. };
  24198. this.configureKeyboardInteraction = () => {
  24199. const { destroyKeyboardInteraction, el } = this;
  24200. if (destroyKeyboardInteraction) {
  24201. destroyKeyboardInteraction();
  24202. }
  24203. this.destroyKeyboardInteraction = configureKeyboardInteraction(el);
  24204. };
  24205. this.configureDismissInteraction = () => {
  24206. const { destroyDismissInteraction, parentPopover, triggerAction, triggerEl, el } = this;
  24207. if (!parentPopover || !triggerEl) {
  24208. return;
  24209. }
  24210. if (destroyDismissInteraction) {
  24211. destroyDismissInteraction();
  24212. }
  24213. this.destroyDismissInteraction = configureDismissInteraction(triggerEl, triggerAction, el, parentPopover);
  24214. };
  24215. this.presented = false;
  24216. this.hasController = false;
  24217. this.delegate = undefined;
  24218. this.overlayIndex = undefined;
  24219. this.enterAnimation = undefined;
  24220. this.leaveAnimation = undefined;
  24221. this.component = undefined;
  24222. this.componentProps = undefined;
  24223. this.keyboardClose = true;
  24224. this.cssClass = undefined;
  24225. this.backdropDismiss = true;
  24226. this.event = undefined;
  24227. this.showBackdrop = true;
  24228. this.translucent = false;
  24229. this.animated = true;
  24230. this.htmlAttributes = undefined;
  24231. this.triggerAction = 'click';
  24232. this.trigger = undefined;
  24233. this.size = 'auto';
  24234. this.dismissOnSelect = false;
  24235. this.reference = 'trigger';
  24236. this.side = 'bottom';
  24237. this.alignment = undefined;
  24238. this.arrow = true;
  24239. this.isOpen = false;
  24240. this.keyboardEvents = false;
  24241. this.focusTrap = true;
  24242. this.keepContentsMounted = false;
  24243. }
  24244. onTriggerChange() {
  24245. this.configureTriggerInteraction();
  24246. }
  24247. onIsOpenChange(newValue, oldValue) {
  24248. if (newValue === true && oldValue === false) {
  24249. this.present();
  24250. }
  24251. else if (newValue === false && oldValue === true) {
  24252. this.dismiss();
  24253. }
  24254. }
  24255. connectedCallback() {
  24256. const { configureTriggerInteraction, el } = this;
  24257. prepareOverlay(el);
  24258. configureTriggerInteraction();
  24259. }
  24260. disconnectedCallback() {
  24261. const { destroyTriggerInteraction } = this;
  24262. if (destroyTriggerInteraction) {
  24263. destroyTriggerInteraction();
  24264. }
  24265. }
  24266. componentWillLoad() {
  24267. var _a, _b;
  24268. const { el } = this;
  24269. const popoverId = (_b = (_a = this.htmlAttributes) === null || _a === void 0 ? void 0 : _a.id) !== null && _b !== void 0 ? _b : setOverlayId(el);
  24270. this.parentPopover = el.closest(`ion-popover:not(#${popoverId})`);
  24271. if (this.alignment === undefined) {
  24272. this.alignment = getIonMode$1(this) === 'ios' ? 'center' : 'start';
  24273. }
  24274. }
  24275. componentDidLoad() {
  24276. const { parentPopover, isOpen } = this;
  24277. /**
  24278. * If popover was rendered with isOpen="true"
  24279. * then we should open popover immediately.
  24280. */
  24281. if (isOpen === true) {
  24282. raf(() => this.present());
  24283. }
  24284. if (parentPopover) {
  24285. addEventListener$1(parentPopover, 'ionPopoverWillDismiss', () => {
  24286. this.dismiss(undefined, undefined, false);
  24287. });
  24288. }
  24289. /**
  24290. * When binding values in frameworks such as Angular
  24291. * it is possible for the value to be set after the Web Component
  24292. * initializes but before the value watcher is set up in Stencil.
  24293. * As a result, the watcher callback may not be fired.
  24294. * We work around this by manually calling the watcher
  24295. * callback when the component has loaded and the watcher
  24296. * is configured.
  24297. */
  24298. this.configureTriggerInteraction();
  24299. }
  24300. /**
  24301. * When opening a popover from a trigger, we should not be
  24302. * modifying the `event` prop from inside the component.
  24303. * Additionally, when pressing the "Right" arrow key, we need
  24304. * to shift focus to the first descendant in the newly presented
  24305. * popover.
  24306. *
  24307. * @internal
  24308. */
  24309. async presentFromTrigger(event, focusDescendant = false) {
  24310. this.focusDescendantOnPresent = focusDescendant;
  24311. await this.present(event);
  24312. this.focusDescendantOnPresent = false;
  24313. }
  24314. /**
  24315. * Determines whether or not an overlay
  24316. * is being used inline or via a controller/JS
  24317. * and returns the correct delegate.
  24318. * By default, subsequent calls to getDelegate
  24319. * will use a cached version of the delegate.
  24320. * This is useful for calling dismiss after
  24321. * present so that the correct delegate is given.
  24322. */
  24323. getDelegate(force = false) {
  24324. if (this.workingDelegate && !force) {
  24325. return {
  24326. delegate: this.workingDelegate,
  24327. inline: this.inline,
  24328. };
  24329. }
  24330. /**
  24331. * If using overlay inline
  24332. * we potentially need to use the coreDelegate
  24333. * so that this works in vanilla JS apps.
  24334. * If a developer has presented this component
  24335. * via a controller, then we can assume
  24336. * the component is already in the
  24337. * correct place.
  24338. */
  24339. const parentEl = this.el.parentNode;
  24340. const inline = (this.inline = parentEl !== null && !this.hasController);
  24341. const delegate = (this.workingDelegate = inline ? this.delegate || this.coreDelegate : this.delegate);
  24342. return { inline, delegate };
  24343. }
  24344. /**
  24345. * Present the popover overlay after it has been created.
  24346. * Developers can pass a mouse, touch, or pointer event
  24347. * to position the popover relative to where that event
  24348. * was dispatched.
  24349. */
  24350. async present(event) {
  24351. const unlock = await this.lockController.lock();
  24352. if (this.presented) {
  24353. unlock();
  24354. return;
  24355. }
  24356. const { el } = this;
  24357. const { inline, delegate } = this.getDelegate(true);
  24358. /**
  24359. * Emit ionMount so JS Frameworks have an opportunity
  24360. * to add the child component to the DOM. The child
  24361. * component will be assigned to this.usersElement below.
  24362. */
  24363. this.ionMount.emit();
  24364. this.usersElement = await attachComponent(delegate, el, this.component, ['popover-viewport'], this.componentProps, inline);
  24365. if (!this.keyboardEvents) {
  24366. this.configureKeyboardInteraction();
  24367. }
  24368. this.configureDismissInteraction();
  24369. /**
  24370. * When using the lazy loaded build of Stencil, we need to wait
  24371. * for every Stencil component instance to be ready before presenting
  24372. * otherwise there can be a flash of unstyled content. With the
  24373. * custom elements bundle we need to wait for the JS framework
  24374. * mount the inner contents of the overlay otherwise WebKit may
  24375. * get the transition incorrect.
  24376. */
  24377. if (hasLazyBuild(el)) {
  24378. await deepReady(this.usersElement);
  24379. /**
  24380. * If keepContentsMounted="true" then the
  24381. * JS Framework has already mounted the inner
  24382. * contents so there is no need to wait.
  24383. * Otherwise, we need to wait for the JS
  24384. * Framework to mount the inner contents
  24385. * of this component.
  24386. */
  24387. }
  24388. else if (!this.keepContentsMounted) {
  24389. await waitForMount();
  24390. }
  24391. await present(this, 'popoverEnter', iosEnterAnimation$1, mdEnterAnimation$1, {
  24392. event: event || this.event,
  24393. size: this.size,
  24394. trigger: this.triggerEl,
  24395. reference: this.reference,
  24396. side: this.side,
  24397. align: this.alignment,
  24398. });
  24399. /**
  24400. * If popover is nested and was
  24401. * presented using the "Right" arrow key,
  24402. * we need to move focus to the first
  24403. * descendant inside of the popover.
  24404. */
  24405. if (this.focusDescendantOnPresent) {
  24406. focusFirstDescendant(el);
  24407. }
  24408. unlock();
  24409. }
  24410. /**
  24411. * Dismiss the popover overlay after it has been presented.
  24412. *
  24413. * @param data Any data to emit in the dismiss events.
  24414. * @param role The role of the element that is dismissing the popover. For example, 'cancel' or 'backdrop'.
  24415. * @param dismissParentPopover If `true`, dismissing this popover will also dismiss
  24416. * a parent popover if this popover is nested. Defaults to `true`.
  24417. *
  24418. * This is a no-op if the overlay has not been presented yet. If you want
  24419. * to remove an overlay from the DOM that was never presented, use the
  24420. * [remove](https://developer.mozilla.org/en-US/docs/Web/API/Element/remove) method.
  24421. */
  24422. async dismiss(data, role, dismissParentPopover = true) {
  24423. const unlock = await this.lockController.lock();
  24424. const { destroyKeyboardInteraction, destroyDismissInteraction } = this;
  24425. if (dismissParentPopover && this.parentPopover) {
  24426. this.parentPopover.dismiss(data, role, dismissParentPopover);
  24427. }
  24428. const shouldDismiss = await dismiss(this, data, role, 'popoverLeave', iosLeaveAnimation$1, mdLeaveAnimation$1, this.event);
  24429. if (shouldDismiss) {
  24430. if (destroyKeyboardInteraction) {
  24431. destroyKeyboardInteraction();
  24432. this.destroyKeyboardInteraction = undefined;
  24433. }
  24434. if (destroyDismissInteraction) {
  24435. destroyDismissInteraction();
  24436. this.destroyDismissInteraction = undefined;
  24437. }
  24438. /**
  24439. * If using popover inline
  24440. * we potentially need to use the coreDelegate
  24441. * so that this works in vanilla JS apps
  24442. */
  24443. const { delegate } = this.getDelegate();
  24444. await detachComponent(delegate, this.usersElement);
  24445. }
  24446. unlock();
  24447. return shouldDismiss;
  24448. }
  24449. /**
  24450. * @internal
  24451. */
  24452. async getParentPopover() {
  24453. return this.parentPopover;
  24454. }
  24455. /**
  24456. * Returns a promise that resolves when the popover did dismiss.
  24457. */
  24458. onDidDismiss() {
  24459. return eventMethod(this.el, 'ionPopoverDidDismiss');
  24460. }
  24461. /**
  24462. * Returns a promise that resolves when the popover will dismiss.
  24463. */
  24464. onWillDismiss() {
  24465. return eventMethod(this.el, 'ionPopoverWillDismiss');
  24466. }
  24467. render() {
  24468. const mode = getIonMode$1(this);
  24469. const { onLifecycle, parentPopover, dismissOnSelect, side, arrow, htmlAttributes, focusTrap } = this;
  24470. const desktop = isPlatform('desktop');
  24471. const enableArrow = arrow && !parentPopover;
  24472. return (hAsync(Host, Object.assign({ key: 'ff24e8d9677711248a36994cce568e74ba151499', "aria-modal": "true", "no-router": true, tabindex: "-1" }, htmlAttributes, { style: {
  24473. zIndex: `${20000 + this.overlayIndex}`,
  24474. }, class: Object.assign(Object.assign({}, getClassMap(this.cssClass)), { [mode]: true, 'popover-translucent': this.translucent, 'overlay-hidden': true, 'popover-desktop': desktop, [`popover-side-${side}`]: true, [FOCUS_TRAP_DISABLE_CLASS]: focusTrap === false, 'popover-nested': !!parentPopover }), onIonPopoverDidPresent: onLifecycle, onIonPopoverWillPresent: onLifecycle, onIonPopoverWillDismiss: onLifecycle, onIonPopoverDidDismiss: onLifecycle, onIonBackdropTap: this.onBackdropTap }), !parentPopover && hAsync("ion-backdrop", { key: 'aca68b4002a08b0e563a976a867141162c20f8b4', tappable: this.backdropDismiss, visible: this.showBackdrop, part: "backdrop" }), hAsync("div", { key: '62d21d1eab5c6d675d49932559ffb161747e5fec', class: "popover-wrapper ion-overlay-wrapper", onClick: dismissOnSelect ? () => this.dismiss() : undefined }, enableArrow && hAsync("div", { key: '1b46cc77d5302637fc979353483bb5fd780fd1d3', class: "popover-arrow", part: "arrow" }), hAsync("div", { key: 'a5657bff26e46d1959b71eb0992e7dc8fcae86f1', class: "popover-content", part: "content" }, hAsync("slot", { key: 'e1a98007226a46b51109e7004c4d338ca1bc0f9e' })))));
  24475. }
  24476. get el() { return getElement(this); }
  24477. static get watchers() { return {
  24478. "trigger": ["onTriggerChange"],
  24479. "triggerAction": ["onTriggerChange"],
  24480. "isOpen": ["onIsOpenChange"]
  24481. }; }
  24482. static get style() { return {
  24483. ios: IonPopoverIosStyle0,
  24484. md: IonPopoverMdStyle0
  24485. }; }
  24486. static get cmpMeta() { return {
  24487. "$flags$": 41,
  24488. "$tagName$": "ion-popover",
  24489. "$members$": {
  24490. "hasController": [4, "has-controller"],
  24491. "delegate": [16],
  24492. "overlayIndex": [2, "overlay-index"],
  24493. "enterAnimation": [16],
  24494. "leaveAnimation": [16],
  24495. "component": [1],
  24496. "componentProps": [16],
  24497. "keyboardClose": [4, "keyboard-close"],
  24498. "cssClass": [1, "css-class"],
  24499. "backdropDismiss": [4, "backdrop-dismiss"],
  24500. "event": [8],
  24501. "showBackdrop": [4, "show-backdrop"],
  24502. "translucent": [4],
  24503. "animated": [4],
  24504. "htmlAttributes": [16],
  24505. "triggerAction": [1, "trigger-action"],
  24506. "trigger": [1],
  24507. "size": [1],
  24508. "dismissOnSelect": [4, "dismiss-on-select"],
  24509. "reference": [1],
  24510. "side": [1],
  24511. "alignment": [1025],
  24512. "arrow": [4],
  24513. "isOpen": [4, "is-open"],
  24514. "keyboardEvents": [4, "keyboard-events"],
  24515. "focusTrap": [4, "focus-trap"],
  24516. "keepContentsMounted": [4, "keep-contents-mounted"],
  24517. "presented": [32],
  24518. "presentFromTrigger": [64],
  24519. "present": [64],
  24520. "dismiss": [64],
  24521. "getParentPopover": [64],
  24522. "onDidDismiss": [64],
  24523. "onWillDismiss": [64]
  24524. },
  24525. "$listeners$": undefined,
  24526. "$lazyBundleId$": "-",
  24527. "$attrsToReflect$": []
  24528. }; }
  24529. }
  24530. const LIFECYCLE_MAP = {
  24531. ionPopoverDidPresent: 'ionViewDidEnter',
  24532. ionPopoverWillPresent: 'ionViewWillEnter',
  24533. ionPopoverWillDismiss: 'ionViewWillLeave',
  24534. ionPopoverDidDismiss: 'ionViewDidLeave',
  24535. };
  24536. const progressBarIosCss = ":host{--background:rgba(var(--ion-color-primary-rgb, 0, 84, 233), 0.3);--progress-background:var(--ion-color-primary, #0054e9);display:block;position:relative;width:100%;contain:strict;direction:ltr;overflow:hidden}.progress,.progress-indeterminate,.indeterminate-bar-primary,.indeterminate-bar-secondary,.progress-buffer-bar{left:0;right:0;top:0;bottom:0;position:absolute;width:100%;height:100%}.buffer-circles-container,.buffer-circles{left:0;right:0;top:0;bottom:0;position:absolute}.buffer-circles{right:-10px;left:-10px;}.progress,.progress-buffer-bar,.buffer-circles-container{-webkit-transform-origin:left top;transform-origin:left top;-webkit-transition:-webkit-transform 150ms linear;transition:-webkit-transform 150ms linear;transition:transform 150ms linear;transition:transform 150ms linear, -webkit-transform 150ms linear}.progress,.progress-indeterminate{background:var(--progress-background);z-index:2}.progress-buffer-bar{background:var(--background);z-index:1}.buffer-circles-container{overflow:hidden}.indeterminate-bar-primary{top:0;right:0;bottom:0;left:-145.166611%;-webkit-animation:primary-indeterminate-translate 2s infinite linear;animation:primary-indeterminate-translate 2s infinite linear}.indeterminate-bar-primary .progress-indeterminate{-webkit-animation:primary-indeterminate-scale 2s infinite linear;animation:primary-indeterminate-scale 2s infinite linear;-webkit-animation-play-state:inherit;animation-play-state:inherit}.indeterminate-bar-secondary{top:0;right:0;bottom:0;left:-54.888891%;-webkit-animation:secondary-indeterminate-translate 2s infinite linear;animation:secondary-indeterminate-translate 2s infinite linear}.indeterminate-bar-secondary .progress-indeterminate{-webkit-animation:secondary-indeterminate-scale 2s infinite linear;animation:secondary-indeterminate-scale 2s infinite linear;-webkit-animation-play-state:inherit;animation-play-state:inherit}.buffer-circles{background-image:radial-gradient(ellipse at center, var(--background) 0%, var(--background) 30%, transparent 30%);background-repeat:repeat-x;background-position:5px center;background-size:10px 10px;z-index:0;-webkit-animation:buffering 450ms infinite linear;animation:buffering 450ms infinite linear}:host(.progress-bar-reversed){-webkit-transform:scaleX(-1);transform:scaleX(-1)}:host(.progress-paused) .indeterminate-bar-secondary,:host(.progress-paused) .indeterminate-bar-primary,:host(.progress-paused) .buffer-circles{-webkit-animation-play-state:paused;animation-play-state:paused}:host(.ion-color) .buffer-circles{background-image:radial-gradient(ellipse at center, rgba(var(--ion-color-base-rgb), 0.3) 0%, rgba(var(--ion-color-base-rgb), 0.3) 30%, transparent 30%)}:host(.ion-color) .progress,:host(.ion-color) .progress-indeterminate{background:var(--ion-color-base)}@-webkit-keyframes primary-indeterminate-translate{0%{-webkit-transform:translateX(0);transform:translateX(0)}20%{-webkit-animation-timing-function:cubic-bezier(0.5, 0, 0.701732, 0.495819);animation-timing-function:cubic-bezier(0.5, 0, 0.701732, 0.495819);-webkit-transform:translateX(0);transform:translateX(0)}59.15%{-webkit-animation-timing-function:cubic-bezier(0.302435, 0.381352, 0.55, 0.956352);animation-timing-function:cubic-bezier(0.302435, 0.381352, 0.55, 0.956352);-webkit-transform:translateX(83.67142%);transform:translateX(83.67142%)}100%{-webkit-transform:translateX(200.611057%);transform:translateX(200.611057%)}}@keyframes primary-indeterminate-translate{0%{-webkit-transform:translateX(0);transform:translateX(0)}20%{-webkit-animation-timing-function:cubic-bezier(0.5, 0, 0.701732, 0.495819);animation-timing-function:cubic-bezier(0.5, 0, 0.701732, 0.495819);-webkit-transform:translateX(0);transform:translateX(0)}59.15%{-webkit-animation-timing-function:cubic-bezier(0.302435, 0.381352, 0.55, 0.956352);animation-timing-function:cubic-bezier(0.302435, 0.381352, 0.55, 0.956352);-webkit-transform:translateX(83.67142%);transform:translateX(83.67142%)}100%{-webkit-transform:translateX(200.611057%);transform:translateX(200.611057%)}}@-webkit-keyframes primary-indeterminate-scale{0%{-webkit-transform:scaleX(0.08);transform:scaleX(0.08)}36.65%{-webkit-animation-timing-function:cubic-bezier(0.334731, 0.12482, 0.785844, 1);animation-timing-function:cubic-bezier(0.334731, 0.12482, 0.785844, 1);-webkit-transform:scaleX(0.08);transform:scaleX(0.08)}69.15%{-webkit-animation-timing-function:cubic-bezier(0.06, 0.11, 0.6, 1);animation-timing-function:cubic-bezier(0.06, 0.11, 0.6, 1);-webkit-transform:scaleX(0.661479);transform:scaleX(0.661479)}100%{-webkit-transform:scaleX(0.08);transform:scaleX(0.08)}}@keyframes primary-indeterminate-scale{0%{-webkit-transform:scaleX(0.08);transform:scaleX(0.08)}36.65%{-webkit-animation-timing-function:cubic-bezier(0.334731, 0.12482, 0.785844, 1);animation-timing-function:cubic-bezier(0.334731, 0.12482, 0.785844, 1);-webkit-transform:scaleX(0.08);transform:scaleX(0.08)}69.15%{-webkit-animation-timing-function:cubic-bezier(0.06, 0.11, 0.6, 1);animation-timing-function:cubic-bezier(0.06, 0.11, 0.6, 1);-webkit-transform:scaleX(0.661479);transform:scaleX(0.661479)}100%{-webkit-transform:scaleX(0.08);transform:scaleX(0.08)}}@-webkit-keyframes secondary-indeterminate-translate{0%{-webkit-animation-timing-function:cubic-bezier(0.15, 0, 0.515058, 0.409685);animation-timing-function:cubic-bezier(0.15, 0, 0.515058, 0.409685);-webkit-transform:translateX(0);transform:translateX(0)}25%{-webkit-animation-timing-function:cubic-bezier(0.31033, 0.284058, 0.8, 0.733712);animation-timing-function:cubic-bezier(0.31033, 0.284058, 0.8, 0.733712);-webkit-transform:translateX(37.651913%);transform:translateX(37.651913%)}48.35%{-webkit-animation-timing-function:cubic-bezier(0.4, 0.627035, 0.6, 0.902026);animation-timing-function:cubic-bezier(0.4, 0.627035, 0.6, 0.902026);-webkit-transform:translateX(84.386165%);transform:translateX(84.386165%)}100%{-webkit-transform:translateX(160.277782%);transform:translateX(160.277782%)}}@keyframes secondary-indeterminate-translate{0%{-webkit-animation-timing-function:cubic-bezier(0.15, 0, 0.515058, 0.409685);animation-timing-function:cubic-bezier(0.15, 0, 0.515058, 0.409685);-webkit-transform:translateX(0);transform:translateX(0)}25%{-webkit-animation-timing-function:cubic-bezier(0.31033, 0.284058, 0.8, 0.733712);animation-timing-function:cubic-bezier(0.31033, 0.284058, 0.8, 0.733712);-webkit-transform:translateX(37.651913%);transform:translateX(37.651913%)}48.35%{-webkit-animation-timing-function:cubic-bezier(0.4, 0.627035, 0.6, 0.902026);animation-timing-function:cubic-bezier(0.4, 0.627035, 0.6, 0.902026);-webkit-transform:translateX(84.386165%);transform:translateX(84.386165%)}100%{-webkit-transform:translateX(160.277782%);transform:translateX(160.277782%)}}@-webkit-keyframes secondary-indeterminate-scale{0%{-webkit-animation-timing-function:cubic-bezier(0.205028, 0.057051, 0.57661, 0.453971);animation-timing-function:cubic-bezier(0.205028, 0.057051, 0.57661, 0.453971);-webkit-transform:scaleX(0.08);transform:scaleX(0.08)}19.15%{-webkit-animation-timing-function:cubic-bezier(0.152313, 0.196432, 0.648374, 1.004315);animation-timing-function:cubic-bezier(0.152313, 0.196432, 0.648374, 1.004315);-webkit-transform:scaleX(0.457104);transform:scaleX(0.457104)}44.15%{-webkit-animation-timing-function:cubic-bezier(0.257759, -0.003163, 0.211762, 1.38179);animation-timing-function:cubic-bezier(0.257759, -0.003163, 0.211762, 1.38179);-webkit-transform:scaleX(0.72796);transform:scaleX(0.72796)}100%{-webkit-transform:scaleX(0.08);transform:scaleX(0.08)}}@keyframes secondary-indeterminate-scale{0%{-webkit-animation-timing-function:cubic-bezier(0.205028, 0.057051, 0.57661, 0.453971);animation-timing-function:cubic-bezier(0.205028, 0.057051, 0.57661, 0.453971);-webkit-transform:scaleX(0.08);transform:scaleX(0.08)}19.15%{-webkit-animation-timing-function:cubic-bezier(0.152313, 0.196432, 0.648374, 1.004315);animation-timing-function:cubic-bezier(0.152313, 0.196432, 0.648374, 1.004315);-webkit-transform:scaleX(0.457104);transform:scaleX(0.457104)}44.15%{-webkit-animation-timing-function:cubic-bezier(0.257759, -0.003163, 0.211762, 1.38179);animation-timing-function:cubic-bezier(0.257759, -0.003163, 0.211762, 1.38179);-webkit-transform:scaleX(0.72796);transform:scaleX(0.72796)}100%{-webkit-transform:scaleX(0.08);transform:scaleX(0.08)}}@-webkit-keyframes buffering{to{-webkit-transform:translateX(-10px);transform:translateX(-10px)}}@keyframes buffering{to{-webkit-transform:translateX(-10px);transform:translateX(-10px)}}:host{border-radius:9999px;height:4px}:host(.progress-bar-solid){--background:var(--ion-color-step-100, var(--ion-background-color-step-100, #e6e6e6))}";
  24537. var IonProgressBarIosStyle0 = progressBarIosCss;
  24538. const progressBarMdCss = ":host{--background:rgba(var(--ion-color-primary-rgb, 0, 84, 233), 0.3);--progress-background:var(--ion-color-primary, #0054e9);display:block;position:relative;width:100%;contain:strict;direction:ltr;overflow:hidden}.progress,.progress-indeterminate,.indeterminate-bar-primary,.indeterminate-bar-secondary,.progress-buffer-bar{left:0;right:0;top:0;bottom:0;position:absolute;width:100%;height:100%}.buffer-circles-container,.buffer-circles{left:0;right:0;top:0;bottom:0;position:absolute}.buffer-circles{right:-10px;left:-10px;}.progress,.progress-buffer-bar,.buffer-circles-container{-webkit-transform-origin:left top;transform-origin:left top;-webkit-transition:-webkit-transform 150ms linear;transition:-webkit-transform 150ms linear;transition:transform 150ms linear;transition:transform 150ms linear, -webkit-transform 150ms linear}.progress,.progress-indeterminate{background:var(--progress-background);z-index:2}.progress-buffer-bar{background:var(--background);z-index:1}.buffer-circles-container{overflow:hidden}.indeterminate-bar-primary{top:0;right:0;bottom:0;left:-145.166611%;-webkit-animation:primary-indeterminate-translate 2s infinite linear;animation:primary-indeterminate-translate 2s infinite linear}.indeterminate-bar-primary .progress-indeterminate{-webkit-animation:primary-indeterminate-scale 2s infinite linear;animation:primary-indeterminate-scale 2s infinite linear;-webkit-animation-play-state:inherit;animation-play-state:inherit}.indeterminate-bar-secondary{top:0;right:0;bottom:0;left:-54.888891%;-webkit-animation:secondary-indeterminate-translate 2s infinite linear;animation:secondary-indeterminate-translate 2s infinite linear}.indeterminate-bar-secondary .progress-indeterminate{-webkit-animation:secondary-indeterminate-scale 2s infinite linear;animation:secondary-indeterminate-scale 2s infinite linear;-webkit-animation-play-state:inherit;animation-play-state:inherit}.buffer-circles{background-image:radial-gradient(ellipse at center, var(--background) 0%, var(--background) 30%, transparent 30%);background-repeat:repeat-x;background-position:5px center;background-size:10px 10px;z-index:0;-webkit-animation:buffering 450ms infinite linear;animation:buffering 450ms infinite linear}:host(.progress-bar-reversed){-webkit-transform:scaleX(-1);transform:scaleX(-1)}:host(.progress-paused) .indeterminate-bar-secondary,:host(.progress-paused) .indeterminate-bar-primary,:host(.progress-paused) .buffer-circles{-webkit-animation-play-state:paused;animation-play-state:paused}:host(.ion-color) .buffer-circles{background-image:radial-gradient(ellipse at center, rgba(var(--ion-color-base-rgb), 0.3) 0%, rgba(var(--ion-color-base-rgb), 0.3) 30%, transparent 30%)}:host(.ion-color) .progress,:host(.ion-color) .progress-indeterminate{background:var(--ion-color-base)}@-webkit-keyframes primary-indeterminate-translate{0%{-webkit-transform:translateX(0);transform:translateX(0)}20%{-webkit-animation-timing-function:cubic-bezier(0.5, 0, 0.701732, 0.495819);animation-timing-function:cubic-bezier(0.5, 0, 0.701732, 0.495819);-webkit-transform:translateX(0);transform:translateX(0)}59.15%{-webkit-animation-timing-function:cubic-bezier(0.302435, 0.381352, 0.55, 0.956352);animation-timing-function:cubic-bezier(0.302435, 0.381352, 0.55, 0.956352);-webkit-transform:translateX(83.67142%);transform:translateX(83.67142%)}100%{-webkit-transform:translateX(200.611057%);transform:translateX(200.611057%)}}@keyframes primary-indeterminate-translate{0%{-webkit-transform:translateX(0);transform:translateX(0)}20%{-webkit-animation-timing-function:cubic-bezier(0.5, 0, 0.701732, 0.495819);animation-timing-function:cubic-bezier(0.5, 0, 0.701732, 0.495819);-webkit-transform:translateX(0);transform:translateX(0)}59.15%{-webkit-animation-timing-function:cubic-bezier(0.302435, 0.381352, 0.55, 0.956352);animation-timing-function:cubic-bezier(0.302435, 0.381352, 0.55, 0.956352);-webkit-transform:translateX(83.67142%);transform:translateX(83.67142%)}100%{-webkit-transform:translateX(200.611057%);transform:translateX(200.611057%)}}@-webkit-keyframes primary-indeterminate-scale{0%{-webkit-transform:scaleX(0.08);transform:scaleX(0.08)}36.65%{-webkit-animation-timing-function:cubic-bezier(0.334731, 0.12482, 0.785844, 1);animation-timing-function:cubic-bezier(0.334731, 0.12482, 0.785844, 1);-webkit-transform:scaleX(0.08);transform:scaleX(0.08)}69.15%{-webkit-animation-timing-function:cubic-bezier(0.06, 0.11, 0.6, 1);animation-timing-function:cubic-bezier(0.06, 0.11, 0.6, 1);-webkit-transform:scaleX(0.661479);transform:scaleX(0.661479)}100%{-webkit-transform:scaleX(0.08);transform:scaleX(0.08)}}@keyframes primary-indeterminate-scale{0%{-webkit-transform:scaleX(0.08);transform:scaleX(0.08)}36.65%{-webkit-animation-timing-function:cubic-bezier(0.334731, 0.12482, 0.785844, 1);animation-timing-function:cubic-bezier(0.334731, 0.12482, 0.785844, 1);-webkit-transform:scaleX(0.08);transform:scaleX(0.08)}69.15%{-webkit-animation-timing-function:cubic-bezier(0.06, 0.11, 0.6, 1);animation-timing-function:cubic-bezier(0.06, 0.11, 0.6, 1);-webkit-transform:scaleX(0.661479);transform:scaleX(0.661479)}100%{-webkit-transform:scaleX(0.08);transform:scaleX(0.08)}}@-webkit-keyframes secondary-indeterminate-translate{0%{-webkit-animation-timing-function:cubic-bezier(0.15, 0, 0.515058, 0.409685);animation-timing-function:cubic-bezier(0.15, 0, 0.515058, 0.409685);-webkit-transform:translateX(0);transform:translateX(0)}25%{-webkit-animation-timing-function:cubic-bezier(0.31033, 0.284058, 0.8, 0.733712);animation-timing-function:cubic-bezier(0.31033, 0.284058, 0.8, 0.733712);-webkit-transform:translateX(37.651913%);transform:translateX(37.651913%)}48.35%{-webkit-animation-timing-function:cubic-bezier(0.4, 0.627035, 0.6, 0.902026);animation-timing-function:cubic-bezier(0.4, 0.627035, 0.6, 0.902026);-webkit-transform:translateX(84.386165%);transform:translateX(84.386165%)}100%{-webkit-transform:translateX(160.277782%);transform:translateX(160.277782%)}}@keyframes secondary-indeterminate-translate{0%{-webkit-animation-timing-function:cubic-bezier(0.15, 0, 0.515058, 0.409685);animation-timing-function:cubic-bezier(0.15, 0, 0.515058, 0.409685);-webkit-transform:translateX(0);transform:translateX(0)}25%{-webkit-animation-timing-function:cubic-bezier(0.31033, 0.284058, 0.8, 0.733712);animation-timing-function:cubic-bezier(0.31033, 0.284058, 0.8, 0.733712);-webkit-transform:translateX(37.651913%);transform:translateX(37.651913%)}48.35%{-webkit-animation-timing-function:cubic-bezier(0.4, 0.627035, 0.6, 0.902026);animation-timing-function:cubic-bezier(0.4, 0.627035, 0.6, 0.902026);-webkit-transform:translateX(84.386165%);transform:translateX(84.386165%)}100%{-webkit-transform:translateX(160.277782%);transform:translateX(160.277782%)}}@-webkit-keyframes secondary-indeterminate-scale{0%{-webkit-animation-timing-function:cubic-bezier(0.205028, 0.057051, 0.57661, 0.453971);animation-timing-function:cubic-bezier(0.205028, 0.057051, 0.57661, 0.453971);-webkit-transform:scaleX(0.08);transform:scaleX(0.08)}19.15%{-webkit-animation-timing-function:cubic-bezier(0.152313, 0.196432, 0.648374, 1.004315);animation-timing-function:cubic-bezier(0.152313, 0.196432, 0.648374, 1.004315);-webkit-transform:scaleX(0.457104);transform:scaleX(0.457104)}44.15%{-webkit-animation-timing-function:cubic-bezier(0.257759, -0.003163, 0.211762, 1.38179);animation-timing-function:cubic-bezier(0.257759, -0.003163, 0.211762, 1.38179);-webkit-transform:scaleX(0.72796);transform:scaleX(0.72796)}100%{-webkit-transform:scaleX(0.08);transform:scaleX(0.08)}}@keyframes secondary-indeterminate-scale{0%{-webkit-animation-timing-function:cubic-bezier(0.205028, 0.057051, 0.57661, 0.453971);animation-timing-function:cubic-bezier(0.205028, 0.057051, 0.57661, 0.453971);-webkit-transform:scaleX(0.08);transform:scaleX(0.08)}19.15%{-webkit-animation-timing-function:cubic-bezier(0.152313, 0.196432, 0.648374, 1.004315);animation-timing-function:cubic-bezier(0.152313, 0.196432, 0.648374, 1.004315);-webkit-transform:scaleX(0.457104);transform:scaleX(0.457104)}44.15%{-webkit-animation-timing-function:cubic-bezier(0.257759, -0.003163, 0.211762, 1.38179);animation-timing-function:cubic-bezier(0.257759, -0.003163, 0.211762, 1.38179);-webkit-transform:scaleX(0.72796);transform:scaleX(0.72796)}100%{-webkit-transform:scaleX(0.08);transform:scaleX(0.08)}}@-webkit-keyframes buffering{to{-webkit-transform:translateX(-10px);transform:translateX(-10px)}}@keyframes buffering{to{-webkit-transform:translateX(-10px);transform:translateX(-10px)}}:host{height:4px}:host(.ion-color) .progress-buffer-bar{background:rgba(var(--ion-color-base-rgb), 0.3)}";
  24539. var IonProgressBarMdStyle0 = progressBarMdCss;
  24540. /**
  24541. * @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
  24542. *
  24543. * @part progress - The progress bar that shows the current value when `type` is `"determinate"` and slides back and forth when `type` is `"indeterminate"`.
  24544. * @part stream - The animated circles that appear while buffering. This only shows when `buffer` is set and `type` is `"determinate"`.
  24545. * @part track - The track bar behind the progress bar. If the `buffer` property is set and `type` is `"determinate"` the track will be the
  24546. * width of the `buffer` value.
  24547. */
  24548. class ProgressBar {
  24549. constructor(hostRef) {
  24550. registerInstance(this, hostRef);
  24551. this.type = 'determinate';
  24552. this.reversed = false;
  24553. this.value = 0;
  24554. this.buffer = 1;
  24555. this.color = undefined;
  24556. }
  24557. render() {
  24558. const { color, type, reversed, value, buffer } = this;
  24559. const paused = config.getBoolean('_testing');
  24560. const mode = getIonMode$1(this);
  24561. // If the progress is displayed as a solid bar.
  24562. const progressSolid = buffer === 1;
  24563. return (hAsync(Host, { key: 'd60eeaa18aaee607e083c0ef9d0de8178d47c4cd', role: "progressbar", "aria-valuenow": type === 'determinate' ? value : null, "aria-valuemin": "0", "aria-valuemax": "1", class: createColorClasses$1(color, {
  24564. [mode]: true,
  24565. [`progress-bar-${type}`]: true,
  24566. 'progress-paused': paused,
  24567. 'progress-bar-reversed': document.dir === 'rtl' ? !reversed : reversed,
  24568. 'progress-bar-solid': progressSolid,
  24569. }) }, type === 'indeterminate' ? renderIndeterminate() : renderProgress(value, buffer)));
  24570. }
  24571. static get style() { return {
  24572. ios: IonProgressBarIosStyle0,
  24573. md: IonProgressBarMdStyle0
  24574. }; }
  24575. static get cmpMeta() { return {
  24576. "$flags$": 41,
  24577. "$tagName$": "ion-progress-bar",
  24578. "$members$": {
  24579. "type": [1],
  24580. "reversed": [4],
  24581. "value": [2],
  24582. "buffer": [2],
  24583. "color": [513]
  24584. },
  24585. "$listeners$": undefined,
  24586. "$lazyBundleId$": "-",
  24587. "$attrsToReflect$": [["color", "color"]]
  24588. }; }
  24589. }
  24590. const renderIndeterminate = () => {
  24591. return (hAsync("div", { part: "track", class: "progress-buffer-bar" }, hAsync("div", { class: "indeterminate-bar-primary" }, hAsync("span", { part: "progress", class: "progress-indeterminate" })), hAsync("div", { class: "indeterminate-bar-secondary" }, hAsync("span", { part: "progress", class: "progress-indeterminate" }))));
  24592. };
  24593. const renderProgress = (value, buffer) => {
  24594. const finalValue = clamp(0, value, 1);
  24595. const finalBuffer = clamp(0, buffer, 1);
  24596. return [
  24597. hAsync("div", { part: "progress", class: "progress", style: { transform: `scaleX(${finalValue})` } }),
  24598. /**
  24599. * Buffer circles with two container to move
  24600. * the circles behind the buffer progress
  24601. * with respecting the animation.
  24602. * When finalBuffer === 1, we use display: none
  24603. * instead of removing the element to avoid flickering.
  24604. */
  24605. hAsync("div", { class: { 'buffer-circles-container': true, 'ion-hide': finalBuffer === 1 }, style: { transform: `translateX(${finalBuffer * 100}%)` } }, hAsync("div", { class: "buffer-circles-container", style: { transform: `translateX(-${finalBuffer * 100}%)` } }, hAsync("div", { part: "stream", class: "buffer-circles" }))),
  24606. hAsync("div", { part: "track", class: "progress-buffer-bar", style: { transform: `scaleX(${finalBuffer})` } }),
  24607. ];
  24608. };
  24609. const radioIosCss = ":host{--inner-border-radius:50%;display:inline-block;position:relative;max-width:100%;min-height:inherit;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;z-index:2;-webkit-box-sizing:border-box;box-sizing:border-box}:host(.radio-disabled){pointer-events:none}.radio-icon{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;width:100%;height:100%;contain:layout size style}.radio-icon,.radio-inner{-webkit-box-sizing:border-box;box-sizing:border-box}input{position:absolute;top:0;left:0;right:0;bottom:0;width:100%;height:100%;margin:0;padding:0;border:0;outline:0;clip:rect(0 0 0 0);opacity:0;overflow:hidden;-webkit-appearance:none;-moz-appearance:none}:host(:focus){outline:none}:host(.in-item){-ms-flex:1 1 0px;flex:1 1 0;width:100%;height:100%}:host([slot=start]),:host([slot=end]){-ms-flex:initial;flex:initial;width:auto}.radio-wrapper{display:-ms-flexbox;display:flex;position:relative;-ms-flex-positive:1;flex-grow:1;-ms-flex-align:center;align-items:center;-ms-flex-pack:justify;justify-content:space-between;height:inherit;min-height:inherit;cursor:inherit}.label-text-wrapper{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}:host(.in-item) .label-text-wrapper{margin-top:10px;margin-bottom:10px}:host(.in-item.radio-label-placement-stacked) .label-text-wrapper{margin-top:10px;margin-bottom:16px}:host(.in-item.radio-label-placement-stacked) .native-wrapper{margin-bottom:10px}.label-text-wrapper-hidden{display:none}.native-wrapper{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center}:host(.radio-justify-space-between) .radio-wrapper{-ms-flex-pack:justify;justify-content:space-between}:host(.radio-justify-start) .radio-wrapper{-ms-flex-pack:start;justify-content:start}:host(.radio-justify-end) .radio-wrapper{-ms-flex-pack:end;justify-content:end}:host(.radio-alignment-start) .radio-wrapper{-ms-flex-align:start;align-items:start}:host(.radio-alignment-center) .radio-wrapper{-ms-flex-align:center;align-items:center}:host(.radio-justify-space-between),:host(.radio-justify-start),:host(.radio-justify-end),:host(.radio-alignment-start),:host(.radio-alignment-center){display:block}:host(.radio-label-placement-start) .radio-wrapper{-ms-flex-direction:row;flex-direction:row}:host(.radio-label-placement-start) .label-text-wrapper{-webkit-margin-start:0;margin-inline-start:0;-webkit-margin-end:16px;margin-inline-end:16px}:host(.radio-label-placement-end) .radio-wrapper{-ms-flex-direction:row-reverse;flex-direction:row-reverse}:host(.radio-label-placement-end) .label-text-wrapper{-webkit-margin-start:16px;margin-inline-start:16px;-webkit-margin-end:0;margin-inline-end:0}:host(.radio-label-placement-fixed) .label-text-wrapper{-webkit-margin-start:0;margin-inline-start:0;-webkit-margin-end:16px;margin-inline-end:16px}:host(.radio-label-placement-fixed) .label-text-wrapper{-ms-flex:0 0 100px;flex:0 0 100px;width:100px;min-width:100px}:host(.radio-label-placement-stacked) .radio-wrapper{-ms-flex-direction:column;flex-direction:column}:host(.radio-label-placement-stacked) .label-text-wrapper{-webkit-transform:scale(0.75);transform:scale(0.75);margin-left:0;margin-right:0;margin-bottom:16px;max-width:calc(100% / 0.75)}:host(.radio-label-placement-stacked.radio-alignment-start) .label-text-wrapper{-webkit-transform-origin:left top;transform-origin:left top}:host-context([dir=rtl]):host(.radio-label-placement-stacked.radio-alignment-start) .label-text-wrapper,:host-context([dir=rtl]).radio-label-placement-stacked.radio-alignment-start .label-text-wrapper{-webkit-transform-origin:right top;transform-origin:right top}@supports selector(:dir(rtl)){:host(.radio-label-placement-stacked.radio-alignment-start:dir(rtl)) .label-text-wrapper{-webkit-transform-origin:right top;transform-origin:right top}}:host(.radio-label-placement-stacked.radio-alignment-center) .label-text-wrapper{-webkit-transform-origin:center top;transform-origin:center top}:host-context([dir=rtl]):host(.radio-label-placement-stacked.radio-alignment-center) .label-text-wrapper,:host-context([dir=rtl]).radio-label-placement-stacked.radio-alignment-center .label-text-wrapper{-webkit-transform-origin:calc(100% - center) top;transform-origin:calc(100% - center) top}@supports selector(:dir(rtl)){:host(.radio-label-placement-stacked.radio-alignment-center:dir(rtl)) .label-text-wrapper{-webkit-transform-origin:calc(100% - center) top;transform-origin:calc(100% - center) top}}:host{--color-checked:var(--ion-color-primary, #0054e9)}:host(.ion-color.radio-checked) .radio-inner{border-color:var(--ion-color-base)}.item-radio.item-ios ion-label{-webkit-margin-start:0;margin-inline-start:0}.radio-inner{width:33%;height:50%}:host(.radio-checked) .radio-inner{-webkit-transform:rotate(45deg);transform:rotate(45deg);border-width:0.125rem;border-top-width:0;border-left-width:0;border-style:solid;border-color:var(--color-checked)}:host(.radio-disabled){opacity:0.3}:host(.ion-focused) .radio-icon::after{border-radius:var(--inner-border-radius);top:-8px;display:block;position:absolute;width:36px;height:36px;background:var(--ion-color-primary-tint, #1a65eb);content:\"\";opacity:0.2}:host(.ion-focused) .radio-icon::after{inset-inline-start:-9px}.native-wrapper .radio-icon{width:0.9375rem;height:1.5rem}";
  24610. var IonRadioIosStyle0 = radioIosCss;
  24611. const radioMdCss = ":host{--inner-border-radius:50%;display:inline-block;position:relative;max-width:100%;min-height:inherit;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;z-index:2;-webkit-box-sizing:border-box;box-sizing:border-box}:host(.radio-disabled){pointer-events:none}.radio-icon{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;width:100%;height:100%;contain:layout size style}.radio-icon,.radio-inner{-webkit-box-sizing:border-box;box-sizing:border-box}input{position:absolute;top:0;left:0;right:0;bottom:0;width:100%;height:100%;margin:0;padding:0;border:0;outline:0;clip:rect(0 0 0 0);opacity:0;overflow:hidden;-webkit-appearance:none;-moz-appearance:none}:host(:focus){outline:none}:host(.in-item){-ms-flex:1 1 0px;flex:1 1 0;width:100%;height:100%}:host([slot=start]),:host([slot=end]){-ms-flex:initial;flex:initial;width:auto}.radio-wrapper{display:-ms-flexbox;display:flex;position:relative;-ms-flex-positive:1;flex-grow:1;-ms-flex-align:center;align-items:center;-ms-flex-pack:justify;justify-content:space-between;height:inherit;min-height:inherit;cursor:inherit}.label-text-wrapper{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}:host(.in-item) .label-text-wrapper{margin-top:10px;margin-bottom:10px}:host(.in-item.radio-label-placement-stacked) .label-text-wrapper{margin-top:10px;margin-bottom:16px}:host(.in-item.radio-label-placement-stacked) .native-wrapper{margin-bottom:10px}.label-text-wrapper-hidden{display:none}.native-wrapper{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center}:host(.radio-justify-space-between) .radio-wrapper{-ms-flex-pack:justify;justify-content:space-between}:host(.radio-justify-start) .radio-wrapper{-ms-flex-pack:start;justify-content:start}:host(.radio-justify-end) .radio-wrapper{-ms-flex-pack:end;justify-content:end}:host(.radio-alignment-start) .radio-wrapper{-ms-flex-align:start;align-items:start}:host(.radio-alignment-center) .radio-wrapper{-ms-flex-align:center;align-items:center}:host(.radio-justify-space-between),:host(.radio-justify-start),:host(.radio-justify-end),:host(.radio-alignment-start),:host(.radio-alignment-center){display:block}:host(.radio-label-placement-start) .radio-wrapper{-ms-flex-direction:row;flex-direction:row}:host(.radio-label-placement-start) .label-text-wrapper{-webkit-margin-start:0;margin-inline-start:0;-webkit-margin-end:16px;margin-inline-end:16px}:host(.radio-label-placement-end) .radio-wrapper{-ms-flex-direction:row-reverse;flex-direction:row-reverse}:host(.radio-label-placement-end) .label-text-wrapper{-webkit-margin-start:16px;margin-inline-start:16px;-webkit-margin-end:0;margin-inline-end:0}:host(.radio-label-placement-fixed) .label-text-wrapper{-webkit-margin-start:0;margin-inline-start:0;-webkit-margin-end:16px;margin-inline-end:16px}:host(.radio-label-placement-fixed) .label-text-wrapper{-ms-flex:0 0 100px;flex:0 0 100px;width:100px;min-width:100px}:host(.radio-label-placement-stacked) .radio-wrapper{-ms-flex-direction:column;flex-direction:column}:host(.radio-label-placement-stacked) .label-text-wrapper{-webkit-transform:scale(0.75);transform:scale(0.75);margin-left:0;margin-right:0;margin-bottom:16px;max-width:calc(100% / 0.75)}:host(.radio-label-placement-stacked.radio-alignment-start) .label-text-wrapper{-webkit-transform-origin:left top;transform-origin:left top}:host-context([dir=rtl]):host(.radio-label-placement-stacked.radio-alignment-start) .label-text-wrapper,:host-context([dir=rtl]).radio-label-placement-stacked.radio-alignment-start .label-text-wrapper{-webkit-transform-origin:right top;transform-origin:right top}@supports selector(:dir(rtl)){:host(.radio-label-placement-stacked.radio-alignment-start:dir(rtl)) .label-text-wrapper{-webkit-transform-origin:right top;transform-origin:right top}}:host(.radio-label-placement-stacked.radio-alignment-center) .label-text-wrapper{-webkit-transform-origin:center top;transform-origin:center top}:host-context([dir=rtl]):host(.radio-label-placement-stacked.radio-alignment-center) .label-text-wrapper,:host-context([dir=rtl]).radio-label-placement-stacked.radio-alignment-center .label-text-wrapper{-webkit-transform-origin:calc(100% - center) top;transform-origin:calc(100% - center) top}@supports selector(:dir(rtl)){:host(.radio-label-placement-stacked.radio-alignment-center:dir(rtl)) .label-text-wrapper{-webkit-transform-origin:calc(100% - center) top;transform-origin:calc(100% - center) top}}:host{--color:rgb(var(--ion-text-color-rgb, 0, 0, 0), 0.6);--color-checked:var(--ion-color-primary, #0054e9);--border-width:0.125rem;--border-style:solid;--border-radius:50%}:host(.ion-color) .radio-inner{background:var(--ion-color-base)}:host(.ion-color.radio-checked) .radio-icon{border-color:var(--ion-color-base)}.radio-icon{margin-left:0;margin-right:0;margin-top:0;margin-bottom:0;border-radius:var(--border-radius);border-width:var(--border-width);border-style:var(--border-style);border-color:var(--color)}.radio-inner{border-radius:var(--inner-border-radius);width:calc(50% + var(--border-width));height:calc(50% + var(--border-width));-webkit-transform:scale3d(0, 0, 0);transform:scale3d(0, 0, 0);-webkit-transition:-webkit-transform 280ms cubic-bezier(0.4, 0, 0.2, 1);transition:-webkit-transform 280ms cubic-bezier(0.4, 0, 0.2, 1);transition:transform 280ms cubic-bezier(0.4, 0, 0.2, 1);transition:transform 280ms cubic-bezier(0.4, 0, 0.2, 1), -webkit-transform 280ms cubic-bezier(0.4, 0, 0.2, 1);background:var(--color-checked)}:host(.radio-checked) .radio-icon{border-color:var(--color-checked)}:host(.radio-checked) .radio-inner{-webkit-transform:scale3d(1, 1, 1);transform:scale3d(1, 1, 1)}:host(.radio-disabled) .label-text-wrapper{opacity:0.38}:host(.radio-disabled) .native-wrapper{opacity:0.63}:host(.ion-focused) .radio-icon::after{border-radius:var(--inner-border-radius);display:block;position:absolute;width:36px;height:36px;background:var(--ion-color-primary-tint, #1a65eb);content:\"\";opacity:0.2}.native-wrapper .radio-icon{width:1.25rem;height:1.25rem}";
  24612. var IonRadioMdStyle0 = radioMdCss;
  24613. /**
  24614. * @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
  24615. *
  24616. * @slot - The label text to associate with the radio. Use the "labelPlacement" property to control where the label is placed relative to the radio.
  24617. *
  24618. * @part container - The container for the radio mark.
  24619. * @part label - The label text describing the radio.
  24620. * @part mark - The checkmark or dot used to indicate the checked state.
  24621. */
  24622. class Radio {
  24623. constructor(hostRef) {
  24624. registerInstance(this, hostRef);
  24625. this.ionFocus = createEvent(this, "ionFocus", 7);
  24626. this.ionBlur = createEvent(this, "ionBlur", 7);
  24627. this.inputId = `ion-rb-${radioButtonIds++}`;
  24628. this.radioGroup = null;
  24629. this.updateState = () => {
  24630. if (this.radioGroup) {
  24631. const { compareWith, value: radioGroupValue } = this.radioGroup;
  24632. this.checked = isOptionSelected(radioGroupValue, this.value, compareWith);
  24633. }
  24634. };
  24635. this.onClick = () => {
  24636. const { radioGroup, checked, disabled } = this;
  24637. if (disabled) {
  24638. return;
  24639. }
  24640. /**
  24641. * The modern control does not use a native input
  24642. * inside of the radio host, so we cannot rely on the
  24643. * ev.preventDefault() behavior above. If the radio
  24644. * is checked and the parent radio group allows for empty
  24645. * selection, then we can set the checked state to false.
  24646. * Otherwise, the checked state should always be set
  24647. * to true because the checked state cannot be toggled.
  24648. */
  24649. if (checked && (radioGroup === null || radioGroup === void 0 ? void 0 : radioGroup.allowEmptySelection)) {
  24650. this.checked = false;
  24651. }
  24652. else {
  24653. this.checked = true;
  24654. }
  24655. };
  24656. this.onFocus = () => {
  24657. this.ionFocus.emit();
  24658. };
  24659. this.onBlur = () => {
  24660. this.ionBlur.emit();
  24661. };
  24662. this.checked = false;
  24663. this.buttonTabindex = -1;
  24664. this.color = undefined;
  24665. this.name = this.inputId;
  24666. this.disabled = false;
  24667. this.value = undefined;
  24668. this.labelPlacement = 'start';
  24669. this.justify = undefined;
  24670. this.alignment = undefined;
  24671. }
  24672. valueChanged() {
  24673. /**
  24674. * The new value of the radio may
  24675. * match the radio group's value,
  24676. * so we see if it should be checked.
  24677. */
  24678. this.updateState();
  24679. }
  24680. componentDidLoad() {
  24681. /**
  24682. * The value may be `undefined` if it
  24683. * gets set before the radio is
  24684. * rendered. This ensures that the radio
  24685. * is checked if the value matches. This
  24686. * happens most often when Angular is
  24687. * rendering the radio.
  24688. */
  24689. this.updateState();
  24690. }
  24691. /** @internal */
  24692. async setFocus(ev) {
  24693. if (ev !== undefined) {
  24694. ev.stopPropagation();
  24695. ev.preventDefault();
  24696. }
  24697. this.el.focus();
  24698. }
  24699. /** @internal */
  24700. async setButtonTabindex(value) {
  24701. this.buttonTabindex = value;
  24702. }
  24703. connectedCallback() {
  24704. if (this.value === undefined) {
  24705. this.value = this.inputId;
  24706. }
  24707. const radioGroup = (this.radioGroup = this.el.closest('ion-radio-group'));
  24708. if (radioGroup) {
  24709. this.updateState();
  24710. addEventListener$1(radioGroup, 'ionValueChange', this.updateState);
  24711. }
  24712. }
  24713. disconnectedCallback() {
  24714. const radioGroup = this.radioGroup;
  24715. if (radioGroup) {
  24716. removeEventListener(radioGroup, 'ionValueChange', this.updateState);
  24717. this.radioGroup = null;
  24718. }
  24719. }
  24720. get hasLabel() {
  24721. return this.el.textContent !== '';
  24722. }
  24723. renderRadioControl() {
  24724. return (hAsync("div", { class: "radio-icon", part: "container" }, hAsync("div", { class: "radio-inner", part: "mark" }), hAsync("div", { class: "radio-ripple" })));
  24725. }
  24726. render() {
  24727. const { checked, disabled, color, el, justify, labelPlacement, hasLabel, buttonTabindex, alignment } = this;
  24728. const mode = getIonMode$1(this);
  24729. const inItem = hostContext('ion-item', el);
  24730. return (hAsync(Host, { key: '8badd4aec277addc0793e14df21f73bb345e99b7', onFocus: this.onFocus, onBlur: this.onBlur, onClick: this.onClick, class: createColorClasses$1(color, {
  24731. [mode]: true,
  24732. 'in-item': inItem,
  24733. 'radio-checked': checked,
  24734. 'radio-disabled': disabled,
  24735. [`radio-justify-${justify}`]: justify !== undefined,
  24736. [`radio-alignment-${alignment}`]: alignment !== undefined,
  24737. [`radio-label-placement-${labelPlacement}`]: true,
  24738. // Focus and active styling should not apply when the radio is in an item
  24739. 'ion-activatable': !inItem,
  24740. 'ion-focusable': !inItem,
  24741. }), role: "radio", "aria-checked": checked ? 'true' : 'false', "aria-disabled": disabled ? 'true' : null, tabindex: buttonTabindex }, hAsync("label", { key: '8765b847edc93a1b5a16506e155ed03da807bb10', class: "radio-wrapper" }, hAsync("div", { key: '3d568a0192a32d4f0b8a920019c79ff02639b5c9', class: {
  24742. 'label-text-wrapper': true,
  24743. 'label-text-wrapper-hidden': !hasLabel,
  24744. }, part: "label" }, hAsync("slot", { key: '331f3dc2ce5f6ed8f124fc4560f92e0f7c668a85' })), hAsync("div", { key: '473bd4aaf448753e385f2dda3fddc9f56379aa19', class: "native-wrapper" }, this.renderRadioControl()))));
  24745. }
  24746. get el() { return getElement(this); }
  24747. static get watchers() { return {
  24748. "value": ["valueChanged"]
  24749. }; }
  24750. static get style() { return {
  24751. ios: IonRadioIosStyle0,
  24752. md: IonRadioMdStyle0
  24753. }; }
  24754. static get cmpMeta() { return {
  24755. "$flags$": 41,
  24756. "$tagName$": "ion-radio",
  24757. "$members$": {
  24758. "color": [513],
  24759. "name": [1],
  24760. "disabled": [4],
  24761. "value": [8],
  24762. "labelPlacement": [1, "label-placement"],
  24763. "justify": [1],
  24764. "alignment": [1],
  24765. "checked": [32],
  24766. "buttonTabindex": [32],
  24767. "setFocus": [64],
  24768. "setButtonTabindex": [64]
  24769. },
  24770. "$listeners$": undefined,
  24771. "$lazyBundleId$": "-",
  24772. "$attrsToReflect$": [["color", "color"]]
  24773. }; }
  24774. }
  24775. let radioButtonIds = 0;
  24776. const radioGroupIosCss = "ion-radio-group{vertical-align:top}.radio-group-wrapper{display:inline}.radio-group-top{line-height:1.5}.radio-group-top .error-text{display:none;color:var(--ion-color-danger, #c5000f)}.radio-group-top .helper-text{display:block;color:var(--ion-color-step-700, var(--ion-text-color-step-300, #4d4d4d))}.ion-touched.ion-invalid .radio-group-top .error-text{display:block}.ion-touched.ion-invalid .radio-group-top .helper-text{display:none}ion-list .radio-group-top{-webkit-padding-start:16px;padding-inline-start:16px;-webkit-padding-end:16px;padding-inline-end:16px}";
  24777. var IonRadioGroupIosStyle0 = radioGroupIosCss;
  24778. const radioGroupMdCss = "ion-radio-group{vertical-align:top}.radio-group-wrapper{display:inline}.radio-group-top{line-height:1.5}.radio-group-top .error-text{display:none;color:var(--ion-color-danger, #c5000f)}.radio-group-top .helper-text{display:block;color:var(--ion-color-step-700, var(--ion-text-color-step-300, #4d4d4d))}.ion-touched.ion-invalid .radio-group-top .error-text{display:block}.ion-touched.ion-invalid .radio-group-top .helper-text{display:none}ion-list .radio-group-top{-webkit-padding-start:16px;padding-inline-start:16px;-webkit-padding-end:16px;padding-inline-end:16px}";
  24779. var IonRadioGroupMdStyle0 = radioGroupMdCss;
  24780. class RadioGroup {
  24781. constructor(hostRef) {
  24782. registerInstance(this, hostRef);
  24783. this.ionChange = createEvent(this, "ionChange", 7);
  24784. this.ionValueChange = createEvent(this, "ionValueChange", 7);
  24785. this.inputId = `ion-rg-${radioGroupIds++}`;
  24786. this.helperTextId = `${this.inputId}-helper-text`;
  24787. this.errorTextId = `${this.inputId}-error-text`;
  24788. this.labelId = `${this.inputId}-lbl`;
  24789. this.setRadioTabindex = (value) => {
  24790. const radios = this.getRadios();
  24791. // Get the first radio that is not disabled and the checked one
  24792. const first = radios.find((radio) => !radio.disabled);
  24793. const checked = radios.find((radio) => radio.value === value && !radio.disabled);
  24794. if (!first && !checked) {
  24795. return;
  24796. }
  24797. // If an enabled checked radio exists, set it to be the focusable radio
  24798. // otherwise we default to focus the first radio
  24799. const focusable = checked || first;
  24800. for (const radio of radios) {
  24801. const tabindex = radio === focusable ? 0 : -1;
  24802. radio.setButtonTabindex(tabindex);
  24803. }
  24804. };
  24805. this.onClick = (ev) => {
  24806. ev.preventDefault();
  24807. /**
  24808. * The Radio Group component mandates that only one radio button
  24809. * within the group can be selected at any given time. Since `ion-radio`
  24810. * is a shadow DOM component, it cannot natively perform this behavior
  24811. * using the `name` attribute.
  24812. */
  24813. const selectedRadio = ev.target && ev.target.closest('ion-radio');
  24814. /**
  24815. * Our current disabled prop definition causes Stencil to mark it
  24816. * as optional. While this is not desired, fixing this behavior
  24817. * in Stencil is a significant breaking change, so this effort is
  24818. * being de-risked in STENCIL-917. Until then, we compromise
  24819. * here by checking for falsy `disabled` values instead of strictly
  24820. * checking `disabled === false`.
  24821. */
  24822. if (selectedRadio && !selectedRadio.disabled) {
  24823. const currentValue = this.value;
  24824. const newValue = selectedRadio.value;
  24825. if (newValue !== currentValue) {
  24826. this.value = newValue;
  24827. this.emitValueChange(ev);
  24828. }
  24829. else if (this.allowEmptySelection) {
  24830. this.value = undefined;
  24831. this.emitValueChange(ev);
  24832. }
  24833. }
  24834. };
  24835. this.allowEmptySelection = false;
  24836. this.compareWith = undefined;
  24837. this.name = this.inputId;
  24838. this.value = undefined;
  24839. this.helperText = undefined;
  24840. this.errorText = undefined;
  24841. }
  24842. valueChanged(value) {
  24843. this.setRadioTabindex(value);
  24844. this.ionValueChange.emit({ value });
  24845. }
  24846. componentDidLoad() {
  24847. /**
  24848. * There's an issue when assigning a value to the radio group
  24849. * within the Angular primary content (rendering within the
  24850. * app component template). When the template is isolated to a route,
  24851. * the value is assigned correctly.
  24852. * To address this issue, we need to ensure that the watcher is
  24853. * called after the component has finished loading,
  24854. * allowing the emit to be dispatched correctly.
  24855. */
  24856. this.valueChanged(this.value);
  24857. }
  24858. async connectedCallback() {
  24859. // Get the list header if it exists and set the id
  24860. // this is used to set aria-labelledby
  24861. const header = this.el.querySelector('ion-list-header') || this.el.querySelector('ion-item-divider');
  24862. if (header) {
  24863. const label = (this.label = header.querySelector('ion-label'));
  24864. if (label) {
  24865. this.labelId = label.id = this.name + '-lbl';
  24866. }
  24867. }
  24868. }
  24869. getRadios() {
  24870. return Array.from(this.el.querySelectorAll('ion-radio'));
  24871. }
  24872. /**
  24873. * Emits an `ionChange` event.
  24874. *
  24875. * This API should be called for user committed changes.
  24876. * This API should not be used for external value changes.
  24877. */
  24878. emitValueChange(event) {
  24879. const { value } = this;
  24880. this.ionChange.emit({ value, event });
  24881. }
  24882. onKeydown(ev) {
  24883. // We don't want the value to automatically change/emit when the radio group is part of a select interface
  24884. // as this will cause the interface to close when navigating through the radio group options
  24885. const inSelectInterface = !!this.el.closest('ion-select-popover') || !!this.el.closest('ion-select-modal');
  24886. if (ev.target && !this.el.contains(ev.target)) {
  24887. return;
  24888. }
  24889. // Get all radios inside of the radio group and then
  24890. // filter out disabled radios since we need to skip those
  24891. const radios = this.getRadios().filter((radio) => !radio.disabled);
  24892. // Only move the radio if the current focus is in the radio group
  24893. if (ev.target && radios.includes(ev.target)) {
  24894. const index = radios.findIndex((radio) => radio === ev.target);
  24895. const current = radios[index];
  24896. let next;
  24897. // If hitting arrow down or arrow right, move to the next radio
  24898. // If we're on the last radio, move to the first radio
  24899. if (['ArrowDown', 'ArrowRight'].includes(ev.key)) {
  24900. next = index === radios.length - 1 ? radios[0] : radios[index + 1];
  24901. }
  24902. // If hitting arrow up or arrow left, move to the previous radio
  24903. // If we're on the first radio, move to the last radio
  24904. if (['ArrowUp', 'ArrowLeft'].includes(ev.key)) {
  24905. next = index === 0 ? radios[radios.length - 1] : radios[index - 1];
  24906. }
  24907. if (next && radios.includes(next)) {
  24908. next.setFocus(ev);
  24909. if (!inSelectInterface) {
  24910. this.value = next.value;
  24911. this.emitValueChange(ev);
  24912. }
  24913. }
  24914. // Update the radio group value when a user presses the
  24915. // space bar on top of a selected radio
  24916. if ([' '].includes(ev.key)) {
  24917. const previousValue = this.value;
  24918. this.value = this.allowEmptySelection && this.value !== undefined ? undefined : current.value;
  24919. if (previousValue !== this.value || this.allowEmptySelection) {
  24920. /**
  24921. * Value change should only be emitted if the value is different,
  24922. * such as selecting a new radio with the space bar or if
  24923. * the radio group allows for empty selection and the user
  24924. * is deselecting a checked radio.
  24925. */
  24926. this.emitValueChange(ev);
  24927. }
  24928. // Prevent browsers from jumping
  24929. // to the bottom of the screen
  24930. ev.preventDefault();
  24931. }
  24932. }
  24933. }
  24934. /** @internal */
  24935. async setFocus() {
  24936. const radioToFocus = this.getRadios().find((r) => r.tabIndex !== -1);
  24937. radioToFocus === null || radioToFocus === void 0 ? void 0 : radioToFocus.setFocus();
  24938. }
  24939. /**
  24940. * Renders the helper text or error text values
  24941. */
  24942. renderHintText() {
  24943. const { helperText, errorText, helperTextId, errorTextId } = this;
  24944. const hasHintText = !!helperText || !!errorText;
  24945. if (!hasHintText) {
  24946. return;
  24947. }
  24948. return (hAsync("div", { class: "radio-group-top" }, hAsync("div", { id: helperTextId, class: "helper-text" }, helperText), hAsync("div", { id: errorTextId, class: "error-text" }, errorText)));
  24949. }
  24950. getHintTextID() {
  24951. const { el, helperText, errorText, helperTextId, errorTextId } = this;
  24952. if (el.classList.contains('ion-touched') && el.classList.contains('ion-invalid') && errorText) {
  24953. return errorTextId;
  24954. }
  24955. if (helperText) {
  24956. return helperTextId;
  24957. }
  24958. return undefined;
  24959. }
  24960. render() {
  24961. const { label, labelId, el, name, value } = this;
  24962. const mode = getIonMode$1(this);
  24963. renderHiddenInput(true, el, name, value, false);
  24964. return (hAsync(Host, { key: 'cac92777297029d7fd1b6af264d92850e35dfbba', role: "radiogroup", "aria-labelledby": label ? labelId : null, "aria-describedby": this.getHintTextID(), "aria-invalid": this.getHintTextID() === this.errorTextId, onClick: this.onClick, class: mode }, this.renderHintText(), hAsync("div", { key: '6b5c634dba30d54eedc031b077863f3d6a9d9e9b', class: "radio-group-wrapper" }, hAsync("slot", { key: '443edb3ff6f4c59d4c4324c8a19f2d6def47a322' }))));
  24965. }
  24966. get el() { return getElement(this); }
  24967. static get watchers() { return {
  24968. "value": ["valueChanged"]
  24969. }; }
  24970. static get style() { return {
  24971. ios: IonRadioGroupIosStyle0,
  24972. md: IonRadioGroupMdStyle0
  24973. }; }
  24974. static get cmpMeta() { return {
  24975. "$flags$": 36,
  24976. "$tagName$": "ion-radio-group",
  24977. "$members$": {
  24978. "allowEmptySelection": [4, "allow-empty-selection"],
  24979. "compareWith": [1, "compare-with"],
  24980. "name": [1],
  24981. "value": [1032],
  24982. "helperText": [1, "helper-text"],
  24983. "errorText": [1, "error-text"],
  24984. "setFocus": [64]
  24985. },
  24986. "$listeners$": [[4, "keydown", "onKeydown"]],
  24987. "$lazyBundleId$": "-",
  24988. "$attrsToReflect$": []
  24989. }; }
  24990. }
  24991. let radioGroupIds = 0;
  24992. function getDecimalPlaces(n) {
  24993. if (!isSafeNumber(n))
  24994. return 0;
  24995. if (n % 1 === 0)
  24996. return 0;
  24997. return n.toString().split('.')[1].length;
  24998. }
  24999. /**
  25000. * Fixes floating point rounding errors in a result by rounding
  25001. * to the same specificity, or number of decimal places (*not*
  25002. * significant figures) as provided reference numbers. If multiple
  25003. * references are provided, the highest number of decimal places
  25004. * between them will be used.
  25005. *
  25006. * The main use case is when numbers x and y are added to produce n,
  25007. * but x and y are floats, so n may have rounding errors (such as
  25008. * 3.1000000004 instead of 3.1). As long as only addition/subtraction
  25009. * occurs between x and y, the specificity of the result will never
  25010. * increase, so x and y should be passed in as the references.
  25011. *
  25012. * If multiplication, division, or other operations were used to
  25013. * calculate n, the rounded result may have less specificity than
  25014. * desired. For example, 1 / 3 = 0.33333(...), but
  25015. * roundToMaxDecimalPlaces((1 / 3), 1, 3) will return 0, since both
  25016. * 1 and 3 are whole numbers.
  25017. *
  25018. * Note that extremely precise reference numbers may lead to rounding
  25019. * errors not being trimmed, due to the error result having the same or
  25020. * fewer decimal places as the reference(s). This is acceptable as we
  25021. * would not be able to tell the difference between a rounding error
  25022. * and correct value in this case, but it does mean there is an implicit
  25023. * precision limit. If precision that high is needed, it is recommended
  25024. * to use a third party data type designed to handle floating point
  25025. * errors instead.
  25026. *
  25027. * @param n The number to round.
  25028. * @param references Number(s) used to calculate n, or that should otherwise
  25029. * be used as a reference for the desired specificity.
  25030. */
  25031. function roundToMaxDecimalPlaces(n, ...references) {
  25032. if (!isSafeNumber(n))
  25033. return 0;
  25034. const maxPlaces = Math.max(...references.map((r) => getDecimalPlaces(r)));
  25035. return Number(n.toFixed(maxPlaces));
  25036. }
  25037. const rangeIosCss = ":host{--knob-handle-size:calc(var(--knob-size) * 2);display:-ms-flexbox;display:flex;position:relative;-ms-flex:3;flex:3;-ms-flex-align:center;align-items:center;font-family:var(--ion-font-family, inherit);-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;z-index:2}:host(.range-disabled){pointer-events:none}::slotted(ion-label){-ms-flex:initial;flex:initial}::slotted(ion-icon[slot]){font-size:24px}.range-slider{position:relative;-ms-flex:1;flex:1;width:100%;height:var(--height);contain:size layout style;cursor:-webkit-grab;cursor:grab;-ms-touch-action:pan-y;touch-action:pan-y}:host(.range-pressed) .range-slider{cursor:-webkit-grabbing;cursor:grabbing}.range-pin{position:absolute;background:var(--ion-color-base);color:var(--ion-color-contrast);text-align:center;-webkit-box-sizing:border-box;box-sizing:border-box}.range-knob-handle{top:calc((var(--height) - var(--knob-handle-size)) / 2);-webkit-margin-start:calc(0px - var(--knob-handle-size) / 2);margin-inline-start:calc(0px - var(--knob-handle-size) / 2);display:-ms-flexbox;display:flex;position:absolute;-ms-flex-pack:center;justify-content:center;width:var(--knob-handle-size);height:var(--knob-handle-size);text-align:center}.range-knob-handle{inset-inline-start:0}:host-context([dir=rtl]) .range-knob-handle{left:unset}[dir=rtl] .range-knob-handle{left:unset}@supports selector(:dir(rtl)){.range-knob-handle:dir(rtl){left:unset}}.range-knob-handle:active,.range-knob-handle:focus{outline:none}.range-bar-container{border-radius:var(--bar-border-radius);top:calc((var(--height) - var(--bar-height)) / 2);position:absolute;width:100%;height:var(--bar-height)}.range-bar-container{inset-inline-start:0}:host-context([dir=rtl]) .range-bar-container{left:unset}[dir=rtl] .range-bar-container{left:unset}@supports selector(:dir(rtl)){.range-bar-container:dir(rtl){left:unset}}.range-bar{border-radius:var(--bar-border-radius);position:absolute;width:100%;height:var(--bar-height);background:var(--bar-background);pointer-events:none}.range-knob{border-radius:var(--knob-border-radius);top:calc(50% - var(--knob-size) / 2);position:absolute;width:var(--knob-size);height:var(--knob-size);background:var(--knob-background);-webkit-box-shadow:var(--knob-box-shadow);box-shadow:var(--knob-box-shadow);z-index:2;pointer-events:none}.range-knob{inset-inline-start:calc(50% - var(--knob-size) / 2)}:host-context([dir=rtl]) .range-knob{left:unset}[dir=rtl] .range-knob{left:unset}@supports selector(:dir(rtl)){.range-knob:dir(rtl){left:unset}}:host(.range-pressed) .range-bar-active{will-change:left, right}:host(.in-item){width:100%}:host([slot=start]),:host([slot=end]){width:auto}:host(.in-item) ::slotted(ion-label){-ms-flex-item-align:center;align-self:center}.range-wrapper{display:-ms-flexbox;display:flex;position:relative;-ms-flex-positive:1;flex-grow:1;-ms-flex-align:center;align-items:center;height:inherit}::slotted([slot=label]){max-width:200px;text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.label-text-wrapper-hidden{display:none}.native-wrapper{display:-ms-flexbox;display:flex;-ms-flex-positive:1;flex-grow:1;-ms-flex-align:center;align-items:center}:host(.range-label-placement-start) .range-wrapper{-ms-flex-direction:row;flex-direction:row}:host(.range-label-placement-start) .label-text-wrapper{-webkit-margin-start:0;margin-inline-start:0;-webkit-margin-end:16px;margin-inline-end:16px;margin-top:0;margin-bottom:0}:host(.range-label-placement-end) .range-wrapper{-ms-flex-direction:row-reverse;flex-direction:row-reverse}:host(.range-label-placement-end) .label-text-wrapper{-webkit-margin-start:16px;margin-inline-start:16px;-webkit-margin-end:0;margin-inline-end:0;margin-top:0;margin-bottom:0}:host(.range-label-placement-fixed) .label-text-wrapper{-webkit-margin-start:0;margin-inline-start:0;-webkit-margin-end:16px;margin-inline-end:16px;margin-top:0;margin-bottom:0}:host(.range-label-placement-fixed) .label-text-wrapper{-ms-flex:0 0 100px;flex:0 0 100px;width:100px;min-width:100px;max-width:200px}:host(.range-label-placement-stacked) .range-wrapper{-ms-flex-direction:column;flex-direction:column;-ms-flex-align:stretch;align-items:stretch}:host(.range-label-placement-stacked) .label-text-wrapper{-webkit-transform-origin:left top;transform-origin:left top;-webkit-transform:scale(0.75);transform:scale(0.75);margin-left:0;margin-right:0;margin-bottom:16px;max-width:calc(100% / 0.75)}:host-context([dir=rtl]):host(.range-label-placement-stacked) .label-text-wrapper,:host-context([dir=rtl]).range-label-placement-stacked .label-text-wrapper{-webkit-transform-origin:right top;transform-origin:right top}@supports selector(:dir(rtl)){:host(.range-label-placement-stacked:dir(rtl)) .label-text-wrapper{-webkit-transform-origin:right top;transform-origin:right top}}:host(.in-item.range-label-placement-stacked) .label-text-wrapper{margin-top:10px;margin-bottom:16px}:host(.in-item.range-label-placement-stacked) .native-wrapper{margin-bottom:0px}:host{--knob-border-radius:50%;--knob-background:#ffffff;--knob-box-shadow:0px 0.5px 4px rgba(0, 0, 0, 0.12), 0px 6px 13px rgba(0, 0, 0, 0.12);--knob-size:26px;--bar-height:4px;--bar-background:var(--ion-color-step-900, var(--ion-background-color-step-900, #e6e6e6));--bar-background-active:var(--ion-color-primary, #0054e9);--bar-border-radius:2px;--height:42px}:host(.range-item-start-adjustment){-webkit-padding-start:24px;padding-inline-start:24px}:host(.range-item-end-adjustment){-webkit-padding-end:24px;padding-inline-end:24px}:host(.ion-color) .range-bar-active,:host(.ion-color) .range-tick-active{background:var(--ion-color-base)}::slotted([slot=start]){-webkit-margin-start:0;margin-inline-start:0;-webkit-margin-end:16px;margin-inline-end:16px;margin-top:0;margin-bottom:0}::slotted([slot=end]){-webkit-margin-start:16px;margin-inline-start:16px;-webkit-margin-end:0;margin-inline-end:0;margin-top:0;margin-bottom:0}:host(.range-has-pin:not(.range-label-placement-stacked)){padding-top:calc(8px + 0.75rem)}:host(.range-has-pin.range-label-placement-stacked) .label-text-wrapper{margin-bottom:calc(8px + 0.75rem)}.range-bar-active{bottom:0;width:auto;background:var(--bar-background-active)}.range-bar-active.has-ticks{border-radius:0;-webkit-margin-start:-2px;margin-inline-start:-2px;-webkit-margin-end:-2px;margin-inline-end:-2px}.range-tick{-webkit-margin-start:-2px;margin-inline-start:-2px;border-radius:0;position:absolute;top:17px;width:4px;height:8px;background:var(--ion-color-step-900, var(--ion-background-color-step-900, #e6e6e6));pointer-events:none}.range-tick-active{background:var(--bar-background-active)}.range-pin{-webkit-transform:translate3d(0, 100%, 0) scale(0.01);transform:translate3d(0, 100%, 0) scale(0.01);-webkit-padding-start:8px;padding-inline-start:8px;-webkit-padding-end:8px;padding-inline-end:8px;padding-top:8px;padding-bottom:8px;min-width:28px;-webkit-transition:-webkit-transform 120ms ease;transition:-webkit-transform 120ms ease;transition:transform 120ms ease;transition:transform 120ms ease, -webkit-transform 120ms ease;background:transparent;color:var(--ion-text-color, #000);font-size:0.75rem;text-align:center}.range-knob-pressed .range-pin,.range-knob-handle.ion-focused .range-pin{-webkit-transform:translate3d(0, calc(-100% + 11px), 0) scale(1);transform:translate3d(0, calc(-100% + 11px), 0) scale(1)}:host(.range-disabled){opacity:0.3}";
  25038. var IonRangeIosStyle0 = rangeIosCss;
  25039. const rangeMdCss = ":host{--knob-handle-size:calc(var(--knob-size) * 2);display:-ms-flexbox;display:flex;position:relative;-ms-flex:3;flex:3;-ms-flex-align:center;align-items:center;font-family:var(--ion-font-family, inherit);-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;z-index:2}:host(.range-disabled){pointer-events:none}::slotted(ion-label){-ms-flex:initial;flex:initial}::slotted(ion-icon[slot]){font-size:24px}.range-slider{position:relative;-ms-flex:1;flex:1;width:100%;height:var(--height);contain:size layout style;cursor:-webkit-grab;cursor:grab;-ms-touch-action:pan-y;touch-action:pan-y}:host(.range-pressed) .range-slider{cursor:-webkit-grabbing;cursor:grabbing}.range-pin{position:absolute;background:var(--ion-color-base);color:var(--ion-color-contrast);text-align:center;-webkit-box-sizing:border-box;box-sizing:border-box}.range-knob-handle{top:calc((var(--height) - var(--knob-handle-size)) / 2);-webkit-margin-start:calc(0px - var(--knob-handle-size) / 2);margin-inline-start:calc(0px - var(--knob-handle-size) / 2);display:-ms-flexbox;display:flex;position:absolute;-ms-flex-pack:center;justify-content:center;width:var(--knob-handle-size);height:var(--knob-handle-size);text-align:center}.range-knob-handle{inset-inline-start:0}:host-context([dir=rtl]) .range-knob-handle{left:unset}[dir=rtl] .range-knob-handle{left:unset}@supports selector(:dir(rtl)){.range-knob-handle:dir(rtl){left:unset}}.range-knob-handle:active,.range-knob-handle:focus{outline:none}.range-bar-container{border-radius:var(--bar-border-radius);top:calc((var(--height) - var(--bar-height)) / 2);position:absolute;width:100%;height:var(--bar-height)}.range-bar-container{inset-inline-start:0}:host-context([dir=rtl]) .range-bar-container{left:unset}[dir=rtl] .range-bar-container{left:unset}@supports selector(:dir(rtl)){.range-bar-container:dir(rtl){left:unset}}.range-bar{border-radius:var(--bar-border-radius);position:absolute;width:100%;height:var(--bar-height);background:var(--bar-background);pointer-events:none}.range-knob{border-radius:var(--knob-border-radius);top:calc(50% - var(--knob-size) / 2);position:absolute;width:var(--knob-size);height:var(--knob-size);background:var(--knob-background);-webkit-box-shadow:var(--knob-box-shadow);box-shadow:var(--knob-box-shadow);z-index:2;pointer-events:none}.range-knob{inset-inline-start:calc(50% - var(--knob-size) / 2)}:host-context([dir=rtl]) .range-knob{left:unset}[dir=rtl] .range-knob{left:unset}@supports selector(:dir(rtl)){.range-knob:dir(rtl){left:unset}}:host(.range-pressed) .range-bar-active{will-change:left, right}:host(.in-item){width:100%}:host([slot=start]),:host([slot=end]){width:auto}:host(.in-item) ::slotted(ion-label){-ms-flex-item-align:center;align-self:center}.range-wrapper{display:-ms-flexbox;display:flex;position:relative;-ms-flex-positive:1;flex-grow:1;-ms-flex-align:center;align-items:center;height:inherit}::slotted([slot=label]){max-width:200px;text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.label-text-wrapper-hidden{display:none}.native-wrapper{display:-ms-flexbox;display:flex;-ms-flex-positive:1;flex-grow:1;-ms-flex-align:center;align-items:center}:host(.range-label-placement-start) .range-wrapper{-ms-flex-direction:row;flex-direction:row}:host(.range-label-placement-start) .label-text-wrapper{-webkit-margin-start:0;margin-inline-start:0;-webkit-margin-end:16px;margin-inline-end:16px;margin-top:0;margin-bottom:0}:host(.range-label-placement-end) .range-wrapper{-ms-flex-direction:row-reverse;flex-direction:row-reverse}:host(.range-label-placement-end) .label-text-wrapper{-webkit-margin-start:16px;margin-inline-start:16px;-webkit-margin-end:0;margin-inline-end:0;margin-top:0;margin-bottom:0}:host(.range-label-placement-fixed) .label-text-wrapper{-webkit-margin-start:0;margin-inline-start:0;-webkit-margin-end:16px;margin-inline-end:16px;margin-top:0;margin-bottom:0}:host(.range-label-placement-fixed) .label-text-wrapper{-ms-flex:0 0 100px;flex:0 0 100px;width:100px;min-width:100px;max-width:200px}:host(.range-label-placement-stacked) .range-wrapper{-ms-flex-direction:column;flex-direction:column;-ms-flex-align:stretch;align-items:stretch}:host(.range-label-placement-stacked) .label-text-wrapper{-webkit-transform-origin:left top;transform-origin:left top;-webkit-transform:scale(0.75);transform:scale(0.75);margin-left:0;margin-right:0;margin-bottom:16px;max-width:calc(100% / 0.75)}:host-context([dir=rtl]):host(.range-label-placement-stacked) .label-text-wrapper,:host-context([dir=rtl]).range-label-placement-stacked .label-text-wrapper{-webkit-transform-origin:right top;transform-origin:right top}@supports selector(:dir(rtl)){:host(.range-label-placement-stacked:dir(rtl)) .label-text-wrapper{-webkit-transform-origin:right top;transform-origin:right top}}:host(.in-item.range-label-placement-stacked) .label-text-wrapper{margin-top:10px;margin-bottom:16px}:host(.in-item.range-label-placement-stacked) .native-wrapper{margin-bottom:0px}:host{--knob-border-radius:50%;--knob-background:var(--bar-background-active);--knob-box-shadow:none;--knob-size:18px;--bar-height:2px;--bar-background:rgba(var(--ion-color-primary-rgb, 0, 84, 233), 0.26);--bar-background-active:var(--ion-color-primary, #0054e9);--bar-border-radius:0;--height:42px;--pin-background:var(--ion-color-primary, #0054e9);--pin-color:var(--ion-color-primary-contrast, #fff)}::slotted(:not(ion-icon)[slot=start]),::slotted(:not(ion-icon)[slot=end]),.native-wrapper{font-size:0.75rem}:host(.range-item-start-adjustment){-webkit-padding-start:18px;padding-inline-start:18px}:host(.range-item-end-adjustment){-webkit-padding-end:18px;padding-inline-end:18px}:host(.ion-color) .range-bar{background:rgba(var(--ion-color-base-rgb), 0.26)}:host(.ion-color) .range-bar-active,:host(.ion-color) .range-knob,:host(.ion-color) .range-knob::before,:host(.ion-color) .range-pin,:host(.ion-color) .range-pin::before,:host(.ion-color) .range-tick{background:var(--ion-color-base);color:var(--ion-color-contrast)}::slotted([slot=start]){-webkit-margin-start:0;margin-inline-start:0;-webkit-margin-end:14px;margin-inline-end:14px;margin-top:0;margin-bottom:0}::slotted([slot=end]){-webkit-margin-start:14px;margin-inline-start:14px;-webkit-margin-end:0;margin-inline-end:0;margin-top:0;margin-bottom:0}:host(.range-has-pin:not(.range-label-placement-stacked)){padding-top:1.75rem}:host(.range-has-pin.range-label-placement-stacked) .label-text-wrapper{margin-bottom:1.75rem}.range-bar-active{bottom:0;width:auto;background:var(--bar-background-active)}.range-knob{-webkit-transform:scale(0.67);transform:scale(0.67);-webkit-transition-duration:120ms;transition-duration:120ms;-webkit-transition-property:background-color, border, -webkit-transform;transition-property:background-color, border, -webkit-transform;transition-property:transform, background-color, border;transition-property:transform, background-color, border, -webkit-transform;-webkit-transition-timing-function:ease;transition-timing-function:ease;z-index:2}.range-knob::before{border-radius:50%;position:absolute;width:var(--knob-size);height:var(--knob-size);-webkit-transform:scale(1);transform:scale(1);-webkit-transition:0.267s cubic-bezier(0, 0, 0.58, 1);transition:0.267s cubic-bezier(0, 0, 0.58, 1);background:var(--knob-background);content:\"\";opacity:0.13;pointer-events:none}.range-knob::before{inset-inline-start:0}.range-tick{position:absolute;top:calc((var(--height) - var(--bar-height)) / 2);width:var(--bar-height);height:var(--bar-height);background:var(--bar-background-active);z-index:1;pointer-events:none}.range-tick-active{background:transparent}.range-pin{padding-left:0;padding-right:0;padding-top:8px;padding-bottom:8px;border-radius:50%;-webkit-transform:translate3d(0, 0, 0) scale(0.01);transform:translate3d(0, 0, 0) scale(0.01);display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;width:1.75rem;height:1.75rem;-webkit-transition:background 120ms ease, -webkit-transform 120ms ease;transition:background 120ms ease, -webkit-transform 120ms ease;transition:transform 120ms ease, background 120ms ease;transition:transform 120ms ease, background 120ms ease, -webkit-transform 120ms ease;background:var(--pin-background);color:var(--pin-color)}.range-pin::before{bottom:-1px;-webkit-margin-start:-13px;margin-inline-start:-13px;border-radius:50% 50% 50% 0;position:absolute;width:26px;height:26px;-webkit-transform:rotate(-45deg);transform:rotate(-45deg);-webkit-transition:background 120ms ease;transition:background 120ms ease;background:var(--pin-background);content:\"\";z-index:-1}.range-pin::before{inset-inline-start:50%}:host-context([dir=rtl]) .range-pin::before{left:unset}[dir=rtl] .range-pin::before{left:unset}@supports selector(:dir(rtl)){.range-pin::before:dir(rtl){left:unset}}.range-knob-pressed .range-pin,.range-knob-handle.ion-focused .range-pin{-webkit-transform:translate3d(0, calc(-100% + 4px), 0) scale(1);transform:translate3d(0, calc(-100% + 4px), 0) scale(1)}@media (any-hover: hover){.range-knob-handle:hover .range-knob:before{-webkit-transform:scale(2);transform:scale(2);opacity:0.13}}.range-knob-handle.ion-activated .range-knob:before,.range-knob-handle.ion-focused .range-knob:before,.range-knob-handle.range-knob-pressed .range-knob:before{-webkit-transform:scale(2);transform:scale(2)}.range-knob-handle.ion-focused .range-knob::before{opacity:0.13}.range-knob-handle.ion-activated .range-knob::before,.range-knob-handle.range-knob-pressed .range-knob::before{opacity:0.25}:host(:not(.range-has-pin)) .range-knob-pressed .range-knob,:host(:not(.range-has-pin)) .range-knob-handle.ion-focused .range-knob{-webkit-transform:scale(1);transform:scale(1)}:host(.range-disabled) .range-bar-active,:host(.range-disabled) .range-bar,:host(.range-disabled) .range-tick{background-color:var(--ion-color-step-250, var(--ion-background-color-step-250, #bfbfbf))}:host(.range-disabled) .range-knob{-webkit-transform:scale(0.55);transform:scale(0.55);outline:5px solid #fff;background-color:var(--ion-color-step-250, var(--ion-background-color-step-250, #bfbfbf))}:host(.range-disabled) .label-text-wrapper,:host(.range-disabled) ::slotted([slot=start]),:host(.range-disabled) ::slotted([slot=end]){opacity:0.38}";
  25040. var IonRangeMdStyle0 = rangeMdCss;
  25041. // TODO(FW-2832): types
  25042. /**
  25043. * @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
  25044. *
  25045. * @slot label - The label text to associate with the range. Use the "labelPlacement" property to control where the label is placed relative to the range.
  25046. * @slot start - Content is placed to the left of the range slider in LTR, and to the right in RTL.
  25047. * @slot end - Content is placed to the right of the range slider in LTR, and to the left in RTL.
  25048. *
  25049. * @part tick - An inactive tick mark.
  25050. * @part tick-active - An active tick mark.
  25051. * @part pin - The counter that appears above a knob.
  25052. * @part knob - The handle that is used to drag the range.
  25053. * @part bar - The inactive part of the bar.
  25054. * @part bar-active - The active part of the bar.
  25055. * @part label - The label text describing the range.
  25056. */
  25057. class Range {
  25058. constructor(hostRef) {
  25059. registerInstance(this, hostRef);
  25060. this.ionChange = createEvent(this, "ionChange", 7);
  25061. this.ionInput = createEvent(this, "ionInput", 7);
  25062. this.ionFocus = createEvent(this, "ionFocus", 7);
  25063. this.ionBlur = createEvent(this, "ionBlur", 7);
  25064. this.ionKnobMoveStart = createEvent(this, "ionKnobMoveStart", 7);
  25065. this.ionKnobMoveEnd = createEvent(this, "ionKnobMoveEnd", 7);
  25066. this.rangeId = `ion-r-${rangeIds++}`;
  25067. this.didLoad = false;
  25068. this.noUpdate = false;
  25069. this.hasFocus = false;
  25070. this.inheritedAttributes = {};
  25071. this.contentEl = null;
  25072. this.initialContentScrollY = true;
  25073. /**
  25074. * Compares two RangeValue inputs to determine if they are different.
  25075. *
  25076. * @param newVal - The new value.
  25077. * @param oldVal - The old value.
  25078. * @returns `true` if the values are different, `false` otherwise.
  25079. */
  25080. this.compareValues = (newVal, oldVal) => {
  25081. if (typeof newVal === 'object' && typeof oldVal === 'object') {
  25082. return newVal.lower !== oldVal.lower || newVal.upper !== oldVal.upper;
  25083. }
  25084. return newVal !== oldVal;
  25085. };
  25086. this.clampBounds = (value) => {
  25087. return clamp(this.min, value, this.max);
  25088. };
  25089. this.ensureValueInBounds = (value) => {
  25090. if (this.dualKnobs) {
  25091. return {
  25092. lower: this.clampBounds(value.lower),
  25093. upper: this.clampBounds(value.upper),
  25094. };
  25095. }
  25096. else {
  25097. return this.clampBounds(value);
  25098. }
  25099. };
  25100. this.setupGesture = async () => {
  25101. const rangeSlider = this.rangeSlider;
  25102. if (rangeSlider) {
  25103. this.gesture = (await Promise.resolve().then(function () { return index; })).createGesture({
  25104. el: rangeSlider,
  25105. gestureName: 'range',
  25106. gesturePriority: 100,
  25107. /**
  25108. * Provide a threshold since the drag movement
  25109. * might be a user scrolling the view.
  25110. * If this is true, then the range
  25111. * should not move.
  25112. */
  25113. threshold: 10,
  25114. onStart: () => this.onStart(),
  25115. onMove: (ev) => this.onMove(ev),
  25116. onEnd: (ev) => this.onEnd(ev),
  25117. });
  25118. this.gesture.enable(!this.disabled);
  25119. }
  25120. };
  25121. this.handleKeyboard = (knob, isIncrease) => {
  25122. const { ensureValueInBounds } = this;
  25123. let step = this.step;
  25124. step = step > 0 ? step : 1;
  25125. step = step / (this.max - this.min);
  25126. if (!isIncrease) {
  25127. step *= -1;
  25128. }
  25129. if (knob === 'A') {
  25130. this.ratioA = clamp(0, this.ratioA + step, 1);
  25131. }
  25132. else {
  25133. this.ratioB = clamp(0, this.ratioB + step, 1);
  25134. }
  25135. this.ionKnobMoveStart.emit({ value: ensureValueInBounds(this.value) });
  25136. this.updateValue();
  25137. this.emitValueChange();
  25138. this.ionKnobMoveEnd.emit({ value: ensureValueInBounds(this.value) });
  25139. };
  25140. this.onBlur = () => {
  25141. if (this.hasFocus) {
  25142. this.hasFocus = false;
  25143. this.ionBlur.emit();
  25144. }
  25145. };
  25146. this.onFocus = () => {
  25147. if (!this.hasFocus) {
  25148. this.hasFocus = true;
  25149. this.ionFocus.emit();
  25150. }
  25151. };
  25152. this.ratioA = 0;
  25153. this.ratioB = 0;
  25154. this.pressedKnob = undefined;
  25155. this.color = undefined;
  25156. this.debounce = undefined;
  25157. this.name = this.rangeId;
  25158. this.label = undefined;
  25159. this.dualKnobs = false;
  25160. this.min = 0;
  25161. this.max = 100;
  25162. this.pin = false;
  25163. this.pinFormatter = (value) => Math.round(value);
  25164. this.snaps = false;
  25165. this.step = 1;
  25166. this.ticks = true;
  25167. this.activeBarStart = undefined;
  25168. this.disabled = false;
  25169. this.value = 0;
  25170. this.labelPlacement = 'start';
  25171. }
  25172. debounceChanged() {
  25173. const { ionInput, debounce, originalIonInput } = this;
  25174. /**
  25175. * If debounce is undefined, we have to manually revert the ionInput emitter in case
  25176. * debounce used to be set to a number. Otherwise, the event would stay debounced.
  25177. */
  25178. this.ionInput = debounce === undefined ? originalIonInput !== null && originalIonInput !== void 0 ? originalIonInput : ionInput : debounceEvent(ionInput, debounce);
  25179. }
  25180. minChanged(newValue) {
  25181. if (!isSafeNumber(newValue)) {
  25182. this.min = 0;
  25183. }
  25184. if (!this.noUpdate) {
  25185. this.updateRatio();
  25186. }
  25187. }
  25188. maxChanged(newValue) {
  25189. if (!isSafeNumber(newValue)) {
  25190. this.max = 100;
  25191. }
  25192. if (!this.noUpdate) {
  25193. this.updateRatio();
  25194. }
  25195. }
  25196. stepChanged(newValue) {
  25197. if (!isSafeNumber(newValue)) {
  25198. this.step = 1;
  25199. }
  25200. }
  25201. activeBarStartChanged() {
  25202. const { activeBarStart } = this;
  25203. if (activeBarStart !== undefined) {
  25204. if (activeBarStart > this.max) {
  25205. printIonWarning(`[ion-range] - The value of activeBarStart (${activeBarStart}) is greater than the max (${this.max}). Valid values are greater than or equal to the min value and less than or equal to the max value.`, this.el);
  25206. this.activeBarStart = this.max;
  25207. }
  25208. else if (activeBarStart < this.min) {
  25209. printIonWarning(`[ion-range] - The value of activeBarStart (${activeBarStart}) is less than the min (${this.min}). Valid values are greater than or equal to the min value and less than or equal to the max value.`, this.el);
  25210. this.activeBarStart = this.min;
  25211. }
  25212. }
  25213. }
  25214. disabledChanged() {
  25215. if (this.gesture) {
  25216. this.gesture.enable(!this.disabled);
  25217. }
  25218. }
  25219. valueChanged(newValue, oldValue) {
  25220. const valuesChanged = this.compareValues(newValue, oldValue);
  25221. if (valuesChanged) {
  25222. this.ionInput.emit({ value: this.value });
  25223. }
  25224. if (!this.noUpdate) {
  25225. this.updateRatio();
  25226. }
  25227. }
  25228. componentWillLoad() {
  25229. /**
  25230. * If user has custom ID set then we should
  25231. * not assign the default incrementing ID.
  25232. */
  25233. if (this.el.hasAttribute('id')) {
  25234. this.rangeId = this.el.getAttribute('id');
  25235. }
  25236. this.inheritedAttributes = inheritAriaAttributes(this.el);
  25237. // If min, max, or step are not safe, set them to 0, 100, and 1, respectively.
  25238. // Each watch does this, but not before the initial load.
  25239. this.min = isSafeNumber(this.min) ? this.min : 0;
  25240. this.max = isSafeNumber(this.max) ? this.max : 100;
  25241. this.step = isSafeNumber(this.step) ? this.step : 1;
  25242. }
  25243. componentDidLoad() {
  25244. this.originalIonInput = this.ionInput;
  25245. this.setupGesture();
  25246. this.updateRatio();
  25247. this.didLoad = true;
  25248. }
  25249. connectedCallback() {
  25250. var _a;
  25251. this.updateRatio();
  25252. this.debounceChanged();
  25253. this.disabledChanged();
  25254. this.activeBarStartChanged();
  25255. /**
  25256. * If we have not yet rendered
  25257. * ion-range, then rangeSlider is not defined.
  25258. * But if we are moving ion-range via appendChild,
  25259. * then rangeSlider will be defined.
  25260. */
  25261. if (this.didLoad) {
  25262. this.setupGesture();
  25263. }
  25264. const ionContent = findClosestIonContent(this.el);
  25265. this.contentEl = (_a = ionContent === null || ionContent === void 0 ? void 0 : ionContent.querySelector('.ion-content-scroll-host')) !== null && _a !== void 0 ? _a : ionContent;
  25266. }
  25267. disconnectedCallback() {
  25268. if (this.gesture) {
  25269. this.gesture.destroy();
  25270. this.gesture = undefined;
  25271. }
  25272. }
  25273. getValue() {
  25274. var _a;
  25275. const value = (_a = this.value) !== null && _a !== void 0 ? _a : 0;
  25276. if (this.dualKnobs) {
  25277. if (typeof value === 'object') {
  25278. return value;
  25279. }
  25280. return {
  25281. lower: 0,
  25282. upper: value,
  25283. };
  25284. }
  25285. else {
  25286. if (typeof value === 'object') {
  25287. return value.upper;
  25288. }
  25289. return value;
  25290. }
  25291. }
  25292. /**
  25293. * Emits an `ionChange` event.
  25294. *
  25295. * This API should be called for user committed changes.
  25296. * This API should not be used for external value changes.
  25297. */
  25298. emitValueChange() {
  25299. this.value = this.ensureValueInBounds(this.value);
  25300. this.ionChange.emit({ value: this.value });
  25301. }
  25302. /**
  25303. * The value should be updated on touch end or
  25304. * when the component is being dragged.
  25305. * This follows the native behavior of mobile devices.
  25306. *
  25307. * For example: When the user lifts their finger from the
  25308. * screen after tapping the bar or dragging the bar or knob.
  25309. */
  25310. onStart() {
  25311. this.ionKnobMoveStart.emit({ value: this.ensureValueInBounds(this.value) });
  25312. }
  25313. /**
  25314. * The value should be updated while dragging the
  25315. * bar or knob.
  25316. *
  25317. * While the user is dragging, the view
  25318. * should not scroll. This is to prevent the user from
  25319. * feeling disoriented while dragging.
  25320. *
  25321. * The user can scroll on the view if the knob or
  25322. * bar is not being dragged.
  25323. *
  25324. * @param detail The details of the gesture event.
  25325. */
  25326. onMove(detail) {
  25327. const { contentEl, pressedKnob } = this;
  25328. const currentX = detail.currentX;
  25329. /**
  25330. * Since the user is dragging on the bar or knob, the view should not scroll.
  25331. *
  25332. * This only needs to be done once.
  25333. */
  25334. if (contentEl && this.pressedKnob === undefined) {
  25335. this.initialContentScrollY = disableContentScrollY(contentEl);
  25336. }
  25337. /**
  25338. * The `pressedKnob` can be undefined if the user just
  25339. * started dragging the knob.
  25340. *
  25341. * This is necessary to determine which knob the user is dragging,
  25342. * especially when it's a dual knob.
  25343. * Plus, it determines when to apply certain styles.
  25344. *
  25345. * This only needs to be done once since the knob won't change
  25346. * while the user is dragging.
  25347. */
  25348. if (pressedKnob === undefined) {
  25349. this.setPressedKnob(currentX);
  25350. }
  25351. this.update(currentX);
  25352. }
  25353. /**
  25354. * The value should be updated on touch end:
  25355. * - When the user lifts their finger from the screen after
  25356. * tapping the bar.
  25357. *
  25358. * @param detail The details of the gesture or mouse event.
  25359. */
  25360. onEnd(detail) {
  25361. var _a;
  25362. const { contentEl, initialContentScrollY } = this;
  25363. const currentX = (_a = detail.currentX) !== null && _a !== void 0 ? _a : detail.clientX;
  25364. /**
  25365. * The `pressedKnob` can be undefined if the user never
  25366. * dragged the knob. They just tapped on the bar.
  25367. *
  25368. * This is necessary to determine which knob the user is changing,
  25369. * especially when it's a dual knob.
  25370. * Plus, it determines when to apply certain styles.
  25371. */
  25372. if (this.pressedKnob === undefined) {
  25373. this.setPressedKnob(currentX);
  25374. }
  25375. /**
  25376. * The user is no longer dragging the bar or
  25377. * knob (if they were dragging it).
  25378. *
  25379. * The user can now scroll on the view in the next gesture event.
  25380. */
  25381. if (contentEl && this.pressedKnob !== undefined) {
  25382. resetContentScrollY(contentEl, initialContentScrollY);
  25383. }
  25384. // update the active knob's position
  25385. this.update(currentX);
  25386. /**
  25387. * Reset the pressed knob to undefined since the user
  25388. * may start dragging a different knob in the next gesture event.
  25389. */
  25390. this.pressedKnob = undefined;
  25391. this.emitValueChange();
  25392. this.ionKnobMoveEnd.emit({ value: this.ensureValueInBounds(this.value) });
  25393. }
  25394. update(currentX) {
  25395. // figure out where the pointer is currently at
  25396. // update the knob being interacted with
  25397. const rect = this.rect;
  25398. let ratio = clamp(0, (currentX - rect.left) / rect.width, 1);
  25399. if (isRTL$1(this.el)) {
  25400. ratio = 1 - ratio;
  25401. }
  25402. if (this.snaps) {
  25403. // snaps the ratio to the current value
  25404. ratio = valueToRatio(ratioToValue(ratio, this.min, this.max, this.step), this.min, this.max);
  25405. }
  25406. // update which knob is pressed
  25407. if (this.pressedKnob === 'A') {
  25408. this.ratioA = ratio;
  25409. }
  25410. else {
  25411. this.ratioB = ratio;
  25412. }
  25413. // Update input value
  25414. this.updateValue();
  25415. }
  25416. setPressedKnob(currentX) {
  25417. const rect = (this.rect = this.rangeSlider.getBoundingClientRect());
  25418. // figure out which knob they started closer to
  25419. let ratio = clamp(0, (currentX - rect.left) / rect.width, 1);
  25420. if (isRTL$1(this.el)) {
  25421. ratio = 1 - ratio;
  25422. }
  25423. this.pressedKnob = !this.dualKnobs || Math.abs(this.ratioA - ratio) < Math.abs(this.ratioB - ratio) ? 'A' : 'B';
  25424. this.setFocus(this.pressedKnob);
  25425. }
  25426. get valA() {
  25427. return ratioToValue(this.ratioA, this.min, this.max, this.step);
  25428. }
  25429. get valB() {
  25430. return ratioToValue(this.ratioB, this.min, this.max, this.step);
  25431. }
  25432. get ratioLower() {
  25433. if (this.dualKnobs) {
  25434. return Math.min(this.ratioA, this.ratioB);
  25435. }
  25436. const { activeBarStart } = this;
  25437. if (activeBarStart == null) {
  25438. return 0;
  25439. }
  25440. return valueToRatio(activeBarStart, this.min, this.max);
  25441. }
  25442. get ratioUpper() {
  25443. if (this.dualKnobs) {
  25444. return Math.max(this.ratioA, this.ratioB);
  25445. }
  25446. return this.ratioA;
  25447. }
  25448. updateRatio() {
  25449. const value = this.getValue();
  25450. const { min, max } = this;
  25451. if (this.dualKnobs) {
  25452. this.ratioA = valueToRatio(value.lower, min, max);
  25453. this.ratioB = valueToRatio(value.upper, min, max);
  25454. }
  25455. else {
  25456. this.ratioA = valueToRatio(value, min, max);
  25457. }
  25458. }
  25459. updateValue() {
  25460. this.noUpdate = true;
  25461. const { valA, valB } = this;
  25462. this.value = !this.dualKnobs
  25463. ? valA
  25464. : {
  25465. lower: Math.min(valA, valB),
  25466. upper: Math.max(valA, valB),
  25467. };
  25468. this.noUpdate = false;
  25469. }
  25470. setFocus(knob) {
  25471. if (this.el.shadowRoot) {
  25472. const knobEl = this.el.shadowRoot.querySelector(knob === 'A' ? '.range-knob-a' : '.range-knob-b');
  25473. if (knobEl) {
  25474. knobEl.focus();
  25475. }
  25476. }
  25477. }
  25478. /**
  25479. * Returns true if content was passed to the "start" slot
  25480. */
  25481. get hasStartSlotContent() {
  25482. return this.el.querySelector('[slot="start"]') !== null;
  25483. }
  25484. /**
  25485. * Returns true if content was passed to the "end" slot
  25486. */
  25487. get hasEndSlotContent() {
  25488. return this.el.querySelector('[slot="end"]') !== null;
  25489. }
  25490. get hasLabel() {
  25491. return this.label !== undefined || this.el.querySelector('[slot="label"]') !== null;
  25492. }
  25493. renderRangeSlider() {
  25494. var _a;
  25495. const { min, max, step, handleKeyboard, pressedKnob, disabled, pin, ratioLower, ratioUpper, pinFormatter, inheritedAttributes, } = this;
  25496. let barStart = `${ratioLower * 100}%`;
  25497. let barEnd = `${100 - ratioUpper * 100}%`;
  25498. const rtl = isRTL$1(this.el);
  25499. const start = rtl ? 'right' : 'left';
  25500. const end = rtl ? 'left' : 'right';
  25501. const tickStyle = (tick) => {
  25502. return {
  25503. [start]: tick[start],
  25504. };
  25505. };
  25506. if (this.dualKnobs === false) {
  25507. /**
  25508. * When the value is less than the activeBarStart or the min value,
  25509. * the knob will display at the start of the active bar.
  25510. */
  25511. if (this.valA < ((_a = this.activeBarStart) !== null && _a !== void 0 ? _a : this.min)) {
  25512. /**
  25513. * Sets the bar positions relative to the upper and lower limits.
  25514. * Converts the ratio values into percentages, used as offsets for left/right styles.
  25515. *
  25516. * The ratioUpper refers to the knob position on the bar.
  25517. * The ratioLower refers to the end position of the active bar (the value).
  25518. */
  25519. barStart = `${ratioUpper * 100}%`;
  25520. barEnd = `${100 - ratioLower * 100}%`;
  25521. }
  25522. else {
  25523. /**
  25524. * Otherwise, the knob will display at the end of the active bar.
  25525. *
  25526. * The ratioLower refers to the start position of the active bar (the value).
  25527. * The ratioUpper refers to the knob position on the bar.
  25528. */
  25529. barStart = `${ratioLower * 100}%`;
  25530. barEnd = `${100 - ratioUpper * 100}%`;
  25531. }
  25532. }
  25533. const barStyle = {
  25534. [start]: barStart,
  25535. [end]: barEnd,
  25536. };
  25537. const ticks = [];
  25538. if (this.snaps && this.ticks) {
  25539. for (let value = min; value <= max; value += step) {
  25540. const ratio = valueToRatio(value, min, max);
  25541. const ratioMin = Math.min(ratioLower, ratioUpper);
  25542. const ratioMax = Math.max(ratioLower, ratioUpper);
  25543. const tick = {
  25544. ratio,
  25545. /**
  25546. * Sets the tick mark as active when the tick is between the min bounds and the knob.
  25547. * When using activeBarStart, the tick mark will be active between the knob and activeBarStart.
  25548. */
  25549. active: ratio >= ratioMin && ratio <= ratioMax,
  25550. };
  25551. tick[start] = `${ratio * 100}%`;
  25552. ticks.push(tick);
  25553. }
  25554. }
  25555. return (hAsync("div", { class: "range-slider", ref: (rangeEl) => (this.rangeSlider = rangeEl),
  25556. /**
  25557. * Since the gesture has a threshold, the value
  25558. * won't change until the user has dragged past
  25559. * the threshold. This is to prevent the range
  25560. * from moving when the user is scrolling.
  25561. *
  25562. * This results in the value not being updated
  25563. * and the event emitters not being triggered
  25564. * if the user taps on the range. This is why
  25565. * we need to listen for the "pointerUp" event.
  25566. */
  25567. onPointerUp: (ev) => {
  25568. /**
  25569. * If the user drags the knob on the web
  25570. * version (does not occur on mobile),
  25571. * the "pointerUp" event will be triggered
  25572. * along with the gesture's events.
  25573. * This leads to duplicate events.
  25574. *
  25575. * By checking if the pressedKnob is undefined,
  25576. * we can determine if the "pointerUp" event was
  25577. * triggered by a tap or a drag. If it was
  25578. * dragged, the pressedKnob will be defined.
  25579. */
  25580. if (this.pressedKnob === undefined) {
  25581. this.onStart();
  25582. this.onEnd(ev);
  25583. }
  25584. } }, ticks.map((tick) => (hAsync("div", { style: tickStyle(tick), role: "presentation", class: {
  25585. 'range-tick': true,
  25586. 'range-tick-active': tick.active,
  25587. }, part: tick.active ? 'tick-active' : 'tick' }))), hAsync("div", { class: "range-bar-container" }, hAsync("div", { class: "range-bar", role: "presentation", part: "bar" }), hAsync("div", { class: {
  25588. 'range-bar': true,
  25589. 'range-bar-active': true,
  25590. 'has-ticks': ticks.length > 0,
  25591. }, role: "presentation", style: barStyle, part: "bar-active" })), renderKnob(rtl, {
  25592. knob: 'A',
  25593. pressed: pressedKnob === 'A',
  25594. value: this.valA,
  25595. ratio: this.ratioA,
  25596. pin,
  25597. pinFormatter,
  25598. disabled,
  25599. handleKeyboard,
  25600. min,
  25601. max,
  25602. inheritedAttributes,
  25603. }), this.dualKnobs &&
  25604. renderKnob(rtl, {
  25605. knob: 'B',
  25606. pressed: pressedKnob === 'B',
  25607. value: this.valB,
  25608. ratio: this.ratioB,
  25609. pin,
  25610. pinFormatter,
  25611. disabled,
  25612. handleKeyboard,
  25613. min,
  25614. max,
  25615. inheritedAttributes,
  25616. })));
  25617. }
  25618. render() {
  25619. const { disabled, el, hasLabel, rangeId, pin, pressedKnob, labelPlacement, label } = this;
  25620. const inItem = hostContext('ion-item', el);
  25621. /**
  25622. * If there is no start content then the knob at
  25623. * the min value will be cut off by the item margin.
  25624. */
  25625. const hasStartContent = (hasLabel && (labelPlacement === 'start' || labelPlacement === 'fixed')) || this.hasStartSlotContent;
  25626. const needsStartAdjustment = inItem && !hasStartContent;
  25627. /**
  25628. * If there is no end content then the knob at
  25629. * the max value will be cut off by the item margin.
  25630. */
  25631. const hasEndContent = (hasLabel && labelPlacement === 'end') || this.hasEndSlotContent;
  25632. const needsEndAdjustment = inItem && !hasEndContent;
  25633. const mode = getIonMode$1(this);
  25634. renderHiddenInput(true, el, this.name, JSON.stringify(this.getValue()), disabled);
  25635. return (hAsync(Host, { key: '3e065039ee048f1f70d97dba5dae98fa1315d867', onFocusin: this.onFocus, onFocusout: this.onBlur, id: rangeId, class: createColorClasses$1(this.color, {
  25636. [mode]: true,
  25637. 'in-item': inItem,
  25638. 'range-disabled': disabled,
  25639. 'range-pressed': pressedKnob !== undefined,
  25640. 'range-has-pin': pin,
  25641. [`range-label-placement-${labelPlacement}`]: true,
  25642. 'range-item-start-adjustment': needsStartAdjustment,
  25643. 'range-item-end-adjustment': needsEndAdjustment,
  25644. }) }, hAsync("label", { key: '27ff22842c9ea79a1b9495302b926f70c9080a95', class: "range-wrapper", id: "range-label" }, hAsync("div", { key: 'da1f9784be02dfe87d2fef34931d8b7f2148189e', class: {
  25645. 'label-text-wrapper': true,
  25646. 'label-text-wrapper-hidden': !hasLabel,
  25647. }, part: "label" }, label !== undefined ? hAsync("div", { class: "label-text" }, label) : hAsync("slot", { name: "label" })), hAsync("div", { key: '4389bf30b08214f5b5917fc30976b38f7bcdd29b', class: "native-wrapper" }, hAsync("slot", { key: 'ad1b2745f8b061ee189617bb5c567e4f1d02250c', name: "start" }), this.renderRangeSlider(), hAsync("slot", { key: 'c6dec9e843e232af2a5f16a0f8ee56439c545d7a', name: "end" })))));
  25648. }
  25649. get el() { return getElement(this); }
  25650. static get watchers() { return {
  25651. "debounce": ["debounceChanged"],
  25652. "min": ["minChanged"],
  25653. "max": ["maxChanged"],
  25654. "step": ["stepChanged"],
  25655. "activeBarStart": ["activeBarStartChanged"],
  25656. "disabled": ["disabledChanged"],
  25657. "value": ["valueChanged"]
  25658. }; }
  25659. static get style() { return {
  25660. ios: IonRangeIosStyle0,
  25661. md: IonRangeMdStyle0
  25662. }; }
  25663. static get cmpMeta() { return {
  25664. "$flags$": 41,
  25665. "$tagName$": "ion-range",
  25666. "$members$": {
  25667. "color": [513],
  25668. "debounce": [2],
  25669. "name": [1],
  25670. "label": [1],
  25671. "dualKnobs": [4, "dual-knobs"],
  25672. "min": [2],
  25673. "max": [2],
  25674. "pin": [4],
  25675. "pinFormatter": [16],
  25676. "snaps": [4],
  25677. "step": [2],
  25678. "ticks": [4],
  25679. "activeBarStart": [1026, "active-bar-start"],
  25680. "disabled": [4],
  25681. "value": [1026],
  25682. "labelPlacement": [1, "label-placement"],
  25683. "ratioA": [32],
  25684. "ratioB": [32],
  25685. "pressedKnob": [32]
  25686. },
  25687. "$listeners$": undefined,
  25688. "$lazyBundleId$": "-",
  25689. "$attrsToReflect$": [["color", "color"]]
  25690. }; }
  25691. }
  25692. const renderKnob = (rtl, { knob, value, ratio, min, max, disabled, pressed, pin, handleKeyboard, pinFormatter, inheritedAttributes }) => {
  25693. const start = rtl ? 'right' : 'left';
  25694. const knobStyle = () => {
  25695. const style = {};
  25696. style[start] = `${ratio * 100}%`;
  25697. return style;
  25698. };
  25699. // The aria label should be preferred over visible text if both are specified
  25700. const ariaLabel = inheritedAttributes['aria-label'];
  25701. return (hAsync("div", { onKeyDown: (ev) => {
  25702. const key = ev.key;
  25703. if (key === 'ArrowLeft' || key === 'ArrowDown') {
  25704. handleKeyboard(knob, false);
  25705. ev.preventDefault();
  25706. ev.stopPropagation();
  25707. }
  25708. else if (key === 'ArrowRight' || key === 'ArrowUp') {
  25709. handleKeyboard(knob, true);
  25710. ev.preventDefault();
  25711. ev.stopPropagation();
  25712. }
  25713. }, class: {
  25714. 'range-knob-handle': true,
  25715. 'range-knob-a': knob === 'A',
  25716. 'range-knob-b': knob === 'B',
  25717. 'range-knob-pressed': pressed,
  25718. 'range-knob-min': value === min,
  25719. 'range-knob-max': value === max,
  25720. 'ion-activatable': true,
  25721. 'ion-focusable': true,
  25722. }, style: knobStyle(), role: "slider", tabindex: disabled ? -1 : 0, "aria-label": ariaLabel !== undefined ? ariaLabel : null, "aria-labelledby": ariaLabel === undefined ? 'range-label' : null, "aria-valuemin": min, "aria-valuemax": max, "aria-disabled": disabled ? 'true' : null, "aria-valuenow": value }, pin && (hAsync("div", { class: "range-pin", role: "presentation", part: "pin" }, pinFormatter(value))), hAsync("div", { class: "range-knob", role: "presentation", part: "knob" })));
  25723. };
  25724. const ratioToValue = (ratio, min, max, step) => {
  25725. let value = (max - min) * ratio;
  25726. if (step > 0) {
  25727. // round to nearest multiple of step, then add min
  25728. value = Math.round(value / step) * step + min;
  25729. }
  25730. const clampedValue = clamp(min, value, max);
  25731. return roundToMaxDecimalPlaces(clampedValue, min, max, step);
  25732. };
  25733. const valueToRatio = (value, min, max) => {
  25734. return clamp(0, (value - min) / (max - min), 1);
  25735. };
  25736. let rangeIds = 0;
  25737. const getRefresherAnimationType = (contentEl) => {
  25738. const previousSibling = contentEl.previousElementSibling;
  25739. const hasHeader = previousSibling !== null && previousSibling.tagName === 'ION-HEADER';
  25740. return hasHeader ? 'translate' : 'scale';
  25741. };
  25742. const createPullingAnimation = (type, pullingSpinner, refresherEl) => {
  25743. return type === 'scale'
  25744. ? createScaleAnimation(pullingSpinner, refresherEl)
  25745. : createTranslateAnimation(pullingSpinner, refresherEl);
  25746. };
  25747. const createBaseAnimation = (pullingRefresherIcon) => {
  25748. const spinner = pullingRefresherIcon.querySelector('ion-spinner');
  25749. const circle = spinner.shadowRoot.querySelector('circle');
  25750. const spinnerArrowContainer = pullingRefresherIcon.querySelector('.spinner-arrow-container');
  25751. const arrowContainer = pullingRefresherIcon.querySelector('.arrow-container');
  25752. const arrow = arrowContainer ? arrowContainer.querySelector('ion-icon') : null;
  25753. const baseAnimation = createAnimation().duration(1000).easing('ease-out');
  25754. const spinnerArrowContainerAnimation = createAnimation()
  25755. .addElement(spinnerArrowContainer)
  25756. .keyframes([
  25757. { offset: 0, opacity: '0.3' },
  25758. { offset: 0.45, opacity: '0.3' },
  25759. { offset: 0.55, opacity: '1' },
  25760. { offset: 1, opacity: '1' },
  25761. ]);
  25762. const circleInnerAnimation = createAnimation()
  25763. .addElement(circle)
  25764. .keyframes([
  25765. { offset: 0, strokeDasharray: '1px, 200px' },
  25766. { offset: 0.2, strokeDasharray: '1px, 200px' },
  25767. { offset: 0.55, strokeDasharray: '100px, 200px' },
  25768. { offset: 1, strokeDasharray: '100px, 200px' },
  25769. ]);
  25770. const circleOuterAnimation = createAnimation()
  25771. .addElement(spinner)
  25772. .keyframes([
  25773. { offset: 0, transform: 'rotate(-90deg)' },
  25774. { offset: 1, transform: 'rotate(210deg)' },
  25775. ]);
  25776. /**
  25777. * Only add arrow animation if present
  25778. * this allows users to customize the spinners
  25779. * without errors being thrown
  25780. */
  25781. if (arrowContainer && arrow) {
  25782. const arrowContainerAnimation = createAnimation()
  25783. .addElement(arrowContainer)
  25784. .keyframes([
  25785. { offset: 0, transform: 'rotate(0deg)' },
  25786. { offset: 0.3, transform: 'rotate(0deg)' },
  25787. { offset: 0.55, transform: 'rotate(280deg)' },
  25788. { offset: 1, transform: 'rotate(400deg)' },
  25789. ]);
  25790. const arrowAnimation = createAnimation()
  25791. .addElement(arrow)
  25792. .keyframes([
  25793. { offset: 0, transform: 'translateX(2px) scale(0)' },
  25794. { offset: 0.3, transform: 'translateX(2px) scale(0)' },
  25795. { offset: 0.55, transform: 'translateX(-1.5px) scale(1)' },
  25796. { offset: 1, transform: 'translateX(-1.5px) scale(1)' },
  25797. ]);
  25798. baseAnimation.addAnimation([arrowContainerAnimation, arrowAnimation]);
  25799. }
  25800. return baseAnimation.addAnimation([spinnerArrowContainerAnimation, circleInnerAnimation, circleOuterAnimation]);
  25801. };
  25802. const createScaleAnimation = (pullingRefresherIcon, refresherEl) => {
  25803. /**
  25804. * Do not take the height of the refresher icon
  25805. * because at this point the DOM has not updated,
  25806. * so the refresher icon is still hidden with
  25807. * display: none.
  25808. * The `ion-refresher` container height
  25809. * is roughly the amount we need to offset
  25810. * the icon by when pulling down.
  25811. */
  25812. const height = refresherEl.clientHeight;
  25813. const spinnerAnimation = createAnimation()
  25814. .addElement(pullingRefresherIcon)
  25815. .keyframes([
  25816. { offset: 0, transform: `scale(0) translateY(-${height}px)` },
  25817. { offset: 1, transform: 'scale(1) translateY(100px)' },
  25818. ]);
  25819. return createBaseAnimation(pullingRefresherIcon).addAnimation([spinnerAnimation]);
  25820. };
  25821. const createTranslateAnimation = (pullingRefresherIcon, refresherEl) => {
  25822. /**
  25823. * Do not take the height of the refresher icon
  25824. * because at this point the DOM has not updated,
  25825. * so the refresher icon is still hidden with
  25826. * display: none.
  25827. * The `ion-refresher` container height
  25828. * is roughly the amount we need to offset
  25829. * the icon by when pulling down.
  25830. */
  25831. const height = refresherEl.clientHeight;
  25832. const spinnerAnimation = createAnimation()
  25833. .addElement(pullingRefresherIcon)
  25834. .keyframes([
  25835. { offset: 0, transform: `translateY(-${height}px)` },
  25836. { offset: 1, transform: 'translateY(100px)' },
  25837. ]);
  25838. return createBaseAnimation(pullingRefresherIcon).addAnimation([spinnerAnimation]);
  25839. };
  25840. const createSnapBackAnimation = (pullingRefresherIcon) => {
  25841. return createAnimation()
  25842. .duration(125)
  25843. .addElement(pullingRefresherIcon)
  25844. .fromTo('transform', 'translateY(var(--ion-pulling-refresher-translate, 100px))', 'translateY(0px)');
  25845. };
  25846. // iOS Native Refresher
  25847. // -----------------------------
  25848. const setSpinnerOpacity = (spinner, opacity) => {
  25849. spinner.style.setProperty('opacity', opacity.toString());
  25850. };
  25851. const handleScrollWhilePulling = (ticks, numTicks, pullAmount) => {
  25852. const max = 1;
  25853. writeTask(() => {
  25854. ticks.forEach((el, i) => {
  25855. /**
  25856. * Compute the opacity of each tick
  25857. * mark as a percentage of the pullAmount
  25858. * offset by max / numTicks so
  25859. * the tick marks are shown staggered.
  25860. */
  25861. const min = i * (max / numTicks);
  25862. const range = max - min;
  25863. const start = pullAmount - min;
  25864. const progression = clamp(0, start / range, 1);
  25865. el.style.setProperty('opacity', progression.toString());
  25866. });
  25867. });
  25868. };
  25869. const handleScrollWhileRefreshing = (spinner, lastVelocityY) => {
  25870. writeTask(() => {
  25871. // If user pulls down quickly, the spinner should spin faster
  25872. spinner.style.setProperty('--refreshing-rotation-duration', lastVelocityY >= 1.0 ? '0.5s' : '2s');
  25873. spinner.style.setProperty('opacity', '1');
  25874. });
  25875. };
  25876. const translateElement = (el, value, duration = 200) => {
  25877. if (!el) {
  25878. return Promise.resolve();
  25879. }
  25880. const trans = transitionEndAsync(el, duration);
  25881. writeTask(() => {
  25882. el.style.setProperty('transition', `${duration}ms all ease-out`);
  25883. if (value === undefined) {
  25884. el.style.removeProperty('transform');
  25885. }
  25886. else {
  25887. el.style.setProperty('transform', `translate3d(0px, ${value}, 0px)`);
  25888. }
  25889. });
  25890. return trans;
  25891. };
  25892. // Utils
  25893. // -----------------------------
  25894. /**
  25895. * In order to use the native iOS refresher the device must support rubber band scrolling.
  25896. * As part of this, we need to exclude Desktop Safari because it has a slightly different rubber band effect that is not compatible with the native refresher in Ionic.
  25897. *
  25898. * We also need to be careful not to include devices that spoof their user agent.
  25899. * For example, when using iOS emulation in Chrome the user agent will be spoofed such that
  25900. * navigator.maxTouchPointer > 0. To work around this,
  25901. * we check to see if the apple-pay-logo is supported as a named image which is only
  25902. * true on Apple devices.
  25903. *
  25904. * We previously checked referencEl.style.webkitOverflowScrolling to explicitly check
  25905. * for rubber band support. However, this property was removed on iPadOS and it's possible
  25906. * that this will be removed on iOS in the future too.
  25907. *
  25908. */
  25909. const supportsRubberBandScrolling = () => {
  25910. return navigator.maxTouchPoints > 0 && CSS.supports('background: -webkit-named-image(apple-pay-logo-black)');
  25911. };
  25912. const shouldUseNativeRefresher = async (referenceEl, mode) => {
  25913. const refresherContent = referenceEl.querySelector('ion-refresher-content');
  25914. if (!refresherContent) {
  25915. return Promise.resolve(false);
  25916. }
  25917. await new Promise((resolve) => componentOnReady(refresherContent, resolve));
  25918. const pullingSpinner = referenceEl.querySelector('ion-refresher-content .refresher-pulling ion-spinner');
  25919. const refreshingSpinner = referenceEl.querySelector('ion-refresher-content .refresher-refreshing ion-spinner');
  25920. return (pullingSpinner !== null &&
  25921. refreshingSpinner !== null &&
  25922. ((mode === 'ios' && supportsRubberBandScrolling()) || mode === 'md'));
  25923. };
  25924. const refresherIosCss = "ion-refresher{top:0;display:none;position:absolute;width:100%;height:60px;pointer-events:none;z-index:-1}ion-refresher{inset-inline-start:0}ion-refresher.refresher-active{display:block}ion-refresher-content{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;-ms-flex-pack:center;justify-content:center;height:100%}.refresher-pulling,.refresher-refreshing{display:none;width:100%}.refresher-pulling-icon,.refresher-refreshing-icon{-webkit-transform-origin:center;transform-origin:center;-webkit-transition:200ms;transition:200ms;font-size:30px;text-align:center}:host-context([dir=rtl]) .refresher-pulling-icon,:host-context([dir=rtl]) .refresher-refreshing-icon{-webkit-transform-origin:calc(100% - center);transform-origin:calc(100% - center)}[dir=rtl] .refresher-pulling-icon,[dir=rtl] .refresher-refreshing-icon{-webkit-transform-origin:calc(100% - center);transform-origin:calc(100% - center)}@supports selector(:dir(rtl)){.refresher-pulling-icon:dir(rtl),.refresher-refreshing-icon:dir(rtl){-webkit-transform-origin:calc(100% - center);transform-origin:calc(100% - center)}}.refresher-pulling-text,.refresher-refreshing-text{font-size:16px;text-align:center}ion-refresher-content .arrow-container{display:none}.refresher-pulling ion-refresher-content .refresher-pulling{display:block}.refresher-ready ion-refresher-content .refresher-pulling{display:block}.refresher-ready ion-refresher-content .refresher-pulling-icon{-webkit-transform:rotate(180deg);transform:rotate(180deg)}.refresher-refreshing ion-refresher-content .refresher-refreshing{display:block}.refresher-cancelling ion-refresher-content .refresher-pulling{display:block}.refresher-cancelling ion-refresher-content .refresher-pulling-icon{-webkit-transform:scale(0);transform:scale(0)}.refresher-completing ion-refresher-content .refresher-refreshing{display:block}.refresher-completing ion-refresher-content .refresher-refreshing-icon{-webkit-transform:scale(0);transform:scale(0)}.refresher-native .refresher-pulling-text,.refresher-native .refresher-refreshing-text{display:none}.refresher-ios .refresher-pulling-icon,.refresher-ios .refresher-refreshing-icon{color:var(--ion-text-color, #000)}.refresher-ios .refresher-pulling-text,.refresher-ios .refresher-refreshing-text{color:var(--ion-text-color, #000)}.refresher-ios .refresher-refreshing .spinner-lines-ios line,.refresher-ios .refresher-refreshing .spinner-lines-small-ios line,.refresher-ios .refresher-refreshing .spinner-crescent circle{stroke:var(--ion-text-color, #000)}.refresher-ios .refresher-refreshing .spinner-bubbles circle,.refresher-ios .refresher-refreshing .spinner-circles circle,.refresher-ios .refresher-refreshing .spinner-dots circle{fill:var(--ion-text-color, #000)}ion-refresher.refresher-native{display:block;z-index:1}ion-refresher.refresher-native ion-spinner{-webkit-margin-start:auto;margin-inline-start:auto;-webkit-margin-end:auto;margin-inline-end:auto;margin-top:0;margin-bottom:0}.refresher-native .refresher-refreshing ion-spinner{--refreshing-rotation-duration:2s;display:none;-webkit-animation:var(--refreshing-rotation-duration) ease-out refresher-rotate forwards;animation:var(--refreshing-rotation-duration) ease-out refresher-rotate forwards}.refresher-native .refresher-refreshing{display:none;-webkit-animation:250ms linear refresher-pop forwards;animation:250ms linear refresher-pop forwards}.refresher-native ion-spinner{width:32px;height:32px;color:var(--ion-color-step-450, var(--ion-background-color-step-450, #747577))}.refresher-native.refresher-refreshing .refresher-pulling ion-spinner,.refresher-native.refresher-completing .refresher-pulling ion-spinner{display:none}.refresher-native.refresher-refreshing .refresher-refreshing ion-spinner,.refresher-native.refresher-completing .refresher-refreshing ion-spinner{display:block}.refresher-native.refresher-pulling .refresher-pulling ion-spinner{display:block}.refresher-native.refresher-pulling .refresher-refreshing ion-spinner{display:none}.refresher-native.refresher-completing ion-refresher-content .refresher-refreshing-icon{-webkit-transform:scale(0) rotate(180deg);transform:scale(0) rotate(180deg);-webkit-transition:300ms;transition:300ms}@-webkit-keyframes refresher-pop{0%{-webkit-transform:scale(1);transform:scale(1);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}50%{-webkit-transform:scale(1.2);transform:scale(1.2);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}100%{-webkit-transform:scale(1);transform:scale(1)}}@keyframes refresher-pop{0%{-webkit-transform:scale(1);transform:scale(1);-webkit-animation-timing-function:ease-in;animation-timing-function:ease-in}50%{-webkit-transform:scale(1.2);transform:scale(1.2);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}100%{-webkit-transform:scale(1);transform:scale(1)}}@-webkit-keyframes refresher-rotate{from{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(180deg);transform:rotate(180deg)}}@keyframes refresher-rotate{from{-webkit-transform:rotate(0deg);transform:rotate(0deg)}to{-webkit-transform:rotate(180deg);transform:rotate(180deg)}}";
  25925. var IonRefresherIosStyle0 = refresherIosCss;
  25926. const refresherMdCss = "ion-refresher{top:0;display:none;position:absolute;width:100%;height:60px;pointer-events:none;z-index:-1}ion-refresher{inset-inline-start:0}ion-refresher.refresher-active{display:block}ion-refresher-content{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;-ms-flex-pack:center;justify-content:center;height:100%}.refresher-pulling,.refresher-refreshing{display:none;width:100%}.refresher-pulling-icon,.refresher-refreshing-icon{-webkit-transform-origin:center;transform-origin:center;-webkit-transition:200ms;transition:200ms;font-size:30px;text-align:center}:host-context([dir=rtl]) .refresher-pulling-icon,:host-context([dir=rtl]) .refresher-refreshing-icon{-webkit-transform-origin:calc(100% - center);transform-origin:calc(100% - center)}[dir=rtl] .refresher-pulling-icon,[dir=rtl] .refresher-refreshing-icon{-webkit-transform-origin:calc(100% - center);transform-origin:calc(100% - center)}@supports selector(:dir(rtl)){.refresher-pulling-icon:dir(rtl),.refresher-refreshing-icon:dir(rtl){-webkit-transform-origin:calc(100% - center);transform-origin:calc(100% - center)}}.refresher-pulling-text,.refresher-refreshing-text{font-size:16px;text-align:center}ion-refresher-content .arrow-container{display:none}.refresher-pulling ion-refresher-content .refresher-pulling{display:block}.refresher-ready ion-refresher-content .refresher-pulling{display:block}.refresher-ready ion-refresher-content .refresher-pulling-icon{-webkit-transform:rotate(180deg);transform:rotate(180deg)}.refresher-refreshing ion-refresher-content .refresher-refreshing{display:block}.refresher-cancelling ion-refresher-content .refresher-pulling{display:block}.refresher-cancelling ion-refresher-content .refresher-pulling-icon{-webkit-transform:scale(0);transform:scale(0)}.refresher-completing ion-refresher-content .refresher-refreshing{display:block}.refresher-completing ion-refresher-content .refresher-refreshing-icon{-webkit-transform:scale(0);transform:scale(0)}.refresher-native .refresher-pulling-text,.refresher-native .refresher-refreshing-text{display:none}.refresher-md .refresher-pulling-icon,.refresher-md .refresher-refreshing-icon{color:var(--ion-text-color, #000)}.refresher-md .refresher-pulling-text,.refresher-md .refresher-refreshing-text{color:var(--ion-text-color, #000)}.refresher-md .refresher-refreshing .spinner-lines-md line,.refresher-md .refresher-refreshing .spinner-lines-small-md line,.refresher-md .refresher-refreshing .spinner-crescent circle{stroke:var(--ion-text-color, #000)}.refresher-md .refresher-refreshing .spinner-bubbles circle,.refresher-md .refresher-refreshing .spinner-circles circle,.refresher-md .refresher-refreshing .spinner-dots circle{fill:var(--ion-text-color, #000)}ion-refresher.refresher-native{display:block;z-index:1}ion-refresher.refresher-native ion-spinner{-webkit-margin-start:auto;margin-inline-start:auto;-webkit-margin-end:auto;margin-inline-end:auto;margin-top:0;margin-bottom:0;width:24px;height:24px;color:var(--ion-color-primary, #0054e9)}ion-refresher.refresher-native .spinner-arrow-container{display:inherit}ion-refresher.refresher-native .arrow-container{display:block;position:absolute;width:24px;height:24px}ion-refresher.refresher-native .arrow-container ion-icon{-webkit-margin-start:auto;margin-inline-start:auto;-webkit-margin-end:auto;margin-inline-end:auto;margin-top:0;margin-bottom:0;left:0;right:0;bottom:-4px;position:absolute;color:var(--ion-color-primary, #0054e9);font-size:12px}ion-refresher.refresher-native.refresher-pulling ion-refresher-content .refresher-pulling,ion-refresher.refresher-native.refresher-ready ion-refresher-content .refresher-pulling{display:-ms-flexbox;display:flex}ion-refresher.refresher-native.refresher-refreshing ion-refresher-content .refresher-refreshing,ion-refresher.refresher-native.refresher-completing ion-refresher-content .refresher-refreshing,ion-refresher.refresher-native.refresher-cancelling ion-refresher-content .refresher-refreshing{display:-ms-flexbox;display:flex}ion-refresher.refresher-native .refresher-pulling-icon{-webkit-transform:translateY(calc(-100% - 10px));transform:translateY(calc(-100% - 10px))}ion-refresher.refresher-native .refresher-pulling-icon,ion-refresher.refresher-native .refresher-refreshing-icon{-webkit-margin-start:auto;margin-inline-start:auto;-webkit-margin-end:auto;margin-inline-end:auto;margin-top:0;margin-bottom:0;border-radius:100%;-webkit-padding-start:8px;padding-inline-start:8px;-webkit-padding-end:8px;padding-inline-end:8px;padding-top:8px;padding-bottom:8px;display:-ms-flexbox;display:flex;border:1px solid var(--ion-color-step-200, var(--ion-background-color-step-200, #ececec));background:var(--ion-color-step-250, var(--ion-background-color-step-250, #ffffff));-webkit-box-shadow:0px 1px 6px rgba(0, 0, 0, 0.1);box-shadow:0px 1px 6px rgba(0, 0, 0, 0.1)}";
  25927. var IonRefresherMdStyle0 = refresherMdCss;
  25928. /**
  25929. * @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
  25930. */
  25931. class Refresher {
  25932. constructor(hostRef) {
  25933. registerInstance(this, hostRef);
  25934. this.ionRefresh = createEvent(this, "ionRefresh", 7);
  25935. this.ionPull = createEvent(this, "ionPull", 7);
  25936. this.ionStart = createEvent(this, "ionStart", 7);
  25937. this.appliedStyles = false;
  25938. this.didStart = false;
  25939. this.progress = 0;
  25940. this.pointerDown = false;
  25941. this.needsCompletion = false;
  25942. this.didRefresh = false;
  25943. this.contentFullscreen = false;
  25944. this.lastVelocityY = 0;
  25945. this.animations = [];
  25946. this.nativeRefresher = false;
  25947. this.state = 1 /* RefresherState.Inactive */;
  25948. this.pullMin = 60;
  25949. this.pullMax = this.pullMin + 60;
  25950. this.closeDuration = '280ms';
  25951. this.snapbackDuration = '280ms';
  25952. this.pullFactor = 1;
  25953. this.disabled = false;
  25954. }
  25955. disabledChanged() {
  25956. if (this.gesture) {
  25957. this.gesture.enable(!this.disabled);
  25958. }
  25959. }
  25960. async checkNativeRefresher() {
  25961. const useNativeRefresher = await shouldUseNativeRefresher(this.el, getIonMode$1(this));
  25962. if (useNativeRefresher && !this.nativeRefresher) {
  25963. const contentEl = this.el.closest('ion-content');
  25964. this.setupNativeRefresher(contentEl);
  25965. }
  25966. else if (!useNativeRefresher) {
  25967. this.destroyNativeRefresher();
  25968. }
  25969. }
  25970. destroyNativeRefresher() {
  25971. if (this.scrollEl && this.scrollListenerCallback) {
  25972. this.scrollEl.removeEventListener('scroll', this.scrollListenerCallback);
  25973. this.scrollListenerCallback = undefined;
  25974. }
  25975. this.nativeRefresher = false;
  25976. }
  25977. async resetNativeRefresher(el, state) {
  25978. this.state = state;
  25979. if (getIonMode$1(this) === 'ios') {
  25980. await translateElement(el, undefined, 300);
  25981. }
  25982. else {
  25983. await transitionEndAsync(this.el.querySelector('.refresher-refreshing-icon'), 200);
  25984. }
  25985. this.didRefresh = false;
  25986. this.needsCompletion = false;
  25987. this.pointerDown = false;
  25988. this.animations.forEach((ani) => ani.destroy());
  25989. this.animations = [];
  25990. this.progress = 0;
  25991. this.state = 1 /* RefresherState.Inactive */;
  25992. }
  25993. async setupiOSNativeRefresher(pullingSpinner, refreshingSpinner) {
  25994. this.elementToTransform = this.scrollEl;
  25995. const ticks = pullingSpinner.shadowRoot.querySelectorAll('svg');
  25996. let MAX_PULL = this.scrollEl.clientHeight * 0.16;
  25997. const NUM_TICKS = ticks.length;
  25998. writeTask(() => ticks.forEach((el) => el.style.setProperty('animation', 'none')));
  25999. this.scrollListenerCallback = () => {
  26000. // If pointer is not on screen or refresher is not active, ignore scroll
  26001. if (!this.pointerDown && this.state === 1 /* RefresherState.Inactive */) {
  26002. return;
  26003. }
  26004. readTask(() => {
  26005. // PTR should only be active when overflow scrolling at the top
  26006. const scrollTop = this.scrollEl.scrollTop;
  26007. const refresherHeight = this.el.clientHeight;
  26008. if (scrollTop > 0) {
  26009. /**
  26010. * If refresher is refreshing and user tries to scroll
  26011. * progressively fade refresher out/in
  26012. */
  26013. if (this.state === 8 /* RefresherState.Refreshing */) {
  26014. const ratio = clamp(0, scrollTop / (refresherHeight * 0.5), 1);
  26015. writeTask(() => setSpinnerOpacity(refreshingSpinner, 1 - ratio));
  26016. return;
  26017. }
  26018. return;
  26019. }
  26020. if (this.pointerDown) {
  26021. if (!this.didStart) {
  26022. this.didStart = true;
  26023. this.ionStart.emit();
  26024. }
  26025. // emit "pulling" on every move
  26026. if (this.pointerDown) {
  26027. this.ionPull.emit();
  26028. }
  26029. }
  26030. /**
  26031. * We want to delay the start of this gesture by ~30px
  26032. * when initially pulling down so the refresher does not
  26033. * overlap with the content. But when letting go of the
  26034. * gesture before the refresher completes, we want the
  26035. * refresher tick marks to quickly fade out.
  26036. */
  26037. const offset = this.didStart ? 30 : 0;
  26038. const pullAmount = (this.progress = clamp(0, (Math.abs(scrollTop) - offset) / MAX_PULL, 1));
  26039. const shouldShowRefreshingSpinner = this.state === 8 /* RefresherState.Refreshing */ || pullAmount === 1;
  26040. if (shouldShowRefreshingSpinner) {
  26041. if (this.pointerDown) {
  26042. handleScrollWhileRefreshing(refreshingSpinner, this.lastVelocityY);
  26043. }
  26044. if (!this.didRefresh) {
  26045. this.beginRefresh();
  26046. this.didRefresh = true;
  26047. hapticImpact({ style: ImpactStyle.Light });
  26048. /**
  26049. * Translate the content element otherwise when pointer is removed
  26050. * from screen the scroll content will bounce back over the refresher
  26051. */
  26052. if (!this.pointerDown) {
  26053. translateElement(this.elementToTransform, `${refresherHeight}px`);
  26054. }
  26055. }
  26056. }
  26057. else {
  26058. this.state = 2 /* RefresherState.Pulling */;
  26059. handleScrollWhilePulling(ticks, NUM_TICKS, pullAmount);
  26060. }
  26061. });
  26062. };
  26063. this.scrollEl.addEventListener('scroll', this.scrollListenerCallback);
  26064. this.gesture = (await Promise.resolve().then(function () { return index; })).createGesture({
  26065. el: this.scrollEl,
  26066. gestureName: 'refresher',
  26067. gesturePriority: 31,
  26068. direction: 'y',
  26069. threshold: 5,
  26070. onStart: () => {
  26071. this.pointerDown = true;
  26072. if (!this.didRefresh) {
  26073. translateElement(this.elementToTransform, '0px');
  26074. }
  26075. /**
  26076. * If the content had `display: none` when
  26077. * the refresher was initialized, its clientHeight
  26078. * will be 0. When the gesture starts, the content
  26079. * will be visible, so try to get the correct
  26080. * client height again. This is most common when
  26081. * using the refresher in an ion-menu.
  26082. */
  26083. if (MAX_PULL === 0) {
  26084. MAX_PULL = this.scrollEl.clientHeight * 0.16;
  26085. }
  26086. },
  26087. onMove: (ev) => {
  26088. this.lastVelocityY = ev.velocityY;
  26089. },
  26090. onEnd: () => {
  26091. this.pointerDown = false;
  26092. this.didStart = false;
  26093. if (this.needsCompletion) {
  26094. this.resetNativeRefresher(this.elementToTransform, 32 /* RefresherState.Completing */);
  26095. this.needsCompletion = false;
  26096. }
  26097. else if (this.didRefresh) {
  26098. readTask(() => translateElement(this.elementToTransform, `${this.el.clientHeight}px`));
  26099. }
  26100. },
  26101. });
  26102. this.disabledChanged();
  26103. }
  26104. async setupMDNativeRefresher(contentEl, pullingSpinner, refreshingSpinner) {
  26105. const circle = getElementRoot(pullingSpinner).querySelector('circle');
  26106. const pullingRefresherIcon = this.el.querySelector('ion-refresher-content .refresher-pulling-icon');
  26107. const refreshingCircle = getElementRoot(refreshingSpinner).querySelector('circle');
  26108. if (circle !== null && refreshingCircle !== null) {
  26109. writeTask(() => {
  26110. circle.style.setProperty('animation', 'none');
  26111. // This lines up the animation on the refreshing spinner with the pulling spinner
  26112. refreshingSpinner.style.setProperty('animation-delay', '-655ms');
  26113. refreshingCircle.style.setProperty('animation-delay', '-655ms');
  26114. });
  26115. }
  26116. this.gesture = (await Promise.resolve().then(function () { return index; })).createGesture({
  26117. el: this.scrollEl,
  26118. gestureName: 'refresher',
  26119. gesturePriority: 31,
  26120. direction: 'y',
  26121. threshold: 5,
  26122. canStart: () => this.state !== 8 /* RefresherState.Refreshing */ &&
  26123. this.state !== 32 /* RefresherState.Completing */ &&
  26124. this.scrollEl.scrollTop === 0,
  26125. onStart: (ev) => {
  26126. this.progress = 0;
  26127. ev.data = { animation: undefined, didStart: false, cancelled: false };
  26128. },
  26129. onMove: (ev) => {
  26130. if ((ev.velocityY < 0 && this.progress === 0 && !ev.data.didStart) || ev.data.cancelled) {
  26131. ev.data.cancelled = true;
  26132. return;
  26133. }
  26134. if (!ev.data.didStart) {
  26135. ev.data.didStart = true;
  26136. this.state = 2 /* RefresherState.Pulling */;
  26137. // When ion-refresher is being used with a custom scroll target, the overflow styles need to be applied directly instead of via a css variable
  26138. const { scrollEl } = this;
  26139. const overflowProperty = scrollEl.matches(ION_CONTENT_CLASS_SELECTOR) ? 'overflow' : '--overflow';
  26140. writeTask(() => scrollEl.style.setProperty(overflowProperty, 'hidden'));
  26141. const animationType = getRefresherAnimationType(contentEl);
  26142. const animation = createPullingAnimation(animationType, pullingRefresherIcon, this.el);
  26143. ev.data.animation = animation;
  26144. animation.progressStart(false, 0);
  26145. this.ionStart.emit();
  26146. this.animations.push(animation);
  26147. return;
  26148. }
  26149. // Since we are using an easing curve, slow the gesture tracking down a bit
  26150. this.progress = clamp(0, (ev.deltaY / 180) * 0.5, 1);
  26151. ev.data.animation.progressStep(this.progress);
  26152. this.ionPull.emit();
  26153. },
  26154. onEnd: (ev) => {
  26155. if (!ev.data.didStart) {
  26156. return;
  26157. }
  26158. this.gesture.enable(false);
  26159. const { scrollEl } = this;
  26160. const overflowProperty = scrollEl.matches(ION_CONTENT_CLASS_SELECTOR) ? 'overflow' : '--overflow';
  26161. writeTask(() => scrollEl.style.removeProperty(overflowProperty));
  26162. if (this.progress <= 0.4) {
  26163. ev.data.animation.progressEnd(0, this.progress, 500).onFinish(() => {
  26164. this.animations.forEach((ani) => ani.destroy());
  26165. this.animations = [];
  26166. this.gesture.enable(true);
  26167. this.state = 1 /* RefresherState.Inactive */;
  26168. });
  26169. return;
  26170. }
  26171. const progress = getTimeGivenProgression([0, 0], [0, 0], [1, 1], [1, 1], this.progress)[0];
  26172. const snapBackAnimation = createSnapBackAnimation(pullingRefresherIcon);
  26173. this.animations.push(snapBackAnimation);
  26174. writeTask(async () => {
  26175. pullingRefresherIcon.style.setProperty('--ion-pulling-refresher-translate', `${progress * 100}px`);
  26176. ev.data.animation.progressEnd();
  26177. await snapBackAnimation.play();
  26178. this.beginRefresh();
  26179. ev.data.animation.destroy();
  26180. this.gesture.enable(true);
  26181. });
  26182. },
  26183. });
  26184. this.disabledChanged();
  26185. }
  26186. async setupNativeRefresher(contentEl) {
  26187. if (this.scrollListenerCallback || !contentEl || this.nativeRefresher || !this.scrollEl) {
  26188. return;
  26189. }
  26190. /**
  26191. * If using non-native refresher before make sure
  26192. * we clean up any old CSS. This can happen when
  26193. * a user manually calls the refresh method in a
  26194. * component create callback before the native
  26195. * refresher is setup.
  26196. */
  26197. this.setCss(0, '', false, '');
  26198. this.nativeRefresher = true;
  26199. const pullingSpinner = this.el.querySelector('ion-refresher-content .refresher-pulling ion-spinner');
  26200. const refreshingSpinner = this.el.querySelector('ion-refresher-content .refresher-refreshing ion-spinner');
  26201. if (getIonMode$1(this) === 'ios') {
  26202. this.setupiOSNativeRefresher(pullingSpinner, refreshingSpinner);
  26203. }
  26204. else {
  26205. this.setupMDNativeRefresher(contentEl, pullingSpinner, refreshingSpinner);
  26206. }
  26207. }
  26208. componentDidUpdate() {
  26209. this.checkNativeRefresher();
  26210. }
  26211. async connectedCallback() {
  26212. if (this.el.getAttribute('slot') !== 'fixed') {
  26213. printIonError('[ion-refresher] - Make sure you use: <ion-refresher slot="fixed">');
  26214. return;
  26215. }
  26216. const contentEl = this.el.closest(ION_CONTENT_ELEMENT_SELECTOR);
  26217. if (!contentEl) {
  26218. printIonContentErrorMsg(this.el);
  26219. return;
  26220. }
  26221. /**
  26222. * Waits for the content to be ready before querying the scroll
  26223. * or the background content element.
  26224. */
  26225. componentOnReady(contentEl, async () => {
  26226. const customScrollTarget = contentEl.querySelector(ION_CONTENT_CLASS_SELECTOR);
  26227. /**
  26228. * Query the custom scroll target (if available), first. In refresher implementations,
  26229. * the ion-refresher element will always be a direct child of ion-content (slot="fixed"). By
  26230. * querying the custom scroll target first and falling back to the ion-content element,
  26231. * the correct scroll element will be returned by the implementation.
  26232. */
  26233. this.scrollEl = await getScrollElement(customScrollTarget !== null && customScrollTarget !== void 0 ? customScrollTarget : contentEl);
  26234. /**
  26235. * Query the background content element from the host ion-content element directly.
  26236. */
  26237. this.backgroundContentEl = await contentEl.getBackgroundElement();
  26238. /**
  26239. * Check if the content element is fullscreen to apply the correct styles
  26240. * when the refresher is refreshing. Otherwise, the refresher will be
  26241. * hidden because it is positioned behind the background content element.
  26242. */
  26243. this.contentFullscreen = contentEl.fullscreen;
  26244. if (await shouldUseNativeRefresher(this.el, getIonMode$1(this))) {
  26245. this.setupNativeRefresher(contentEl);
  26246. }
  26247. else {
  26248. this.gesture = (await Promise.resolve().then(function () { return index; })).createGesture({
  26249. el: contentEl,
  26250. gestureName: 'refresher',
  26251. gesturePriority: 31,
  26252. direction: 'y',
  26253. threshold: 20,
  26254. passive: false,
  26255. canStart: () => this.canStart(),
  26256. onStart: () => this.onStart(),
  26257. onMove: (ev) => this.onMove(ev),
  26258. onEnd: () => this.onEnd(),
  26259. });
  26260. this.disabledChanged();
  26261. }
  26262. });
  26263. }
  26264. disconnectedCallback() {
  26265. this.destroyNativeRefresher();
  26266. this.scrollEl = undefined;
  26267. if (this.gesture) {
  26268. this.gesture.destroy();
  26269. this.gesture = undefined;
  26270. }
  26271. }
  26272. /**
  26273. * Call `complete()` when your async operation has completed.
  26274. * For example, the `refreshing` state is while the app is performing
  26275. * an asynchronous operation, such as receiving more data from an
  26276. * AJAX request. Once the data has been received, you then call this
  26277. * method to signify that the refreshing has completed and to close
  26278. * the refresher. This method also changes the refresher's state from
  26279. * `refreshing` to `completing`.
  26280. */
  26281. async complete() {
  26282. if (this.nativeRefresher) {
  26283. this.needsCompletion = true;
  26284. // Do not reset scroll el until user removes pointer from screen
  26285. if (!this.pointerDown) {
  26286. raf(() => raf(() => this.resetNativeRefresher(this.elementToTransform, 32 /* RefresherState.Completing */)));
  26287. }
  26288. }
  26289. else {
  26290. this.close(32 /* RefresherState.Completing */, '120ms');
  26291. }
  26292. }
  26293. /**
  26294. * Changes the refresher's state from `refreshing` to `cancelling`.
  26295. */
  26296. async cancel() {
  26297. if (this.nativeRefresher) {
  26298. // Do not reset scroll el until user removes pointer from screen
  26299. if (!this.pointerDown) {
  26300. raf(() => raf(() => this.resetNativeRefresher(this.elementToTransform, 16 /* RefresherState.Cancelling */)));
  26301. }
  26302. }
  26303. else {
  26304. this.close(16 /* RefresherState.Cancelling */, '');
  26305. }
  26306. }
  26307. /**
  26308. * A number representing how far down the user has pulled.
  26309. * The number `0` represents the user hasn't pulled down at all. The
  26310. * number `1`, and anything greater than `1`, represents that the user
  26311. * has pulled far enough down that when they let go then the refresh will
  26312. * happen. If they let go and the number is less than `1`, then the
  26313. * refresh will not happen, and the content will return to it's original
  26314. * position.
  26315. */
  26316. getProgress() {
  26317. return Promise.resolve(this.progress);
  26318. }
  26319. canStart() {
  26320. if (!this.scrollEl) {
  26321. return false;
  26322. }
  26323. if (this.state !== 1 /* RefresherState.Inactive */) {
  26324. return false;
  26325. }
  26326. // if the scrollTop is greater than zero then it's
  26327. // not possible to pull the content down yet
  26328. if (this.scrollEl.scrollTop > 0) {
  26329. return false;
  26330. }
  26331. return true;
  26332. }
  26333. onStart() {
  26334. this.progress = 0;
  26335. this.state = 1 /* RefresherState.Inactive */;
  26336. this.memoizeOverflowStyle();
  26337. /**
  26338. * If the content is fullscreen, then we need to
  26339. * set the offset-top style on the background content
  26340. * element to ensure that the refresher is shown.
  26341. */
  26342. if (this.contentFullscreen && this.backgroundContentEl) {
  26343. this.backgroundContentEl.style.setProperty('--offset-top', '0px');
  26344. }
  26345. }
  26346. onMove(detail) {
  26347. if (!this.scrollEl) {
  26348. return;
  26349. }
  26350. // this method can get called like a bazillion times per second,
  26351. // so it's built to be as efficient as possible, and does its
  26352. // best to do any DOM read/writes only when absolutely necessary
  26353. // if multi-touch then get out immediately
  26354. const ev = detail.event;
  26355. if (ev.touches !== undefined && ev.touches.length > 1) {
  26356. return;
  26357. }
  26358. // do nothing if it's actively refreshing
  26359. // or it's in the way of closing
  26360. // or this was never a startY
  26361. if ((this.state & 56 /* RefresherState._BUSY_ */) !== 0) {
  26362. return;
  26363. }
  26364. const pullFactor = Number.isNaN(this.pullFactor) || this.pullFactor < 0 ? 1 : this.pullFactor;
  26365. const deltaY = detail.deltaY * pullFactor;
  26366. // don't bother if they're scrolling up
  26367. // and have not already started dragging
  26368. if (deltaY <= 0) {
  26369. // the current Y is higher than the starting Y
  26370. // so they scrolled up enough to be ignored
  26371. this.progress = 0;
  26372. this.state = 1 /* RefresherState.Inactive */;
  26373. if (this.appliedStyles) {
  26374. // reset the styles only if they were applied
  26375. this.setCss(0, '', false, '');
  26376. return;
  26377. }
  26378. return;
  26379. }
  26380. if (this.state === 1 /* RefresherState.Inactive */) {
  26381. // this refresh is not already actively pulling down
  26382. // get the content's scrollTop
  26383. const scrollHostScrollTop = this.scrollEl.scrollTop;
  26384. // if the scrollTop is greater than zero then it's
  26385. // not possible to pull the content down yet
  26386. if (scrollHostScrollTop > 0) {
  26387. this.progress = 0;
  26388. return;
  26389. }
  26390. // content scrolled all the way to the top, and dragging down
  26391. this.state = 2 /* RefresherState.Pulling */;
  26392. }
  26393. // prevent native scroll events
  26394. if (ev.cancelable) {
  26395. ev.preventDefault();
  26396. }
  26397. // the refresher is actively pulling at this point
  26398. // move the scroll element within the content element
  26399. this.setCss(deltaY, '0ms', true, '');
  26400. if (deltaY === 0) {
  26401. // don't continue if there's no delta yet
  26402. this.progress = 0;
  26403. return;
  26404. }
  26405. const pullMin = this.pullMin;
  26406. // set pull progress
  26407. this.progress = deltaY / pullMin;
  26408. // emit "start" if it hasn't started yet
  26409. if (!this.didStart) {
  26410. this.didStart = true;
  26411. this.ionStart.emit();
  26412. }
  26413. // emit "pulling" on every move
  26414. this.ionPull.emit();
  26415. // do nothing if the delta is less than the pull threshold
  26416. if (deltaY < pullMin) {
  26417. // ensure it stays in the pulling state, cuz its not ready yet
  26418. this.state = 2 /* RefresherState.Pulling */;
  26419. return;
  26420. }
  26421. if (deltaY > this.pullMax) {
  26422. // they pulled farther than the max, so kick off the refresh
  26423. this.beginRefresh();
  26424. return;
  26425. }
  26426. // pulled farther than the pull min!!
  26427. // it is now in the `ready` state!!
  26428. // if they let go then it'll refresh, kerpow!!
  26429. this.state = 4 /* RefresherState.Ready */;
  26430. return;
  26431. }
  26432. onEnd() {
  26433. // only run in a zone when absolutely necessary
  26434. if (this.state === 4 /* RefresherState.Ready */) {
  26435. // they pulled down far enough, so it's ready to refresh
  26436. this.beginRefresh();
  26437. }
  26438. else if (this.state === 2 /* RefresherState.Pulling */) {
  26439. // they were pulling down, but didn't pull down far enough
  26440. // set the content back to it's original location
  26441. // and close the refresher
  26442. // set that the refresh is actively cancelling
  26443. this.cancel();
  26444. }
  26445. else if (this.state === 1 /* RefresherState.Inactive */) {
  26446. /**
  26447. * The pull to refresh gesture was aborted
  26448. * so we should immediately restore any overflow styles
  26449. * that have been modified. Do not call this.cancel
  26450. * because the styles will only be reset after a timeout.
  26451. * If the gesture is aborted then scrolling should be
  26452. * available right away.
  26453. */
  26454. this.restoreOverflowStyle();
  26455. }
  26456. }
  26457. beginRefresh() {
  26458. // assumes we're already back in a zone
  26459. // they pulled down far enough, so it's ready to refresh
  26460. this.state = 8 /* RefresherState.Refreshing */;
  26461. // place the content in a hangout position while it thinks
  26462. this.setCss(this.pullMin, this.snapbackDuration, true, '');
  26463. // emit "refresh" because it was pulled down far enough
  26464. // and they let go to begin refreshing
  26465. this.ionRefresh.emit({
  26466. complete: this.complete.bind(this),
  26467. });
  26468. }
  26469. close(state, delay) {
  26470. // create fallback timer incase something goes wrong with transitionEnd event
  26471. setTimeout(() => {
  26472. var _a;
  26473. this.state = 1 /* RefresherState.Inactive */;
  26474. this.progress = 0;
  26475. this.didStart = false;
  26476. /**
  26477. * Reset any overflow styles so the
  26478. * user can scroll again.
  26479. */
  26480. this.setCss(0, '0ms', false, '', true);
  26481. /**
  26482. * Reset the offset-top style on the background content
  26483. * when the refresher is no longer refreshing and the
  26484. * content is fullscreen.
  26485. *
  26486. * This ensures that the behavior of background content
  26487. * does not change when refreshing is complete.
  26488. */
  26489. if (this.contentFullscreen && this.backgroundContentEl) {
  26490. (_a = this.backgroundContentEl) === null || _a === void 0 ? void 0 : _a.style.removeProperty('--offset-top');
  26491. }
  26492. }, 600);
  26493. // reset the styles on the scroll element
  26494. // set that the refresh is actively cancelling/completing
  26495. this.state = state;
  26496. this.setCss(0, this.closeDuration, true, delay);
  26497. }
  26498. setCss(y, duration, overflowVisible, delay, shouldRestoreOverflowStyle = false) {
  26499. if (this.nativeRefresher) {
  26500. return;
  26501. }
  26502. this.appliedStyles = y > 0;
  26503. writeTask(() => {
  26504. if (this.scrollEl && this.backgroundContentEl) {
  26505. const scrollStyle = this.scrollEl.style;
  26506. const backgroundStyle = this.backgroundContentEl.style;
  26507. scrollStyle.transform = backgroundStyle.transform = y > 0 ? `translateY(${y}px) translateZ(0px)` : '';
  26508. scrollStyle.transitionDuration = backgroundStyle.transitionDuration = duration;
  26509. scrollStyle.transitionDelay = backgroundStyle.transitionDelay = delay;
  26510. scrollStyle.overflow = overflowVisible ? 'hidden' : '';
  26511. }
  26512. /**
  26513. * Reset the overflow styles only once
  26514. * the pull to refresh effect has been closed.
  26515. * This ensures that the gesture is done
  26516. * and the refresh operation has either
  26517. * been aborted or has completed.
  26518. */
  26519. if (shouldRestoreOverflowStyle) {
  26520. this.restoreOverflowStyle();
  26521. }
  26522. });
  26523. }
  26524. memoizeOverflowStyle() {
  26525. if (this.scrollEl) {
  26526. const { overflow, overflowX, overflowY } = this.scrollEl.style;
  26527. this.overflowStyles = {
  26528. overflow: overflow !== null && overflow !== void 0 ? overflow : '',
  26529. overflowX: overflowX !== null && overflowX !== void 0 ? overflowX : '',
  26530. overflowY: overflowY !== null && overflowY !== void 0 ? overflowY : '',
  26531. };
  26532. }
  26533. }
  26534. restoreOverflowStyle() {
  26535. if (this.overflowStyles !== undefined && this.scrollEl !== undefined) {
  26536. const { overflow, overflowX, overflowY } = this.overflowStyles;
  26537. this.scrollEl.style.overflow = overflow;
  26538. this.scrollEl.style.overflowX = overflowX;
  26539. this.scrollEl.style.overflowY = overflowY;
  26540. this.overflowStyles = undefined;
  26541. }
  26542. }
  26543. render() {
  26544. const mode = getIonMode$1(this);
  26545. return (hAsync(Host, { key: 'c717c16f2ca3e42351848cc8ad37918dec28961d', slot: "fixed", class: {
  26546. [mode]: true,
  26547. // Used internally for styling
  26548. [`refresher-${mode}`]: true,
  26549. 'refresher-native': this.nativeRefresher,
  26550. 'refresher-active': this.state !== 1 /* RefresherState.Inactive */,
  26551. 'refresher-pulling': this.state === 2 /* RefresherState.Pulling */,
  26552. 'refresher-ready': this.state === 4 /* RefresherState.Ready */,
  26553. 'refresher-refreshing': this.state === 8 /* RefresherState.Refreshing */,
  26554. 'refresher-cancelling': this.state === 16 /* RefresherState.Cancelling */,
  26555. 'refresher-completing': this.state === 32 /* RefresherState.Completing */,
  26556. } }));
  26557. }
  26558. get el() { return getElement(this); }
  26559. static get watchers() { return {
  26560. "disabled": ["disabledChanged"]
  26561. }; }
  26562. static get style() { return {
  26563. ios: IonRefresherIosStyle0,
  26564. md: IonRefresherMdStyle0
  26565. }; }
  26566. static get cmpMeta() { return {
  26567. "$flags$": 32,
  26568. "$tagName$": "ion-refresher",
  26569. "$members$": {
  26570. "pullMin": [2, "pull-min"],
  26571. "pullMax": [2, "pull-max"],
  26572. "closeDuration": [1, "close-duration"],
  26573. "snapbackDuration": [1, "snapback-duration"],
  26574. "pullFactor": [2, "pull-factor"],
  26575. "disabled": [4],
  26576. "nativeRefresher": [32],
  26577. "state": [32],
  26578. "complete": [64],
  26579. "cancel": [64],
  26580. "getProgress": [64]
  26581. },
  26582. "$listeners$": undefined,
  26583. "$lazyBundleId$": "-",
  26584. "$attrsToReflect$": []
  26585. }; }
  26586. }
  26587. const spinners = {
  26588. bubbles: {
  26589. dur: 1000,
  26590. circles: 9,
  26591. fn: (dur, index, total) => {
  26592. const animationDelay = `${(dur * index) / total - dur}ms`;
  26593. const angle = (2 * Math.PI * index) / total;
  26594. return {
  26595. r: 5,
  26596. style: {
  26597. top: `${32 * Math.sin(angle)}%`,
  26598. left: `${32 * Math.cos(angle)}%`,
  26599. 'animation-delay': animationDelay,
  26600. },
  26601. };
  26602. },
  26603. },
  26604. circles: {
  26605. dur: 1000,
  26606. circles: 8,
  26607. fn: (dur, index, total) => {
  26608. const step = index / total;
  26609. const animationDelay = `${dur * step - dur}ms`;
  26610. const angle = 2 * Math.PI * step;
  26611. return {
  26612. r: 5,
  26613. style: {
  26614. top: `${32 * Math.sin(angle)}%`,
  26615. left: `${32 * Math.cos(angle)}%`,
  26616. 'animation-delay': animationDelay,
  26617. },
  26618. };
  26619. },
  26620. },
  26621. circular: {
  26622. dur: 1400,
  26623. elmDuration: true,
  26624. circles: 1,
  26625. fn: () => {
  26626. return {
  26627. r: 20,
  26628. cx: 48,
  26629. cy: 48,
  26630. fill: 'none',
  26631. viewBox: '24 24 48 48',
  26632. transform: 'translate(0,0)',
  26633. style: {},
  26634. };
  26635. },
  26636. },
  26637. crescent: {
  26638. dur: 750,
  26639. circles: 1,
  26640. fn: () => {
  26641. return {
  26642. r: 26,
  26643. style: {},
  26644. };
  26645. },
  26646. },
  26647. dots: {
  26648. dur: 750,
  26649. circles: 3,
  26650. fn: (_, index) => {
  26651. const animationDelay = -(110 * index) + 'ms';
  26652. return {
  26653. r: 6,
  26654. style: {
  26655. left: `${32 - 32 * index}%`,
  26656. 'animation-delay': animationDelay,
  26657. },
  26658. };
  26659. },
  26660. },
  26661. lines: {
  26662. dur: 1000,
  26663. lines: 8,
  26664. fn: (dur, index, total) => {
  26665. const transform = `rotate(${(360 / total) * index + (index < total / 2 ? 180 : -180)}deg)`;
  26666. const animationDelay = `${(dur * index) / total - dur}ms`;
  26667. return {
  26668. y1: 14,
  26669. y2: 26,
  26670. style: {
  26671. transform: transform,
  26672. 'animation-delay': animationDelay,
  26673. },
  26674. };
  26675. },
  26676. },
  26677. 'lines-small': {
  26678. dur: 1000,
  26679. lines: 8,
  26680. fn: (dur, index, total) => {
  26681. const transform = `rotate(${(360 / total) * index + (index < total / 2 ? 180 : -180)}deg)`;
  26682. const animationDelay = `${(dur * index) / total - dur}ms`;
  26683. return {
  26684. y1: 12,
  26685. y2: 20,
  26686. style: {
  26687. transform: transform,
  26688. 'animation-delay': animationDelay,
  26689. },
  26690. };
  26691. },
  26692. },
  26693. 'lines-sharp': {
  26694. dur: 1000,
  26695. lines: 12,
  26696. fn: (dur, index, total) => {
  26697. const transform = `rotate(${30 * index + (index < 6 ? 180 : -180)}deg)`;
  26698. const animationDelay = `${(dur * index) / total - dur}ms`;
  26699. return {
  26700. y1: 17,
  26701. y2: 29,
  26702. style: {
  26703. transform: transform,
  26704. 'animation-delay': animationDelay,
  26705. },
  26706. };
  26707. },
  26708. },
  26709. 'lines-sharp-small': {
  26710. dur: 1000,
  26711. lines: 12,
  26712. fn: (dur, index, total) => {
  26713. const transform = `rotate(${30 * index + (index < 6 ? 180 : -180)}deg)`;
  26714. const animationDelay = `${(dur * index) / total - dur}ms`;
  26715. return {
  26716. y1: 12,
  26717. y2: 20,
  26718. style: {
  26719. transform: transform,
  26720. 'animation-delay': animationDelay,
  26721. },
  26722. };
  26723. },
  26724. },
  26725. };
  26726. const SPINNERS = spinners;
  26727. class RefresherContent {
  26728. constructor(hostRef) {
  26729. registerInstance(this, hostRef);
  26730. this.customHTMLEnabled = config.get('innerHTMLTemplatesEnabled', ENABLE_HTML_CONTENT_DEFAULT);
  26731. this.pullingIcon = undefined;
  26732. this.pullingText = undefined;
  26733. this.refreshingSpinner = undefined;
  26734. this.refreshingText = undefined;
  26735. }
  26736. componentWillLoad() {
  26737. if (this.pullingIcon === undefined) {
  26738. /**
  26739. * The native iOS refresher uses a spinner instead of
  26740. * an icon, so we need to see if this device supports
  26741. * the native iOS refresher.
  26742. */
  26743. const hasRubberBandScrolling = supportsRubberBandScrolling();
  26744. const mode = getIonMode$1(this);
  26745. const overflowRefresher = hasRubberBandScrolling ? 'lines' : arrowDown;
  26746. this.pullingIcon = config.get('refreshingIcon', mode === 'ios' && hasRubberBandScrolling ? config.get('spinner', overflowRefresher) : 'circular');
  26747. }
  26748. if (this.refreshingSpinner === undefined) {
  26749. const mode = getIonMode$1(this);
  26750. this.refreshingSpinner = config.get('refreshingSpinner', config.get('spinner', mode === 'ios' ? 'lines' : 'circular'));
  26751. }
  26752. }
  26753. renderPullingText() {
  26754. const { customHTMLEnabled, pullingText } = this;
  26755. if (customHTMLEnabled) {
  26756. return hAsync("div", { class: "refresher-pulling-text", innerHTML: sanitizeDOMString(pullingText) });
  26757. }
  26758. return hAsync("div", { class: "refresher-pulling-text" }, pullingText);
  26759. }
  26760. renderRefreshingText() {
  26761. const { customHTMLEnabled, refreshingText } = this;
  26762. if (customHTMLEnabled) {
  26763. return hAsync("div", { class: "refresher-refreshing-text", innerHTML: sanitizeDOMString(refreshingText) });
  26764. }
  26765. return hAsync("div", { class: "refresher-refreshing-text" }, refreshingText);
  26766. }
  26767. render() {
  26768. const pullingIcon = this.pullingIcon;
  26769. const hasSpinner = pullingIcon != null && SPINNERS[pullingIcon] !== undefined;
  26770. const mode = getIonMode$1(this);
  26771. return (hAsync(Host, { key: 'fb78d7e31f8feb31025e58903eb9de85cb928dbd', class: mode }, hAsync("div", { key: '23f67800f09765ef8fde8cf85a843e19e667f337', class: "refresher-pulling" }, this.pullingIcon && hasSpinner && (hAsync("div", { key: '5a08d3b69762f8b51dcd3dcfbaf3fddb707257fa', class: "refresher-pulling-icon" }, hAsync("div", { key: '42a613b029e092acdff7fe613a429375d89f157e', class: "spinner-arrow-container" }, hAsync("ion-spinner", { key: '2f9cdc75938c4d306de7a717ed67901daef71c2c', name: this.pullingIcon, paused: true }), mode === 'md' && this.pullingIcon === 'circular' && (hAsync("div", { key: '1f8a6347b4a46417ba55286a79f1a41f04bf9c91', class: "arrow-container" }, hAsync("ion-icon", { key: '326713d11d482d420ba5a739ff4528400a37e9ca', icon: caretBackSharp, "aria-hidden": "true" })))))), this.pullingIcon && !hasSpinner && (hAsync("div", { key: 'ab18c7cbea7bcbfa034f90f317652af4d93660ed', class: "refresher-pulling-icon" }, hAsync("ion-icon", { key: 'f488acd54acc8a61b6c5a279f0d7f9a437c370c0', icon: this.pullingIcon, lazy: false, "aria-hidden": "true" }))), this.pullingText !== undefined && this.renderPullingText()), hAsync("div", { key: '914ad6139442dac53af47120ea821fa11c309a38', class: "refresher-refreshing" }, this.refreshingSpinner && (hAsync("div", { key: '7eba732f5e2d72b90399d68a3e89617d8979b3d1', class: "refresher-refreshing-icon" }, hAsync("ion-spinner", { key: '838d66d8bef6f56622c62b1068e7fed29e094302', name: this.refreshingSpinner }))), this.refreshingText !== undefined && this.renderRefreshingText())));
  26772. }
  26773. get el() { return getElement(this); }
  26774. static get cmpMeta() { return {
  26775. "$flags$": 0,
  26776. "$tagName$": "ion-refresher-content",
  26777. "$members$": {
  26778. "pullingIcon": [1025, "pulling-icon"],
  26779. "pullingText": [1, "pulling-text"],
  26780. "refreshingSpinner": [1025, "refreshing-spinner"],
  26781. "refreshingText": [1, "refreshing-text"]
  26782. },
  26783. "$listeners$": undefined,
  26784. "$lazyBundleId$": "-",
  26785. "$attrsToReflect$": []
  26786. }; }
  26787. }
  26788. const reorderIosCss = ":host([slot]){display:none;line-height:0;z-index:100}.reorder-icon{display:block}::slotted(ion-icon){font-size:dynamic-font(16px)}.reorder-icon{font-size:2.125rem;opacity:0.4}";
  26789. var IonReorderIosStyle0 = reorderIosCss;
  26790. const reorderMdCss = ":host([slot]){display:none;line-height:0;z-index:100}.reorder-icon{display:block}::slotted(ion-icon){font-size:dynamic-font(16px)}.reorder-icon{font-size:1.9375rem;opacity:0.3}";
  26791. var IonReorderMdStyle0 = reorderMdCss;
  26792. /**
  26793. * @part icon - The icon of the reorder handle (uses ion-icon).
  26794. */
  26795. class Reorder {
  26796. constructor(hostRef) {
  26797. registerInstance(this, hostRef);
  26798. }
  26799. onClick(ev) {
  26800. const reorderGroup = this.el.closest('ion-reorder-group');
  26801. ev.preventDefault();
  26802. // Only stop event propagation if the reorder is inside of an enabled
  26803. // reorder group. This allows interaction with clickable children components.
  26804. if (!reorderGroup || !reorderGroup.disabled) {
  26805. ev.stopImmediatePropagation();
  26806. }
  26807. }
  26808. render() {
  26809. const mode = getIonMode$1(this);
  26810. const reorderIcon = mode === 'ios' ? reorderThreeOutline : reorderTwoSharp;
  26811. return (hAsync(Host, { key: '17adf3165f4e09283d5d6434d7cd47bd23519048', class: mode }, hAsync("slot", { key: 'd00d1cd97c689fc5c7b7175a2051cf697fe22871' }, hAsync("ion-icon", { key: 'eec219aebde6083de98358be3e75965c5a5dc3d0', icon: reorderIcon, lazy: false, class: "reorder-icon", part: "icon", "aria-hidden": "true" }))));
  26812. }
  26813. get el() { return getElement(this); }
  26814. static get style() { return {
  26815. ios: IonReorderIosStyle0,
  26816. md: IonReorderMdStyle0
  26817. }; }
  26818. static get cmpMeta() { return {
  26819. "$flags$": 41,
  26820. "$tagName$": "ion-reorder",
  26821. "$members$": undefined,
  26822. "$listeners$": [[2, "click", "onClick"]],
  26823. "$lazyBundleId$": "-",
  26824. "$attrsToReflect$": []
  26825. }; }
  26826. }
  26827. const reorderGroupCss = ".reorder-list-active>*{display:block;-webkit-transition:-webkit-transform 300ms;transition:-webkit-transform 300ms;transition:transform 300ms;transition:transform 300ms, -webkit-transform 300ms;will-change:transform}.reorder-enabled{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.reorder-enabled ion-reorder{display:block;cursor:-webkit-grab;cursor:grab;pointer-events:all;-ms-touch-action:none;touch-action:none}.reorder-selected,.reorder-selected ion-reorder{cursor:-webkit-grabbing;cursor:grabbing}.reorder-selected{position:relative;-webkit-transition:none !important;transition:none !important;-webkit-box-shadow:0 0 10px rgba(0, 0, 0, 0.4);box-shadow:0 0 10px rgba(0, 0, 0, 0.4);opacity:0.8;z-index:100}.reorder-visible ion-reorder .reorder-icon{-webkit-transform:translate3d(0, 0, 0);transform:translate3d(0, 0, 0)}";
  26828. var IonReorderGroupStyle0 = reorderGroupCss;
  26829. class ReorderGroup {
  26830. constructor(hostRef) {
  26831. registerInstance(this, hostRef);
  26832. this.ionItemReorder = createEvent(this, "ionItemReorder", 7);
  26833. this.lastToIndex = -1;
  26834. this.cachedHeights = [];
  26835. this.scrollElTop = 0;
  26836. this.scrollElBottom = 0;
  26837. this.scrollElInitial = 0;
  26838. this.containerTop = 0;
  26839. this.containerBottom = 0;
  26840. this.state = 0 /* ReorderGroupState.Idle */;
  26841. this.disabled = true;
  26842. }
  26843. disabledChanged() {
  26844. if (this.gesture) {
  26845. this.gesture.enable(!this.disabled);
  26846. }
  26847. }
  26848. async connectedCallback() {
  26849. const contentEl = findClosestIonContent(this.el);
  26850. if (contentEl) {
  26851. this.scrollEl = await getScrollElement(contentEl);
  26852. }
  26853. this.gesture = (await Promise.resolve().then(function () { return index; })).createGesture({
  26854. el: this.el,
  26855. gestureName: 'reorder',
  26856. gesturePriority: 110,
  26857. threshold: 0,
  26858. direction: 'y',
  26859. passive: false,
  26860. canStart: (detail) => this.canStart(detail),
  26861. onStart: (ev) => this.onStart(ev),
  26862. onMove: (ev) => this.onMove(ev),
  26863. onEnd: () => this.onEnd(),
  26864. });
  26865. this.disabledChanged();
  26866. }
  26867. disconnectedCallback() {
  26868. this.onEnd();
  26869. if (this.gesture) {
  26870. this.gesture.destroy();
  26871. this.gesture = undefined;
  26872. }
  26873. }
  26874. /**
  26875. * Completes the reorder operation. Must be called by the `ionItemReorder` event.
  26876. *
  26877. * If a list of items is passed, the list will be reordered and returned in the
  26878. * proper order.
  26879. *
  26880. * If no parameters are passed or if `true` is passed in, the reorder will complete
  26881. * and the item will remain in the position it was dragged to. If `false` is passed,
  26882. * the reorder will complete and the item will bounce back to its original position.
  26883. *
  26884. * @param listOrReorder A list of items to be sorted and returned in the new order or a
  26885. * boolean of whether or not the reorder should reposition the item.
  26886. */
  26887. complete(listOrReorder) {
  26888. return Promise.resolve(this.completeReorder(listOrReorder));
  26889. }
  26890. canStart(ev) {
  26891. if (this.selectedItemEl || this.state !== 0 /* ReorderGroupState.Idle */) {
  26892. return false;
  26893. }
  26894. const target = ev.event.target;
  26895. const reorderEl = target.closest('ion-reorder');
  26896. if (!reorderEl) {
  26897. return false;
  26898. }
  26899. const item = findReorderItem(reorderEl, this.el);
  26900. if (!item) {
  26901. return false;
  26902. }
  26903. ev.data = item;
  26904. return true;
  26905. }
  26906. onStart(ev) {
  26907. ev.event.preventDefault();
  26908. const item = (this.selectedItemEl = ev.data);
  26909. const heights = this.cachedHeights;
  26910. heights.length = 0;
  26911. const el = this.el;
  26912. const children = el.children;
  26913. if (!children || children.length === 0) {
  26914. return;
  26915. }
  26916. let sum = 0;
  26917. for (let i = 0; i < children.length; i++) {
  26918. const child = children[i];
  26919. sum += child.offsetHeight;
  26920. heights.push(sum);
  26921. child.$ionIndex = i;
  26922. }
  26923. const box = el.getBoundingClientRect();
  26924. this.containerTop = box.top;
  26925. this.containerBottom = box.bottom;
  26926. if (this.scrollEl) {
  26927. const scrollBox = this.scrollEl.getBoundingClientRect();
  26928. this.scrollElInitial = this.scrollEl.scrollTop;
  26929. this.scrollElTop = scrollBox.top + AUTO_SCROLL_MARGIN;
  26930. this.scrollElBottom = scrollBox.bottom - AUTO_SCROLL_MARGIN;
  26931. }
  26932. else {
  26933. this.scrollElInitial = 0;
  26934. this.scrollElTop = 0;
  26935. this.scrollElBottom = 0;
  26936. }
  26937. this.lastToIndex = indexForItem(item);
  26938. this.selectedItemHeight = item.offsetHeight;
  26939. this.state = 1 /* ReorderGroupState.Active */;
  26940. item.classList.add(ITEM_REORDER_SELECTED);
  26941. hapticSelectionStart();
  26942. }
  26943. onMove(ev) {
  26944. const selectedItem = this.selectedItemEl;
  26945. if (!selectedItem) {
  26946. return;
  26947. }
  26948. // Scroll if we reach the scroll margins
  26949. const scroll = this.autoscroll(ev.currentY);
  26950. // // Get coordinate
  26951. const top = this.containerTop - scroll;
  26952. const bottom = this.containerBottom - scroll;
  26953. const currentY = Math.max(top, Math.min(ev.currentY, bottom));
  26954. const deltaY = scroll + currentY - ev.startY;
  26955. const normalizedY = currentY - top;
  26956. const toIndex = this.itemIndexForTop(normalizedY);
  26957. if (toIndex !== this.lastToIndex) {
  26958. const fromIndex = indexForItem(selectedItem);
  26959. this.lastToIndex = toIndex;
  26960. hapticSelectionChanged();
  26961. this.reorderMove(fromIndex, toIndex);
  26962. }
  26963. // Update selected item position
  26964. selectedItem.style.transform = `translateY(${deltaY}px)`;
  26965. }
  26966. onEnd() {
  26967. const selectedItemEl = this.selectedItemEl;
  26968. this.state = 2 /* ReorderGroupState.Complete */;
  26969. if (!selectedItemEl) {
  26970. this.state = 0 /* ReorderGroupState.Idle */;
  26971. return;
  26972. }
  26973. const toIndex = this.lastToIndex;
  26974. const fromIndex = indexForItem(selectedItemEl);
  26975. if (toIndex === fromIndex) {
  26976. this.completeReorder();
  26977. }
  26978. else {
  26979. this.ionItemReorder.emit({
  26980. from: fromIndex,
  26981. to: toIndex,
  26982. complete: this.completeReorder.bind(this),
  26983. });
  26984. }
  26985. hapticSelectionEnd();
  26986. }
  26987. completeReorder(listOrReorder) {
  26988. const selectedItemEl = this.selectedItemEl;
  26989. if (selectedItemEl && this.state === 2 /* ReorderGroupState.Complete */) {
  26990. const children = this.el.children;
  26991. const len = children.length;
  26992. const toIndex = this.lastToIndex;
  26993. const fromIndex = indexForItem(selectedItemEl);
  26994. /**
  26995. * insertBefore and setting the transform
  26996. * needs to happen in the same frame otherwise
  26997. * there will be a duplicate transition. This primarily
  26998. * impacts Firefox where insertBefore and transform operations
  26999. * are happening in two separate frames.
  27000. */
  27001. raf(() => {
  27002. if (toIndex !== fromIndex && (listOrReorder === undefined || listOrReorder === true)) {
  27003. const ref = fromIndex < toIndex ? children[toIndex + 1] : children[toIndex];
  27004. this.el.insertBefore(selectedItemEl, ref);
  27005. }
  27006. for (let i = 0; i < len; i++) {
  27007. children[i].style['transform'] = '';
  27008. }
  27009. });
  27010. if (Array.isArray(listOrReorder)) {
  27011. listOrReorder = reorderArray(listOrReorder, fromIndex, toIndex);
  27012. }
  27013. selectedItemEl.style.transition = '';
  27014. selectedItemEl.classList.remove(ITEM_REORDER_SELECTED);
  27015. this.selectedItemEl = undefined;
  27016. this.state = 0 /* ReorderGroupState.Idle */;
  27017. }
  27018. return listOrReorder;
  27019. }
  27020. itemIndexForTop(deltaY) {
  27021. const heights = this.cachedHeights;
  27022. for (let i = 0; i < heights.length; i++) {
  27023. if (heights[i] > deltaY) {
  27024. return i;
  27025. }
  27026. }
  27027. return heights.length - 1;
  27028. }
  27029. /********* DOM WRITE ********* */
  27030. reorderMove(fromIndex, toIndex) {
  27031. const itemHeight = this.selectedItemHeight;
  27032. const children = this.el.children;
  27033. for (let i = 0; i < children.length; i++) {
  27034. const style = children[i].style;
  27035. let value = '';
  27036. if (i > fromIndex && i <= toIndex) {
  27037. value = `translateY(${-itemHeight}px)`;
  27038. }
  27039. else if (i < fromIndex && i >= toIndex) {
  27040. value = `translateY(${itemHeight}px)`;
  27041. }
  27042. style['transform'] = value;
  27043. }
  27044. }
  27045. autoscroll(posY) {
  27046. if (!this.scrollEl) {
  27047. return 0;
  27048. }
  27049. let amount = 0;
  27050. if (posY < this.scrollElTop) {
  27051. amount = -SCROLL_JUMP;
  27052. }
  27053. else if (posY > this.scrollElBottom) {
  27054. amount = SCROLL_JUMP;
  27055. }
  27056. if (amount !== 0) {
  27057. this.scrollEl.scrollBy(0, amount);
  27058. }
  27059. return this.scrollEl.scrollTop - this.scrollElInitial;
  27060. }
  27061. render() {
  27062. const mode = getIonMode$1(this);
  27063. return (hAsync(Host, { key: '6ca009dd65302a914d459aec638e62977440db20', class: {
  27064. [mode]: true,
  27065. 'reorder-enabled': !this.disabled,
  27066. 'reorder-list-active': this.state !== 0 /* ReorderGroupState.Idle */,
  27067. } }));
  27068. }
  27069. get el() { return getElement(this); }
  27070. static get watchers() { return {
  27071. "disabled": ["disabledChanged"]
  27072. }; }
  27073. static get style() { return IonReorderGroupStyle0; }
  27074. static get cmpMeta() { return {
  27075. "$flags$": 0,
  27076. "$tagName$": "ion-reorder-group",
  27077. "$members$": {
  27078. "disabled": [4],
  27079. "state": [32],
  27080. "complete": [64]
  27081. },
  27082. "$listeners$": undefined,
  27083. "$lazyBundleId$": "-",
  27084. "$attrsToReflect$": []
  27085. }; }
  27086. }
  27087. const indexForItem = (element) => {
  27088. return element['$ionIndex'];
  27089. };
  27090. const findReorderItem = (node, container) => {
  27091. let parent;
  27092. while (node) {
  27093. parent = node.parentElement;
  27094. if (parent === container) {
  27095. return node;
  27096. }
  27097. node = parent;
  27098. }
  27099. return undefined;
  27100. };
  27101. const AUTO_SCROLL_MARGIN = 60;
  27102. const SCROLL_JUMP = 10;
  27103. const ITEM_REORDER_SELECTED = 'reorder-selected';
  27104. const reorderArray = (array, from, to) => {
  27105. const element = array[from];
  27106. array.splice(from, 1);
  27107. array.splice(to, 0, element);
  27108. return array.slice();
  27109. };
  27110. const rippleEffectCss = ":host{left:0;right:0;top:0;bottom:0;position:absolute;contain:strict;pointer-events:none}:host(.unbounded){contain:layout size style}.ripple-effect{border-radius:50%;position:absolute;background-color:currentColor;color:inherit;contain:strict;opacity:0;-webkit-animation:225ms rippleAnimation forwards, 75ms fadeInAnimation forwards;animation:225ms rippleAnimation forwards, 75ms fadeInAnimation forwards;will-change:transform, opacity;pointer-events:none}.fade-out{-webkit-transform:translate(var(--translate-end)) scale(var(--final-scale, 1));transform:translate(var(--translate-end)) scale(var(--final-scale, 1));-webkit-animation:150ms fadeOutAnimation forwards;animation:150ms fadeOutAnimation forwards}@-webkit-keyframes rippleAnimation{from{-webkit-animation-timing-function:cubic-bezier(0.4, 0, 0.2, 1);animation-timing-function:cubic-bezier(0.4, 0, 0.2, 1);-webkit-transform:scale(1);transform:scale(1)}to{-webkit-transform:translate(var(--translate-end)) scale(var(--final-scale, 1));transform:translate(var(--translate-end)) scale(var(--final-scale, 1))}}@keyframes rippleAnimation{from{-webkit-animation-timing-function:cubic-bezier(0.4, 0, 0.2, 1);animation-timing-function:cubic-bezier(0.4, 0, 0.2, 1);-webkit-transform:scale(1);transform:scale(1)}to{-webkit-transform:translate(var(--translate-end)) scale(var(--final-scale, 1));transform:translate(var(--translate-end)) scale(var(--final-scale, 1))}}@-webkit-keyframes fadeInAnimation{from{-webkit-animation-timing-function:linear;animation-timing-function:linear;opacity:0}to{opacity:0.16}}@keyframes fadeInAnimation{from{-webkit-animation-timing-function:linear;animation-timing-function:linear;opacity:0}to{opacity:0.16}}@-webkit-keyframes fadeOutAnimation{from{-webkit-animation-timing-function:linear;animation-timing-function:linear;opacity:0.16}to{opacity:0}}@keyframes fadeOutAnimation{from{-webkit-animation-timing-function:linear;animation-timing-function:linear;opacity:0.16}to{opacity:0}}";
  27111. var IonRippleEffectStyle0 = rippleEffectCss;
  27112. class RippleEffect {
  27113. constructor(hostRef) {
  27114. registerInstance(this, hostRef);
  27115. this.type = 'bounded';
  27116. }
  27117. /**
  27118. * Adds the ripple effect to the parent element.
  27119. *
  27120. * @param x The horizontal coordinate of where the ripple should start.
  27121. * @param y The vertical coordinate of where the ripple should start.
  27122. */
  27123. async addRipple(x, y) {
  27124. return new Promise((resolve) => {
  27125. readTask(() => {
  27126. const rect = this.el.getBoundingClientRect();
  27127. const width = rect.width;
  27128. const height = rect.height;
  27129. const hypotenuse = Math.sqrt(width * width + height * height);
  27130. const maxDim = Math.max(height, width);
  27131. const maxRadius = this.unbounded ? maxDim : hypotenuse + PADDING;
  27132. const initialSize = Math.floor(maxDim * INITIAL_ORIGIN_SCALE);
  27133. const finalScale = maxRadius / initialSize;
  27134. let posX = x - rect.left;
  27135. let posY = y - rect.top;
  27136. if (this.unbounded) {
  27137. posX = width * 0.5;
  27138. posY = height * 0.5;
  27139. }
  27140. const styleX = posX - initialSize * 0.5;
  27141. const styleY = posY - initialSize * 0.5;
  27142. const moveX = width * 0.5 - posX;
  27143. const moveY = height * 0.5 - posY;
  27144. writeTask(() => {
  27145. const div = document.createElement('div');
  27146. div.classList.add('ripple-effect');
  27147. const style = div.style;
  27148. style.top = styleY + 'px';
  27149. style.left = styleX + 'px';
  27150. style.width = style.height = initialSize + 'px';
  27151. style.setProperty('--final-scale', `${finalScale}`);
  27152. style.setProperty('--translate-end', `${moveX}px, ${moveY}px`);
  27153. const container = this.el.shadowRoot || this.el;
  27154. container.appendChild(div);
  27155. setTimeout(() => {
  27156. resolve(() => {
  27157. removeRipple(div);
  27158. });
  27159. }, 225 + 100);
  27160. });
  27161. });
  27162. });
  27163. }
  27164. get unbounded() {
  27165. return this.type === 'unbounded';
  27166. }
  27167. render() {
  27168. const mode = getIonMode$1(this);
  27169. return (hAsync(Host, { key: '40c7f73e7f5f67e29f83e1236a61c6e1c9943c42', role: "presentation", class: {
  27170. [mode]: true,
  27171. unbounded: this.unbounded,
  27172. } }));
  27173. }
  27174. get el() { return getElement(this); }
  27175. static get style() { return IonRippleEffectStyle0; }
  27176. static get cmpMeta() { return {
  27177. "$flags$": 9,
  27178. "$tagName$": "ion-ripple-effect",
  27179. "$members$": {
  27180. "type": [1],
  27181. "addRipple": [64]
  27182. },
  27183. "$listeners$": undefined,
  27184. "$lazyBundleId$": "-",
  27185. "$attrsToReflect$": []
  27186. }; }
  27187. }
  27188. const removeRipple = (ripple) => {
  27189. ripple.classList.add('fade-out');
  27190. setTimeout(() => {
  27191. ripple.remove();
  27192. }, 200);
  27193. };
  27194. const PADDING = 10;
  27195. const INITIAL_ORIGIN_SCALE = 0.5;
  27196. // TODO(FW-2832): types
  27197. class Route {
  27198. constructor(hostRef) {
  27199. registerInstance(this, hostRef);
  27200. this.ionRouteDataChanged = createEvent(this, "ionRouteDataChanged", 7);
  27201. this.url = '';
  27202. this.component = undefined;
  27203. this.componentProps = undefined;
  27204. this.beforeLeave = undefined;
  27205. this.beforeEnter = undefined;
  27206. }
  27207. onUpdate(newValue) {
  27208. this.ionRouteDataChanged.emit(newValue);
  27209. }
  27210. onComponentProps(newValue, oldValue) {
  27211. if (newValue === oldValue) {
  27212. return;
  27213. }
  27214. const keys1 = newValue ? Object.keys(newValue) : [];
  27215. const keys2 = oldValue ? Object.keys(oldValue) : [];
  27216. if (keys1.length !== keys2.length) {
  27217. this.onUpdate(newValue);
  27218. return;
  27219. }
  27220. for (const key of keys1) {
  27221. if (newValue[key] !== oldValue[key]) {
  27222. this.onUpdate(newValue);
  27223. return;
  27224. }
  27225. }
  27226. }
  27227. connectedCallback() {
  27228. this.ionRouteDataChanged.emit();
  27229. }
  27230. static get watchers() { return {
  27231. "url": ["onUpdate"],
  27232. "component": ["onUpdate"],
  27233. "componentProps": ["onComponentProps"]
  27234. }; }
  27235. static get cmpMeta() { return {
  27236. "$flags$": 0,
  27237. "$tagName$": "ion-route",
  27238. "$members$": {
  27239. "url": [1],
  27240. "component": [1],
  27241. "componentProps": [16],
  27242. "beforeLeave": [16],
  27243. "beforeEnter": [16]
  27244. },
  27245. "$listeners$": undefined,
  27246. "$lazyBundleId$": "-",
  27247. "$attrsToReflect$": []
  27248. }; }
  27249. }
  27250. class RouteRedirect {
  27251. constructor(hostRef) {
  27252. registerInstance(this, hostRef);
  27253. this.ionRouteRedirectChanged = createEvent(this, "ionRouteRedirectChanged", 7);
  27254. this.from = undefined;
  27255. this.to = undefined;
  27256. }
  27257. propDidChange() {
  27258. this.ionRouteRedirectChanged.emit();
  27259. }
  27260. connectedCallback() {
  27261. this.ionRouteRedirectChanged.emit();
  27262. }
  27263. static get watchers() { return {
  27264. "from": ["propDidChange"],
  27265. "to": ["propDidChange"]
  27266. }; }
  27267. static get cmpMeta() { return {
  27268. "$flags$": 0,
  27269. "$tagName$": "ion-route-redirect",
  27270. "$members$": {
  27271. "from": [1],
  27272. "to": [1]
  27273. },
  27274. "$listeners$": undefined,
  27275. "$lazyBundleId$": "-",
  27276. "$attrsToReflect$": []
  27277. }; }
  27278. }
  27279. const ROUTER_INTENT_NONE = 'root';
  27280. const ROUTER_INTENT_FORWARD = 'forward';
  27281. const ROUTER_INTENT_BACK = 'back';
  27282. /** Join the non empty segments with "/". */
  27283. const generatePath = (segments) => {
  27284. const path = segments.filter((s) => s.length > 0).join('/');
  27285. return '/' + path;
  27286. };
  27287. const generateUrl = (segments, useHash, queryString) => {
  27288. let url = generatePath(segments);
  27289. if (useHash) {
  27290. url = '#' + url;
  27291. }
  27292. if (queryString !== undefined) {
  27293. url += '?' + queryString;
  27294. }
  27295. return url;
  27296. };
  27297. const writeSegments = (history, root, useHash, segments, direction, state, queryString) => {
  27298. const url = generateUrl([...parsePath(root).segments, ...segments], useHash, queryString);
  27299. if (direction === ROUTER_INTENT_FORWARD) {
  27300. history.pushState(state, '', url);
  27301. }
  27302. else {
  27303. history.replaceState(state, '', url);
  27304. }
  27305. };
  27306. /**
  27307. * Transforms a chain to a list of segments.
  27308. *
  27309. * Notes:
  27310. * - parameter segments of the form :param are replaced with their value,
  27311. * - null is returned when a value is missing for any parameter segment.
  27312. */
  27313. const chainToSegments = (chain) => {
  27314. const segments = [];
  27315. for (const route of chain) {
  27316. for (const segment of route.segments) {
  27317. if (segment[0] === ':') {
  27318. // eslint-disable-next-line @typescript-eslint/prefer-optional-chain
  27319. const param = route.params && route.params[segment.slice(1)];
  27320. if (!param) {
  27321. return null;
  27322. }
  27323. segments.push(param);
  27324. }
  27325. else if (segment !== '') {
  27326. segments.push(segment);
  27327. }
  27328. }
  27329. }
  27330. return segments;
  27331. };
  27332. /**
  27333. * Removes the prefix segments from the path segments.
  27334. *
  27335. * Return:
  27336. * - null when the path segments do not start with the passed prefix,
  27337. * - the path segments after the prefix otherwise.
  27338. */
  27339. const removePrefix = (prefix, segments) => {
  27340. if (prefix.length > segments.length) {
  27341. return null;
  27342. }
  27343. if (prefix.length <= 1 && prefix[0] === '') {
  27344. return segments;
  27345. }
  27346. for (let i = 0; i < prefix.length; i++) {
  27347. if (prefix[i] !== segments[i]) {
  27348. return null;
  27349. }
  27350. }
  27351. if (segments.length === prefix.length) {
  27352. return [''];
  27353. }
  27354. return segments.slice(prefix.length);
  27355. };
  27356. const readSegments = (loc, root, useHash) => {
  27357. const prefix = parsePath(root).segments;
  27358. const pathname = useHash ? loc.hash.slice(1) : loc.pathname;
  27359. const segments = parsePath(pathname).segments;
  27360. return removePrefix(prefix, segments);
  27361. };
  27362. /**
  27363. * Parses the path to:
  27364. * - segments an array of '/' separated parts,
  27365. * - queryString (undefined when no query string).
  27366. */
  27367. const parsePath = (path) => {
  27368. let segments = [''];
  27369. let queryString;
  27370. if (path != null) {
  27371. const qsStart = path.indexOf('?');
  27372. if (qsStart > -1) {
  27373. queryString = path.substring(qsStart + 1);
  27374. path = path.substring(0, qsStart);
  27375. }
  27376. segments = path
  27377. .split('/')
  27378. .map((s) => s.trim())
  27379. .filter((s) => s.length > 0);
  27380. if (segments.length === 0) {
  27381. segments = [''];
  27382. }
  27383. }
  27384. return { segments, queryString };
  27385. };
  27386. const printRoutes = (routes) => {
  27387. console.group(`[ion-core] ROUTES[${routes.length}]`);
  27388. for (const chain of routes) {
  27389. const segments = [];
  27390. chain.forEach((r) => segments.push(...r.segments));
  27391. const ids = chain.map((r) => r.id);
  27392. console.debug(`%c ${generatePath(segments)}`, 'font-weight: bold; padding-left: 20px', '=>\t', `(${ids.join(', ')})`);
  27393. }
  27394. console.groupEnd();
  27395. };
  27396. const printRedirects = (redirects) => {
  27397. console.group(`[ion-core] REDIRECTS[${redirects.length}]`);
  27398. for (const redirect of redirects) {
  27399. if (redirect.to) {
  27400. console.debug('FROM: ', `$c ${generatePath(redirect.from)}`, 'font-weight: bold', ' TO: ', `$c ${generatePath(redirect.to.segments)}`, 'font-weight: bold');
  27401. }
  27402. }
  27403. console.groupEnd();
  27404. };
  27405. /**
  27406. * Activates the passed route chain.
  27407. *
  27408. * There must be exactly one outlet per route entry in the chain.
  27409. *
  27410. * The methods calls setRouteId on each of the outlet with the corresponding route entry in the chain.
  27411. * setRouteId will create or select the view in the outlet.
  27412. */
  27413. const writeNavState = async (root, chain, direction, index, changed = false, animation) => {
  27414. try {
  27415. // find next navigation outlet in the DOM
  27416. const outlet = searchNavNode(root);
  27417. // make sure we can continue interacting the DOM, otherwise abort
  27418. if (index >= chain.length || !outlet) {
  27419. return changed;
  27420. }
  27421. await new Promise((resolve) => componentOnReady(outlet, resolve));
  27422. const route = chain[index];
  27423. const result = await outlet.setRouteId(route.id, route.params, direction, animation);
  27424. // if the outlet changed the page, reset navigation to neutral (no direction)
  27425. // this means nested outlets will not animate
  27426. if (result.changed) {
  27427. direction = ROUTER_INTENT_NONE;
  27428. changed = true;
  27429. }
  27430. // recursively set nested outlets
  27431. changed = await writeNavState(result.element, chain, direction, index + 1, changed, animation);
  27432. // once all nested outlets are visible let's make the parent visible too,
  27433. // using markVisible prevents flickering
  27434. if (result.markVisible) {
  27435. await result.markVisible();
  27436. }
  27437. return changed;
  27438. }
  27439. catch (e) {
  27440. printIonError('[ion-router] - Exception in writeNavState:', e);
  27441. return false;
  27442. }
  27443. };
  27444. /**
  27445. * Recursively walks the outlet in the DOM.
  27446. *
  27447. * The function returns a list of RouteID corresponding to each of the outlet and the last outlet without a RouteID.
  27448. */
  27449. const readNavState = async (root) => {
  27450. const ids = [];
  27451. let outlet;
  27452. let node = root;
  27453. // eslint-disable-next-line no-cond-assign
  27454. while ((outlet = searchNavNode(node))) {
  27455. const id = await outlet.getRouteId();
  27456. if (id) {
  27457. node = id.element;
  27458. id.element = undefined;
  27459. ids.push(id);
  27460. }
  27461. else {
  27462. break;
  27463. }
  27464. }
  27465. return { ids, outlet };
  27466. };
  27467. const waitUntilNavNode = () => {
  27468. if (searchNavNode(document.body)) {
  27469. return Promise.resolve();
  27470. }
  27471. return new Promise((resolve) => {
  27472. window.addEventListener('ionNavWillLoad', () => resolve(), { once: true });
  27473. });
  27474. };
  27475. /** Selector for all the outlets supported by the router. */
  27476. const OUTLET_SELECTOR = ':not([no-router]) ion-nav, :not([no-router]) ion-tabs, :not([no-router]) ion-router-outlet';
  27477. const searchNavNode = (root) => {
  27478. if (!root) {
  27479. return undefined;
  27480. }
  27481. if (root.matches(OUTLET_SELECTOR)) {
  27482. return root;
  27483. }
  27484. const outlet = root.querySelector(OUTLET_SELECTOR);
  27485. return outlet !== null && outlet !== void 0 ? outlet : undefined;
  27486. };
  27487. /**
  27488. * Returns whether the given redirect matches the given path segments.
  27489. *
  27490. * A redirect matches when the segments of the path and redirect.from are equal.
  27491. * Note that segments are only checked until redirect.from contains a '*' which matches any path segment.
  27492. * The path ['some', 'path', 'to', 'page'] matches both ['some', 'path', 'to', 'page'] and ['some', 'path', '*'].
  27493. */
  27494. const matchesRedirect = (segments, redirect) => {
  27495. const { from, to } = redirect;
  27496. if (to === undefined) {
  27497. return false;
  27498. }
  27499. if (from.length > segments.length) {
  27500. return false;
  27501. }
  27502. for (let i = 0; i < from.length; i++) {
  27503. const expected = from[i];
  27504. if (expected === '*') {
  27505. return true;
  27506. }
  27507. if (expected !== segments[i]) {
  27508. return false;
  27509. }
  27510. }
  27511. return from.length === segments.length;
  27512. };
  27513. /** Returns the first redirect matching the path segments or undefined when no match found. */
  27514. const findRouteRedirect = (segments, redirects) => {
  27515. return redirects.find((redirect) => matchesRedirect(segments, redirect));
  27516. };
  27517. const matchesIDs = (ids, chain) => {
  27518. const len = Math.min(ids.length, chain.length);
  27519. let score = 0;
  27520. for (let i = 0; i < len; i++) {
  27521. const routeId = ids[i];
  27522. const routeChain = chain[i];
  27523. // Skip results where the route id does not match the chain at the same index
  27524. if (routeId.id.toLowerCase() !== routeChain.id) {
  27525. break;
  27526. }
  27527. if (routeId.params) {
  27528. const routeIdParams = Object.keys(routeId.params);
  27529. // Only compare routes with the chain that have the same number of parameters.
  27530. if (routeIdParams.length === routeChain.segments.length) {
  27531. // Maps the route's params into a path based on the path variable names,
  27532. // to compare against the route chain format.
  27533. //
  27534. // Before:
  27535. // ```ts
  27536. // {
  27537. // params: {
  27538. // s1: 'a',
  27539. // s2: 'b'
  27540. // }
  27541. // }
  27542. // ```
  27543. //
  27544. // After:
  27545. // ```ts
  27546. // [':s1',':s2']
  27547. // ```
  27548. //
  27549. const pathWithParams = routeIdParams.map((key) => `:${key}`);
  27550. for (let j = 0; j < pathWithParams.length; j++) {
  27551. // Skip results where the path variable is not a match
  27552. if (pathWithParams[j].toLowerCase() !== routeChain.segments[j]) {
  27553. break;
  27554. }
  27555. // Weight path matches for the same index higher.
  27556. score++;
  27557. }
  27558. }
  27559. }
  27560. // Weight id matches
  27561. score++;
  27562. }
  27563. return score;
  27564. };
  27565. /**
  27566. * Matches the segments against the chain.
  27567. *
  27568. * Returns:
  27569. * - null when there is no match,
  27570. * - a chain with the params properties updated with the parameter segments on match.
  27571. */
  27572. const matchesSegments = (segments, chain) => {
  27573. const inputSegments = new RouterSegments(segments);
  27574. let matchesDefault = false;
  27575. let allparams;
  27576. for (let i = 0; i < chain.length; i++) {
  27577. const chainSegments = chain[i].segments;
  27578. if (chainSegments[0] === '') {
  27579. matchesDefault = true;
  27580. }
  27581. else {
  27582. for (const segment of chainSegments) {
  27583. const data = inputSegments.next();
  27584. // data param
  27585. if (segment[0] === ':') {
  27586. if (data === '') {
  27587. return null;
  27588. }
  27589. allparams = allparams || [];
  27590. const params = allparams[i] || (allparams[i] = {});
  27591. params[segment.slice(1)] = data;
  27592. }
  27593. else if (data !== segment) {
  27594. return null;
  27595. }
  27596. }
  27597. matchesDefault = false;
  27598. }
  27599. }
  27600. const matches = matchesDefault ? matchesDefault === (inputSegments.next() === '') : true;
  27601. if (!matches) {
  27602. return null;
  27603. }
  27604. if (allparams) {
  27605. return chain.map((route, i) => ({
  27606. id: route.id,
  27607. segments: route.segments,
  27608. params: mergeParams(route.params, allparams[i]),
  27609. beforeEnter: route.beforeEnter,
  27610. beforeLeave: route.beforeLeave,
  27611. }));
  27612. }
  27613. return chain;
  27614. };
  27615. /**
  27616. * Merges the route parameter objects.
  27617. * Returns undefined when both parameters are undefined.
  27618. */
  27619. const mergeParams = (a, b) => {
  27620. return a || b ? Object.assign(Object.assign({}, a), b) : undefined;
  27621. };
  27622. /**
  27623. * Finds the best match for the ids in the chains.
  27624. *
  27625. * Returns the best match or null when no match is found.
  27626. * When a chain is returned the parameters are updated from the RouteIDs.
  27627. * That is they contain both the componentProps of the <ion-route> and the parameter segment.
  27628. */
  27629. const findChainForIDs = (ids, chains) => {
  27630. let match = null;
  27631. let maxMatches = 0;
  27632. for (const chain of chains) {
  27633. const score = matchesIDs(ids, chain);
  27634. if (score > maxMatches) {
  27635. match = chain;
  27636. maxMatches = score;
  27637. }
  27638. }
  27639. if (match) {
  27640. return match.map((route, i) => {
  27641. var _a;
  27642. return ({
  27643. id: route.id,
  27644. segments: route.segments,
  27645. params: mergeParams(route.params, (_a = ids[i]) === null || _a === void 0 ? void 0 : _a.params),
  27646. });
  27647. });
  27648. }
  27649. return null;
  27650. };
  27651. /**
  27652. * Finds the best match for the segments in the chains.
  27653. *
  27654. * Returns the best match or null when no match is found.
  27655. * When a chain is returned the parameters are updated from the segments.
  27656. * That is they contain both the componentProps of the <ion-route> and the parameter segments.
  27657. */
  27658. const findChainForSegments = (segments, chains) => {
  27659. let match = null;
  27660. let bestScore = 0;
  27661. for (const chain of chains) {
  27662. const matchedChain = matchesSegments(segments, chain);
  27663. if (matchedChain !== null) {
  27664. const score = computePriority(matchedChain);
  27665. if (score > bestScore) {
  27666. bestScore = score;
  27667. match = matchedChain;
  27668. }
  27669. }
  27670. }
  27671. return match;
  27672. };
  27673. /**
  27674. * Computes the priority of a chain.
  27675. *
  27676. * Parameter segments are given a lower priority over fixed segments.
  27677. *
  27678. * Considering the following 2 chains matching the path /path/to/page:
  27679. * - /path/to/:where
  27680. * - /path/to/page
  27681. *
  27682. * The second one will be given a higher priority because "page" is a fixed segment (vs ":where", a parameter segment).
  27683. */
  27684. const computePriority = (chain) => {
  27685. let score = 1;
  27686. let level = 1;
  27687. for (const route of chain) {
  27688. for (const segment of route.segments) {
  27689. if (segment[0] === ':') {
  27690. score += Math.pow(1, level);
  27691. }
  27692. else if (segment !== '') {
  27693. score += Math.pow(2, level);
  27694. }
  27695. level++;
  27696. }
  27697. }
  27698. return score;
  27699. };
  27700. class RouterSegments {
  27701. constructor(segments) {
  27702. this.segments = segments.slice();
  27703. }
  27704. next() {
  27705. if (this.segments.length > 0) {
  27706. return this.segments.shift();
  27707. }
  27708. return '';
  27709. }
  27710. }
  27711. const readProp = (el, prop) => {
  27712. if (prop in el) {
  27713. return el[prop];
  27714. }
  27715. if (el.hasAttribute(prop)) {
  27716. return el.getAttribute(prop);
  27717. }
  27718. return null;
  27719. };
  27720. /**
  27721. * Extracts the redirects (that is <ion-route-redirect> elements inside the root).
  27722. *
  27723. * The redirects are returned as a list of RouteRedirect.
  27724. */
  27725. const readRedirects = (root) => {
  27726. return Array.from(root.children)
  27727. .filter((el) => el.tagName === 'ION-ROUTE-REDIRECT')
  27728. .map((el) => {
  27729. const to = readProp(el, 'to');
  27730. return {
  27731. from: parsePath(readProp(el, 'from')).segments,
  27732. to: to == null ? undefined : parsePath(to),
  27733. };
  27734. });
  27735. };
  27736. /**
  27737. * Extracts all the routes (that is <ion-route> elements inside the root).
  27738. *
  27739. * The routes are returned as a list of chains - the flattened tree.
  27740. */
  27741. const readRoutes = (root) => {
  27742. return flattenRouterTree(readRouteNodes(root));
  27743. };
  27744. /**
  27745. * Reads the route nodes as a tree modeled after the DOM tree of <ion-route> elements.
  27746. *
  27747. * Note: routes without a component are ignored together with their children.
  27748. */
  27749. const readRouteNodes = (node) => {
  27750. return Array.from(node.children)
  27751. .filter((el) => el.tagName === 'ION-ROUTE' && el.component)
  27752. .map((el) => {
  27753. const component = readProp(el, 'component');
  27754. return {
  27755. segments: parsePath(readProp(el, 'url')).segments,
  27756. id: component.toLowerCase(),
  27757. params: el.componentProps,
  27758. beforeLeave: el.beforeLeave,
  27759. beforeEnter: el.beforeEnter,
  27760. children: readRouteNodes(el),
  27761. };
  27762. });
  27763. };
  27764. /**
  27765. * Flattens a RouterTree in a list of chains.
  27766. *
  27767. * Each chain represents a path from the root node to a terminal node.
  27768. */
  27769. const flattenRouterTree = (nodes) => {
  27770. const chains = [];
  27771. for (const node of nodes) {
  27772. flattenNode([], chains, node);
  27773. }
  27774. return chains;
  27775. };
  27776. /** Flattens a route node recursively and push each branch to the chains list. */
  27777. const flattenNode = (chain, chains, node) => {
  27778. chain = [
  27779. ...chain,
  27780. {
  27781. id: node.id,
  27782. segments: node.segments,
  27783. params: node.params,
  27784. beforeLeave: node.beforeLeave,
  27785. beforeEnter: node.beforeEnter,
  27786. },
  27787. ];
  27788. if (node.children.length === 0) {
  27789. chains.push(chain);
  27790. return;
  27791. }
  27792. for (const child of node.children) {
  27793. flattenNode(chain, chains, child);
  27794. }
  27795. };
  27796. class Router {
  27797. constructor(hostRef) {
  27798. registerInstance(this, hostRef);
  27799. this.ionRouteWillChange = createEvent(this, "ionRouteWillChange", 7);
  27800. this.ionRouteDidChange = createEvent(this, "ionRouteDidChange", 7);
  27801. this.previousPath = null;
  27802. this.busy = false;
  27803. this.state = 0;
  27804. this.lastState = 0;
  27805. this.root = '/';
  27806. this.useHash = true;
  27807. }
  27808. async componentWillLoad() {
  27809. await waitUntilNavNode();
  27810. const canProceed = await this.runGuards(this.getSegments());
  27811. if (canProceed !== true) {
  27812. if (typeof canProceed === 'object') {
  27813. const { redirect } = canProceed;
  27814. const path = parsePath(redirect);
  27815. this.setSegments(path.segments, ROUTER_INTENT_NONE, path.queryString);
  27816. await this.writeNavStateRoot(path.segments, ROUTER_INTENT_NONE);
  27817. }
  27818. }
  27819. else {
  27820. await this.onRoutesChanged();
  27821. }
  27822. }
  27823. componentDidLoad() {
  27824. window.addEventListener('ionRouteRedirectChanged', debounce(this.onRedirectChanged.bind(this), 10));
  27825. window.addEventListener('ionRouteDataChanged', debounce(this.onRoutesChanged.bind(this), 100));
  27826. }
  27827. async onPopState() {
  27828. const direction = this.historyDirection();
  27829. let segments = this.getSegments();
  27830. const canProceed = await this.runGuards(segments);
  27831. if (canProceed !== true) {
  27832. if (typeof canProceed === 'object') {
  27833. segments = parsePath(canProceed.redirect).segments;
  27834. }
  27835. else {
  27836. return false;
  27837. }
  27838. }
  27839. return this.writeNavStateRoot(segments, direction);
  27840. }
  27841. onBackButton(ev) {
  27842. ev.detail.register(0, (processNextHandler) => {
  27843. this.back();
  27844. processNextHandler();
  27845. });
  27846. }
  27847. /** @internal */
  27848. async canTransition() {
  27849. const canProceed = await this.runGuards();
  27850. if (canProceed !== true) {
  27851. if (typeof canProceed === 'object') {
  27852. return canProceed.redirect;
  27853. }
  27854. else {
  27855. return false;
  27856. }
  27857. }
  27858. return true;
  27859. }
  27860. /**
  27861. * Navigate to the specified path.
  27862. *
  27863. * @param path The path to navigate to.
  27864. * @param direction The direction of the animation. Defaults to `"forward"`.
  27865. */
  27866. async push(path, direction = 'forward', animation) {
  27867. var _a;
  27868. if (path.startsWith('.')) {
  27869. const currentPath = (_a = this.previousPath) !== null && _a !== void 0 ? _a : '/';
  27870. // Convert currentPath to an URL by pre-pending a protocol and a host to resolve the relative path.
  27871. const url = new URL(path, `https://host/${currentPath}`);
  27872. path = url.pathname + url.search;
  27873. }
  27874. let parsedPath = parsePath(path);
  27875. const canProceed = await this.runGuards(parsedPath.segments);
  27876. if (canProceed !== true) {
  27877. if (typeof canProceed === 'object') {
  27878. parsedPath = parsePath(canProceed.redirect);
  27879. }
  27880. else {
  27881. return false;
  27882. }
  27883. }
  27884. this.setSegments(parsedPath.segments, direction, parsedPath.queryString);
  27885. return this.writeNavStateRoot(parsedPath.segments, direction, animation);
  27886. }
  27887. /** Go back to previous page in the window.history. */
  27888. back() {
  27889. window.history.back();
  27890. return Promise.resolve(this.waitPromise);
  27891. }
  27892. /** @internal */
  27893. async printDebug() {
  27894. printRoutes(readRoutes(this.el));
  27895. printRedirects(readRedirects(this.el));
  27896. }
  27897. /** @internal */
  27898. async navChanged(direction) {
  27899. if (this.busy) {
  27900. printIonWarning('[ion-router] - Router is busy, navChanged was cancelled.');
  27901. return false;
  27902. }
  27903. const { ids, outlet } = await readNavState(window.document.body);
  27904. const routes = readRoutes(this.el);
  27905. const chain = findChainForIDs(ids, routes);
  27906. if (!chain) {
  27907. printIonWarning('[ion-router] - No matching URL for', ids.map((i) => i.id));
  27908. return false;
  27909. }
  27910. const segments = chainToSegments(chain);
  27911. if (!segments) {
  27912. printIonWarning('[ion-router] - Router could not match path because some required param is missing.');
  27913. return false;
  27914. }
  27915. this.setSegments(segments, direction);
  27916. await this.safeWriteNavState(outlet, chain, ROUTER_INTENT_NONE, segments, null, ids.length);
  27917. return true;
  27918. }
  27919. /** This handler gets called when a `ion-route-redirect` component is added to the DOM or if the from or to property of such node changes. */
  27920. onRedirectChanged() {
  27921. const segments = this.getSegments();
  27922. if (segments && findRouteRedirect(segments, readRedirects(this.el))) {
  27923. this.writeNavStateRoot(segments, ROUTER_INTENT_NONE);
  27924. }
  27925. }
  27926. /** This handler gets called when a `ion-route` component is added to the DOM or if the from or to property of such node changes. */
  27927. onRoutesChanged() {
  27928. return this.writeNavStateRoot(this.getSegments(), ROUTER_INTENT_NONE);
  27929. }
  27930. historyDirection() {
  27931. var _a;
  27932. const win = window;
  27933. if (win.history.state === null) {
  27934. this.state++;
  27935. win.history.replaceState(this.state, win.document.title, (_a = win.document.location) === null || _a === void 0 ? void 0 : _a.href);
  27936. }
  27937. const state = win.history.state;
  27938. const lastState = this.lastState;
  27939. this.lastState = state;
  27940. if (state > lastState || (state >= lastState && lastState > 0)) {
  27941. return ROUTER_INTENT_FORWARD;
  27942. }
  27943. if (state < lastState) {
  27944. return ROUTER_INTENT_BACK;
  27945. }
  27946. return ROUTER_INTENT_NONE;
  27947. }
  27948. async writeNavStateRoot(segments, direction, animation) {
  27949. if (!segments) {
  27950. printIonError('[ion-router] - URL is not part of the routing set.');
  27951. return false;
  27952. }
  27953. // lookup redirect rule
  27954. const redirects = readRedirects(this.el);
  27955. const redirect = findRouteRedirect(segments, redirects);
  27956. let redirectFrom = null;
  27957. if (redirect) {
  27958. const { segments: toSegments, queryString } = redirect.to;
  27959. this.setSegments(toSegments, direction, queryString);
  27960. redirectFrom = redirect.from;
  27961. segments = toSegments;
  27962. }
  27963. // lookup route chain
  27964. const routes = readRoutes(this.el);
  27965. const chain = findChainForSegments(segments, routes);
  27966. if (!chain) {
  27967. printIonError('[ion-router] - The path does not match any route.');
  27968. return false;
  27969. }
  27970. // write DOM give
  27971. return this.safeWriteNavState(document.body, chain, direction, segments, redirectFrom, 0, animation);
  27972. }
  27973. async safeWriteNavState(node, chain, direction, segments, redirectFrom, index = 0, animation) {
  27974. const unlock = await this.lock();
  27975. let changed = false;
  27976. try {
  27977. changed = await this.writeNavState(node, chain, direction, segments, redirectFrom, index, animation);
  27978. }
  27979. catch (e) {
  27980. printIonError('[ion-router] - Exception in safeWriteNavState:', e);
  27981. }
  27982. unlock();
  27983. return changed;
  27984. }
  27985. async lock() {
  27986. const p = this.waitPromise;
  27987. let resolve;
  27988. this.waitPromise = new Promise((r) => (resolve = r));
  27989. if (p !== undefined) {
  27990. await p;
  27991. }
  27992. return resolve;
  27993. }
  27994. /**
  27995. * Executes the beforeLeave hook of the source route and the beforeEnter hook of the target route if they exist.
  27996. *
  27997. * When the beforeLeave hook does not return true (to allow navigating) then that value is returned early and the beforeEnter is executed.
  27998. * Otherwise the beforeEnterHook hook of the target route is executed.
  27999. */
  28000. async runGuards(to = this.getSegments(), from) {
  28001. if (from === undefined) {
  28002. from = parsePath(this.previousPath).segments;
  28003. }
  28004. if (!to || !from) {
  28005. return true;
  28006. }
  28007. const routes = readRoutes(this.el);
  28008. const fromChain = findChainForSegments(from, routes);
  28009. // eslint-disable-next-line @typescript-eslint/prefer-optional-chain
  28010. const beforeLeaveHook = fromChain && fromChain[fromChain.length - 1].beforeLeave;
  28011. const canLeave = beforeLeaveHook ? await beforeLeaveHook() : true;
  28012. if (canLeave === false || typeof canLeave === 'object') {
  28013. return canLeave;
  28014. }
  28015. const toChain = findChainForSegments(to, routes);
  28016. // eslint-disable-next-line @typescript-eslint/prefer-optional-chain
  28017. const beforeEnterHook = toChain && toChain[toChain.length - 1].beforeEnter;
  28018. return beforeEnterHook ? beforeEnterHook() : true;
  28019. }
  28020. async writeNavState(node, chain, direction, segments, redirectFrom, index = 0, animation) {
  28021. if (this.busy) {
  28022. printIonWarning('[ion-router] - Router is busy, transition was cancelled.');
  28023. return false;
  28024. }
  28025. this.busy = true;
  28026. // generate route event and emit will change
  28027. const routeEvent = this.routeChangeEvent(segments, redirectFrom);
  28028. if (routeEvent) {
  28029. this.ionRouteWillChange.emit(routeEvent);
  28030. }
  28031. const changed = await writeNavState(node, chain, direction, index, false, animation);
  28032. this.busy = false;
  28033. // emit did change
  28034. if (routeEvent) {
  28035. this.ionRouteDidChange.emit(routeEvent);
  28036. }
  28037. return changed;
  28038. }
  28039. setSegments(segments, direction, queryString) {
  28040. this.state++;
  28041. writeSegments(window.history, this.root, this.useHash, segments, direction, this.state, queryString);
  28042. }
  28043. getSegments() {
  28044. return readSegments(window.location, this.root, this.useHash);
  28045. }
  28046. routeChangeEvent(toSegments, redirectFromSegments) {
  28047. const from = this.previousPath;
  28048. const to = generatePath(toSegments);
  28049. this.previousPath = to;
  28050. if (to === from) {
  28051. return null;
  28052. }
  28053. const redirectedFrom = redirectFromSegments ? generatePath(redirectFromSegments) : null;
  28054. return {
  28055. from,
  28056. redirectedFrom,
  28057. to,
  28058. };
  28059. }
  28060. get el() { return getElement(this); }
  28061. static get cmpMeta() { return {
  28062. "$flags$": 0,
  28063. "$tagName$": "ion-router",
  28064. "$members$": {
  28065. "root": [1],
  28066. "useHash": [4, "use-hash"],
  28067. "canTransition": [64],
  28068. "push": [64],
  28069. "back": [64],
  28070. "printDebug": [64],
  28071. "navChanged": [64]
  28072. },
  28073. "$listeners$": [[8, "popstate", "onPopState"], [4, "ionBackButton", "onBackButton"]],
  28074. "$lazyBundleId$": "-",
  28075. "$attrsToReflect$": []
  28076. }; }
  28077. }
  28078. const routerLinkCss = ":host{--background:transparent;--color:var(--ion-color-primary, #0054e9);background:var(--background);color:var(--color)}:host(.ion-color){color:var(--ion-color-base)}a{font-family:inherit;font-size:inherit;font-style:inherit;font-weight:inherit;letter-spacing:inherit;text-decoration:inherit;text-indent:inherit;text-overflow:inherit;text-transform:inherit;text-align:inherit;white-space:inherit;color:inherit}";
  28079. var IonRouterLinkStyle0 = routerLinkCss;
  28080. class RouterLink {
  28081. constructor(hostRef) {
  28082. registerInstance(this, hostRef);
  28083. this.onClick = (ev) => {
  28084. openURL(this.href, ev, this.routerDirection, this.routerAnimation);
  28085. };
  28086. this.color = undefined;
  28087. this.href = undefined;
  28088. this.rel = undefined;
  28089. this.routerDirection = 'forward';
  28090. this.routerAnimation = undefined;
  28091. this.target = undefined;
  28092. }
  28093. render() {
  28094. const mode = getIonMode$1(this);
  28095. const attrs = {
  28096. href: this.href,
  28097. rel: this.rel,
  28098. target: this.target,
  28099. };
  28100. return (hAsync(Host, { key: '11183264fb6ae0db9a7a47c71b6862d60001b834', onClick: this.onClick, class: createColorClasses$1(this.color, {
  28101. [mode]: true,
  28102. 'ion-activatable': true,
  28103. }) }, hAsync("a", Object.assign({ key: '3e0e5242161cb0df593d6d573e51b8ba750065a1' }, attrs), hAsync("slot", { key: '5bd808e98a4627bb1236f0d955f4b32971355417' }))));
  28104. }
  28105. static get style() { return IonRouterLinkStyle0; }
  28106. static get cmpMeta() { return {
  28107. "$flags$": 9,
  28108. "$tagName$": "ion-router-link",
  28109. "$members$": {
  28110. "color": [513],
  28111. "href": [1],
  28112. "rel": [1],
  28113. "routerDirection": [1, "router-direction"],
  28114. "routerAnimation": [16],
  28115. "target": [1]
  28116. },
  28117. "$listeners$": undefined,
  28118. "$lazyBundleId$": "-",
  28119. "$attrsToReflect$": [["color", "color"]]
  28120. }; }
  28121. }
  28122. const routerOutletCss = ":host{left:0;right:0;top:0;bottom:0;position:absolute;contain:layout size style;z-index:0}";
  28123. var IonRouterOutletStyle0 = routerOutletCss;
  28124. class RouterOutlet {
  28125. constructor(hostRef) {
  28126. registerInstance(this, hostRef);
  28127. this.ionNavWillLoad = createEvent(this, "ionNavWillLoad", 7);
  28128. this.ionNavWillChange = createEvent(this, "ionNavWillChange", 3);
  28129. this.ionNavDidChange = createEvent(this, "ionNavDidChange", 3);
  28130. this.lockController = createLockController();
  28131. this.gestureOrAnimationInProgress = false;
  28132. this.mode = getIonMode$1(this);
  28133. this.delegate = undefined;
  28134. this.animated = true;
  28135. this.animation = undefined;
  28136. this.swipeHandler = undefined;
  28137. }
  28138. swipeHandlerChanged() {
  28139. if (this.gesture) {
  28140. this.gesture.enable(this.swipeHandler !== undefined);
  28141. }
  28142. }
  28143. async connectedCallback() {
  28144. const onStart = () => {
  28145. this.gestureOrAnimationInProgress = true;
  28146. if (this.swipeHandler) {
  28147. this.swipeHandler.onStart();
  28148. }
  28149. };
  28150. this.gesture = (await Promise.resolve().then(function () { return swipeBack; })).createSwipeBackGesture(this.el, () => !this.gestureOrAnimationInProgress && !!this.swipeHandler && this.swipeHandler.canStart(), () => onStart(), (step) => { var _a; return (_a = this.ani) === null || _a === void 0 ? void 0 : _a.progressStep(step); }, (shouldComplete, step, dur) => {
  28151. if (this.ani) {
  28152. this.ani.onFinish(() => {
  28153. this.gestureOrAnimationInProgress = false;
  28154. if (this.swipeHandler) {
  28155. this.swipeHandler.onEnd(shouldComplete);
  28156. }
  28157. }, { oneTimeCallback: true });
  28158. // Account for rounding errors in JS
  28159. let newStepValue = shouldComplete ? -0.001 : 0.001;
  28160. /**
  28161. * Animation will be reversed here, so need to
  28162. * reverse the easing curve as well
  28163. *
  28164. * Additionally, we need to account for the time relative
  28165. * to the new easing curve, as `stepValue` is going to be given
  28166. * in terms of a linear curve.
  28167. */
  28168. if (!shouldComplete) {
  28169. this.ani.easing('cubic-bezier(1, 0, 0.68, 0.28)');
  28170. newStepValue += getTimeGivenProgression([0, 0], [1, 0], [0.68, 0.28], [1, 1], step)[0];
  28171. }
  28172. else {
  28173. newStepValue += getTimeGivenProgression([0, 0], [0.32, 0.72], [0, 1], [1, 1], step)[0];
  28174. }
  28175. this.ani.progressEnd(shouldComplete ? 1 : 0, newStepValue, dur);
  28176. }
  28177. else {
  28178. this.gestureOrAnimationInProgress = false;
  28179. }
  28180. });
  28181. this.swipeHandlerChanged();
  28182. }
  28183. componentWillLoad() {
  28184. this.ionNavWillLoad.emit();
  28185. }
  28186. disconnectedCallback() {
  28187. if (this.gesture) {
  28188. this.gesture.destroy();
  28189. this.gesture = undefined;
  28190. }
  28191. }
  28192. /** @internal */
  28193. async commit(enteringEl, leavingEl, opts) {
  28194. const unlock = await this.lockController.lock();
  28195. let changed = false;
  28196. try {
  28197. changed = await this.transition(enteringEl, leavingEl, opts);
  28198. }
  28199. catch (e) {
  28200. printIonError('[ion-router-outlet] - Exception in commit:', e);
  28201. }
  28202. unlock();
  28203. return changed;
  28204. }
  28205. /** @internal */
  28206. async setRouteId(id, params, direction, animation) {
  28207. const changed = await this.setRoot(id, params, {
  28208. duration: direction === 'root' ? 0 : undefined,
  28209. direction: direction === 'back' ? 'back' : 'forward',
  28210. animationBuilder: animation,
  28211. });
  28212. return {
  28213. changed,
  28214. element: this.activeEl,
  28215. };
  28216. }
  28217. /** @internal */
  28218. async getRouteId() {
  28219. const active = this.activeEl;
  28220. return active
  28221. ? {
  28222. id: active.tagName,
  28223. element: active,
  28224. params: this.activeParams,
  28225. }
  28226. : undefined;
  28227. }
  28228. async setRoot(component, params, opts) {
  28229. if (this.activeComponent === component && shallowEqualStringMap(params, this.activeParams)) {
  28230. return false;
  28231. }
  28232. // attach entering view to DOM
  28233. const leavingEl = this.activeEl;
  28234. const enteringEl = await attachComponent(this.delegate, this.el, component, ['ion-page', 'ion-page-invisible'], params);
  28235. this.activeComponent = component;
  28236. this.activeEl = enteringEl;
  28237. this.activeParams = params;
  28238. // commit animation
  28239. await this.commit(enteringEl, leavingEl, opts);
  28240. await detachComponent(this.delegate, leavingEl);
  28241. return true;
  28242. }
  28243. async transition(enteringEl, leavingEl, opts = {}) {
  28244. if (leavingEl === enteringEl) {
  28245. return false;
  28246. }
  28247. // emit nav will change event
  28248. this.ionNavWillChange.emit();
  28249. const { el, mode } = this;
  28250. const animated = this.animated && config.getBoolean('animated', true);
  28251. const animationBuilder = opts.animationBuilder || this.animation || config.get('navAnimation');
  28252. await transition(Object.assign(Object.assign({ mode,
  28253. animated,
  28254. enteringEl,
  28255. leavingEl, baseEl: el,
  28256. /**
  28257. * We need to wait for all Stencil components
  28258. * to be ready only when using the lazy
  28259. * loaded bundle.
  28260. */
  28261. deepWait: hasLazyBuild(el), progressCallback: opts.progressAnimation
  28262. ? (ani) => {
  28263. /**
  28264. * Because this progress callback is called asynchronously
  28265. * it is possible for the gesture to start and end before
  28266. * the animation is ever set. In that scenario, we should
  28267. * immediately call progressEnd so that the transition promise
  28268. * resolves and the gesture does not get locked up.
  28269. */
  28270. if (ani !== undefined && !this.gestureOrAnimationInProgress) {
  28271. this.gestureOrAnimationInProgress = true;
  28272. ani.onFinish(() => {
  28273. this.gestureOrAnimationInProgress = false;
  28274. if (this.swipeHandler) {
  28275. this.swipeHandler.onEnd(false);
  28276. }
  28277. }, { oneTimeCallback: true });
  28278. /**
  28279. * Playing animation to beginning
  28280. * with a duration of 0 prevents
  28281. * any flickering when the animation
  28282. * is later cleaned up.
  28283. */
  28284. ani.progressEnd(0, 0, 0);
  28285. }
  28286. else {
  28287. this.ani = ani;
  28288. }
  28289. }
  28290. : undefined }, opts), { animationBuilder }));
  28291. // emit nav changed event
  28292. this.ionNavDidChange.emit();
  28293. return true;
  28294. }
  28295. render() {
  28296. return hAsync("slot", { key: 'e34e02b5154172c8d5cdd187b6ea58119b6946eb' });
  28297. }
  28298. get el() { return getElement(this); }
  28299. static get watchers() { return {
  28300. "swipeHandler": ["swipeHandlerChanged"]
  28301. }; }
  28302. static get style() { return IonRouterOutletStyle0; }
  28303. static get cmpMeta() { return {
  28304. "$flags$": 9,
  28305. "$tagName$": "ion-router-outlet",
  28306. "$members$": {
  28307. "mode": [1025],
  28308. "delegate": [16],
  28309. "animated": [4],
  28310. "animation": [16],
  28311. "swipeHandler": [16],
  28312. "commit": [64],
  28313. "setRouteId": [64],
  28314. "getRouteId": [64]
  28315. },
  28316. "$listeners$": undefined,
  28317. "$lazyBundleId$": "-",
  28318. "$attrsToReflect$": []
  28319. }; }
  28320. }
  28321. const rowCss = ":host{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap}";
  28322. var IonRowStyle0 = rowCss;
  28323. class Row {
  28324. constructor(hostRef) {
  28325. registerInstance(this, hostRef);
  28326. }
  28327. render() {
  28328. return (hAsync(Host, { key: 'a690022e2abdce6946d24264574e4aa0886a8ea5', class: getIonMode$1(this) }, hAsync("slot", { key: 'd1a0e831dd1dbfe7877d3ad01d0a3045a5fb29e3' })));
  28329. }
  28330. static get style() { return IonRowStyle0; }
  28331. static get cmpMeta() { return {
  28332. "$flags$": 9,
  28333. "$tagName$": "ion-row",
  28334. "$members$": undefined,
  28335. "$listeners$": undefined,
  28336. "$lazyBundleId$": "-",
  28337. "$attrsToReflect$": []
  28338. }; }
  28339. }
  28340. const searchbarIosCss = ".sc-ion-searchbar-ios-h{--placeholder-color:initial;--placeholder-font-style:initial;--placeholder-font-weight:initial;--placeholder-opacity:var(--ion-placeholder-opacity, 0.6);-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;display:-ms-flexbox;display:flex;position:relative;-ms-flex-align:center;align-items:center;width:100%;color:var(--color);font-family:var(--ion-font-family, inherit);-webkit-box-sizing:border-box;box-sizing:border-box}.ion-color.sc-ion-searchbar-ios-h{color:var(--ion-color-contrast)}.ion-color.sc-ion-searchbar-ios-h .searchbar-input.sc-ion-searchbar-ios{background:var(--ion-color-base)}.ion-color.sc-ion-searchbar-ios-h .searchbar-clear-button.sc-ion-searchbar-ios,.ion-color.sc-ion-searchbar-ios-h .searchbar-cancel-button.sc-ion-searchbar-ios,.ion-color.sc-ion-searchbar-ios-h .searchbar-search-icon.sc-ion-searchbar-ios{color:inherit}.searchbar-search-icon.sc-ion-searchbar-ios{color:var(--icon-color);pointer-events:none}.searchbar-input-container.sc-ion-searchbar-ios{display:block;position:relative;-ms-flex-negative:1;flex-shrink:1;width:100%}.searchbar-input.sc-ion-searchbar-ios{font-family:inherit;font-size:inherit;font-style:inherit;font-weight:inherit;letter-spacing:inherit;text-decoration:inherit;text-indent:inherit;text-overflow:inherit;text-transform:inherit;text-align:inherit;white-space:inherit;color:inherit;border-radius:var(--border-radius);display:block;width:100%;min-height:inherit;border:0;outline:none;background:var(--background);font-family:inherit;-webkit-box-shadow:var(--box-shadow);box-shadow:var(--box-shadow);-webkit-box-sizing:border-box;box-sizing:border-box;-webkit-appearance:none;-moz-appearance:none;appearance:none}.searchbar-input.sc-ion-searchbar-ios::-webkit-input-placeholder{color:var(--placeholder-color);font-family:inherit;font-style:var(--placeholder-font-style);font-weight:var(--placeholder-font-weight);opacity:var(--placeholder-opacity)}.searchbar-input.sc-ion-searchbar-ios::-moz-placeholder{color:var(--placeholder-color);font-family:inherit;font-style:var(--placeholder-font-style);font-weight:var(--placeholder-font-weight);opacity:var(--placeholder-opacity)}.searchbar-input.sc-ion-searchbar-ios:-ms-input-placeholder{color:var(--placeholder-color);font-family:inherit;font-style:var(--placeholder-font-style);font-weight:var(--placeholder-font-weight);opacity:var(--placeholder-opacity)}.searchbar-input.sc-ion-searchbar-ios::-ms-input-placeholder{color:var(--placeholder-color);font-family:inherit;font-style:var(--placeholder-font-style);font-weight:var(--placeholder-font-weight);opacity:var(--placeholder-opacity)}.searchbar-input.sc-ion-searchbar-ios::placeholder{color:var(--placeholder-color);font-family:inherit;font-style:var(--placeholder-font-style);font-weight:var(--placeholder-font-weight);opacity:var(--placeholder-opacity)}.searchbar-input.sc-ion-searchbar-ios::-webkit-search-cancel-button,.searchbar-input.sc-ion-searchbar-ios::-ms-clear{display:none}.searchbar-cancel-button.sc-ion-searchbar-ios{margin-left:0;margin-right:0;margin-top:0;margin-bottom:0;display:none;height:100%;border:0;outline:none;color:var(--cancel-button-color);cursor:pointer;-webkit-appearance:none;-moz-appearance:none;appearance:none}.searchbar-cancel-button.sc-ion-searchbar-ios>div.sc-ion-searchbar-ios{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;width:100%;height:100%}.searchbar-clear-button.sc-ion-searchbar-ios{margin-left:0;margin-right:0;margin-top:0;margin-bottom:0;padding-left:0;padding-right:0;padding-top:0;padding-bottom:0;display:none;min-height:0;outline:none;color:var(--clear-button-color);-webkit-appearance:none;-moz-appearance:none;appearance:none}.searchbar-clear-button.sc-ion-searchbar-ios:focus{opacity:0.5}.searchbar-has-value.searchbar-should-show-clear.sc-ion-searchbar-ios-h .searchbar-clear-button.sc-ion-searchbar-ios{display:block}.searchbar-disabled.sc-ion-searchbar-ios-h{cursor:default;opacity:0.4;pointer-events:none}.sc-ion-searchbar-ios-h{--background:rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.07);--border-radius:10px;--box-shadow:none;--cancel-button-color:var(--ion-color-primary, #0054e9);--clear-button-color:var(--ion-color-step-600, var(--ion-text-color-step-400, #666666));--color:var(--ion-text-color, #000);--icon-color:var(--ion-color-step-600, var(--ion-text-color-step-400, #666666));-webkit-padding-start:12px;padding-inline-start:12px;-webkit-padding-end:12px;padding-inline-end:12px;padding-top:12px;padding-bottom:12px;min-height:60px;contain:content}.searchbar-input-container.sc-ion-searchbar-ios{min-height:36px}.searchbar-search-icon.sc-ion-searchbar-ios{-webkit-margin-start:calc(50% - 60px);margin-inline-start:calc(50% - 60px);top:0;position:absolute;width:1.375rem;height:100%;contain:strict}.searchbar-search-icon.sc-ion-searchbar-ios{inset-inline-start:5px}.searchbar-input.sc-ion-searchbar-ios{-webkit-padding-start:0px;padding-inline-start:0px;-webkit-padding-end:0px;padding-inline-end:0px;padding-top:6px;padding-bottom:6px;height:100%;font-size:1.0625rem;font-weight:400;contain:strict}.searchbar-has-value.searchbar-should-show-clear.sc-ion-searchbar-ios-h .searchbar-input.sc-ion-searchbar-ios{-webkit-padding-start:1.75rem;padding-inline-start:1.75rem;-webkit-padding-end:1.75rem;padding-inline-end:1.75rem}.searchbar-clear-button.sc-ion-searchbar-ios{top:0;background-position:center;position:absolute;width:1.875rem;height:100%;border:0;background-color:transparent}.searchbar-clear-button.sc-ion-searchbar-ios{inset-inline-end:0}.searchbar-clear-icon.sc-ion-searchbar-ios{width:1.125rem;height:100%}.searchbar-cancel-button.sc-ion-searchbar-ios{-webkit-padding-start:12px;padding-inline-start:12px;-webkit-padding-end:0;padding-inline-end:0;padding-top:0;padding-bottom:0;-ms-flex-negative:0;flex-shrink:0;background-color:transparent;font-size:17px}.searchbar-left-aligned.sc-ion-searchbar-ios-h .searchbar-search-icon.sc-ion-searchbar-ios{-webkit-margin-start:0;margin-inline-start:0}.searchbar-left-aligned.sc-ion-searchbar-ios-h .searchbar-input.sc-ion-searchbar-ios{-webkit-padding-start:1.875rem;padding-inline-start:1.875rem}.searchbar-has-focus.sc-ion-searchbar-ios-h .searchbar-cancel-button.sc-ion-searchbar-ios,.searchbar-should-show-cancel.sc-ion-searchbar-ios-h .searchbar-cancel-button.sc-ion-searchbar-ios,.searchbar-animated.sc-ion-searchbar-ios-h .searchbar-cancel-button.sc-ion-searchbar-ios{display:block}.searchbar-animated.sc-ion-searchbar-ios-h .searchbar-search-icon.sc-ion-searchbar-ios,.searchbar-animated.sc-ion-searchbar-ios-h .searchbar-input.sc-ion-searchbar-ios{-webkit-transition:all 300ms ease;transition:all 300ms ease}.searchbar-animated.searchbar-has-focus.sc-ion-searchbar-ios-h .searchbar-cancel-button.sc-ion-searchbar-ios,.searchbar-animated.searchbar-should-show-cancel.sc-ion-searchbar-ios-h .searchbar-cancel-button.sc-ion-searchbar-ios{opacity:1;pointer-events:auto}.searchbar-animated.sc-ion-searchbar-ios-h .searchbar-cancel-button.sc-ion-searchbar-ios{-webkit-margin-end:-100%;margin-inline-end:-100%;-webkit-transform:translate3d(0, 0, 0);transform:translate3d(0, 0, 0);-webkit-transition:all 300ms ease;transition:all 300ms ease;opacity:0;pointer-events:none}.searchbar-no-animate.sc-ion-searchbar-ios-h .searchbar-search-icon.sc-ion-searchbar-ios,.searchbar-no-animate.sc-ion-searchbar-ios-h .searchbar-input.sc-ion-searchbar-ios,.searchbar-no-animate.sc-ion-searchbar-ios-h .searchbar-cancel-button.sc-ion-searchbar-ios{-webkit-transition-duration:0ms;transition-duration:0ms}.ion-color.sc-ion-searchbar-ios-h .searchbar-cancel-button.sc-ion-searchbar-ios{color:var(--ion-color-base)}@media (any-hover: hover){.ion-color.sc-ion-searchbar-ios-h .searchbar-cancel-button.sc-ion-searchbar-ios:hover{color:var(--ion-color-tint)}}ion-toolbar.sc-ion-searchbar-ios-h,ion-toolbar .sc-ion-searchbar-ios-h{padding-top:1px;padding-bottom:15px;min-height:52px}ion-toolbar.ion-color.sc-ion-searchbar-ios-h:not(.ion-color),ion-toolbar.ion-color .sc-ion-searchbar-ios-h:not(.ion-color){color:inherit}ion-toolbar.ion-color.sc-ion-searchbar-ios-h:not(.ion-color) .searchbar-cancel-button.sc-ion-searchbar-ios,ion-toolbar.ion-color .sc-ion-searchbar-ios-h:not(.ion-color) .searchbar-cancel-button.sc-ion-searchbar-ios{color:currentColor}ion-toolbar.ion-color.sc-ion-searchbar-ios-h .searchbar-search-icon.sc-ion-searchbar-ios,ion-toolbar.ion-color .sc-ion-searchbar-ios-h .searchbar-search-icon.sc-ion-searchbar-ios{color:currentColor;opacity:0.5}ion-toolbar.ion-color.sc-ion-searchbar-ios-h:not(.ion-color) .searchbar-input.sc-ion-searchbar-ios,ion-toolbar.ion-color .sc-ion-searchbar-ios-h:not(.ion-color) .searchbar-input.sc-ion-searchbar-ios{background:rgba(var(--ion-color-contrast-rgb), 0.07);color:currentColor}ion-toolbar.ion-color.sc-ion-searchbar-ios-h:not(.ion-color) .searchbar-clear-button.sc-ion-searchbar-ios,ion-toolbar.ion-color .sc-ion-searchbar-ios-h:not(.ion-color) .searchbar-clear-button.sc-ion-searchbar-ios{color:currentColor;opacity:0.5}";
  28341. var IonSearchbarIosStyle0 = searchbarIosCss;
  28342. const searchbarMdCss = ".sc-ion-searchbar-md-h{--placeholder-color:initial;--placeholder-font-style:initial;--placeholder-font-weight:initial;--placeholder-opacity:var(--ion-placeholder-opacity, 0.6);-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;display:-ms-flexbox;display:flex;position:relative;-ms-flex-align:center;align-items:center;width:100%;color:var(--color);font-family:var(--ion-font-family, inherit);-webkit-box-sizing:border-box;box-sizing:border-box}.ion-color.sc-ion-searchbar-md-h{color:var(--ion-color-contrast)}.ion-color.sc-ion-searchbar-md-h .searchbar-input.sc-ion-searchbar-md{background:var(--ion-color-base)}.ion-color.sc-ion-searchbar-md-h .searchbar-clear-button.sc-ion-searchbar-md,.ion-color.sc-ion-searchbar-md-h .searchbar-cancel-button.sc-ion-searchbar-md,.ion-color.sc-ion-searchbar-md-h .searchbar-search-icon.sc-ion-searchbar-md{color:inherit}.searchbar-search-icon.sc-ion-searchbar-md{color:var(--icon-color);pointer-events:none}.searchbar-input-container.sc-ion-searchbar-md{display:block;position:relative;-ms-flex-negative:1;flex-shrink:1;width:100%}.searchbar-input.sc-ion-searchbar-md{font-family:inherit;font-size:inherit;font-style:inherit;font-weight:inherit;letter-spacing:inherit;text-decoration:inherit;text-indent:inherit;text-overflow:inherit;text-transform:inherit;text-align:inherit;white-space:inherit;color:inherit;border-radius:var(--border-radius);display:block;width:100%;min-height:inherit;border:0;outline:none;background:var(--background);font-family:inherit;-webkit-box-shadow:var(--box-shadow);box-shadow:var(--box-shadow);-webkit-box-sizing:border-box;box-sizing:border-box;-webkit-appearance:none;-moz-appearance:none;appearance:none}.searchbar-input.sc-ion-searchbar-md::-webkit-input-placeholder{color:var(--placeholder-color);font-family:inherit;font-style:var(--placeholder-font-style);font-weight:var(--placeholder-font-weight);opacity:var(--placeholder-opacity)}.searchbar-input.sc-ion-searchbar-md::-moz-placeholder{color:var(--placeholder-color);font-family:inherit;font-style:var(--placeholder-font-style);font-weight:var(--placeholder-font-weight);opacity:var(--placeholder-opacity)}.searchbar-input.sc-ion-searchbar-md:-ms-input-placeholder{color:var(--placeholder-color);font-family:inherit;font-style:var(--placeholder-font-style);font-weight:var(--placeholder-font-weight);opacity:var(--placeholder-opacity)}.searchbar-input.sc-ion-searchbar-md::-ms-input-placeholder{color:var(--placeholder-color);font-family:inherit;font-style:var(--placeholder-font-style);font-weight:var(--placeholder-font-weight);opacity:var(--placeholder-opacity)}.searchbar-input.sc-ion-searchbar-md::placeholder{color:var(--placeholder-color);font-family:inherit;font-style:var(--placeholder-font-style);font-weight:var(--placeholder-font-weight);opacity:var(--placeholder-opacity)}.searchbar-input.sc-ion-searchbar-md::-webkit-search-cancel-button,.searchbar-input.sc-ion-searchbar-md::-ms-clear{display:none}.searchbar-cancel-button.sc-ion-searchbar-md{margin-left:0;margin-right:0;margin-top:0;margin-bottom:0;display:none;height:100%;border:0;outline:none;color:var(--cancel-button-color);cursor:pointer;-webkit-appearance:none;-moz-appearance:none;appearance:none}.searchbar-cancel-button.sc-ion-searchbar-md>div.sc-ion-searchbar-md{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;width:100%;height:100%}.searchbar-clear-button.sc-ion-searchbar-md{margin-left:0;margin-right:0;margin-top:0;margin-bottom:0;padding-left:0;padding-right:0;padding-top:0;padding-bottom:0;display:none;min-height:0;outline:none;color:var(--clear-button-color);-webkit-appearance:none;-moz-appearance:none;appearance:none}.searchbar-clear-button.sc-ion-searchbar-md:focus{opacity:0.5}.searchbar-has-value.searchbar-should-show-clear.sc-ion-searchbar-md-h .searchbar-clear-button.sc-ion-searchbar-md{display:block}.searchbar-disabled.sc-ion-searchbar-md-h{cursor:default;opacity:0.4;pointer-events:none}.sc-ion-searchbar-md-h{--background:var(--ion-background-color, #fff);--border-radius:2px;--box-shadow:0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 3px 1px -2px rgba(0, 0, 0, 0.2), 0 1px 5px 0 rgba(0, 0, 0, 0.12);--cancel-button-color:var(--ion-color-step-900, var(--ion-text-color-step-100, #1a1a1a));--clear-button-color:initial;--color:var(--ion-color-step-850, var(--ion-text-color-step-150, #262626));--icon-color:var(--ion-color-step-600, var(--ion-text-color-step-400, #666666));-webkit-padding-start:8px;padding-inline-start:8px;-webkit-padding-end:8px;padding-inline-end:8px;padding-top:8px;padding-bottom:8px;background:inherit}.searchbar-search-icon.sc-ion-searchbar-md{top:11px;width:1.3125rem;height:1.3125rem}.searchbar-search-icon.sc-ion-searchbar-md{inset-inline-start:16px}.searchbar-cancel-button.sc-ion-searchbar-md{top:0;background-color:transparent;font-size:1.5em}.searchbar-cancel-button.sc-ion-searchbar-md{inset-inline-start:9px}.searchbar-search-icon.sc-ion-searchbar-md,.searchbar-cancel-button.sc-ion-searchbar-md{position:absolute}.searchbar-search-icon.ion-activated.sc-ion-searchbar-md,.searchbar-cancel-button.ion-activated.sc-ion-searchbar-md{background-color:transparent}.searchbar-input.sc-ion-searchbar-md{-webkit-padding-start:3.4375rem;padding-inline-start:3.4375rem;-webkit-padding-end:3.4375rem;padding-inline-end:3.4375rem;padding-top:0.375rem;padding-bottom:0.375rem;background-position:left 8px center;height:auto;font-size:1rem;font-weight:400;line-height:30px}[dir=rtl].sc-ion-searchbar-md-h .searchbar-input.sc-ion-searchbar-md,[dir=rtl] .sc-ion-searchbar-md-h .searchbar-input.sc-ion-searchbar-md{background-position:right 8px center}[dir=rtl].sc-ion-searchbar-md .searchbar-input.sc-ion-searchbar-md{background-position:right 8px center}@supports selector(:dir(rtl)){.searchbar-input.sc-ion-searchbar-md:dir(rtl){background-position:right 8px center}}.searchbar-clear-button.sc-ion-searchbar-md{top:0;padding-left:0;padding-right:0;padding-top:0;padding-bottom:0;position:absolute;height:100%;border:0;background-color:transparent}.searchbar-clear-button.sc-ion-searchbar-md{inset-inline-end:13px}.searchbar-clear-button.ion-activated.sc-ion-searchbar-md{background-color:transparent}.searchbar-clear-icon.sc-ion-searchbar-md{width:1.375rem;height:100%}.searchbar-has-focus.sc-ion-searchbar-md-h .searchbar-search-icon.sc-ion-searchbar-md{display:block}.searchbar-has-focus.sc-ion-searchbar-md-h .searchbar-cancel-button.sc-ion-searchbar-md,.searchbar-should-show-cancel.sc-ion-searchbar-md-h .searchbar-cancel-button.sc-ion-searchbar-md{display:block}.searchbar-has-focus.sc-ion-searchbar-md-h .searchbar-cancel-button.sc-ion-searchbar-md+.searchbar-search-icon.sc-ion-searchbar-md,.searchbar-should-show-cancel.sc-ion-searchbar-md-h .searchbar-cancel-button.sc-ion-searchbar-md+.searchbar-search-icon.sc-ion-searchbar-md{display:none}ion-toolbar.sc-ion-searchbar-md-h,ion-toolbar .sc-ion-searchbar-md-h{-webkit-padding-start:7px;padding-inline-start:7px;-webkit-padding-end:7px;padding-inline-end:7px;padding-top:3px;padding-bottom:3px}";
  28343. var IonSearchbarMdStyle0 = searchbarMdCss;
  28344. /**
  28345. * @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
  28346. */
  28347. class Searchbar {
  28348. constructor(hostRef) {
  28349. registerInstance(this, hostRef);
  28350. this.ionInput = createEvent(this, "ionInput", 7);
  28351. this.ionChange = createEvent(this, "ionChange", 7);
  28352. this.ionCancel = createEvent(this, "ionCancel", 7);
  28353. this.ionClear = createEvent(this, "ionClear", 7);
  28354. this.ionBlur = createEvent(this, "ionBlur", 7);
  28355. this.ionFocus = createEvent(this, "ionFocus", 7);
  28356. this.ionStyle = createEvent(this, "ionStyle", 7);
  28357. this.isCancelVisible = false;
  28358. this.shouldAlignLeft = true;
  28359. this.inputId = `ion-searchbar-${searchbarIds++}`;
  28360. this.inheritedAttributes = {};
  28361. /**
  28362. * Clears the input field and triggers the control change.
  28363. */
  28364. this.onClearInput = async (shouldFocus) => {
  28365. this.ionClear.emit();
  28366. return new Promise((resolve) => {
  28367. // setTimeout() fixes https://github.com/ionic-team/ionic-framework/issues/7527
  28368. // wait for 4 frames
  28369. setTimeout(() => {
  28370. const value = this.getValue();
  28371. if (value !== '') {
  28372. this.value = '';
  28373. this.emitInputChange();
  28374. /**
  28375. * When tapping clear button
  28376. * ensure input is focused after
  28377. * clearing input so users
  28378. * can quickly start typing.
  28379. */
  28380. if (shouldFocus && !this.focused) {
  28381. this.setFocus();
  28382. /**
  28383. * The setFocus call above will clear focusedValue,
  28384. * but ionChange will never have gotten a chance to
  28385. * fire. Manually revert focusedValue so onBlur can
  28386. * compare against what was in the box before the clear.
  28387. */
  28388. this.focusedValue = value;
  28389. }
  28390. }
  28391. resolve();
  28392. }, 16 * 4);
  28393. });
  28394. };
  28395. /**
  28396. * Clears the input field and tells the input to blur since
  28397. * the clearInput function doesn't want the input to blur
  28398. * then calls the custom cancel function if the user passed one in.
  28399. */
  28400. this.onCancelSearchbar = async (ev) => {
  28401. if (ev) {
  28402. ev.preventDefault();
  28403. ev.stopPropagation();
  28404. }
  28405. this.ionCancel.emit();
  28406. // get cached values before clearing the input
  28407. const value = this.getValue();
  28408. const focused = this.focused;
  28409. await this.onClearInput();
  28410. /**
  28411. * If there used to be something in the box, and we weren't focused
  28412. * beforehand (meaning no blur fired that would already handle this),
  28413. * manually fire ionChange.
  28414. */
  28415. if (value && !focused) {
  28416. this.emitValueChange(ev);
  28417. }
  28418. if (this.nativeInput) {
  28419. this.nativeInput.blur();
  28420. }
  28421. };
  28422. /**
  28423. * Update the Searchbar input value when the input changes
  28424. */
  28425. this.onInput = (ev) => {
  28426. const input = ev.target;
  28427. if (input) {
  28428. this.value = input.value;
  28429. }
  28430. this.emitInputChange(ev);
  28431. };
  28432. this.onChange = (ev) => {
  28433. this.emitValueChange(ev);
  28434. };
  28435. /**
  28436. * Sets the Searchbar to not focused and checks if it should align left
  28437. * based on whether there is a value in the searchbar or not.
  28438. */
  28439. this.onBlur = (ev) => {
  28440. this.focused = false;
  28441. this.ionBlur.emit();
  28442. this.positionElements();
  28443. if (this.focusedValue !== this.value) {
  28444. this.emitValueChange(ev);
  28445. }
  28446. this.focusedValue = undefined;
  28447. };
  28448. /**
  28449. * Sets the Searchbar to focused and active on input focus.
  28450. */
  28451. this.onFocus = () => {
  28452. this.focused = true;
  28453. this.focusedValue = this.value;
  28454. this.ionFocus.emit();
  28455. this.positionElements();
  28456. };
  28457. this.focused = false;
  28458. this.noAnimate = true;
  28459. this.color = undefined;
  28460. this.animated = false;
  28461. this.autocapitalize = 'off';
  28462. this.autocomplete = 'off';
  28463. this.autocorrect = 'off';
  28464. this.cancelButtonIcon = config.get('backButtonIcon', arrowBackSharp);
  28465. this.cancelButtonText = 'Cancel';
  28466. this.clearIcon = undefined;
  28467. this.debounce = undefined;
  28468. this.disabled = false;
  28469. this.inputmode = undefined;
  28470. this.enterkeyhint = undefined;
  28471. this.maxlength = undefined;
  28472. this.minlength = undefined;
  28473. this.name = this.inputId;
  28474. this.placeholder = 'Search';
  28475. this.searchIcon = undefined;
  28476. this.showCancelButton = 'never';
  28477. this.showClearButton = 'always';
  28478. this.spellcheck = false;
  28479. this.type = 'search';
  28480. this.value = '';
  28481. }
  28482. /**
  28483. * lang and dir are globally enumerated attributes.
  28484. * As a result, creating these as properties
  28485. * can have unintended side effects. Instead, we
  28486. * listen for attribute changes and inherit them
  28487. * to the inner `<input>` element.
  28488. */
  28489. onLangChanged(newValue) {
  28490. this.inheritedAttributes = Object.assign(Object.assign({}, this.inheritedAttributes), { lang: newValue });
  28491. }
  28492. onDirChanged(newValue) {
  28493. this.inheritedAttributes = Object.assign(Object.assign({}, this.inheritedAttributes), { dir: newValue });
  28494. }
  28495. debounceChanged() {
  28496. const { ionInput, debounce, originalIonInput } = this;
  28497. /**
  28498. * If debounce is undefined, we have to manually revert the ionInput emitter in case
  28499. * debounce used to be set to a number. Otherwise, the event would stay debounced.
  28500. */
  28501. this.ionInput = debounce === undefined ? originalIonInput !== null && originalIonInput !== void 0 ? originalIonInput : ionInput : debounceEvent(ionInput, debounce);
  28502. }
  28503. valueChanged() {
  28504. const inputEl = this.nativeInput;
  28505. const value = this.getValue();
  28506. if (inputEl && inputEl.value !== value) {
  28507. inputEl.value = value;
  28508. }
  28509. }
  28510. showCancelButtonChanged() {
  28511. requestAnimationFrame(() => {
  28512. this.positionElements();
  28513. });
  28514. }
  28515. connectedCallback() {
  28516. this.emitStyle();
  28517. }
  28518. componentWillLoad() {
  28519. this.inheritedAttributes = Object.assign({}, inheritAttributes$1(this.el, ['lang', 'dir']));
  28520. }
  28521. componentDidLoad() {
  28522. this.originalIonInput = this.ionInput;
  28523. this.positionElements();
  28524. this.debounceChanged();
  28525. setTimeout(() => {
  28526. this.noAnimate = false;
  28527. }, 300);
  28528. }
  28529. emitStyle() {
  28530. this.ionStyle.emit({
  28531. searchbar: true,
  28532. });
  28533. }
  28534. /**
  28535. * Sets focus on the native `input` in `ion-searchbar`. Use this method instead of the global
  28536. * `input.focus()`.
  28537. *
  28538. * Developers who wish to focus an input when a page enters
  28539. * should call `setFocus()` in the `ionViewDidEnter()` lifecycle method.
  28540. *
  28541. * Developers who wish to focus an input when an overlay is presented
  28542. * should call `setFocus` after `didPresent` has resolved.
  28543. *
  28544. * See [managing focus](/docs/developing/managing-focus) for more information.
  28545. */
  28546. async setFocus() {
  28547. if (this.nativeInput) {
  28548. this.nativeInput.focus();
  28549. }
  28550. }
  28551. /**
  28552. * Returns the native `<input>` element used under the hood.
  28553. */
  28554. async getInputElement() {
  28555. /**
  28556. * If this gets called in certain early lifecycle hooks (ex: Vue onMounted),
  28557. * nativeInput won't be defined yet with the custom elements build, so wait for it to load in.
  28558. */
  28559. if (!this.nativeInput) {
  28560. await new Promise((resolve) => componentOnReady(this.el, resolve));
  28561. }
  28562. return Promise.resolve(this.nativeInput);
  28563. }
  28564. /**
  28565. * Emits an `ionChange` event.
  28566. *
  28567. * This API should be called for user committed changes.
  28568. * This API should not be used for external value changes.
  28569. */
  28570. emitValueChange(event) {
  28571. const { value } = this;
  28572. // Checks for both null and undefined values
  28573. const newValue = value == null ? value : value.toString();
  28574. // Emitting a value change should update the internal state for tracking the focused value
  28575. this.focusedValue = newValue;
  28576. this.ionChange.emit({ value: newValue, event });
  28577. }
  28578. /**
  28579. * Emits an `ionInput` event.
  28580. */
  28581. emitInputChange(event) {
  28582. const { value } = this;
  28583. this.ionInput.emit({ value, event });
  28584. }
  28585. /**
  28586. * Positions the input search icon, placeholder, and the cancel button
  28587. * based on the input value and if it is focused. (ios only)
  28588. */
  28589. positionElements() {
  28590. const value = this.getValue();
  28591. const prevAlignLeft = this.shouldAlignLeft;
  28592. const mode = getIonMode$1(this);
  28593. const shouldAlignLeft = !this.animated || value.trim() !== '' || !!this.focused;
  28594. this.shouldAlignLeft = shouldAlignLeft;
  28595. if (mode !== 'ios') {
  28596. return;
  28597. }
  28598. if (prevAlignLeft !== shouldAlignLeft) {
  28599. this.positionPlaceholder();
  28600. }
  28601. if (this.animated) {
  28602. this.positionCancelButton();
  28603. }
  28604. }
  28605. /**
  28606. * Positions the input placeholder
  28607. */
  28608. positionPlaceholder() {
  28609. const inputEl = this.nativeInput;
  28610. if (!inputEl) {
  28611. return;
  28612. }
  28613. const rtl = isRTL$1(this.el);
  28614. const iconEl = (this.el.shadowRoot || this.el).querySelector('.searchbar-search-icon');
  28615. if (this.shouldAlignLeft) {
  28616. inputEl.removeAttribute('style');
  28617. iconEl.removeAttribute('style');
  28618. }
  28619. else {
  28620. // Create a dummy span to get the placeholder width
  28621. const doc = document;
  28622. const tempSpan = doc.createElement('span');
  28623. tempSpan.innerText = this.placeholder || '';
  28624. doc.body.appendChild(tempSpan);
  28625. // Get the width of the span then remove it
  28626. raf(() => {
  28627. const textWidth = tempSpan.offsetWidth;
  28628. tempSpan.remove();
  28629. // Calculate the input padding
  28630. const inputLeft = 'calc(50% - ' + textWidth / 2 + 'px)';
  28631. // Calculate the icon margin
  28632. /**
  28633. * We take the icon width to account
  28634. * for any text scales applied to the icon
  28635. * such as Dynamic Type on iOS as well as 8px
  28636. * of padding.
  28637. */
  28638. const iconLeft = 'calc(50% - ' + (textWidth / 2 + iconEl.clientWidth + 8) + 'px)';
  28639. // Set the input padding start and icon margin start
  28640. if (rtl) {
  28641. inputEl.style.paddingRight = inputLeft;
  28642. iconEl.style.marginRight = iconLeft;
  28643. }
  28644. else {
  28645. inputEl.style.paddingLeft = inputLeft;
  28646. iconEl.style.marginLeft = iconLeft;
  28647. }
  28648. });
  28649. }
  28650. }
  28651. /**
  28652. * Show the iOS Cancel button on focus, hide it offscreen otherwise
  28653. */
  28654. positionCancelButton() {
  28655. const rtl = isRTL$1(this.el);
  28656. const cancelButton = (this.el.shadowRoot || this.el).querySelector('.searchbar-cancel-button');
  28657. const shouldShowCancel = this.shouldShowCancelButton();
  28658. if (cancelButton !== null && shouldShowCancel !== this.isCancelVisible) {
  28659. const cancelStyle = cancelButton.style;
  28660. this.isCancelVisible = shouldShowCancel;
  28661. if (shouldShowCancel) {
  28662. if (rtl) {
  28663. cancelStyle.marginLeft = '0';
  28664. }
  28665. else {
  28666. cancelStyle.marginRight = '0';
  28667. }
  28668. }
  28669. else {
  28670. const offset = cancelButton.offsetWidth;
  28671. if (offset > 0) {
  28672. if (rtl) {
  28673. cancelStyle.marginLeft = -offset + 'px';
  28674. }
  28675. else {
  28676. cancelStyle.marginRight = -offset + 'px';
  28677. }
  28678. }
  28679. }
  28680. }
  28681. }
  28682. getValue() {
  28683. return this.value || '';
  28684. }
  28685. hasValue() {
  28686. return this.getValue() !== '';
  28687. }
  28688. /**
  28689. * Determines whether or not the cancel button should be visible onscreen.
  28690. * Cancel button should be shown if one of two conditions applies:
  28691. * 1. `showCancelButton` is set to `always`.
  28692. * 2. `showCancelButton` is set to `focus`, and the searchbar has been focused.
  28693. */
  28694. shouldShowCancelButton() {
  28695. if (this.showCancelButton === 'never' || (this.showCancelButton === 'focus' && !this.focused)) {
  28696. return false;
  28697. }
  28698. return true;
  28699. }
  28700. /**
  28701. * Determines whether or not the clear button should be visible onscreen.
  28702. * Clear button should be shown if one of two conditions applies:
  28703. * 1. `showClearButton` is set to `always`.
  28704. * 2. `showClearButton` is set to `focus`, and the searchbar has been focused.
  28705. */
  28706. shouldShowClearButton() {
  28707. if (this.showClearButton === 'never' || (this.showClearButton === 'focus' && !this.focused)) {
  28708. return false;
  28709. }
  28710. return true;
  28711. }
  28712. render() {
  28713. const { cancelButtonText, autocapitalize } = this;
  28714. const animated = this.animated && config.getBoolean('animated', true);
  28715. const mode = getIonMode$1(this);
  28716. const clearIcon = this.clearIcon || (mode === 'ios' ? closeCircle : closeSharp);
  28717. const searchIcon = this.searchIcon || (mode === 'ios' ? searchOutline : searchSharp);
  28718. const shouldShowCancelButton = this.shouldShowCancelButton();
  28719. const cancelButton = this.showCancelButton !== 'never' && (hAsync("button", { key: '989f3e84c472ada6e66dd9b249d0d268bf17ce26', "aria-label": cancelButtonText, "aria-hidden": shouldShowCancelButton ? undefined : 'true', type: "button", tabIndex: mode === 'ios' && !shouldShowCancelButton ? -1 : undefined, onMouseDown: this.onCancelSearchbar, onTouchStart: this.onCancelSearchbar, class: "searchbar-cancel-button" }, hAsync("div", { key: '7d335d4fde33822dc79d26b748ba2e98db7494bb', "aria-hidden": "true" }, mode === 'md' ? (hAsync("ion-icon", { "aria-hidden": "true", mode: mode, icon: this.cancelButtonIcon, lazy: false })) : (cancelButtonText))));
  28720. return (hAsync(Host, { key: 'd1a1972725e949fb102c91487aaa7b9d10c2d718', role: "search", "aria-disabled": this.disabled ? 'true' : null, class: createColorClasses$1(this.color, {
  28721. [mode]: true,
  28722. 'searchbar-animated': animated,
  28723. 'searchbar-disabled': this.disabled,
  28724. 'searchbar-no-animate': animated && this.noAnimate,
  28725. 'searchbar-has-value': this.hasValue(),
  28726. 'searchbar-left-aligned': this.shouldAlignLeft,
  28727. 'searchbar-has-focus': this.focused,
  28728. 'searchbar-should-show-clear': this.shouldShowClearButton(),
  28729. 'searchbar-should-show-cancel': this.shouldShowCancelButton(),
  28730. }) }, hAsync("div", { key: 'add53640b2994cb6b2bf02792dafe51aba6b1684', class: "searchbar-input-container" }, hAsync("input", Object.assign({ key: '160cc36459a4a652e7f41ccd14dcdc782278779e', "aria-label": "search text", disabled: this.disabled, ref: (el) => (this.nativeInput = el), class: "searchbar-input", inputMode: this.inputmode, enterKeyHint: this.enterkeyhint, name: this.name, onInput: this.onInput, onChange: this.onChange, onBlur: this.onBlur, onFocus: this.onFocus, minLength: this.minlength, maxLength: this.maxlength, placeholder: this.placeholder, type: this.type, value: this.getValue(), autoCapitalize: autocapitalize === 'default' ? undefined : autocapitalize, autoComplete: this.autocomplete, autoCorrect: this.autocorrect, spellcheck: this.spellcheck }, this.inheritedAttributes)), mode === 'md' && cancelButton, hAsync("ion-icon", { key: '8825fd13af0d2dea451ccc0e00ae7b5021dc01c4', "aria-hidden": "true", mode: mode, icon: searchIcon, lazy: false, class: "searchbar-search-icon" }), hAsync("button", { key: '8a7b56da278b9ca5c4f5a4ee9c01924fd5ae29d8', "aria-label": "reset", type: "button", "no-blur": true, class: "searchbar-clear-button", onPointerDown: (ev) => {
  28731. /**
  28732. * This prevents mobile browsers from
  28733. * blurring the input when the clear
  28734. * button is activated.
  28735. */
  28736. ev.preventDefault();
  28737. }, onClick: () => this.onClearInput(true) }, hAsync("ion-icon", { key: '24c55274516ab012d8c25f03525c6cdb9409e52f', "aria-hidden": "true", mode: mode, icon: clearIcon, lazy: false, class: "searchbar-clear-icon" }))), mode === 'ios' && cancelButton));
  28738. }
  28739. get el() { return getElement(this); }
  28740. static get watchers() { return {
  28741. "lang": ["onLangChanged"],
  28742. "dir": ["onDirChanged"],
  28743. "debounce": ["debounceChanged"],
  28744. "value": ["valueChanged"],
  28745. "showCancelButton": ["showCancelButtonChanged"]
  28746. }; }
  28747. static get style() { return {
  28748. ios: IonSearchbarIosStyle0,
  28749. md: IonSearchbarMdStyle0
  28750. }; }
  28751. static get cmpMeta() { return {
  28752. "$flags$": 34,
  28753. "$tagName$": "ion-searchbar",
  28754. "$members$": {
  28755. "color": [513],
  28756. "animated": [4],
  28757. "autocapitalize": [1],
  28758. "autocomplete": [1],
  28759. "autocorrect": [1],
  28760. "cancelButtonIcon": [1, "cancel-button-icon"],
  28761. "cancelButtonText": [1, "cancel-button-text"],
  28762. "clearIcon": [1, "clear-icon"],
  28763. "debounce": [2],
  28764. "disabled": [4],
  28765. "inputmode": [1],
  28766. "enterkeyhint": [1],
  28767. "maxlength": [2],
  28768. "minlength": [2],
  28769. "name": [1],
  28770. "placeholder": [1],
  28771. "searchIcon": [1, "search-icon"],
  28772. "showCancelButton": [1, "show-cancel-button"],
  28773. "showClearButton": [1, "show-clear-button"],
  28774. "spellcheck": [4],
  28775. "type": [1],
  28776. "value": [1025],
  28777. "focused": [32],
  28778. "noAnimate": [32],
  28779. "setFocus": [64],
  28780. "getInputElement": [64]
  28781. },
  28782. "$listeners$": undefined,
  28783. "$lazyBundleId$": "-",
  28784. "$attrsToReflect$": [["color", "color"]]
  28785. }; }
  28786. }
  28787. let searchbarIds = 0;
  28788. const segmentIosCss = ":host{--ripple-color:currentColor;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;display:grid;grid-auto-columns:1fr;position:relative;-ms-flex-align:stretch;align-items:stretch;-ms-flex-pack:center;justify-content:center;width:100%;background:var(--background);font-family:var(--ion-font-family, inherit);text-align:center;contain:paint;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}:host(.segment-scrollable){-ms-flex-pack:start;justify-content:start;width:auto;overflow-x:auto;grid-auto-columns:minmax(-webkit-min-content, 1fr);grid-auto-columns:minmax(min-content, 1fr)}:host(.segment-scrollable::-webkit-scrollbar){display:none}:host{--background:rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.065);border-radius:8px;overflow:hidden;z-index:0}:host(.ion-color){background:rgba(var(--ion-color-base-rgb), 0.065)}:host(.in-toolbar){-webkit-margin-start:auto;margin-inline-start:auto;-webkit-margin-end:auto;margin-inline-end:auto;margin-top:0;margin-bottom:0;width:auto}:host(.in-toolbar:not(.ion-color)){background:var(--ion-toolbar-segment-background, var(--background))}:host(.in-toolbar-color:not(.ion-color)){background:rgba(var(--ion-color-contrast-rgb), 0.11)}";
  28789. var IonSegmentIosStyle0 = segmentIosCss;
  28790. const segmentMdCss = ":host{--ripple-color:currentColor;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;display:grid;grid-auto-columns:1fr;position:relative;-ms-flex-align:stretch;align-items:stretch;-ms-flex-pack:center;justify-content:center;width:100%;background:var(--background);font-family:var(--ion-font-family, inherit);text-align:center;contain:paint;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}:host(.segment-scrollable){-ms-flex-pack:start;justify-content:start;width:auto;overflow-x:auto;grid-auto-columns:minmax(-webkit-min-content, 1fr);grid-auto-columns:minmax(min-content, 1fr)}:host(.segment-scrollable::-webkit-scrollbar){display:none}:host{--background:transparent;grid-auto-columns:minmax(auto, 360px)}:host(.in-toolbar){min-height:var(--min-height)}:host(.segment-scrollable) ::slotted(ion-segment-button){min-width:auto}";
  28791. var IonSegmentMdStyle0 = segmentMdCss;
  28792. /**
  28793. * @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
  28794. */
  28795. class Segment {
  28796. constructor(hostRef) {
  28797. registerInstance(this, hostRef);
  28798. this.ionChange = createEvent(this, "ionChange", 7);
  28799. this.ionSelect = createEvent(this, "ionSelect", 7);
  28800. this.ionStyle = createEvent(this, "ionStyle", 7);
  28801. this.segmentViewEl = null;
  28802. this.onClick = (ev) => {
  28803. const current = ev.target;
  28804. const previous = this.checked;
  28805. // If the current element is a segment then that means
  28806. // the user tried to swipe to a segment button and
  28807. // click a segment button at the same time so we should
  28808. // not update the checked segment button
  28809. if (current.tagName === 'ION-SEGMENT') {
  28810. return;
  28811. }
  28812. this.value = current.value;
  28813. if (current !== previous) {
  28814. this.emitValueChange();
  28815. }
  28816. if (this.segmentViewEl) {
  28817. this.updateSegmentView();
  28818. if (this.scrollable && previous) {
  28819. this.checkButton(previous, current);
  28820. }
  28821. }
  28822. else if (this.scrollable || !this.swipeGesture) {
  28823. if (previous) {
  28824. this.checkButton(previous, current);
  28825. }
  28826. else {
  28827. this.setCheckedClasses();
  28828. }
  28829. }
  28830. };
  28831. this.onSlottedItemsChange = () => {
  28832. /**
  28833. * When the slotted segment buttons change we need to
  28834. * ensure that the new segment buttons are checked if
  28835. * the value matches the segment button value.
  28836. */
  28837. this.valueChanged(this.value);
  28838. };
  28839. this.getSegmentButton = (selector) => {
  28840. var _a, _b;
  28841. const buttons = this.getButtons().filter((button) => !button.disabled);
  28842. const currIndex = buttons.findIndex((button) => button === document.activeElement);
  28843. switch (selector) {
  28844. case 'first':
  28845. return buttons[0];
  28846. case 'last':
  28847. return buttons[buttons.length - 1];
  28848. case 'next':
  28849. return (_a = buttons[currIndex + 1]) !== null && _a !== void 0 ? _a : buttons[0];
  28850. case 'previous':
  28851. return (_b = buttons[currIndex - 1]) !== null && _b !== void 0 ? _b : buttons[buttons.length - 1];
  28852. default:
  28853. return null;
  28854. }
  28855. };
  28856. this.activated = false;
  28857. this.color = undefined;
  28858. this.disabled = false;
  28859. this.scrollable = false;
  28860. this.swipeGesture = true;
  28861. this.value = undefined;
  28862. this.selectOnFocus = false;
  28863. }
  28864. colorChanged(value, oldValue) {
  28865. /**
  28866. * If color is set after not having
  28867. * previously been set (or vice versa),
  28868. * we need to emit style so the segment-buttons
  28869. * can apply their color classes properly.
  28870. */
  28871. if ((oldValue === undefined && value !== undefined) || (oldValue !== undefined && value === undefined)) {
  28872. this.emitStyle();
  28873. }
  28874. }
  28875. swipeGestureChanged() {
  28876. this.gestureChanged();
  28877. }
  28878. valueChanged(value, oldValue) {
  28879. // Force a value to exist if we're using a segment view
  28880. if (this.segmentViewEl && value === undefined) {
  28881. this.value = this.getButtons()[0].value;
  28882. return;
  28883. }
  28884. if (oldValue !== undefined && value !== undefined) {
  28885. const buttons = this.getButtons();
  28886. const previous = buttons.find((button) => button.value === oldValue);
  28887. const current = buttons.find((button) => button.value === value);
  28888. if (previous && current) {
  28889. if (!this.segmentViewEl) {
  28890. this.checkButton(previous, current);
  28891. }
  28892. else if (this.triggerScrollOnValueChange !== false) {
  28893. this.updateSegmentView();
  28894. }
  28895. }
  28896. }
  28897. else if (value !== undefined && oldValue === undefined && this.segmentViewEl) {
  28898. this.updateSegmentView();
  28899. }
  28900. /**
  28901. * `ionSelect` is emitted every time the value changes (internal or external changes).
  28902. * Used by `ion-segment-button` to determine if the button should be checked.
  28903. */
  28904. this.ionSelect.emit({ value });
  28905. // The scroll listener should handle scrolling the active button into view as needed
  28906. if (!this.segmentViewEl) {
  28907. this.scrollActiveButtonIntoView();
  28908. }
  28909. this.triggerScrollOnValueChange = undefined;
  28910. }
  28911. disabledChanged() {
  28912. this.gestureChanged();
  28913. if (!this.segmentViewEl) {
  28914. const buttons = this.getButtons();
  28915. for (const button of buttons) {
  28916. button.disabled = this.disabled;
  28917. }
  28918. }
  28919. else {
  28920. this.segmentViewEl.disabled = this.disabled;
  28921. }
  28922. }
  28923. gestureChanged() {
  28924. if (this.gesture) {
  28925. this.gesture.enable(!this.scrollable && !this.disabled && this.swipeGesture);
  28926. }
  28927. }
  28928. connectedCallback() {
  28929. this.emitStyle();
  28930. this.segmentViewEl = this.getSegmentView();
  28931. }
  28932. disconnectedCallback() {
  28933. this.segmentViewEl = null;
  28934. }
  28935. componentWillLoad() {
  28936. this.emitStyle();
  28937. }
  28938. async componentDidLoad() {
  28939. this.segmentViewEl = this.getSegmentView();
  28940. this.setCheckedClasses();
  28941. /**
  28942. * We need to wait for the buttons to all be rendered
  28943. * before we can scroll.
  28944. */
  28945. raf(() => {
  28946. /**
  28947. * When the segment loads for the first
  28948. * time we just want to snap the active button into
  28949. * place instead of scroll. Smooth scrolling should only
  28950. * happen when the user interacts with the segment.
  28951. */
  28952. this.scrollActiveButtonIntoView(false);
  28953. });
  28954. this.gesture = (await Promise.resolve().then(function () { return index; })).createGesture({
  28955. el: this.el,
  28956. gestureName: 'segment',
  28957. gesturePriority: 100,
  28958. threshold: 0,
  28959. passive: false,
  28960. onStart: (ev) => this.onStart(ev),
  28961. onMove: (ev) => this.onMove(ev),
  28962. onEnd: (ev) => this.onEnd(ev),
  28963. });
  28964. this.gestureChanged();
  28965. if (this.disabled) {
  28966. this.disabledChanged();
  28967. }
  28968. // Update segment view based on the initial value,
  28969. // but do not animate the scroll
  28970. this.updateSegmentView(false);
  28971. }
  28972. onStart(detail) {
  28973. this.valueBeforeGesture = this.value;
  28974. this.activate(detail);
  28975. }
  28976. onMove(detail) {
  28977. this.setNextIndex(detail);
  28978. }
  28979. onEnd(detail) {
  28980. this.setActivated(false);
  28981. this.setNextIndex(detail, true);
  28982. detail.event.stopImmediatePropagation();
  28983. const value = this.value;
  28984. if (value !== undefined) {
  28985. if (this.valueBeforeGesture !== value) {
  28986. this.emitValueChange();
  28987. this.updateSegmentView();
  28988. }
  28989. }
  28990. this.valueBeforeGesture = undefined;
  28991. }
  28992. /**
  28993. * Emits an `ionChange` event.
  28994. *
  28995. * This API should be called for user committed changes.
  28996. * This API should not be used for external value changes.
  28997. */
  28998. emitValueChange() {
  28999. const { value } = this;
  29000. this.ionChange.emit({ value });
  29001. }
  29002. getButtons() {
  29003. return Array.from(this.el.querySelectorAll('ion-segment-button'));
  29004. }
  29005. get checked() {
  29006. return this.getButtons().find((button) => button.value === this.value);
  29007. }
  29008. /*
  29009. * Activate both the segment and the buttons
  29010. * due to a bug with ::slotted in Safari
  29011. */
  29012. setActivated(activated) {
  29013. const buttons = this.getButtons();
  29014. buttons.forEach((button) => {
  29015. button.classList.toggle('segment-button-activated', activated);
  29016. });
  29017. this.activated = activated;
  29018. }
  29019. activate(detail) {
  29020. const clicked = detail.event.target;
  29021. const buttons = this.getButtons();
  29022. const checked = buttons.find((button) => button.value === this.value);
  29023. // Make sure we are only checking for activation on a segment button
  29024. // since disabled buttons will get the click on the segment
  29025. if (clicked.tagName !== 'ION-SEGMENT-BUTTON') {
  29026. return;
  29027. }
  29028. // If there are no checked buttons, set the current button to checked
  29029. if (!checked) {
  29030. this.value = clicked.value;
  29031. this.setCheckedClasses();
  29032. }
  29033. // If the gesture began on the clicked button with the indicator
  29034. // then we should activate the indicator
  29035. if (this.value === clicked.value) {
  29036. this.setActivated(true);
  29037. }
  29038. }
  29039. getIndicator(button) {
  29040. const root = button.shadowRoot || button;
  29041. return root.querySelector('.segment-button-indicator');
  29042. }
  29043. checkButton(previous, current) {
  29044. const previousIndicator = this.getIndicator(previous);
  29045. const currentIndicator = this.getIndicator(current);
  29046. if (previousIndicator === null || currentIndicator === null) {
  29047. return;
  29048. }
  29049. const previousClientRect = previousIndicator.getBoundingClientRect();
  29050. const currentClientRect = currentIndicator.getBoundingClientRect();
  29051. const widthDelta = previousClientRect.width / currentClientRect.width;
  29052. const xPosition = previousClientRect.left - currentClientRect.left;
  29053. // Scale the indicator width to match the previous indicator width
  29054. // and translate it on top of the previous indicator
  29055. const transform = `translate3d(${xPosition}px, 0, 0) scaleX(${widthDelta})`;
  29056. writeTask(() => {
  29057. // Remove the transition before positioning on top of the previous indicator
  29058. currentIndicator.classList.remove('segment-button-indicator-animated');
  29059. currentIndicator.style.setProperty('transform', transform);
  29060. // Force a repaint to ensure the transform happens
  29061. currentIndicator.getBoundingClientRect();
  29062. // Add the transition to move the indicator into place
  29063. currentIndicator.classList.add('segment-button-indicator-animated');
  29064. // Remove the transform to slide the indicator back to the button clicked
  29065. currentIndicator.style.setProperty('transform', '');
  29066. this.scrollActiveButtonIntoView(true);
  29067. });
  29068. this.value = current.value;
  29069. this.setCheckedClasses();
  29070. }
  29071. setCheckedClasses() {
  29072. const buttons = this.getButtons();
  29073. const index = buttons.findIndex((button) => button.value === this.value);
  29074. const next = index + 1;
  29075. for (const button of buttons) {
  29076. button.classList.remove('segment-button-after-checked');
  29077. }
  29078. if (next < buttons.length) {
  29079. buttons[next].classList.add('segment-button-after-checked');
  29080. }
  29081. }
  29082. getSegmentView() {
  29083. const buttons = this.getButtons();
  29084. // Get the first button with a contentId
  29085. const firstContentId = buttons.find((button) => button.contentId);
  29086. // Get the segment content with an id matching the button's contentId
  29087. const segmentContent = document.querySelector(`ion-segment-content[id="${firstContentId === null || firstContentId === void 0 ? void 0 : firstContentId.contentId}"]`);
  29088. // Return the segment view for that matching segment content
  29089. return segmentContent === null || segmentContent === void 0 ? void 0 : segmentContent.closest('ion-segment-view');
  29090. }
  29091. handleSegmentViewScroll(ev) {
  29092. const { scrollRatio, isManualScroll } = ev.detail;
  29093. if (!isManualScroll) {
  29094. return;
  29095. }
  29096. const dispatchedFrom = ev.target;
  29097. const segmentViewEl = this.segmentViewEl;
  29098. const segmentEl = this.el;
  29099. // Only update the indicator if the event was dispatched from the correct segment view
  29100. if (ev.composedPath().includes(segmentViewEl) || (dispatchedFrom === null || dispatchedFrom === void 0 ? void 0 : dispatchedFrom.contains(segmentEl))) {
  29101. const buttons = this.getButtons();
  29102. // If no buttons are found or there is no value set then do nothing
  29103. if (!buttons.length)
  29104. return;
  29105. const index = buttons.findIndex((button) => button.value === this.value);
  29106. const current = buttons[index];
  29107. const nextIndex = Math.round(scrollRatio * (buttons.length - 1));
  29108. if (this.lastNextIndex === undefined || this.lastNextIndex !== nextIndex) {
  29109. this.lastNextIndex = nextIndex;
  29110. this.triggerScrollOnValueChange = false;
  29111. this.checkButton(current, buttons[nextIndex]);
  29112. this.emitValueChange();
  29113. }
  29114. }
  29115. }
  29116. /**
  29117. * Finds the related segment view and sets its current content
  29118. * based on the selected segment button. This method
  29119. * should be called on initial load of the segment,
  29120. * after the gesture is completed (if dragging between segments)
  29121. * and when a segment button is clicked directly.
  29122. */
  29123. updateSegmentView(smoothScroll = true) {
  29124. const buttons = this.getButtons();
  29125. const button = buttons.find((btn) => btn.value === this.value);
  29126. // If the button does not have a contentId then there is
  29127. // no associated segment view to update
  29128. if (!(button === null || button === void 0 ? void 0 : button.contentId)) {
  29129. return;
  29130. }
  29131. const segmentView = this.segmentViewEl;
  29132. if (segmentView) {
  29133. segmentView.setContent(button.contentId, smoothScroll);
  29134. }
  29135. }
  29136. scrollActiveButtonIntoView(smoothScroll = true) {
  29137. const { scrollable, value, el } = this;
  29138. if (scrollable) {
  29139. const buttons = this.getButtons();
  29140. const activeButton = buttons.find((button) => button.value === value);
  29141. if (activeButton !== undefined) {
  29142. const scrollContainerBox = el.getBoundingClientRect();
  29143. const activeButtonBox = activeButton.getBoundingClientRect();
  29144. /**
  29145. * Subtract the active button x position from the scroll
  29146. * container x position. This will give us the x position
  29147. * of the active button within the scroll container.
  29148. */
  29149. const activeButtonLeft = activeButtonBox.x - scrollContainerBox.x;
  29150. /**
  29151. * If we just used activeButtonLeft, then the active button
  29152. * would be aligned with the left edge of the scroll container.
  29153. * Instead, we want the segment button to be centered. As a result,
  29154. * we subtract half of the scroll container width. This will position
  29155. * the left edge of the active button at the midpoint of the scroll container.
  29156. * We then add half of the active button width. This will position the active
  29157. * button such that the midpoint of the active button is at the midpoint of the
  29158. * scroll container.
  29159. */
  29160. const centeredX = activeButtonLeft - scrollContainerBox.width / 2 + activeButtonBox.width / 2;
  29161. /**
  29162. * newScrollPosition is the absolute scroll position that the
  29163. * container needs to move to in order to center the active button.
  29164. * It is calculated by adding the current scroll position
  29165. * (scrollLeft) to the offset needed to center the button
  29166. * (centeredX).
  29167. */
  29168. const newScrollPosition = el.scrollLeft + centeredX;
  29169. /**
  29170. * We intentionally use scrollTo here instead of scrollIntoView
  29171. * to avoid a WebKit bug where accelerated animations break
  29172. * when using scrollIntoView. Using scrollIntoView will cause the
  29173. * segment container to jump during the transition and then snap into place.
  29174. * This is because scrollIntoView can potentially cause parent element
  29175. * containers to also scroll. scrollTo does not have this same behavior, so
  29176. * we use this API instead.
  29177. *
  29178. * scrollTo is used instead of scrollBy because there is a
  29179. * Webkit bug that causes scrollBy to not work smoothly when
  29180. * the active button is near the edge of the scroll container.
  29181. * This leads to the buttons to jump around during the transition.
  29182. *
  29183. * Note that if there is not enough scrolling space to center the element
  29184. * within the scroll container, the browser will attempt
  29185. * to center by as much as it can.
  29186. */
  29187. el.scrollTo({
  29188. top: 0,
  29189. left: newScrollPosition,
  29190. behavior: smoothScroll ? 'smooth' : 'instant',
  29191. });
  29192. }
  29193. }
  29194. }
  29195. setNextIndex(detail, isEnd = false) {
  29196. const rtl = isRTL$1(this.el);
  29197. const activated = this.activated;
  29198. const buttons = this.getButtons();
  29199. const index = buttons.findIndex((button) => button.value === this.value);
  29200. const previous = buttons[index];
  29201. let current;
  29202. let nextIndex;
  29203. if (index === -1) {
  29204. return;
  29205. }
  29206. // Get the element that the touch event started on in case
  29207. // it was the checked button, then we will move the indicator
  29208. const rect = previous.getBoundingClientRect();
  29209. const left = rect.left;
  29210. const width = rect.width;
  29211. // Get the element that the gesture is on top of based on the currentX of the
  29212. // gesture event and the Y coordinate of the starting element, since the gesture
  29213. // can move up and down off of the segment
  29214. const currentX = detail.currentX;
  29215. const previousY = rect.top + rect.height / 2;
  29216. /**
  29217. * Segment can be used inside the shadow dom
  29218. * so doing document.elementFromPoint would never
  29219. * return a segment button in that instance.
  29220. * We use getRootNode to which will return the parent
  29221. * shadow root if used inside a shadow component and
  29222. * returns document otherwise.
  29223. */
  29224. const root = this.el.getRootNode();
  29225. const nextEl = root.elementFromPoint(currentX, previousY);
  29226. const decreaseIndex = rtl ? currentX > left + width : currentX < left;
  29227. const increaseIndex = rtl ? currentX < left : currentX > left + width;
  29228. // If the indicator is currently activated then we have started the gesture
  29229. // on top of the checked button so we need to slide the indicator
  29230. // by checking the button next to it as we move
  29231. if (activated && !isEnd) {
  29232. // Decrease index, move left in LTR & right in RTL
  29233. if (decreaseIndex) {
  29234. const newIndex = index - 1;
  29235. if (newIndex >= 0) {
  29236. nextIndex = newIndex;
  29237. }
  29238. // Increase index, moves right in LTR & left in RTL
  29239. }
  29240. else if (increaseIndex) {
  29241. if (activated && !isEnd) {
  29242. const newIndex = index + 1;
  29243. if (newIndex < buttons.length) {
  29244. nextIndex = newIndex;
  29245. }
  29246. }
  29247. }
  29248. if (nextIndex !== undefined && !buttons[nextIndex].disabled) {
  29249. current = buttons[nextIndex];
  29250. }
  29251. }
  29252. // If the indicator is not activated then we will just set the indicator
  29253. // to the element where the gesture ended
  29254. if (!activated && isEnd) {
  29255. current = nextEl;
  29256. }
  29257. if (current != null) {
  29258. /**
  29259. * If current element is ion-segment then that means
  29260. * user tried to select a disabled ion-segment-button,
  29261. * and we should not update the ripple.
  29262. */
  29263. if (current.tagName === 'ION-SEGMENT') {
  29264. return false;
  29265. }
  29266. if (previous !== current) {
  29267. this.checkButton(previous, current);
  29268. }
  29269. }
  29270. return true;
  29271. }
  29272. emitStyle() {
  29273. this.ionStyle.emit({
  29274. segment: true,
  29275. });
  29276. }
  29277. onKeyDown(ev) {
  29278. const rtl = isRTL$1(this.el);
  29279. let keyDownSelectsButton = this.selectOnFocus;
  29280. let current;
  29281. switch (ev.key) {
  29282. case 'ArrowRight':
  29283. ev.preventDefault();
  29284. current = rtl ? this.getSegmentButton('previous') : this.getSegmentButton('next');
  29285. break;
  29286. case 'ArrowLeft':
  29287. ev.preventDefault();
  29288. current = rtl ? this.getSegmentButton('next') : this.getSegmentButton('previous');
  29289. break;
  29290. case 'Home':
  29291. ev.preventDefault();
  29292. current = this.getSegmentButton('first');
  29293. break;
  29294. case 'End':
  29295. ev.preventDefault();
  29296. current = this.getSegmentButton('last');
  29297. break;
  29298. case ' ':
  29299. case 'Enter':
  29300. ev.preventDefault();
  29301. current = document.activeElement;
  29302. keyDownSelectsButton = true;
  29303. }
  29304. if (!current) {
  29305. return;
  29306. }
  29307. if (keyDownSelectsButton) {
  29308. const previous = this.checked;
  29309. this.checkButton(previous || current, current);
  29310. if (current !== previous) {
  29311. this.emitValueChange();
  29312. }
  29313. }
  29314. current.setFocus();
  29315. }
  29316. render() {
  29317. const mode = getIonMode$1(this);
  29318. return (hAsync(Host, { key: 'a64e39352050b516f7dc82ce95a4bcff8431d1d0', role: "tablist", onClick: this.onClick, class: createColorClasses$1(this.color, {
  29319. [mode]: true,
  29320. 'in-toolbar': hostContext('ion-toolbar', this.el),
  29321. 'in-toolbar-color': hostContext('ion-toolbar[color]', this.el),
  29322. 'segment-activated': this.activated,
  29323. 'segment-disabled': this.disabled,
  29324. 'segment-scrollable': this.scrollable,
  29325. }) }, hAsync("slot", { key: 'bb3f3ec30e59e0461fa620d8961ab730cc802a4e', onSlotchange: this.onSlottedItemsChange })));
  29326. }
  29327. get el() { return getElement(this); }
  29328. static get watchers() { return {
  29329. "color": ["colorChanged"],
  29330. "swipeGesture": ["swipeGestureChanged"],
  29331. "value": ["valueChanged"],
  29332. "disabled": ["disabledChanged"]
  29333. }; }
  29334. static get style() { return {
  29335. ios: IonSegmentIosStyle0,
  29336. md: IonSegmentMdStyle0
  29337. }; }
  29338. static get cmpMeta() { return {
  29339. "$flags$": 41,
  29340. "$tagName$": "ion-segment",
  29341. "$members$": {
  29342. "color": [513],
  29343. "disabled": [4],
  29344. "scrollable": [4],
  29345. "swipeGesture": [4, "swipe-gesture"],
  29346. "value": [1032],
  29347. "selectOnFocus": [4, "select-on-focus"],
  29348. "activated": [32]
  29349. },
  29350. "$listeners$": [[16, "ionSegmentViewScroll", "handleSegmentViewScroll"], [0, "keydown", "onKeyDown"]],
  29351. "$lazyBundleId$": "-",
  29352. "$attrsToReflect$": [["color", "color"]]
  29353. }; }
  29354. }
  29355. const segmentButtonIosCss = ":host{--color:initial;--color-hover:var(--color);--color-checked:var(--color);--color-disabled:var(--color);--padding-start:0;--padding-end:0;--padding-top:0;--padding-bottom:0;border-radius:var(--border-radius);display:-ms-flexbox;display:flex;position:relative;-ms-flex-direction:column;flex-direction:column;height:auto;background:var(--background);color:var(--color);text-decoration:none;text-overflow:ellipsis;white-space:nowrap;cursor:pointer;grid-row:1;-webkit-font-kerning:none;font-kerning:none}.button-native{border-radius:0;font-family:inherit;font-size:inherit;font-style:inherit;font-weight:inherit;letter-spacing:inherit;text-decoration:inherit;text-indent:inherit;text-overflow:inherit;text-transform:inherit;text-align:inherit;white-space:inherit;color:inherit;-webkit-margin-start:var(--margin-start);margin-inline-start:var(--margin-start);-webkit-margin-end:var(--margin-end);margin-inline-end:var(--margin-end);margin-top:var(--margin-top);margin-bottom:var(--margin-bottom);-webkit-padding-start:var(--padding-start);padding-inline-start:var(--padding-start);-webkit-padding-end:var(--padding-end);padding-inline-end:var(--padding-end);padding-top:var(--padding-top);padding-bottom:var(--padding-bottom);-webkit-transform:translate3d(0, 0, 0);transform:translate3d(0, 0, 0);display:-ms-flexbox;display:flex;position:relative;-ms-flex-direction:inherit;flex-direction:inherit;-ms-flex-positive:1;flex-grow:1;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;width:100%;min-width:inherit;max-width:inherit;height:auto;min-height:inherit;max-height:inherit;-webkit-transition:var(--transition);transition:var(--transition);border:none;outline:none;background:transparent;contain:content;pointer-events:none;overflow:hidden;z-index:2}.button-native::after{left:0;right:0;top:0;bottom:0;position:absolute;content:\"\";opacity:0}.button-inner{display:-ms-flexbox;display:flex;position:relative;-ms-flex-flow:inherit;flex-flow:inherit;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;width:100%;height:100%;z-index:1}:host(.segment-button-checked){background:var(--background-checked);color:var(--color-checked)}:host(.segment-button-disabled){cursor:default;pointer-events:none}:host(.ion-focused) .button-native{color:var(--color-focused)}:host(.ion-focused) .button-native::after{background:var(--background-focused);opacity:var(--background-focused-opacity)}:host(:focus){outline:none}@media (any-hover: hover){:host(:hover) .button-native{color:var(--color-hover)}:host(:hover) .button-native::after{background:var(--background-hover);opacity:var(--background-hover-opacity)}:host(.segment-button-checked:hover) .button-native{color:var(--color-checked)}}::slotted(ion-icon){-ms-flex-negative:0;flex-shrink:0;-ms-flex-order:-1;order:-1;pointer-events:none}::slotted(ion-label){display:block;-ms-flex-item-align:center;align-self:center;max-width:100%;line-height:22px;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;-webkit-box-sizing:border-box;box-sizing:border-box;pointer-events:none}:host(.segment-button-layout-icon-top) .button-native{-ms-flex-direction:column;flex-direction:column}:host(.segment-button-layout-icon-start) .button-native{-ms-flex-direction:row;flex-direction:row}:host(.segment-button-layout-icon-end) .button-native{-ms-flex-direction:row-reverse;flex-direction:row-reverse}:host(.segment-button-layout-icon-bottom) .button-native{-ms-flex-direction:column-reverse;flex-direction:column-reverse}:host(.segment-button-layout-icon-hide) ::slotted(ion-icon){display:none}:host(.segment-button-layout-label-hide) ::slotted(ion-label){display:none}ion-ripple-effect{color:var(--ripple-color, var(--color-checked))}.segment-button-indicator{-webkit-transform-origin:left;transform-origin:left;position:absolute;opacity:0;-webkit-box-sizing:border-box;box-sizing:border-box;will-change:transform, opacity;pointer-events:none}.segment-button-indicator-background{width:100%;height:var(--indicator-height);-webkit-transform:var(--indicator-transform);transform:var(--indicator-transform);-webkit-box-shadow:var(--indicator-box-shadow);box-shadow:var(--indicator-box-shadow);pointer-events:none}.segment-button-indicator-animated{-webkit-transition:var(--indicator-transition);transition:var(--indicator-transition)}:host(.segment-button-checked) .segment-button-indicator{opacity:1}@media (prefers-reduced-motion: reduce){.segment-button-indicator-background{-webkit-transform:none;transform:none}.segment-button-indicator-animated{-webkit-transition:none;transition:none}}:host{--background:none;--background-checked:none;--background-hover:none;--background-hover-opacity:0;--background-focused:none;--background-focused-opacity:0;--border-radius:7px;--border-width:1px;--border-color:rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.12);--border-style:solid;--indicator-box-shadow:0 0 5px rgba(0, 0, 0, 0.16);--indicator-color:var(--ion-color-step-350, var(--ion-background-color-step-350, var(--ion-background-color, #fff)));--indicator-height:100%;--indicator-transition:transform 260ms cubic-bezier(0.4, 0, 0.2, 1);--indicator-transform:none;--transition:100ms all linear;--padding-top:0;--padding-end:13px;--padding-bottom:0;--padding-start:13px;margin-top:2px;margin-bottom:2px;position:relative;-ms-flex-direction:row;flex-direction:row;min-width:70px;min-height:28px;-webkit-transform:translate3d(0, 0, 0);transform:translate3d(0, 0, 0);font-size:13px;font-weight:450;line-height:37px}:host::before{margin-left:0;margin-right:0;margin-top:5px;margin-bottom:5px;-webkit-transition:160ms opacity ease-in-out;transition:160ms opacity ease-in-out;-webkit-transition-delay:100ms;transition-delay:100ms;border-left:var(--border-width) var(--border-style) var(--border-color);content:\"\";opacity:1;will-change:opacity}:host(:first-of-type)::before{border-left-color:transparent}:host(.segment-button-disabled){opacity:0.3}::slotted(ion-icon){font-size:24px}:host(.segment-button-layout-icon-start) ::slotted(ion-label){-webkit-margin-start:2px;margin-inline-start:2px;-webkit-margin-end:0;margin-inline-end:0}:host(.segment-button-layout-icon-end) ::slotted(ion-label){-webkit-margin-start:0;margin-inline-start:0;-webkit-margin-end:2px;margin-inline-end:2px}.segment-button-indicator{-webkit-padding-start:2px;padding-inline-start:2px;-webkit-padding-end:2px;padding-inline-end:2px;left:0;right:0;top:0;bottom:0}.segment-button-indicator-background{border-radius:var(--border-radius);background:var(--indicator-color)}.segment-button-indicator-background{-webkit-transition:var(--indicator-transition);transition:var(--indicator-transition)}:host(.segment-button-checked)::before,:host(.segment-button-after-checked)::before{opacity:0}:host(.segment-button-checked){z-index:-1}:host(.segment-button-activated){--indicator-transform:scale(0.95)}:host(.ion-focused) .button-native{opacity:0.7}@media (any-hover: hover){:host(:hover) .button-native{opacity:0.5}:host(.segment-button-checked:hover) .button-native{opacity:1}}:host(.in-segment-color){background:none;color:var(--ion-text-color, #000)}:host(.in-segment-color) .segment-button-indicator-background{background:var(--ion-color-step-350, var(--ion-background-color-step-350, var(--ion-background-color, #fff)))}@media (any-hover: hover){:host(.in-segment-color:hover) .button-native,:host(.in-segment-color.segment-button-checked:hover) .button-native{color:var(--ion-text-color, #000)}}:host(.in-toolbar:not(.in-segment-color)){--background-checked:var(--ion-toolbar-segment-background-checked, none);--color:var(--ion-toolbar-segment-color, var(--ion-toolbar-color), initial);--color-checked:var(--ion-toolbar-segment-color-checked, var(--ion-toolbar-color), initial);--indicator-color:var(--ion-toolbar-segment-indicator-color, var(--ion-color-step-350, var(--ion-background-color-step-350, var(--ion-background-color, #fff))))}:host(.in-toolbar-color) .segment-button-indicator-background{background:var(--ion-color-contrast)}:host(.in-toolbar-color:not(.in-segment-color)) .button-native{color:var(--ion-color-contrast)}:host(.in-toolbar-color.segment-button-checked:not(.in-segment-color)) .button-native{color:var(--ion-color-base)}@media (any-hover: hover){:host(.in-toolbar-color:not(.in-segment-color):hover) .button-native{color:var(--ion-color-contrast)}:host(.in-toolbar-color.segment-button-checked:not(.in-segment-color):hover) .button-native{color:var(--ion-color-base)}}";
  29356. var IonSegmentButtonIosStyle0 = segmentButtonIosCss;
  29357. const segmentButtonMdCss = ":host{--color:initial;--color-hover:var(--color);--color-checked:var(--color);--color-disabled:var(--color);--padding-start:0;--padding-end:0;--padding-top:0;--padding-bottom:0;border-radius:var(--border-radius);display:-ms-flexbox;display:flex;position:relative;-ms-flex-direction:column;flex-direction:column;height:auto;background:var(--background);color:var(--color);text-decoration:none;text-overflow:ellipsis;white-space:nowrap;cursor:pointer;grid-row:1;-webkit-font-kerning:none;font-kerning:none}.button-native{border-radius:0;font-family:inherit;font-size:inherit;font-style:inherit;font-weight:inherit;letter-spacing:inherit;text-decoration:inherit;text-indent:inherit;text-overflow:inherit;text-transform:inherit;text-align:inherit;white-space:inherit;color:inherit;-webkit-margin-start:var(--margin-start);margin-inline-start:var(--margin-start);-webkit-margin-end:var(--margin-end);margin-inline-end:var(--margin-end);margin-top:var(--margin-top);margin-bottom:var(--margin-bottom);-webkit-padding-start:var(--padding-start);padding-inline-start:var(--padding-start);-webkit-padding-end:var(--padding-end);padding-inline-end:var(--padding-end);padding-top:var(--padding-top);padding-bottom:var(--padding-bottom);-webkit-transform:translate3d(0, 0, 0);transform:translate3d(0, 0, 0);display:-ms-flexbox;display:flex;position:relative;-ms-flex-direction:inherit;flex-direction:inherit;-ms-flex-positive:1;flex-grow:1;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;width:100%;min-width:inherit;max-width:inherit;height:auto;min-height:inherit;max-height:inherit;-webkit-transition:var(--transition);transition:var(--transition);border:none;outline:none;background:transparent;contain:content;pointer-events:none;overflow:hidden;z-index:2}.button-native::after{left:0;right:0;top:0;bottom:0;position:absolute;content:\"\";opacity:0}.button-inner{display:-ms-flexbox;display:flex;position:relative;-ms-flex-flow:inherit;flex-flow:inherit;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;width:100%;height:100%;z-index:1}:host(.segment-button-checked){background:var(--background-checked);color:var(--color-checked)}:host(.segment-button-disabled){cursor:default;pointer-events:none}:host(.ion-focused) .button-native{color:var(--color-focused)}:host(.ion-focused) .button-native::after{background:var(--background-focused);opacity:var(--background-focused-opacity)}:host(:focus){outline:none}@media (any-hover: hover){:host(:hover) .button-native{color:var(--color-hover)}:host(:hover) .button-native::after{background:var(--background-hover);opacity:var(--background-hover-opacity)}:host(.segment-button-checked:hover) .button-native{color:var(--color-checked)}}::slotted(ion-icon){-ms-flex-negative:0;flex-shrink:0;-ms-flex-order:-1;order:-1;pointer-events:none}::slotted(ion-label){display:block;-ms-flex-item-align:center;align-self:center;max-width:100%;line-height:22px;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;-webkit-box-sizing:border-box;box-sizing:border-box;pointer-events:none}:host(.segment-button-layout-icon-top) .button-native{-ms-flex-direction:column;flex-direction:column}:host(.segment-button-layout-icon-start) .button-native{-ms-flex-direction:row;flex-direction:row}:host(.segment-button-layout-icon-end) .button-native{-ms-flex-direction:row-reverse;flex-direction:row-reverse}:host(.segment-button-layout-icon-bottom) .button-native{-ms-flex-direction:column-reverse;flex-direction:column-reverse}:host(.segment-button-layout-icon-hide) ::slotted(ion-icon){display:none}:host(.segment-button-layout-label-hide) ::slotted(ion-label){display:none}ion-ripple-effect{color:var(--ripple-color, var(--color-checked))}.segment-button-indicator{-webkit-transform-origin:left;transform-origin:left;position:absolute;opacity:0;-webkit-box-sizing:border-box;box-sizing:border-box;will-change:transform, opacity;pointer-events:none}.segment-button-indicator-background{width:100%;height:var(--indicator-height);-webkit-transform:var(--indicator-transform);transform:var(--indicator-transform);-webkit-box-shadow:var(--indicator-box-shadow);box-shadow:var(--indicator-box-shadow);pointer-events:none}.segment-button-indicator-animated{-webkit-transition:var(--indicator-transition);transition:var(--indicator-transition)}:host(.segment-button-checked) .segment-button-indicator{opacity:1}@media (prefers-reduced-motion: reduce){.segment-button-indicator-background{-webkit-transform:none;transform:none}.segment-button-indicator-animated{-webkit-transition:none;transition:none}}:host{--background:none;--background-checked:none;--background-hover:var(--color-checked);--background-focused:var(--color-checked);--background-activated-opacity:0;--background-focused-opacity:.12;--background-hover-opacity:.04;--color:rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.6);--color-checked:var(--ion-color-primary, #0054e9);--indicator-box-shadow:none;--indicator-color:var(--color-checked);--indicator-height:2px;--indicator-transition:transform 250ms cubic-bezier(0.4, 0, 0.2, 1);--indicator-transform:none;--padding-top:0;--padding-end:16px;--padding-bottom:0;--padding-start:16px;--transition:color 0.15s linear 0s, opacity 0.15s linear 0s;min-width:90px;min-height:48px;border-width:var(--border-width);border-style:var(--border-style);border-color:var(--border-color);font-size:14px;font-weight:500;letter-spacing:0.06em;line-height:40px;text-transform:uppercase}:host(.segment-button-disabled){opacity:0.3}:host(.in-segment-color){background:none;color:rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.6)}:host(.in-segment-color) ion-ripple-effect{color:var(--ion-color-base)}:host(.in-segment-color) .segment-button-indicator-background{background:var(--ion-color-base)}:host(.in-segment-color.segment-button-checked) .button-native{color:var(--ion-color-base)}:host(.in-segment-color.ion-focused) .button-native::after{background:var(--ion-color-base)}@media (any-hover: hover){:host(.in-segment-color:hover) .button-native{color:rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.6)}:host(.in-segment-color:hover) .button-native::after{background:var(--ion-color-base)}:host(.in-segment-color.segment-button-checked:hover) .button-native{color:var(--ion-color-base)}}:host(.in-toolbar:not(.in-segment-color)){--background:var(--ion-toolbar-segment-background, none);--background-checked:var(--ion-toolbar-segment-background-checked, none);--color:var(--ion-toolbar-segment-color, rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.6));--color-checked:var(--ion-toolbar-segment-color-checked, var(--ion-color-primary, #0054e9));--indicator-color:var(--ion-toolbar-segment-color-checked, var(--color-checked))}:host(.in-toolbar-color:not(.in-segment-color)) .button-native{color:rgba(var(--ion-color-contrast-rgb), 0.6)}:host(.in-toolbar-color.segment-button-checked:not(.in-segment-color)) .button-native{color:var(--ion-color-contrast)}@media (any-hover: hover){:host(.in-toolbar-color:not(.in-segment-color)) .button-native::after{background:var(--ion-color-contrast)}}::slotted(ion-icon){margin-top:12px;margin-bottom:12px;font-size:24px}::slotted(ion-label){margin-top:12px;margin-bottom:12px}:host(.segment-button-layout-icon-top) ::slotted(ion-label),:host(.segment-button-layout-icon-bottom) ::slotted(ion-icon){margin-top:0}:host(.segment-button-layout-icon-top) ::slotted(ion-icon),:host(.segment-button-layout-icon-bottom) ::slotted(ion-label){margin-bottom:0}:host(.segment-button-layout-icon-start) ::slotted(ion-label){-webkit-margin-start:8px;margin-inline-start:8px;-webkit-margin-end:0;margin-inline-end:0}:host(.segment-button-layout-icon-end) ::slotted(ion-label){-webkit-margin-start:0;margin-inline-start:0;-webkit-margin-end:8px;margin-inline-end:8px}:host(.segment-button-has-icon-only) ::slotted(ion-icon){margin-top:12px;margin-bottom:12px}:host(.segment-button-has-label-only) ::slotted(ion-label){margin-top:12px;margin-bottom:12px}.segment-button-indicator{left:0;right:0;bottom:0}.segment-button-indicator-background{background:var(--indicator-color)}:host(.in-toolbar:not(.in-segment-color)) .segment-button-indicator-background{background:var(--ion-toolbar-segment-indicator-color, var(--indicator-color))}:host(.in-toolbar-color:not(.in-segment-color)) .segment-button-indicator-background{background:var(--ion-color-contrast)}";
  29358. var IonSegmentButtonMdStyle0 = segmentButtonMdCss;
  29359. let ids = 0;
  29360. /**
  29361. * @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
  29362. *
  29363. * @part native - The native HTML button element that wraps all child elements.
  29364. * @part indicator - The indicator displayed on the checked segment button.
  29365. * @part indicator-background - The background element for the indicator displayed on the checked segment button.
  29366. */
  29367. class SegmentButton {
  29368. constructor(hostRef) {
  29369. registerInstance(this, hostRef);
  29370. this.segmentEl = null;
  29371. this.inheritedAttributes = {};
  29372. this.updateStyle = () => {
  29373. };
  29374. this.updateState = () => {
  29375. const { segmentEl } = this;
  29376. if (segmentEl) {
  29377. this.checked = segmentEl.value === this.value;
  29378. if (segmentEl.disabled) {
  29379. this.disabled = true;
  29380. }
  29381. }
  29382. };
  29383. this.checked = false;
  29384. this.contentId = undefined;
  29385. this.disabled = false;
  29386. this.layout = 'icon-top';
  29387. this.type = 'button';
  29388. this.value = 'ion-sb-' + ids++;
  29389. }
  29390. valueChanged() {
  29391. this.updateState();
  29392. }
  29393. connectedCallback() {
  29394. const segmentEl = (this.segmentEl = this.el.closest('ion-segment'));
  29395. if (segmentEl) {
  29396. this.updateState();
  29397. addEventListener$1(segmentEl, 'ionSelect', this.updateState);
  29398. addEventListener$1(segmentEl, 'ionStyle', this.updateStyle);
  29399. }
  29400. // Prevent buttons from being disabled when associated with segment content
  29401. if (this.contentId && this.disabled) {
  29402. printIonWarning(`[ion-segment-button] - Segment buttons cannot be disabled when associated with an <ion-segment-content>.`);
  29403. this.disabled = false;
  29404. }
  29405. }
  29406. disconnectedCallback() {
  29407. const segmentEl = this.segmentEl;
  29408. if (segmentEl) {
  29409. removeEventListener(segmentEl, 'ionSelect', this.updateState);
  29410. removeEventListener(segmentEl, 'ionStyle', this.updateStyle);
  29411. this.segmentEl = null;
  29412. }
  29413. }
  29414. componentWillLoad() {
  29415. this.inheritedAttributes = Object.assign({}, inheritAttributes$1(this.el, ['aria-label']));
  29416. // Return if there is no contentId defined
  29417. if (!this.contentId)
  29418. return;
  29419. // Attempt to find the Segment Content by its contentId
  29420. const segmentContent = document.getElementById(this.contentId);
  29421. // If no associated Segment Content exists, log an error and return
  29422. if (!segmentContent) {
  29423. printIonError(`[ion-segment-button] - Unable to find Segment Content with id="${this.contentId}".`);
  29424. return;
  29425. }
  29426. // Ensure the found element is a valid ION-SEGMENT-CONTENT
  29427. if (segmentContent.tagName !== 'ION-SEGMENT-CONTENT') {
  29428. printIonError(`[ion-segment-button] - Element with id="${this.contentId}" is not an <ion-segment-content> element.`);
  29429. return;
  29430. }
  29431. }
  29432. get hasLabel() {
  29433. return !!this.el.querySelector('ion-label');
  29434. }
  29435. get hasIcon() {
  29436. return !!this.el.querySelector('ion-icon');
  29437. }
  29438. /**
  29439. * @internal
  29440. * Focuses the native <button> element
  29441. * inside of ion-segment-button.
  29442. */
  29443. async setFocus() {
  29444. const { nativeEl } = this;
  29445. if (nativeEl !== undefined) {
  29446. nativeEl.focus();
  29447. }
  29448. }
  29449. render() {
  29450. const { checked, type, disabled, hasIcon, hasLabel, layout, segmentEl } = this;
  29451. const mode = getIonMode$1(this);
  29452. const hasSegmentColor = () => (segmentEl === null || segmentEl === void 0 ? void 0 : segmentEl.color) !== undefined;
  29453. return (hAsync(Host, { key: 'd79dad80db69123510c6d52bbf4424558600c14a', class: {
  29454. [mode]: true,
  29455. 'in-toolbar': hostContext('ion-toolbar', this.el),
  29456. 'in-toolbar-color': hostContext('ion-toolbar[color]', this.el),
  29457. 'in-segment': hostContext('ion-segment', this.el),
  29458. 'in-segment-color': hasSegmentColor(),
  29459. 'segment-button-has-label': hasLabel,
  29460. 'segment-button-has-icon': hasIcon,
  29461. 'segment-button-has-label-only': hasLabel && !hasIcon,
  29462. 'segment-button-has-icon-only': hasIcon && !hasLabel,
  29463. 'segment-button-disabled': disabled,
  29464. 'segment-button-checked': checked,
  29465. [`segment-button-layout-${layout}`]: true,
  29466. 'ion-activatable': true,
  29467. 'ion-activatable-instant': true,
  29468. 'ion-focusable': true,
  29469. } }, hAsync("button", Object.assign({ key: '781fd7fef443a2fbd404b8a399d1203794759a69', "aria-selected": checked ? 'true' : 'false', role: "tab", ref: (el) => (this.nativeEl = el), type: type, class: "button-native", part: "native", disabled: disabled }, this.inheritedAttributes), hAsync("span", { key: '64df08f60ea17481183f8ad284884b9979eaeb24', class: "button-inner" }, hAsync("slot", { key: '2b7ef328023ab5ccc0adc6f865e5e7121467eeb8' })), mode === 'md' && hAsync("ion-ripple-effect", { key: '1fd5e6179227925a03b6c3b5258bbf4ea99bfef1' })), hAsync("div", { key: 'dbcedad6988b0eadeebe02bdafdedb8eb37af19c', part: "indicator", class: "segment-button-indicator segment-button-indicator-animated" }, hAsync("div", { key: 'f4f1789f66bdfa2de5445bc0d292116a93bad7cc', part: "indicator-background", class: "segment-button-indicator-background" }))));
  29470. }
  29471. get el() { return getElement(this); }
  29472. static get watchers() { return {
  29473. "value": ["valueChanged"]
  29474. }; }
  29475. static get style() { return {
  29476. ios: IonSegmentButtonIosStyle0,
  29477. md: IonSegmentButtonMdStyle0
  29478. }; }
  29479. static get cmpMeta() { return {
  29480. "$flags$": 41,
  29481. "$tagName$": "ion-segment-button",
  29482. "$members$": {
  29483. "contentId": [513, "content-id"],
  29484. "disabled": [1028],
  29485. "layout": [1],
  29486. "type": [1],
  29487. "value": [8],
  29488. "checked": [32],
  29489. "setFocus": [64]
  29490. },
  29491. "$listeners$": undefined,
  29492. "$lazyBundleId$": "-",
  29493. "$attrsToReflect$": [["contentId", "content-id"]]
  29494. }; }
  29495. }
  29496. const segmentContentCss = ":host{scroll-snap-align:center;scroll-snap-stop:always;-ms-flex-negative:0;flex-shrink:0;width:100%;overflow-y:scroll;scrollbar-width:none;-ms-overflow-style:none;}:host::-webkit-scrollbar{display:none}";
  29497. var IonSegmentContentStyle0 = segmentContentCss;
  29498. class SegmentContent {
  29499. constructor(hostRef) {
  29500. registerInstance(this, hostRef);
  29501. }
  29502. render() {
  29503. return (hAsync(Host, { key: '64b3965b14c749e77e9ce13b59f349d971e245c8' }, hAsync("slot", { key: '2d0bed34f9bc93f92e713cb51e42220f3cecd8f5' })));
  29504. }
  29505. static get style() { return IonSegmentContentStyle0; }
  29506. static get cmpMeta() { return {
  29507. "$flags$": 9,
  29508. "$tagName$": "ion-segment-content",
  29509. "$members$": undefined,
  29510. "$listeners$": undefined,
  29511. "$lazyBundleId$": "-",
  29512. "$attrsToReflect$": []
  29513. }; }
  29514. }
  29515. const segmentViewIosCss = ":host{display:-ms-flexbox;display:flex;height:100%;overflow-x:scroll;-webkit-scroll-snap-type:x mandatory;-ms-scroll-snap-type:x mandatory;scroll-snap-type:x mandatory;scrollbar-width:none;-ms-overflow-style:none}:host::-webkit-scrollbar{display:none}:host(.segment-view-disabled){-ms-touch-action:none;touch-action:none;overflow-x:hidden}:host(.segment-view-scroll-disabled){pointer-events:none}:host(.segment-view-disabled){opacity:0.3}";
  29516. var IonSegmentViewIosStyle0 = segmentViewIosCss;
  29517. const segmentViewMdCss = ":host{display:-ms-flexbox;display:flex;height:100%;overflow-x:scroll;-webkit-scroll-snap-type:x mandatory;-ms-scroll-snap-type:x mandatory;scroll-snap-type:x mandatory;scrollbar-width:none;-ms-overflow-style:none}:host::-webkit-scrollbar{display:none}:host(.segment-view-disabled){-ms-touch-action:none;touch-action:none;overflow-x:hidden}:host(.segment-view-scroll-disabled){pointer-events:none}:host(.segment-view-disabled){opacity:0.3}";
  29518. var IonSegmentViewMdStyle0 = segmentViewMdCss;
  29519. class SegmentView {
  29520. constructor(hostRef) {
  29521. registerInstance(this, hostRef);
  29522. this.ionSegmentViewScroll = createEvent(this, "ionSegmentViewScroll", 7);
  29523. this.scrollEndTimeout = null;
  29524. this.isTouching = false;
  29525. this.disabled = false;
  29526. this.isManualScroll = undefined;
  29527. }
  29528. handleScroll(ev) {
  29529. var _a;
  29530. const { scrollLeft, scrollWidth, clientWidth } = ev.target;
  29531. const scrollRatio = scrollLeft / (scrollWidth - clientWidth);
  29532. this.ionSegmentViewScroll.emit({
  29533. scrollRatio,
  29534. isManualScroll: (_a = this.isManualScroll) !== null && _a !== void 0 ? _a : true,
  29535. });
  29536. // Reset the timeout to check for scroll end
  29537. this.resetScrollEndTimeout();
  29538. }
  29539. /**
  29540. * Handle touch start event to know when the user is actively dragging the segment view.
  29541. */
  29542. handleScrollStart() {
  29543. if (this.scrollEndTimeout) {
  29544. clearTimeout(this.scrollEndTimeout);
  29545. this.scrollEndTimeout = null;
  29546. }
  29547. this.isTouching = true;
  29548. }
  29549. /**
  29550. * Handle touch end event to know when the user is no longer dragging the segment view.
  29551. */
  29552. handleTouchEnd() {
  29553. this.isTouching = false;
  29554. }
  29555. /**
  29556. * Reset the scroll end detection timer. This is called on every scroll event.
  29557. */
  29558. resetScrollEndTimeout() {
  29559. if (this.scrollEndTimeout) {
  29560. clearTimeout(this.scrollEndTimeout);
  29561. this.scrollEndTimeout = null;
  29562. }
  29563. this.scrollEndTimeout = setTimeout(() => {
  29564. this.checkForScrollEnd();
  29565. },
  29566. // Setting this to a lower value may result in inconsistencies in behavior
  29567. // across browsers (particularly Firefox).
  29568. // Ideally, all of this logic is removed once the scroll end event is
  29569. // supported on all browsers (https://caniuse.com/?search=scrollend)
  29570. 100);
  29571. }
  29572. /**
  29573. * Check if the scroll has ended and the user is not actively touching.
  29574. * If the conditions are met (active content is enabled and no active touch),
  29575. * reset the scroll position and emit the scroll end event.
  29576. */
  29577. checkForScrollEnd() {
  29578. // Only emit scroll end event if the active content is not disabled and
  29579. // the user is not touching the segment view
  29580. if (!this.isTouching) {
  29581. this.isManualScroll = undefined;
  29582. }
  29583. }
  29584. /**
  29585. * @internal
  29586. *
  29587. * This method is used to programmatically set the displayed segment content
  29588. * in the segment view. Calling this method will update the `value` of the
  29589. * corresponding segment button.
  29590. *
  29591. * @param id: The id of the segment content to display.
  29592. * @param smoothScroll: Whether to animate the scroll transition.
  29593. */
  29594. async setContent(id, smoothScroll = true) {
  29595. const contents = this.getSegmentContents();
  29596. const index = contents.findIndex((content) => content.id === id);
  29597. if (index === -1)
  29598. return;
  29599. this.isManualScroll = false;
  29600. this.resetScrollEndTimeout();
  29601. const contentWidth = this.el.offsetWidth;
  29602. this.el.scrollTo({
  29603. top: 0,
  29604. left: index * contentWidth,
  29605. behavior: smoothScroll ? 'smooth' : 'instant',
  29606. });
  29607. }
  29608. getSegmentContents() {
  29609. return Array.from(this.el.querySelectorAll('ion-segment-content'));
  29610. }
  29611. render() {
  29612. const { disabled, isManualScroll } = this;
  29613. return (hAsync(Host, { key: 'fa528d2d9ae0f00fc3067defe2a047dce77c814a', class: {
  29614. 'segment-view-disabled': disabled,
  29615. 'segment-view-scroll-disabled': isManualScroll === false,
  29616. } }, hAsync("slot", { key: '74dc8b4d073caeff1bab272d11b9ea3e1a215954' })));
  29617. }
  29618. get el() { return getElement(this); }
  29619. static get style() { return {
  29620. ios: IonSegmentViewIosStyle0,
  29621. md: IonSegmentViewMdStyle0
  29622. }; }
  29623. static get cmpMeta() { return {
  29624. "$flags$": 41,
  29625. "$tagName$": "ion-segment-view",
  29626. "$members$": {
  29627. "disabled": [4],
  29628. "isManualScroll": [32],
  29629. "setContent": [64]
  29630. },
  29631. "$listeners$": [[1, "scroll", "handleScroll"], [1, "touchstart", "handleScrollStart"], [1, "touchend", "handleTouchEnd"]],
  29632. "$lazyBundleId$": "-",
  29633. "$attrsToReflect$": []
  29634. }; }
  29635. }
  29636. const selectIosCss = ":host{--padding-top:0px;--padding-end:0px;--padding-bottom:0px;--padding-start:0px;--placeholder-color:currentColor;--placeholder-opacity:var(--ion-placeholder-opacity, 0.6);--background:transparent;--border-style:solid;--highlight-color-focused:var(--ion-color-primary, #0054e9);--highlight-color-valid:var(--ion-color-success, #2dd55b);--highlight-color-invalid:var(--ion-color-danger, #c5000f);--highlight-color:var(--highlight-color-focused);display:block;position:relative;width:100%;min-height:44px;font-family:var(--ion-font-family, inherit);white-space:nowrap;cursor:pointer;z-index:2}:host(.select-label-placement-floating),:host(.select-label-placement-stacked){min-height:56px}:host(.ion-color){--highlight-color-focused:var(--ion-color-base)}:host(.in-item){-ms-flex:1 1 0px;flex:1 1 0}:host(.select-disabled){pointer-events:none}:host(.has-focus) button{border:2px solid #5e9ed6}:host([slot=start]),:host([slot=end]){-ms-flex:initial;flex:initial;width:auto}.select-placeholder{color:var(--placeholder-color);opacity:var(--placeholder-opacity)}button{position:absolute;top:0;left:0;right:0;bottom:0;width:100%;height:100%;margin:0;padding:0;border:0;outline:0;clip:rect(0 0 0 0);opacity:0;overflow:hidden;-webkit-appearance:none;-moz-appearance:none}.select-icon{-webkit-margin-start:4px;margin-inline-start:4px;-webkit-margin-end:0;margin-inline-end:0;margin-top:0;margin-bottom:0;position:relative;-ms-flex-negative:0;flex-shrink:0}:host(.in-item-color) .select-icon{color:inherit}:host(.select-label-placement-stacked) .select-icon,:host(.select-label-placement-floating) .select-icon{position:absolute;height:100%}:host(.select-ltr.select-label-placement-stacked) .select-icon,:host(.select-ltr.select-label-placement-floating) .select-icon{right:var(--padding-end, 0)}:host(.select-rtl.select-label-placement-stacked) .select-icon,:host(.select-rtl.select-label-placement-floating) .select-icon{left:var(--padding-start, 0)}.select-text{-ms-flex:1;flex:1;min-width:16px;font-size:inherit;text-overflow:ellipsis;white-space:inherit;overflow:hidden}.select-wrapper{-webkit-padding-start:var(--padding-start);padding-inline-start:var(--padding-start);-webkit-padding-end:var(--padding-end);padding-inline-end:var(--padding-end);padding-top:var(--padding-top);padding-bottom:var(--padding-bottom);border-radius:var(--border-radius);display:-ms-flexbox;display:flex;position:relative;-ms-flex-positive:1;flex-grow:1;-ms-flex-align:center;align-items:center;-ms-flex-pack:justify;justify-content:space-between;height:inherit;min-height:inherit;-webkit-transition:background-color 15ms linear;transition:background-color 15ms linear;background:var(--background);line-height:normal;cursor:inherit;-webkit-box-sizing:border-box;box-sizing:border-box}.select-wrapper .select-placeholder{-webkit-transition:opacity 150ms cubic-bezier(0.4, 0, 0.2, 1);transition:opacity 150ms cubic-bezier(0.4, 0, 0.2, 1)}.select-wrapper-inner{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;overflow:hidden}:host(.select-label-placement-stacked) .select-wrapper-inner,:host(.select-label-placement-floating) .select-wrapper-inner{-ms-flex-positive:1;flex-grow:1}:host(.ion-touched.ion-invalid){--highlight-color:var(--highlight-color-invalid)}:host(.ion-valid){--highlight-color:var(--highlight-color-valid)}.select-bottom{-webkit-padding-start:var(--padding-start);padding-inline-start:var(--padding-start);-webkit-padding-end:var(--padding-end);padding-inline-end:var(--padding-end);padding-top:5px;padding-bottom:0;display:-ms-flexbox;display:flex;-ms-flex-pack:justify;justify-content:space-between;border-top:var(--border-width) var(--border-style) var(--border-color);font-size:0.75rem;white-space:normal}:host(.has-focus.ion-valid),:host(.select-expanded.ion-valid),:host(.ion-touched.ion-invalid),:host(.select-expanded.ion-touched.ion-invalid){--border-color:var(--highlight-color)}.select-bottom .error-text{display:none;color:var(--highlight-color-invalid)}.select-bottom .helper-text{display:block;color:var(--ion-color-step-700, var(--ion-text-color-step-300, #4d4d4d))}:host(.ion-touched.ion-invalid) .select-bottom .error-text{display:block}:host(.ion-touched.ion-invalid) .select-bottom .helper-text{display:none}.label-text-wrapper{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;max-width:200px;-webkit-transition:color 150ms cubic-bezier(0.4, 0, 0.2, 1), -webkit-transform 150ms cubic-bezier(0.4, 0, 0.2, 1);transition:color 150ms cubic-bezier(0.4, 0, 0.2, 1), -webkit-transform 150ms cubic-bezier(0.4, 0, 0.2, 1);transition:color 150ms cubic-bezier(0.4, 0, 0.2, 1), transform 150ms cubic-bezier(0.4, 0, 0.2, 1);transition:color 150ms cubic-bezier(0.4, 0, 0.2, 1), transform 150ms cubic-bezier(0.4, 0, 0.2, 1), -webkit-transform 150ms cubic-bezier(0.4, 0, 0.2, 1);pointer-events:none}.label-text,::slotted([slot=label]){text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.label-text-wrapper-hidden,.select-outline-notch-hidden{display:none}.native-wrapper{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-webkit-transition:opacity 150ms cubic-bezier(0.4, 0, 0.2, 1);transition:opacity 150ms cubic-bezier(0.4, 0, 0.2, 1);overflow:hidden}:host(.select-justify-space-between) .select-wrapper{-ms-flex-pack:justify;justify-content:space-between}:host(.select-justify-start) .select-wrapper{-ms-flex-pack:start;justify-content:start}:host(.select-justify-end) .select-wrapper{-ms-flex-pack:end;justify-content:end}:host(.select-label-placement-start) .select-wrapper{-ms-flex-direction:row;flex-direction:row}:host(.select-label-placement-start) .label-text-wrapper{-webkit-margin-start:0;margin-inline-start:0;-webkit-margin-end:16px;margin-inline-end:16px;margin-top:0;margin-bottom:0}:host(.select-label-placement-end) .select-wrapper{-ms-flex-direction:row-reverse;flex-direction:row-reverse}:host(.select-label-placement-end) .label-text-wrapper{-webkit-margin-start:16px;margin-inline-start:16px;-webkit-margin-end:0;margin-inline-end:0;margin-top:0;margin-bottom:0}:host(.select-label-placement-fixed) .label-text-wrapper{-webkit-margin-start:0;margin-inline-start:0;-webkit-margin-end:16px;margin-inline-end:16px;margin-top:0;margin-bottom:0}:host(.select-label-placement-fixed) .label-text-wrapper{-ms-flex:0 0 100px;flex:0 0 100px;width:100px;min-width:100px;max-width:200px}:host(.select-label-placement-stacked) .select-wrapper,:host(.select-label-placement-floating) .select-wrapper{-ms-flex-direction:column;flex-direction:column;-ms-flex-align:start;align-items:start}:host(.select-label-placement-stacked) .label-text-wrapper,:host(.select-label-placement-floating) .label-text-wrapper{max-width:100%}:host(.select-ltr.select-label-placement-stacked) .label-text-wrapper,:host(.select-ltr.select-label-placement-floating) .label-text-wrapper{-webkit-transform-origin:left top;transform-origin:left top}:host(.select-rtl.select-label-placement-stacked) .label-text-wrapper,:host(.select-rtl.select-label-placement-floating) .label-text-wrapper{-webkit-transform-origin:right top;transform-origin:right top}:host(.select-label-placement-stacked) .native-wrapper,:host(.select-label-placement-floating) .native-wrapper{margin-left:0;margin-right:0;margin-top:1px;margin-bottom:0;-ms-flex-positive:1;flex-grow:1;width:100%}:host(.select-label-placement-floating) .label-text-wrapper{-webkit-transform:translateY(100%) scale(1);transform:translateY(100%) scale(1)}:host(.select-label-placement-floating:not(.label-floating)) .native-wrapper .select-placeholder{opacity:0}:host(.select-expanded.select-label-placement-floating) .native-wrapper .select-placeholder,:host(.has-focus.select-label-placement-floating) .native-wrapper .select-placeholder,:host(.has-value.select-label-placement-floating) .native-wrapper .select-placeholder{opacity:1}:host(.label-floating) .label-text-wrapper{-webkit-transform:translateY(50%) scale(0.75);transform:translateY(50%) scale(0.75);max-width:calc(100% / 0.75)}::slotted([slot=start]),::slotted([slot=end]){-ms-flex-negative:0;flex-shrink:0}::slotted([slot=start]:last-of-type){-webkit-margin-end:16px;margin-inline-end:16px;-webkit-margin-start:0;margin-inline-start:0}::slotted([slot=end]:first-of-type){-webkit-margin-start:16px;margin-inline-start:16px;-webkit-margin-end:0;margin-inline-end:0}:host{--border-width:0.55px;--border-color:var(--ion-item-border-color, var(--ion-border-color, var(--ion-color-step-250, var(--ion-background-color-step-250, #c8c7cc))));--highlight-height:0px}.select-icon{width:1.125rem;height:1.125rem;color:var(--ion-color-step-650, var(--ion-text-color-step-350, #595959))}:host(.select-label-placement-stacked) .select-wrapper-inner,:host(.select-label-placement-floating) .select-wrapper-inner{width:calc(100% - 1.125rem - 4px)}:host(.select-disabled){opacity:0.3}::slotted(ion-button[slot=start].button-has-icon-only),::slotted(ion-button[slot=end].button-has-icon-only){--border-radius:50%;--padding-start:0;--padding-end:0;--padding-top:0;--padding-bottom:0;aspect-ratio:1}";
  29637. var IonSelectIosStyle0 = selectIosCss;
  29638. const selectMdCss = ":host{--padding-top:0px;--padding-end:0px;--padding-bottom:0px;--padding-start:0px;--placeholder-color:currentColor;--placeholder-opacity:var(--ion-placeholder-opacity, 0.6);--background:transparent;--border-style:solid;--highlight-color-focused:var(--ion-color-primary, #0054e9);--highlight-color-valid:var(--ion-color-success, #2dd55b);--highlight-color-invalid:var(--ion-color-danger, #c5000f);--highlight-color:var(--highlight-color-focused);display:block;position:relative;width:100%;min-height:44px;font-family:var(--ion-font-family, inherit);white-space:nowrap;cursor:pointer;z-index:2}:host(.select-label-placement-floating),:host(.select-label-placement-stacked){min-height:56px}:host(.ion-color){--highlight-color-focused:var(--ion-color-base)}:host(.in-item){-ms-flex:1 1 0px;flex:1 1 0}:host(.select-disabled){pointer-events:none}:host(.has-focus) button{border:2px solid #5e9ed6}:host([slot=start]),:host([slot=end]){-ms-flex:initial;flex:initial;width:auto}.select-placeholder{color:var(--placeholder-color);opacity:var(--placeholder-opacity)}button{position:absolute;top:0;left:0;right:0;bottom:0;width:100%;height:100%;margin:0;padding:0;border:0;outline:0;clip:rect(0 0 0 0);opacity:0;overflow:hidden;-webkit-appearance:none;-moz-appearance:none}.select-icon{-webkit-margin-start:4px;margin-inline-start:4px;-webkit-margin-end:0;margin-inline-end:0;margin-top:0;margin-bottom:0;position:relative;-ms-flex-negative:0;flex-shrink:0}:host(.in-item-color) .select-icon{color:inherit}:host(.select-label-placement-stacked) .select-icon,:host(.select-label-placement-floating) .select-icon{position:absolute;height:100%}:host(.select-ltr.select-label-placement-stacked) .select-icon,:host(.select-ltr.select-label-placement-floating) .select-icon{right:var(--padding-end, 0)}:host(.select-rtl.select-label-placement-stacked) .select-icon,:host(.select-rtl.select-label-placement-floating) .select-icon{left:var(--padding-start, 0)}.select-text{-ms-flex:1;flex:1;min-width:16px;font-size:inherit;text-overflow:ellipsis;white-space:inherit;overflow:hidden}.select-wrapper{-webkit-padding-start:var(--padding-start);padding-inline-start:var(--padding-start);-webkit-padding-end:var(--padding-end);padding-inline-end:var(--padding-end);padding-top:var(--padding-top);padding-bottom:var(--padding-bottom);border-radius:var(--border-radius);display:-ms-flexbox;display:flex;position:relative;-ms-flex-positive:1;flex-grow:1;-ms-flex-align:center;align-items:center;-ms-flex-pack:justify;justify-content:space-between;height:inherit;min-height:inherit;-webkit-transition:background-color 15ms linear;transition:background-color 15ms linear;background:var(--background);line-height:normal;cursor:inherit;-webkit-box-sizing:border-box;box-sizing:border-box}.select-wrapper .select-placeholder{-webkit-transition:opacity 150ms cubic-bezier(0.4, 0, 0.2, 1);transition:opacity 150ms cubic-bezier(0.4, 0, 0.2, 1)}.select-wrapper-inner{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;overflow:hidden}:host(.select-label-placement-stacked) .select-wrapper-inner,:host(.select-label-placement-floating) .select-wrapper-inner{-ms-flex-positive:1;flex-grow:1}:host(.ion-touched.ion-invalid){--highlight-color:var(--highlight-color-invalid)}:host(.ion-valid){--highlight-color:var(--highlight-color-valid)}.select-bottom{-webkit-padding-start:var(--padding-start);padding-inline-start:var(--padding-start);-webkit-padding-end:var(--padding-end);padding-inline-end:var(--padding-end);padding-top:5px;padding-bottom:0;display:-ms-flexbox;display:flex;-ms-flex-pack:justify;justify-content:space-between;border-top:var(--border-width) var(--border-style) var(--border-color);font-size:0.75rem;white-space:normal}:host(.has-focus.ion-valid),:host(.select-expanded.ion-valid),:host(.ion-touched.ion-invalid),:host(.select-expanded.ion-touched.ion-invalid){--border-color:var(--highlight-color)}.select-bottom .error-text{display:none;color:var(--highlight-color-invalid)}.select-bottom .helper-text{display:block;color:var(--ion-color-step-700, var(--ion-text-color-step-300, #4d4d4d))}:host(.ion-touched.ion-invalid) .select-bottom .error-text{display:block}:host(.ion-touched.ion-invalid) .select-bottom .helper-text{display:none}.label-text-wrapper{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;max-width:200px;-webkit-transition:color 150ms cubic-bezier(0.4, 0, 0.2, 1), -webkit-transform 150ms cubic-bezier(0.4, 0, 0.2, 1);transition:color 150ms cubic-bezier(0.4, 0, 0.2, 1), -webkit-transform 150ms cubic-bezier(0.4, 0, 0.2, 1);transition:color 150ms cubic-bezier(0.4, 0, 0.2, 1), transform 150ms cubic-bezier(0.4, 0, 0.2, 1);transition:color 150ms cubic-bezier(0.4, 0, 0.2, 1), transform 150ms cubic-bezier(0.4, 0, 0.2, 1), -webkit-transform 150ms cubic-bezier(0.4, 0, 0.2, 1);pointer-events:none}.label-text,::slotted([slot=label]){text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.label-text-wrapper-hidden,.select-outline-notch-hidden{display:none}.native-wrapper{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-webkit-transition:opacity 150ms cubic-bezier(0.4, 0, 0.2, 1);transition:opacity 150ms cubic-bezier(0.4, 0, 0.2, 1);overflow:hidden}:host(.select-justify-space-between) .select-wrapper{-ms-flex-pack:justify;justify-content:space-between}:host(.select-justify-start) .select-wrapper{-ms-flex-pack:start;justify-content:start}:host(.select-justify-end) .select-wrapper{-ms-flex-pack:end;justify-content:end}:host(.select-label-placement-start) .select-wrapper{-ms-flex-direction:row;flex-direction:row}:host(.select-label-placement-start) .label-text-wrapper{-webkit-margin-start:0;margin-inline-start:0;-webkit-margin-end:16px;margin-inline-end:16px;margin-top:0;margin-bottom:0}:host(.select-label-placement-end) .select-wrapper{-ms-flex-direction:row-reverse;flex-direction:row-reverse}:host(.select-label-placement-end) .label-text-wrapper{-webkit-margin-start:16px;margin-inline-start:16px;-webkit-margin-end:0;margin-inline-end:0;margin-top:0;margin-bottom:0}:host(.select-label-placement-fixed) .label-text-wrapper{-webkit-margin-start:0;margin-inline-start:0;-webkit-margin-end:16px;margin-inline-end:16px;margin-top:0;margin-bottom:0}:host(.select-label-placement-fixed) .label-text-wrapper{-ms-flex:0 0 100px;flex:0 0 100px;width:100px;min-width:100px;max-width:200px}:host(.select-label-placement-stacked) .select-wrapper,:host(.select-label-placement-floating) .select-wrapper{-ms-flex-direction:column;flex-direction:column;-ms-flex-align:start;align-items:start}:host(.select-label-placement-stacked) .label-text-wrapper,:host(.select-label-placement-floating) .label-text-wrapper{max-width:100%}:host(.select-ltr.select-label-placement-stacked) .label-text-wrapper,:host(.select-ltr.select-label-placement-floating) .label-text-wrapper{-webkit-transform-origin:left top;transform-origin:left top}:host(.select-rtl.select-label-placement-stacked) .label-text-wrapper,:host(.select-rtl.select-label-placement-floating) .label-text-wrapper{-webkit-transform-origin:right top;transform-origin:right top}:host(.select-label-placement-stacked) .native-wrapper,:host(.select-label-placement-floating) .native-wrapper{margin-left:0;margin-right:0;margin-top:1px;margin-bottom:0;-ms-flex-positive:1;flex-grow:1;width:100%}:host(.select-label-placement-floating) .label-text-wrapper{-webkit-transform:translateY(100%) scale(1);transform:translateY(100%) scale(1)}:host(.select-label-placement-floating:not(.label-floating)) .native-wrapper .select-placeholder{opacity:0}:host(.select-expanded.select-label-placement-floating) .native-wrapper .select-placeholder,:host(.has-focus.select-label-placement-floating) .native-wrapper .select-placeholder,:host(.has-value.select-label-placement-floating) .native-wrapper .select-placeholder{opacity:1}:host(.label-floating) .label-text-wrapper{-webkit-transform:translateY(50%) scale(0.75);transform:translateY(50%) scale(0.75);max-width:calc(100% / 0.75)}::slotted([slot=start]),::slotted([slot=end]){-ms-flex-negative:0;flex-shrink:0}::slotted([slot=start]:last-of-type){-webkit-margin-end:16px;margin-inline-end:16px;-webkit-margin-start:0;margin-inline-start:0}::slotted([slot=end]:first-of-type){-webkit-margin-start:16px;margin-inline-start:16px;-webkit-margin-end:0;margin-inline-end:0}:host(.select-fill-solid){--background:var(--ion-color-step-50, var(--ion-background-color-step-50, #f2f2f2));--border-color:var(--ion-color-step-500, var(--ion-background-color-step-500, gray));--border-radius:4px;--padding-start:16px;--padding-end:16px;min-height:56px}:host(.select-fill-solid) .select-wrapper{border-bottom:var(--border-width) var(--border-style) var(--border-color)}:host(.select-expanded.select-fill-solid.ion-valid),:host(.has-focus.select-fill-solid.ion-valid),:host(.select-fill-solid.ion-touched.ion-invalid){--border-color:var(--highlight-color)}:host(.select-fill-solid) .select-bottom{border-top:none}@media (any-hover: hover){:host(.select-fill-solid:hover){--background:var(--ion-color-step-100, var(--ion-background-color-step-100, #e6e6e6));--border-color:var(--ion-color-step-750, var(--ion-background-color-step-750, #404040))}}:host(.select-fill-solid.select-expanded),:host(.select-fill-solid.has-focus){--background:var(--ion-color-step-150, var(--ion-background-color-step-150, #d9d9d9));--border-color:var(--highlight-color)}:host(.select-fill-solid) .select-wrapper{border-start-start-radius:var(--border-radius);border-start-end-radius:var(--border-radius);border-end-end-radius:0px;border-end-start-radius:0px}:host(.label-floating.select-fill-solid) .label-text-wrapper{max-width:calc(100% / 0.75)}:host(.in-item.select-expanded.select-fill-solid) .select-wrapper .select-icon,:host(.in-item.has-focus.select-fill-solid) .select-wrapper .select-icon,:host(.in-item.has-focus.ion-valid.select-fill-solid) .select-wrapper .select-icon,:host(.in-item.ion-touched.ion-invalid.select-fill-solid) .select-wrapper .select-icon{color:var(--highlight-color)}:host(.select-fill-outline){--border-color:var(--ion-color-step-300, var(--ion-background-color-step-300, #b3b3b3));--border-radius:4px;--padding-start:16px;--padding-end:16px;min-height:56px}:host(.select-fill-outline.select-shape-round){--border-radius:28px;--padding-start:32px;--padding-end:32px}:host(.has-focus.select-fill-outline.ion-valid),:host(.select-fill-outline.ion-touched.ion-invalid){--border-color:var(--highlight-color)}@media (any-hover: hover){:host(.select-fill-outline:hover){--border-color:var(--ion-color-step-750, var(--ion-background-color-step-750, #404040))}}:host(.select-fill-outline.select-expanded),:host(.select-fill-outline.has-focus){--border-width:var(--highlight-height);--border-color:var(--highlight-color)}:host(.select-fill-outline) .select-bottom{border-top:none}:host(.select-fill-outline) .select-wrapper{border-bottom:none}:host(.select-ltr.select-fill-outline.select-label-placement-stacked) .label-text-wrapper,:host(.select-ltr.select-fill-outline.select-label-placement-floating) .label-text-wrapper{-webkit-transform-origin:left top;transform-origin:left top}:host(.select-rtl.select-fill-outline.select-label-placement-stacked) .label-text-wrapper,:host(.select-rtl.select-fill-outline.select-label-placement-floating) .label-text-wrapper{-webkit-transform-origin:right top;transform-origin:right top}:host(.select-fill-outline.select-label-placement-stacked) .label-text-wrapper,:host(.select-fill-outline.select-label-placement-floating) .label-text-wrapper{position:absolute;max-width:calc(100% - var(--padding-start) - var(--padding-end))}:host(.select-fill-outline) .label-text-wrapper{position:relative;z-index:1}:host(.label-floating.select-fill-outline) .label-text-wrapper{-webkit-transform:translateY(-32%) scale(0.75);transform:translateY(-32%) scale(0.75);margin-left:0;margin-right:0;margin-top:0;margin-bottom:0;max-width:calc((100% - var(--padding-start) - var(--padding-end) - 8px) / 0.75)}:host(.select-fill-outline.select-label-placement-stacked) select,:host(.select-fill-outline.select-label-placement-floating) select{margin-left:0;margin-right:0;margin-top:6px;margin-bottom:6px}:host(.select-fill-outline) .select-outline-container{left:0;right:0;top:0;bottom:0;display:-ms-flexbox;display:flex;position:absolute;width:100%;height:100%}:host(.select-fill-outline) .select-outline-start,:host(.select-fill-outline) .select-outline-end{pointer-events:none}:host(.select-fill-outline) .select-outline-start,:host(.select-fill-outline) .select-outline-notch,:host(.select-fill-outline) .select-outline-end{border-top:var(--border-width) var(--border-style) var(--border-color);border-bottom:var(--border-width) var(--border-style) var(--border-color);-webkit-box-sizing:border-box;box-sizing:border-box}:host(.select-fill-outline) .select-outline-notch{max-width:calc(100% - var(--padding-start) - var(--padding-end))}:host(.select-fill-outline) .notch-spacer{-webkit-padding-end:8px;padding-inline-end:8px;font-size:calc(1em * 0.75);opacity:0;pointer-events:none}:host(.select-fill-outline) .select-outline-start{-webkit-border-start:var(--border-width) var(--border-style) var(--border-color);border-inline-start:var(--border-width) var(--border-style) var(--border-color)}:host(.select-fill-outline) .select-outline-start{border-start-start-radius:var(--border-radius);border-start-end-radius:0px;border-end-end-radius:0px;border-end-start-radius:var(--border-radius)}:host(.select-fill-outline) .select-outline-start{width:calc(var(--padding-start) - 4px)}:host(.select-fill-outline) .select-outline-end{-webkit-border-end:var(--border-width) var(--border-style) var(--border-color);border-inline-end:var(--border-width) var(--border-style) var(--border-color)}:host(.select-fill-outline) .select-outline-end{border-start-start-radius:0px;border-start-end-radius:var(--border-radius);border-end-end-radius:var(--border-radius);border-end-start-radius:0px}:host(.select-fill-outline) .select-outline-end{-ms-flex-positive:1;flex-grow:1}:host(.label-floating.select-fill-outline) .select-outline-notch{border-top:none}:host(.in-item.select-expanded.select-fill-outline) .select-wrapper .select-icon,:host(.in-item.has-focus.select-fill-outline) .select-wrapper .select-icon,:host(.in-item.has-focus.ion-valid.select-fill-outline) .select-wrapper .select-icon,:host(.in-item.ion-touched.ion-invalid.select-fill-outline) .select-wrapper .select-icon{color:var(--highlight-color)}:host{--border-width:1px;--border-color:var(--ion-item-border-color, var(--ion-border-color, var(--ion-color-step-150, var(--ion-background-color-step-150, rgba(0, 0, 0, 0.13)))));--highlight-height:2px}:host(.select-label-placement-floating.select-expanded) .label-text-wrapper,:host(.select-label-placement-floating.has-focus) .label-text-wrapper,:host(.select-label-placement-stacked.select-expanded) .label-text-wrapper,:host(.select-label-placement-stacked.has-focus) .label-text-wrapper{color:var(--highlight-color)}:host(.has-focus.select-label-placement-floating.ion-valid) .label-text-wrapper,:host(.select-label-placement-floating.ion-touched.ion-invalid) .label-text-wrapper,:host(.has-focus.select-label-placement-stacked.ion-valid) .label-text-wrapper,:host(.select-label-placement-stacked.ion-touched.ion-invalid) .label-text-wrapper{color:var(--highlight-color)}.select-highlight{bottom:-1px;position:absolute;width:100%;height:var(--highlight-height);-webkit-transform:scale(0);transform:scale(0);-webkit-transition:-webkit-transform 200ms;transition:-webkit-transform 200ms;transition:transform 200ms;transition:transform 200ms, -webkit-transform 200ms;background:var(--highlight-color)}.select-highlight{inset-inline-start:0}:host(.select-expanded) .select-highlight,:host(.has-focus) .select-highlight{-webkit-transform:scale(1);transform:scale(1)}:host(.in-item) .select-highlight{bottom:0}:host(.in-item) .select-highlight{inset-inline-start:0}.select-icon{width:0.8125rem;-webkit-transition:-webkit-transform 0.15s cubic-bezier(0.4, 0, 0.2, 1);transition:-webkit-transform 0.15s cubic-bezier(0.4, 0, 0.2, 1);transition:transform 0.15s cubic-bezier(0.4, 0, 0.2, 1);transition:transform 0.15s cubic-bezier(0.4, 0, 0.2, 1), -webkit-transform 0.15s cubic-bezier(0.4, 0, 0.2, 1);color:var(--ion-color-step-500, var(--ion-text-color-step-500, gray))}:host(.select-expanded:not(.has-expanded-icon)) .select-icon{-webkit-transform:rotate(180deg);transform:rotate(180deg)}:host(.in-item.select-expanded) .select-wrapper .select-icon,:host(.in-item.has-focus) .select-wrapper .select-icon,:host(.in-item.has-focus.ion-valid) .select-wrapper .select-icon,:host(.in-item.ion-touched.ion-invalid) .select-wrapper .select-icon{color:var(--ion-color-step-500, var(--ion-text-color-step-500, gray))}:host(.select-expanded) .select-wrapper .select-icon,:host(.has-focus.ion-valid) .select-wrapper .select-icon,:host(.ion-touched.ion-invalid) .select-wrapper .select-icon,:host(.has-focus) .select-wrapper .select-icon{color:var(--highlight-color)}:host(.select-shape-round){--border-radius:16px}:host(.select-label-placement-stacked) .select-wrapper-inner,:host(.select-label-placement-floating) .select-wrapper-inner{width:calc(100% - 0.8125rem - 4px)}:host(.select-disabled){opacity:0.38}::slotted(ion-button[slot=start].button-has-icon-only),::slotted(ion-button[slot=end].button-has-icon-only){--border-radius:50%;--padding-start:8px;--padding-end:8px;--padding-top:8px;--padding-bottom:8px;aspect-ratio:1;min-height:40px}";
  29639. var IonSelectMdStyle0 = selectMdCss;
  29640. // TODO(FW-2832): types
  29641. /**
  29642. * @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
  29643. *
  29644. * @slot label - The label text to associate with the select. Use the `labelPlacement` property to control where the label is placed relative to the select. Use this if you need to render a label with custom HTML.
  29645. * @slot start - Content to display at the leading edge of the select.
  29646. * @slot end - Content to display at the trailing edge of the select.
  29647. *
  29648. * @part placeholder - The text displayed in the select when there is no value.
  29649. * @part text - The displayed value of the select.
  29650. * @part icon - The select icon container.
  29651. * @part container - The container for the selected text or placeholder.
  29652. * @part label - The label text describing the select.
  29653. * @part supporting-text - Supporting text displayed beneath the select.
  29654. * @part helper-text - Supporting text displayed beneath the select when the select is valid.
  29655. * @part error-text - Supporting text displayed beneath the select when the select is invalid and touched.
  29656. */
  29657. class Select {
  29658. constructor(hostRef) {
  29659. registerInstance(this, hostRef);
  29660. this.ionChange = createEvent(this, "ionChange", 7);
  29661. this.ionCancel = createEvent(this, "ionCancel", 7);
  29662. this.ionDismiss = createEvent(this, "ionDismiss", 7);
  29663. this.ionFocus = createEvent(this, "ionFocus", 7);
  29664. this.ionBlur = createEvent(this, "ionBlur", 7);
  29665. this.ionStyle = createEvent(this, "ionStyle", 7);
  29666. this.inputId = `ion-sel-${selectIds++}`;
  29667. this.helperTextId = `${this.inputId}-helper-text`;
  29668. this.errorTextId = `${this.inputId}-error-text`;
  29669. this.inheritedAttributes = {};
  29670. this.onClick = (ev) => {
  29671. const target = ev.target;
  29672. const closestSlot = target.closest('[slot="start"], [slot="end"]');
  29673. if (target === this.el || closestSlot === null) {
  29674. this.setFocus();
  29675. this.open(ev);
  29676. }
  29677. else {
  29678. /**
  29679. * Prevent clicks to the start/end slots from opening the select.
  29680. * We ensure the target isn't this element in case the select is slotted
  29681. * in, for example, an item. This would prevent the select from ever
  29682. * being opened since the element itself has slot="start"/"end".
  29683. *
  29684. * Clicking a slotted element also causes a click
  29685. * on the <label> element (since it wraps the slots).
  29686. * Clicking <label> dispatches another click event on
  29687. * the native form control that then bubbles up to this
  29688. * listener. This additional event targets the host
  29689. * element, so the select overlay is opened.
  29690. *
  29691. * When the slotted elements are clicked (and therefore
  29692. * the ancestor <label> element) we want to prevent the label
  29693. * from dispatching another click event.
  29694. *
  29695. * Do not call stopPropagation() because this will cause
  29696. * click handlers on the slotted elements to never fire in React.
  29697. * When developers do onClick in React a native "click" listener
  29698. * is added on the root element, not the slotted element. When that
  29699. * native click listener fires, React then dispatches the synthetic
  29700. * click event on the slotted element. However, if stopPropagation
  29701. * is called then the native click event will never bubble up
  29702. * to the root element.
  29703. */
  29704. ev.preventDefault();
  29705. }
  29706. };
  29707. this.onFocus = () => {
  29708. this.hasFocus = true;
  29709. this.ionFocus.emit();
  29710. };
  29711. this.onBlur = () => {
  29712. this.hasFocus = false;
  29713. this.ionBlur.emit();
  29714. };
  29715. /**
  29716. * Stops propagation when the label is clicked,
  29717. * otherwise, two clicks will be triggered.
  29718. */
  29719. this.onLabelClick = (ev) => {
  29720. // Only stop propagation if the click was directly on the label
  29721. // and not on the input or other child elements
  29722. if (ev.target === ev.currentTarget) {
  29723. ev.stopPropagation();
  29724. }
  29725. };
  29726. this.isExpanded = false;
  29727. this.hasFocus = false;
  29728. this.cancelText = 'Cancel';
  29729. this.color = undefined;
  29730. this.compareWith = undefined;
  29731. this.disabled = false;
  29732. this.fill = undefined;
  29733. this.errorText = undefined;
  29734. this.helperText = undefined;
  29735. this.interface = 'alert';
  29736. this.interfaceOptions = {};
  29737. this.justify = undefined;
  29738. this.label = undefined;
  29739. this.labelPlacement = 'start';
  29740. this.multiple = false;
  29741. this.name = this.inputId;
  29742. this.okText = 'OK';
  29743. this.placeholder = undefined;
  29744. this.selectedText = undefined;
  29745. this.toggleIcon = undefined;
  29746. this.expandedIcon = undefined;
  29747. this.shape = undefined;
  29748. this.value = undefined;
  29749. this.required = false;
  29750. }
  29751. styleChanged() {
  29752. this.emitStyle();
  29753. }
  29754. setValue(value) {
  29755. this.value = value;
  29756. this.ionChange.emit({ value });
  29757. }
  29758. async connectedCallback() {
  29759. const { el } = this;
  29760. this.notchController = createNotchController(el, () => this.notchSpacerEl, () => this.labelSlot);
  29761. this.updateOverlayOptions();
  29762. this.emitStyle();
  29763. this.mutationO = watchForOptions(this.el, 'ion-select-option', async () => {
  29764. this.updateOverlayOptions();
  29765. });
  29766. }
  29767. componentWillLoad() {
  29768. this.inheritedAttributes = inheritAttributes$1(this.el, ['aria-label']);
  29769. }
  29770. componentDidLoad() {
  29771. /**
  29772. * If any of the conditions that trigger the styleChanged callback
  29773. * are met on component load, it is possible the event emitted
  29774. * prior to a parent web component registering an event listener.
  29775. *
  29776. * To ensure the parent web component receives the event, we
  29777. * emit the style event again after the component has loaded.
  29778. *
  29779. * This is often seen in Angular with the `dist` output target.
  29780. */
  29781. this.emitStyle();
  29782. }
  29783. disconnectedCallback() {
  29784. if (this.mutationO) {
  29785. this.mutationO.disconnect();
  29786. this.mutationO = undefined;
  29787. }
  29788. if (this.notchController) {
  29789. this.notchController.destroy();
  29790. this.notchController = undefined;
  29791. }
  29792. }
  29793. /**
  29794. * Open the select overlay. The overlay is either an alert, action sheet, or popover,
  29795. * depending on the `interface` property on the `ion-select`.
  29796. *
  29797. * @param event The user interface event that called the open.
  29798. */
  29799. async open(event) {
  29800. if (this.disabled || this.isExpanded) {
  29801. return undefined;
  29802. }
  29803. this.isExpanded = true;
  29804. const overlay = (this.overlay = await this.createOverlay(event));
  29805. // Add logic to scroll selected item into view before presenting
  29806. const scrollSelectedIntoView = () => {
  29807. const indexOfSelected = this.childOpts.findIndex((o) => o.value === this.value);
  29808. if (indexOfSelected > -1) {
  29809. const selectedItem = overlay.querySelector(`.select-interface-option:nth-child(${indexOfSelected + 1})`);
  29810. if (selectedItem) {
  29811. /**
  29812. * Browsers such as Firefox do not
  29813. * correctly delegate focus when manually
  29814. * focusing an element with delegatesFocus.
  29815. * We work around this by manually focusing
  29816. * the interactive element.
  29817. * ion-radio and ion-checkbox are the only
  29818. * elements that ion-select-popover uses, so
  29819. * we only need to worry about those two components
  29820. * when focusing.
  29821. */
  29822. const interactiveEl = selectedItem.querySelector('ion-radio, ion-checkbox');
  29823. if (interactiveEl) {
  29824. selectedItem.scrollIntoView({ block: 'nearest' });
  29825. // Needs to be called before `focusVisibleElement` to prevent issue with focus event bubbling
  29826. // and removing `ion-focused` style
  29827. interactiveEl.setFocus();
  29828. }
  29829. focusVisibleElement(selectedItem);
  29830. }
  29831. }
  29832. else {
  29833. /**
  29834. * If no value is set then focus the first enabled option.
  29835. */
  29836. const firstEnabledOption = overlay.querySelector('ion-radio:not(.radio-disabled), ion-checkbox:not(.checkbox-disabled)');
  29837. if (firstEnabledOption) {
  29838. /**
  29839. * Focus the option for the same reason as we do above.
  29840. *
  29841. * Needs to be called before `focusVisibleElement` to prevent issue with focus event bubbling
  29842. * and removing `ion-focused` style
  29843. */
  29844. firstEnabledOption.setFocus();
  29845. focusVisibleElement(firstEnabledOption.closest('ion-item'));
  29846. }
  29847. }
  29848. };
  29849. // For modals and popovers, we can scroll before they're visible
  29850. if (this.interface === 'modal') {
  29851. overlay.addEventListener('ionModalWillPresent', scrollSelectedIntoView, { once: true });
  29852. }
  29853. else if (this.interface === 'popover') {
  29854. overlay.addEventListener('ionPopoverWillPresent', scrollSelectedIntoView, { once: true });
  29855. }
  29856. else {
  29857. /**
  29858. * For alerts and action sheets, we need to wait a frame after willPresent
  29859. * because these overlays don't have their content in the DOM immediately
  29860. * when willPresent fires. By waiting a frame, we ensure the content is
  29861. * rendered and can be properly scrolled into view.
  29862. */
  29863. const scrollAfterRender = () => {
  29864. requestAnimationFrame(() => {
  29865. scrollSelectedIntoView();
  29866. });
  29867. };
  29868. if (this.interface === 'alert') {
  29869. overlay.addEventListener('ionAlertWillPresent', scrollAfterRender, { once: true });
  29870. }
  29871. else if (this.interface === 'action-sheet') {
  29872. overlay.addEventListener('ionActionSheetWillPresent', scrollAfterRender, { once: true });
  29873. }
  29874. }
  29875. overlay.onDidDismiss().then(() => {
  29876. this.overlay = undefined;
  29877. this.isExpanded = false;
  29878. this.ionDismiss.emit();
  29879. this.setFocus();
  29880. });
  29881. await overlay.present();
  29882. return overlay;
  29883. }
  29884. createOverlay(ev) {
  29885. let selectInterface = this.interface;
  29886. if (selectInterface === 'action-sheet' && this.multiple) {
  29887. printIonWarning(`[ion-select] - Interface cannot be "${selectInterface}" with a multi-value select. Using the "alert" interface instead.`);
  29888. selectInterface = 'alert';
  29889. }
  29890. if (selectInterface === 'popover' && !ev) {
  29891. printIonWarning(`[ion-select] - Interface cannot be a "${selectInterface}" without passing an event. Using the "alert" interface instead.`);
  29892. selectInterface = 'alert';
  29893. }
  29894. if (selectInterface === 'action-sheet') {
  29895. return this.openActionSheet();
  29896. }
  29897. if (selectInterface === 'popover') {
  29898. return this.openPopover(ev);
  29899. }
  29900. if (selectInterface === 'modal') {
  29901. return this.openModal();
  29902. }
  29903. return this.openAlert();
  29904. }
  29905. updateOverlayOptions() {
  29906. const overlay = this.overlay;
  29907. if (!overlay) {
  29908. return;
  29909. }
  29910. const childOpts = this.childOpts;
  29911. const value = this.value;
  29912. switch (this.interface) {
  29913. case 'action-sheet':
  29914. overlay.buttons = this.createActionSheetButtons(childOpts, value);
  29915. break;
  29916. case 'popover':
  29917. const popover = overlay.querySelector('ion-select-popover');
  29918. if (popover) {
  29919. popover.options = this.createOverlaySelectOptions(childOpts, value);
  29920. }
  29921. break;
  29922. case 'modal':
  29923. const modal = overlay.querySelector('ion-select-modal');
  29924. if (modal) {
  29925. modal.options = this.createOverlaySelectOptions(childOpts, value);
  29926. }
  29927. break;
  29928. case 'alert':
  29929. const inputType = this.multiple ? 'checkbox' : 'radio';
  29930. overlay.inputs = this.createAlertInputs(childOpts, inputType, value);
  29931. break;
  29932. }
  29933. }
  29934. createActionSheetButtons(data, selectValue) {
  29935. const actionSheetButtons = data.map((option) => {
  29936. const value = getOptionValue(option);
  29937. // Remove hydrated before copying over classes
  29938. const copyClasses = Array.from(option.classList)
  29939. .filter((cls) => cls !== 'hydrated')
  29940. .join(' ');
  29941. const optClass = `${OPTION_CLASS} ${copyClasses}`;
  29942. return {
  29943. role: isOptionSelected(selectValue, value, this.compareWith) ? 'selected' : '',
  29944. text: option.textContent,
  29945. cssClass: optClass,
  29946. handler: () => {
  29947. this.setValue(value);
  29948. },
  29949. };
  29950. });
  29951. // Add "cancel" button
  29952. actionSheetButtons.push({
  29953. text: this.cancelText,
  29954. role: 'cancel',
  29955. handler: () => {
  29956. this.ionCancel.emit();
  29957. },
  29958. });
  29959. return actionSheetButtons;
  29960. }
  29961. createAlertInputs(data, inputType, selectValue) {
  29962. const alertInputs = data.map((option) => {
  29963. const value = getOptionValue(option);
  29964. // Remove hydrated before copying over classes
  29965. const copyClasses = Array.from(option.classList)
  29966. .filter((cls) => cls !== 'hydrated')
  29967. .join(' ');
  29968. const optClass = `${OPTION_CLASS} ${copyClasses}`;
  29969. return {
  29970. type: inputType,
  29971. cssClass: optClass,
  29972. label: option.textContent || '',
  29973. value,
  29974. checked: isOptionSelected(selectValue, value, this.compareWith),
  29975. disabled: option.disabled,
  29976. };
  29977. });
  29978. return alertInputs;
  29979. }
  29980. createOverlaySelectOptions(data, selectValue) {
  29981. const popoverOptions = data.map((option) => {
  29982. const value = getOptionValue(option);
  29983. // Remove hydrated before copying over classes
  29984. const copyClasses = Array.from(option.classList)
  29985. .filter((cls) => cls !== 'hydrated')
  29986. .join(' ');
  29987. const optClass = `${OPTION_CLASS} ${copyClasses}`;
  29988. return {
  29989. text: option.textContent || '',
  29990. cssClass: optClass,
  29991. value,
  29992. checked: isOptionSelected(selectValue, value, this.compareWith),
  29993. disabled: option.disabled,
  29994. handler: (selected) => {
  29995. this.setValue(selected);
  29996. if (!this.multiple) {
  29997. this.close();
  29998. }
  29999. },
  30000. };
  30001. });
  30002. return popoverOptions;
  30003. }
  30004. async openPopover(ev) {
  30005. const { fill, labelPlacement } = this;
  30006. const interfaceOptions = this.interfaceOptions;
  30007. const mode = getIonMode$1(this);
  30008. const showBackdrop = mode === 'md' ? false : true;
  30009. const multiple = this.multiple;
  30010. const value = this.value;
  30011. let event = ev;
  30012. let size = 'auto';
  30013. const hasFloatingOrStackedLabel = labelPlacement === 'floating' || labelPlacement === 'stacked';
  30014. /**
  30015. * The popover should take up the full width
  30016. * when using a fill in MD mode or if the
  30017. * label is floating/stacked.
  30018. */
  30019. if (hasFloatingOrStackedLabel || (mode === 'md' && fill !== undefined)) {
  30020. size = 'cover';
  30021. /**
  30022. * Otherwise the popover
  30023. * should be positioned relative
  30024. * to the native element.
  30025. */
  30026. }
  30027. else {
  30028. event = Object.assign(Object.assign({}, ev), { detail: {
  30029. ionShadowTarget: this.nativeWrapperEl,
  30030. } });
  30031. }
  30032. const popoverOpts = Object.assign(Object.assign({ mode,
  30033. event, alignment: 'center', size,
  30034. showBackdrop }, interfaceOptions), { component: 'ion-select-popover', cssClass: ['select-popover', interfaceOptions.cssClass], componentProps: {
  30035. header: interfaceOptions.header,
  30036. subHeader: interfaceOptions.subHeader,
  30037. message: interfaceOptions.message,
  30038. multiple,
  30039. value,
  30040. options: this.createOverlaySelectOptions(this.childOpts, value),
  30041. } });
  30042. return popoverController.create(popoverOpts);
  30043. }
  30044. async openActionSheet() {
  30045. const mode = getIonMode$1(this);
  30046. const interfaceOptions = this.interfaceOptions;
  30047. const actionSheetOpts = Object.assign(Object.assign({ mode }, interfaceOptions), { buttons: this.createActionSheetButtons(this.childOpts, this.value), cssClass: ['select-action-sheet', interfaceOptions.cssClass] });
  30048. return actionSheetController.create(actionSheetOpts);
  30049. }
  30050. async openAlert() {
  30051. const interfaceOptions = this.interfaceOptions;
  30052. const inputType = this.multiple ? 'checkbox' : 'radio';
  30053. const mode = getIonMode$1(this);
  30054. const alertOpts = Object.assign(Object.assign({ mode }, interfaceOptions), { header: interfaceOptions.header ? interfaceOptions.header : this.labelText, inputs: this.createAlertInputs(this.childOpts, inputType, this.value), buttons: [
  30055. {
  30056. text: this.cancelText,
  30057. role: 'cancel',
  30058. handler: () => {
  30059. this.ionCancel.emit();
  30060. },
  30061. },
  30062. {
  30063. text: this.okText,
  30064. handler: (selectedValues) => {
  30065. this.setValue(selectedValues);
  30066. },
  30067. },
  30068. ], cssClass: [
  30069. 'select-alert',
  30070. interfaceOptions.cssClass,
  30071. this.multiple ? 'multiple-select-alert' : 'single-select-alert',
  30072. ] });
  30073. return alertController.create(alertOpts);
  30074. }
  30075. openModal() {
  30076. const { multiple, value, interfaceOptions } = this;
  30077. const mode = getIonMode$1(this);
  30078. const modalOpts = Object.assign(Object.assign({}, interfaceOptions), { mode, cssClass: ['select-modal', interfaceOptions.cssClass], component: 'ion-select-modal', componentProps: {
  30079. header: interfaceOptions.header,
  30080. multiple,
  30081. value,
  30082. options: this.createOverlaySelectOptions(this.childOpts, value),
  30083. } });
  30084. return modalController.create(modalOpts);
  30085. }
  30086. /**
  30087. * Close the select interface.
  30088. */
  30089. close() {
  30090. if (!this.overlay) {
  30091. return Promise.resolve(false);
  30092. }
  30093. return this.overlay.dismiss();
  30094. }
  30095. hasValue() {
  30096. return this.getText() !== '';
  30097. }
  30098. get childOpts() {
  30099. return Array.from(this.el.querySelectorAll('ion-select-option'));
  30100. }
  30101. /**
  30102. * Returns any plaintext associated with
  30103. * the label (either prop or slot).
  30104. * Note: This will not return any custom
  30105. * HTML. Use the `hasLabel` getter if you
  30106. * want to know if any slotted label content
  30107. * was passed.
  30108. */
  30109. get labelText() {
  30110. const { label } = this;
  30111. if (label !== undefined) {
  30112. return label;
  30113. }
  30114. const { labelSlot } = this;
  30115. if (labelSlot !== null) {
  30116. return labelSlot.textContent;
  30117. }
  30118. return;
  30119. }
  30120. getText() {
  30121. const selectedText = this.selectedText;
  30122. if (selectedText != null && selectedText !== '') {
  30123. return selectedText;
  30124. }
  30125. return generateText(this.childOpts, this.value, this.compareWith);
  30126. }
  30127. setFocus() {
  30128. if (this.focusEl) {
  30129. this.focusEl.focus();
  30130. }
  30131. }
  30132. emitStyle() {
  30133. const { disabled } = this;
  30134. const style = {
  30135. 'interactive-disabled': disabled,
  30136. };
  30137. this.ionStyle.emit(style);
  30138. }
  30139. renderLabel() {
  30140. const { label } = this;
  30141. return (hAsync("div", { class: {
  30142. 'label-text-wrapper': true,
  30143. 'label-text-wrapper-hidden': !this.hasLabel,
  30144. }, part: "label" }, label === undefined ? hAsync("slot", { name: "label" }) : hAsync("div", { class: "label-text" }, label)));
  30145. }
  30146. componentDidRender() {
  30147. var _a;
  30148. (_a = this.notchController) === null || _a === void 0 ? void 0 : _a.calculateNotchWidth();
  30149. }
  30150. /**
  30151. * Gets any content passed into the `label` slot,
  30152. * not the <slot> definition.
  30153. */
  30154. get labelSlot() {
  30155. return this.el.querySelector('[slot="label"]');
  30156. }
  30157. /**
  30158. * Returns `true` if label content is provided
  30159. * either by a prop or a content. If you want
  30160. * to get the plaintext value of the label use
  30161. * the `labelText` getter instead.
  30162. */
  30163. get hasLabel() {
  30164. return this.label !== undefined || this.labelSlot !== null;
  30165. }
  30166. /**
  30167. * Renders the border container
  30168. * when fill="outline".
  30169. */
  30170. renderLabelContainer() {
  30171. const mode = getIonMode$1(this);
  30172. const hasOutlineFill = mode === 'md' && this.fill === 'outline';
  30173. if (hasOutlineFill) {
  30174. /**
  30175. * The outline fill has a special outline
  30176. * that appears around the select and the label.
  30177. * Certain stacked and floating label placements cause the
  30178. * label to translate up and create a "cut out"
  30179. * inside of that border by using the notch-spacer element.
  30180. */
  30181. return [
  30182. hAsync("div", { class: "select-outline-container" }, hAsync("div", { class: "select-outline-start" }), hAsync("div", { class: {
  30183. 'select-outline-notch': true,
  30184. 'select-outline-notch-hidden': !this.hasLabel,
  30185. } }, hAsync("div", { class: "notch-spacer", "aria-hidden": "true", ref: (el) => (this.notchSpacerEl = el) }, this.label)), hAsync("div", { class: "select-outline-end" })),
  30186. this.renderLabel(),
  30187. ];
  30188. }
  30189. /**
  30190. * If not using the outline style,
  30191. * we can render just the label.
  30192. */
  30193. return this.renderLabel();
  30194. }
  30195. /**
  30196. * Renders either the placeholder
  30197. * or the selected values based on
  30198. * the state of the select.
  30199. */
  30200. renderSelectText() {
  30201. const { placeholder } = this;
  30202. const displayValue = this.getText();
  30203. let addPlaceholderClass = false;
  30204. let selectText = displayValue;
  30205. if (selectText === '' && placeholder !== undefined) {
  30206. selectText = placeholder;
  30207. addPlaceholderClass = true;
  30208. }
  30209. const selectTextClasses = {
  30210. 'select-text': true,
  30211. 'select-placeholder': addPlaceholderClass,
  30212. };
  30213. const textPart = addPlaceholderClass ? 'placeholder' : 'text';
  30214. return (hAsync("div", { "aria-hidden": "true", class: selectTextClasses, part: textPart }, selectText));
  30215. }
  30216. /**
  30217. * Renders the chevron icon
  30218. * next to the select text.
  30219. */
  30220. renderSelectIcon() {
  30221. const mode = getIonMode$1(this);
  30222. const { isExpanded, toggleIcon, expandedIcon } = this;
  30223. let icon;
  30224. if (isExpanded && expandedIcon !== undefined) {
  30225. icon = expandedIcon;
  30226. }
  30227. else {
  30228. const defaultIcon = mode === 'ios' ? chevronExpand : caretDownSharp;
  30229. icon = toggleIcon !== null && toggleIcon !== void 0 ? toggleIcon : defaultIcon;
  30230. }
  30231. return hAsync("ion-icon", { class: "select-icon", part: "icon", "aria-hidden": "true", icon: icon });
  30232. }
  30233. get ariaLabel() {
  30234. var _a;
  30235. const { placeholder, inheritedAttributes } = this;
  30236. const displayValue = this.getText();
  30237. // The aria label should be preferred over visible text if both are specified
  30238. const definedLabel = (_a = inheritedAttributes['aria-label']) !== null && _a !== void 0 ? _a : this.labelText;
  30239. /**
  30240. * If developer has specified a placeholder
  30241. * and there is nothing selected, the selectText
  30242. * should have the placeholder value.
  30243. */
  30244. let renderedLabel = displayValue;
  30245. if (renderedLabel === '' && placeholder !== undefined) {
  30246. renderedLabel = placeholder;
  30247. }
  30248. /**
  30249. * If there is a developer-defined label,
  30250. * then we need to concatenate the developer label
  30251. * string with the current current value.
  30252. * The label for the control should be read
  30253. * before the values of the control.
  30254. */
  30255. if (definedLabel !== undefined) {
  30256. renderedLabel = renderedLabel === '' ? definedLabel : `${definedLabel}, ${renderedLabel}`;
  30257. }
  30258. return renderedLabel;
  30259. }
  30260. renderListbox() {
  30261. const { disabled, inputId, isExpanded, required } = this;
  30262. return (hAsync("button", { disabled: disabled, id: inputId, "aria-label": this.ariaLabel, "aria-haspopup": "dialog", "aria-expanded": `${isExpanded}`, "aria-describedby": this.getHintTextID(), "aria-invalid": this.getHintTextID() === this.errorTextId, "aria-required": `${required}`, onFocus: this.onFocus, onBlur: this.onBlur, ref: (focusEl) => (this.focusEl = focusEl) }));
  30263. }
  30264. getHintTextID() {
  30265. const { el, helperText, errorText, helperTextId, errorTextId } = this;
  30266. if (el.classList.contains('ion-touched') && el.classList.contains('ion-invalid') && errorText) {
  30267. return errorTextId;
  30268. }
  30269. if (helperText) {
  30270. return helperTextId;
  30271. }
  30272. return undefined;
  30273. }
  30274. /**
  30275. * Renders the helper text or error text values
  30276. */
  30277. renderHintText() {
  30278. const { helperText, errorText, helperTextId, errorTextId } = this;
  30279. return [
  30280. hAsync("div", { id: helperTextId, class: "helper-text", part: "supporting-text helper-text" }, helperText),
  30281. hAsync("div", { id: errorTextId, class: "error-text", part: "supporting-text error-text" }, errorText),
  30282. ];
  30283. }
  30284. /**
  30285. * Responsible for rendering helper text, and error text. This element
  30286. * should only be rendered if hint text is set.
  30287. */
  30288. renderBottomContent() {
  30289. const { helperText, errorText } = this;
  30290. /**
  30291. * undefined and empty string values should
  30292. * be treated as not having helper/error text.
  30293. */
  30294. const hasHintText = !!helperText || !!errorText;
  30295. if (!hasHintText) {
  30296. return;
  30297. }
  30298. return hAsync("div", { class: "select-bottom" }, this.renderHintText());
  30299. }
  30300. render() {
  30301. const { disabled, el, isExpanded, expandedIcon, labelPlacement, justify, placeholder, fill, shape, name, value, hasFocus, } = this;
  30302. const mode = getIonMode$1(this);
  30303. const hasFloatingOrStackedLabel = labelPlacement === 'floating' || labelPlacement === 'stacked';
  30304. const justifyEnabled = !hasFloatingOrStackedLabel && justify !== undefined;
  30305. const rtl = isRTL$1(el) ? 'rtl' : 'ltr';
  30306. const inItem = hostContext('ion-item', this.el);
  30307. const shouldRenderHighlight = mode === 'md' && fill !== 'outline' && !inItem;
  30308. const hasValue = this.hasValue();
  30309. const hasStartEndSlots = el.querySelector('[slot="start"], [slot="end"]') !== null;
  30310. renderHiddenInput(true, el, name, parseValue(value), disabled);
  30311. /**
  30312. * If the label is stacked, it should always sit above the select.
  30313. * For floating labels, the label should move above the select if
  30314. * the select has a value, is open, or has anything in either
  30315. * the start or end slot.
  30316. *
  30317. * If there is content in the start slot, the label would overlap
  30318. * it if not forced to float. This is also applied to the end slot
  30319. * because with the default or solid fills, the select is not
  30320. * vertically centered in the container, but the label is. This
  30321. * causes the slots and label to appear vertically offset from each
  30322. * other when the label isn't floating above the input. This doesn't
  30323. * apply to the outline fill, but this was not accounted for to keep
  30324. * things consistent.
  30325. *
  30326. * TODO(FW-5592): Remove hasStartEndSlots condition
  30327. */
  30328. const labelShouldFloat = labelPlacement === 'stacked' || (labelPlacement === 'floating' && (hasValue || isExpanded || hasStartEndSlots));
  30329. return (hAsync(Host, { key: '6dd3c92dc3c587960d767c7dd1c142fc20bef8ed', onClick: this.onClick, class: createColorClasses$1(this.color, {
  30330. [mode]: true,
  30331. 'in-item': inItem,
  30332. 'in-item-color': hostContext('ion-item.ion-color', el),
  30333. 'select-disabled': disabled,
  30334. 'select-expanded': isExpanded,
  30335. 'has-expanded-icon': expandedIcon !== undefined,
  30336. 'has-value': hasValue,
  30337. 'label-floating': labelShouldFloat,
  30338. 'has-placeholder': placeholder !== undefined,
  30339. 'has-focus': hasFocus,
  30340. // TODO(FW-6451): Remove `ion-focusable` class in favor of `has-focus`.
  30341. 'ion-focusable': true,
  30342. [`select-${rtl}`]: true,
  30343. [`select-fill-${fill}`]: fill !== undefined,
  30344. [`select-justify-${justify}`]: justifyEnabled,
  30345. [`select-shape-${shape}`]: shape !== undefined,
  30346. [`select-label-placement-${labelPlacement}`]: true,
  30347. }) }, hAsync("label", { key: 'bc80ee471debb20b33d1cf55f55932b621f1744a', class: "select-wrapper", id: "select-label", onClick: this.onLabelClick }, this.renderLabelContainer(), hAsync("div", { key: 'deea85c3a3769e90af0933c522028148ee5781a3', class: "select-wrapper-inner" }, hAsync("slot", { key: 'af8192f4d8d5426b39a00ef2ed96f3c4a9e12908', name: "start" }), hAsync("div", { key: '6c278fc6c56b18e26cae930d375aa1da05af135b', class: "native-wrapper", ref: (el) => (this.nativeWrapperEl = el), part: "container" }, this.renderSelectText(), this.renderListbox()), hAsync("slot", { key: 'c459d54471029872b8b3e63f7dfb6bdb869b4942', name: "end" }), !hasFloatingOrStackedLabel && this.renderSelectIcon()), hasFloatingOrStackedLabel && this.renderSelectIcon(), shouldRenderHighlight && hAsync("div", { key: '718960718fa91163dd4412e1865f476fef089127', class: "select-highlight" })), this.renderBottomContent()));
  30348. }
  30349. get el() { return getElement(this); }
  30350. static get watchers() { return {
  30351. "disabled": ["styleChanged"],
  30352. "isExpanded": ["styleChanged"],
  30353. "placeholder": ["styleChanged"],
  30354. "value": ["styleChanged"]
  30355. }; }
  30356. static get style() { return {
  30357. ios: IonSelectIosStyle0,
  30358. md: IonSelectMdStyle0
  30359. }; }
  30360. static get cmpMeta() { return {
  30361. "$flags$": 41,
  30362. "$tagName$": "ion-select",
  30363. "$members$": {
  30364. "cancelText": [1, "cancel-text"],
  30365. "color": [513],
  30366. "compareWith": [1, "compare-with"],
  30367. "disabled": [4],
  30368. "fill": [1],
  30369. "errorText": [1, "error-text"],
  30370. "helperText": [1, "helper-text"],
  30371. "interface": [1],
  30372. "interfaceOptions": [8, "interface-options"],
  30373. "justify": [1],
  30374. "label": [1],
  30375. "labelPlacement": [1, "label-placement"],
  30376. "multiple": [4],
  30377. "name": [1],
  30378. "okText": [1, "ok-text"],
  30379. "placeholder": [1],
  30380. "selectedText": [1, "selected-text"],
  30381. "toggleIcon": [1, "toggle-icon"],
  30382. "expandedIcon": [1, "expanded-icon"],
  30383. "shape": [1],
  30384. "value": [1032],
  30385. "required": [4],
  30386. "isExpanded": [32],
  30387. "hasFocus": [32],
  30388. "open": [64]
  30389. },
  30390. "$listeners$": undefined,
  30391. "$lazyBundleId$": "-",
  30392. "$attrsToReflect$": [["color", "color"]]
  30393. }; }
  30394. }
  30395. const getOptionValue = (el) => {
  30396. const value = el.value;
  30397. return value === undefined ? el.textContent || '' : value;
  30398. };
  30399. const parseValue = (value) => {
  30400. if (value == null) {
  30401. return undefined;
  30402. }
  30403. if (Array.isArray(value)) {
  30404. return value.join(',');
  30405. }
  30406. return value.toString();
  30407. };
  30408. const generateText = (opts, value, compareWith) => {
  30409. if (value === undefined) {
  30410. return '';
  30411. }
  30412. if (Array.isArray(value)) {
  30413. return value
  30414. .map((v) => textForValue(opts, v, compareWith))
  30415. .filter((opt) => opt !== null)
  30416. .join(', ');
  30417. }
  30418. else {
  30419. return textForValue(opts, value, compareWith) || '';
  30420. }
  30421. };
  30422. const textForValue = (opts, value, compareWith) => {
  30423. const selectOpt = opts.find((opt) => {
  30424. return compareOptions(value, getOptionValue(opt), compareWith);
  30425. });
  30426. return selectOpt ? selectOpt.textContent : null;
  30427. };
  30428. let selectIds = 0;
  30429. const OPTION_CLASS = 'select-interface-option';
  30430. const ionicSelectModalMdCss = ".sc-ion-select-modal-ionic-h{height:100%}ion-list.sc-ion-select-modal-ionic ion-radio.sc-ion-select-modal-ionic::part(container){display:none}ion-list.sc-ion-select-modal-ionic ion-radio.sc-ion-select-modal-ionic::part(label){margin-left:0;margin-right:0;margin-top:0;margin-bottom:0}ion-item.sc-ion-select-modal-ionic{--inner-border-width:0}.item-radio-checked.sc-ion-select-modal-ionic{--background:rgba(var(--ion-color-primary-rgb, 0, 84, 233), 0.08);--background-focused:var(--ion-color-primary, #0054e9);--background-focused-opacity:0.2;--background-hover:var(--ion-color-primary, #0054e9);--background-hover-opacity:0.12}.item-checkbox-checked.sc-ion-select-modal-ionic{--background-activated:var(--ion-item-color, var(--ion-text-color, #000));--background-focused:var(--ion-item-color, var(--ion-text-color, #000));--background-hover:var(--ion-item-color, var(--ion-text-color, #000));--color:var(--ion-color-primary, #0054e9)}";
  30431. var IonSelectModalIonicStyle0 = ionicSelectModalMdCss;
  30432. const selectModalIosCss = ".sc-ion-select-modal-ios-h{height:100%}ion-item.sc-ion-select-modal-ios{--inner-padding-end:0}ion-radio.sc-ion-select-modal-ios::after{bottom:0;position:absolute;width:calc(100% - 0.9375rem - 16px);border-width:0px 0px 0.55px 0px;border-style:solid;border-color:var(--ion-item-border-color, var(--ion-border-color, var(--ion-color-step-250, var(--ion-background-color-step-250, #c8c7cc))));content:\"\"}ion-radio.sc-ion-select-modal-ios::after{inset-inline-start:calc(0.9375rem + 16px)}";
  30433. var IonSelectModalIosStyle0 = selectModalIosCss;
  30434. const selectModalMdCss = ".sc-ion-select-modal-md-h{height:100%}ion-list.sc-ion-select-modal-md ion-radio.sc-ion-select-modal-md::part(container){display:none}ion-list.sc-ion-select-modal-md ion-radio.sc-ion-select-modal-md::part(label){margin-left:0;margin-right:0;margin-top:0;margin-bottom:0}ion-item.sc-ion-select-modal-md{--inner-border-width:0}.item-radio-checked.sc-ion-select-modal-md{--background:rgba(var(--ion-color-primary-rgb, 0, 84, 233), 0.08);--background-focused:var(--ion-color-primary, #0054e9);--background-focused-opacity:0.2;--background-hover:var(--ion-color-primary, #0054e9);--background-hover-opacity:0.12}.item-checkbox-checked.sc-ion-select-modal-md{--background-activated:var(--ion-item-color, var(--ion-text-color, #000));--background-focused:var(--ion-item-color, var(--ion-text-color, #000));--background-hover:var(--ion-item-color, var(--ion-text-color, #000));--color:var(--ion-color-primary, #0054e9)}";
  30435. var IonSelectModalMdStyle0 = selectModalMdCss;
  30436. class SelectModal {
  30437. constructor(hostRef) {
  30438. registerInstance(this, hostRef);
  30439. this.header = undefined;
  30440. this.multiple = undefined;
  30441. this.options = [];
  30442. }
  30443. closeModal() {
  30444. const modal = this.el.closest('ion-modal');
  30445. if (modal) {
  30446. modal.dismiss();
  30447. }
  30448. }
  30449. findOptionFromEvent(ev) {
  30450. const { options } = this;
  30451. return options.find((o) => o.value === ev.target.value);
  30452. }
  30453. getValues(ev) {
  30454. const { multiple, options } = this;
  30455. if (multiple) {
  30456. // this is a modal with checkboxes (multiple value select)
  30457. // return an array of all the checked values
  30458. return options.filter((o) => o.checked).map((o) => o.value);
  30459. }
  30460. // this is a modal with radio buttons (single value select)
  30461. // return the value that was clicked, otherwise undefined
  30462. const option = ev ? this.findOptionFromEvent(ev) : null;
  30463. return option ? option.value : undefined;
  30464. }
  30465. callOptionHandler(ev) {
  30466. const option = this.findOptionFromEvent(ev);
  30467. const values = this.getValues(ev);
  30468. if (option === null || option === void 0 ? void 0 : option.handler) {
  30469. safeCall(option.handler, values);
  30470. }
  30471. }
  30472. setChecked(ev) {
  30473. const { multiple } = this;
  30474. const option = this.findOptionFromEvent(ev);
  30475. // this is a modal with checkboxes (multiple value select)
  30476. // we need to set the checked value for this option
  30477. if (multiple && option) {
  30478. option.checked = ev.detail.checked;
  30479. }
  30480. }
  30481. renderRadioOptions() {
  30482. const checked = this.options.filter((o) => o.checked).map((o) => o.value)[0];
  30483. return (hAsync("ion-radio-group", { value: checked, onIonChange: (ev) => this.callOptionHandler(ev) }, this.options.map((option) => (hAsync("ion-item", { lines: "none", class: Object.assign({
  30484. // TODO FW-4784
  30485. 'item-radio-checked': option.value === checked
  30486. }, getClassMap(option.cssClass)) }, hAsync("ion-radio", { value: option.value, disabled: option.disabled, justify: "start", labelPlacement: "end", onClick: () => this.closeModal(), onKeyUp: (ev) => {
  30487. if (ev.key === ' ') {
  30488. /**
  30489. * Selecting a radio option with keyboard navigation,
  30490. * either through the Enter or Space keys, should
  30491. * dismiss the modal.
  30492. */
  30493. this.closeModal();
  30494. }
  30495. } }, option.text))))));
  30496. }
  30497. renderCheckboxOptions() {
  30498. return this.options.map((option) => (hAsync("ion-item", { class: Object.assign({
  30499. // TODO FW-4784
  30500. 'item-checkbox-checked': option.checked
  30501. }, getClassMap(option.cssClass)) }, hAsync("ion-checkbox", { value: option.value, disabled: option.disabled, checked: option.checked, justify: "start", labelPlacement: "end", onIonChange: (ev) => {
  30502. this.setChecked(ev);
  30503. this.callOptionHandler(ev);
  30504. } }, option.text))));
  30505. }
  30506. render() {
  30507. return (hAsync(Host, { key: '885198a9f21884e3bfb9bf0af53e0ee3ae37b231', class: getIonMode$1(this) }, hAsync("ion-header", { key: 'd8b63726869747ac711e4fda78a50ce46f72970c' }, hAsync("ion-toolbar", { key: '9ab2a4c1480dd74eeae38d7b580a2e87fb71270e' }, this.header !== undefined && hAsync("ion-title", { key: '87a7034385ef57f55cefdd0371dbb66a64827290' }, this.header), hAsync("ion-buttons", { key: '0a35424ea13ca002abc9a43b6138730254f187d0', slot: "end" }, hAsync("ion-button", { key: '238bf40b47128d9aa995d14d9ff9ebcae4f79492', onClick: () => this.closeModal() }, "Close")))), hAsync("ion-content", { key: '4a256f3381f8cabbc7194337b8ae4aa1c3ab1066' }, hAsync("ion-list", { key: 'acd38fc52024632176467ed6a84106a454021544' }, this.multiple === true ? this.renderCheckboxOptions() : this.renderRadioOptions()))));
  30508. }
  30509. get el() { return getElement(this); }
  30510. static get style() { return {
  30511. ionic: IonSelectModalIonicStyle0,
  30512. ios: IonSelectModalIosStyle0,
  30513. md: IonSelectModalMdStyle0
  30514. }; }
  30515. static get cmpMeta() { return {
  30516. "$flags$": 34,
  30517. "$tagName$": "ion-select-modal",
  30518. "$members$": {
  30519. "header": [1],
  30520. "multiple": [4],
  30521. "options": [16]
  30522. },
  30523. "$listeners$": undefined,
  30524. "$lazyBundleId$": "-",
  30525. "$attrsToReflect$": []
  30526. }; }
  30527. }
  30528. const selectOptionCss = ":host{display:none}";
  30529. var IonSelectOptionStyle0 = selectOptionCss;
  30530. class SelectOption {
  30531. constructor(hostRef) {
  30532. registerInstance(this, hostRef);
  30533. this.inputId = `ion-selopt-${selectOptionIds++}`;
  30534. this.disabled = false;
  30535. this.value = undefined;
  30536. }
  30537. render() {
  30538. return hAsync(Host, { key: '8c96c199ce3a3065de3fe446500f567236e0610a', role: "option", id: this.inputId, class: getIonMode$1(this) });
  30539. }
  30540. get el() { return getElement(this); }
  30541. static get style() { return IonSelectOptionStyle0; }
  30542. static get cmpMeta() { return {
  30543. "$flags$": 9,
  30544. "$tagName$": "ion-select-option",
  30545. "$members$": {
  30546. "disabled": [4],
  30547. "value": [8]
  30548. },
  30549. "$listeners$": undefined,
  30550. "$lazyBundleId$": "-",
  30551. "$attrsToReflect$": []
  30552. }; }
  30553. }
  30554. let selectOptionIds = 0;
  30555. const selectPopoverIosCss = ".sc-ion-select-popover-ios-h ion-list.sc-ion-select-popover-ios{margin-left:0;margin-right:0;margin-top:0;margin-bottom:0}ion-list-header.sc-ion-select-popover-ios,ion-label.sc-ion-select-popover-ios{margin-left:0;margin-right:0;margin-top:0;margin-bottom:0}.sc-ion-select-popover-ios-h{overflow-y:auto}";
  30556. var IonSelectPopoverIosStyle0 = selectPopoverIosCss;
  30557. const selectPopoverMdCss = ".sc-ion-select-popover-md-h ion-list.sc-ion-select-popover-md{margin-left:0;margin-right:0;margin-top:0;margin-bottom:0}ion-list-header.sc-ion-select-popover-md,ion-label.sc-ion-select-popover-md{margin-left:0;margin-right:0;margin-top:0;margin-bottom:0}.sc-ion-select-popover-md-h{overflow-y:auto}ion-list.sc-ion-select-popover-md ion-radio.sc-ion-select-popover-md::part(container){display:none}ion-list.sc-ion-select-popover-md ion-radio.sc-ion-select-popover-md::part(label){margin-left:0;margin-right:0;margin-top:0;margin-bottom:0}ion-item.sc-ion-select-popover-md{--inner-border-width:0}.item-radio-checked.sc-ion-select-popover-md{--background:rgba(var(--ion-color-primary-rgb, 0, 84, 233), 0.08);--background-focused:var(--ion-color-primary, #0054e9);--background-focused-opacity:0.2;--background-hover:var(--ion-color-primary, #0054e9);--background-hover-opacity:0.12}.item-checkbox-checked.sc-ion-select-popover-md{--background-activated:var(--ion-item-color, var(--ion-text-color, #000));--background-focused:var(--ion-item-color, var(--ion-text-color, #000));--background-hover:var(--ion-item-color, var(--ion-text-color, #000));--color:var(--ion-color-primary, #0054e9)}";
  30558. var IonSelectPopoverMdStyle0 = selectPopoverMdCss;
  30559. /**
  30560. * @internal
  30561. */
  30562. class SelectPopover {
  30563. constructor(hostRef) {
  30564. registerInstance(this, hostRef);
  30565. this.header = undefined;
  30566. this.subHeader = undefined;
  30567. this.message = undefined;
  30568. this.multiple = undefined;
  30569. this.options = [];
  30570. }
  30571. findOptionFromEvent(ev) {
  30572. const { options } = this;
  30573. return options.find((o) => o.value === ev.target.value);
  30574. }
  30575. /**
  30576. * When an option is selected we need to get the value(s)
  30577. * of the selected option(s) and return it in the option
  30578. * handler
  30579. */
  30580. callOptionHandler(ev) {
  30581. const option = this.findOptionFromEvent(ev);
  30582. const values = this.getValues(ev);
  30583. if (option === null || option === void 0 ? void 0 : option.handler) {
  30584. safeCall(option.handler, values);
  30585. }
  30586. }
  30587. /**
  30588. * Dismisses the host popover that the `ion-select-popover`
  30589. * is rendered within.
  30590. */
  30591. dismissParentPopover() {
  30592. const popover = this.el.closest('ion-popover');
  30593. if (popover) {
  30594. popover.dismiss();
  30595. }
  30596. }
  30597. setChecked(ev) {
  30598. const { multiple } = this;
  30599. const option = this.findOptionFromEvent(ev);
  30600. // this is a popover with checkboxes (multiple value select)
  30601. // we need to set the checked value for this option
  30602. if (multiple && option) {
  30603. option.checked = ev.detail.checked;
  30604. }
  30605. }
  30606. getValues(ev) {
  30607. const { multiple, options } = this;
  30608. if (multiple) {
  30609. // this is a popover with checkboxes (multiple value select)
  30610. // return an array of all the checked values
  30611. return options.filter((o) => o.checked).map((o) => o.value);
  30612. }
  30613. // this is a popover with radio buttons (single value select)
  30614. // return the value that was clicked, otherwise undefined
  30615. const option = this.findOptionFromEvent(ev);
  30616. return option ? option.value : undefined;
  30617. }
  30618. renderOptions(options) {
  30619. const { multiple } = this;
  30620. switch (multiple) {
  30621. case true:
  30622. return this.renderCheckboxOptions(options);
  30623. default:
  30624. return this.renderRadioOptions(options);
  30625. }
  30626. }
  30627. renderCheckboxOptions(options) {
  30628. return options.map((option) => (hAsync("ion-item", { class: Object.assign({
  30629. // TODO FW-4784
  30630. 'item-checkbox-checked': option.checked
  30631. }, getClassMap(option.cssClass)) }, hAsync("ion-checkbox", { value: option.value, disabled: option.disabled, checked: option.checked, justify: "start", labelPlacement: "end", onIonChange: (ev) => {
  30632. this.setChecked(ev);
  30633. this.callOptionHandler(ev);
  30634. } }, option.text))));
  30635. }
  30636. renderRadioOptions(options) {
  30637. const checked = options.filter((o) => o.checked).map((o) => o.value)[0];
  30638. return (hAsync("ion-radio-group", { value: checked, onIonChange: (ev) => this.callOptionHandler(ev) }, options.map((option) => (hAsync("ion-item", { class: Object.assign({
  30639. // TODO FW-4784
  30640. 'item-radio-checked': option.value === checked
  30641. }, getClassMap(option.cssClass)) }, hAsync("ion-radio", { value: option.value, disabled: option.disabled, onClick: () => this.dismissParentPopover(), onKeyUp: (ev) => {
  30642. if (ev.key === ' ') {
  30643. /**
  30644. * Selecting a radio option with keyboard navigation,
  30645. * either through the Enter or Space keys, should
  30646. * dismiss the popover.
  30647. */
  30648. this.dismissParentPopover();
  30649. }
  30650. } }, option.text))))));
  30651. }
  30652. render() {
  30653. const { header, message, options, subHeader } = this;
  30654. const hasSubHeaderOrMessage = subHeader !== undefined || message !== undefined;
  30655. return (hAsync(Host, { key: '542367ab8fb72bfebf7e65630b91017d68827fd6', class: getIonMode$1(this) }, hAsync("ion-list", { key: 'f2f0f37e1365cd7780b02de1a1698700d0df48a7' }, header !== undefined && hAsync("ion-list-header", { key: '4b8800a68e800f19277a44b7074ca24b70218daf' }, header), hasSubHeaderOrMessage && (hAsync("ion-item", { key: '932b7903daf97d5a57d289b7ee49e868bb9b0cf5' }, hAsync("ion-label", { key: 'fc3f1b69aa2a0bc6125d35692dcad3a8a99fd160', class: "ion-text-wrap" }, subHeader !== undefined && hAsync("h3", { key: 'eceab2f47afa95f04b138342b0bdbfa1f50919a8' }, subHeader), message !== undefined && hAsync("p", { key: '70f4e27ad1316318efd0c17efce31e5e45c8fa02' }, message)))), this.renderOptions(options))));
  30656. }
  30657. get el() { return getElement(this); }
  30658. static get style() { return {
  30659. ios: IonSelectPopoverIosStyle0,
  30660. md: IonSelectPopoverMdStyle0
  30661. }; }
  30662. static get cmpMeta() { return {
  30663. "$flags$": 34,
  30664. "$tagName$": "ion-select-popover",
  30665. "$members$": {
  30666. "header": [1],
  30667. "subHeader": [1, "sub-header"],
  30668. "message": [1],
  30669. "multiple": [4],
  30670. "options": [16]
  30671. },
  30672. "$listeners$": undefined,
  30673. "$lazyBundleId$": "-",
  30674. "$attrsToReflect$": []
  30675. }; }
  30676. }
  30677. const skeletonTextCss = ":host{--background:rgba(var(--background-rgb, var(--ion-text-color-rgb, 0, 0, 0)), 0.065);border-radius:var(--border-radius, inherit);display:block;width:100%;height:inherit;margin-top:4px;margin-bottom:4px;background:var(--background);line-height:10px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;pointer-events:none}span{display:inline-block}:host(.in-media){margin-left:0;margin-right:0;margin-top:0;margin-bottom:0;height:100%}:host(.skeleton-text-animated){position:relative;background:-webkit-gradient(linear, left top, right top, color-stop(8%, rgba(var(--background-rgb, var(--ion-text-color-rgb, 0, 0, 0)), 0.065)), color-stop(18%, rgba(var(--background-rgb, var(--ion-text-color-rgb, 0, 0, 0)), 0.135)), color-stop(33%, rgba(var(--background-rgb, var(--ion-text-color-rgb, 0, 0, 0)), 0.065)));background:linear-gradient(to right, rgba(var(--background-rgb, var(--ion-text-color-rgb, 0, 0, 0)), 0.065) 8%, rgba(var(--background-rgb, var(--ion-text-color-rgb, 0, 0, 0)), 0.135) 18%, rgba(var(--background-rgb, var(--ion-text-color-rgb, 0, 0, 0)), 0.065) 33%);background-size:800px 104px;-webkit-animation-duration:1s;animation-duration:1s;-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards;-webkit-animation-iteration-count:infinite;animation-iteration-count:infinite;-webkit-animation-name:shimmer;animation-name:shimmer;-webkit-animation-timing-function:linear;animation-timing-function:linear}@-webkit-keyframes shimmer{0%{background-position:-400px 0}100%{background-position:400px 0}}@keyframes shimmer{0%{background-position:-400px 0}100%{background-position:400px 0}}";
  30678. var IonSkeletonTextStyle0 = skeletonTextCss;
  30679. class SkeletonText {
  30680. constructor(hostRef) {
  30681. registerInstance(this, hostRef);
  30682. this.ionStyle = createEvent(this, "ionStyle", 7);
  30683. this.animated = false;
  30684. }
  30685. componentWillLoad() {
  30686. this.emitStyle();
  30687. }
  30688. emitStyle() {
  30689. // The emitted property is used by item in order
  30690. // to add the item-skeleton-text class which applies
  30691. // overflow: hidden to its label
  30692. const style = {
  30693. 'skeleton-text': true,
  30694. };
  30695. this.ionStyle.emit(style);
  30696. }
  30697. render() {
  30698. const animated = this.animated && config.getBoolean('animated', true);
  30699. const inMedia = hostContext('ion-avatar', this.el) || hostContext('ion-thumbnail', this.el);
  30700. const mode = getIonMode$1(this);
  30701. return (hAsync(Host, { key: 'c193f9a8e8efab5139544f047bdae4b6d421aa86', class: {
  30702. [mode]: true,
  30703. 'skeleton-text-animated': animated,
  30704. 'in-media': inMedia,
  30705. } }, hAsync("span", { key: 'e15db679bd3c359b4df5123efd2f92e5b380fde3' }, "\u00A0")));
  30706. }
  30707. get el() { return getElement(this); }
  30708. static get style() { return IonSkeletonTextStyle0; }
  30709. static get cmpMeta() { return {
  30710. "$flags$": 9,
  30711. "$tagName$": "ion-skeleton-text",
  30712. "$members$": {
  30713. "animated": [4]
  30714. },
  30715. "$listeners$": undefined,
  30716. "$lazyBundleId$": "-",
  30717. "$attrsToReflect$": []
  30718. }; }
  30719. }
  30720. const spinnerCss = ":host{display:inline-block;position:relative;width:28px;height:28px;color:var(--color);-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}:host(.ion-color){color:var(--ion-color-base)}svg{-webkit-transform-origin:center;transform-origin:center;position:absolute;top:0;left:0;width:100%;height:100%;-webkit-transform:translateZ(0);transform:translateZ(0)}:host-context([dir=rtl]) svg{-webkit-transform-origin:calc(100% - center);transform-origin:calc(100% - center)}[dir=rtl] svg{-webkit-transform-origin:calc(100% - center);transform-origin:calc(100% - center)}@supports selector(:dir(rtl)){svg:dir(rtl){-webkit-transform-origin:calc(100% - center);transform-origin:calc(100% - center)}}:host(.spinner-lines) line,:host(.spinner-lines-small) line{stroke-width:7px}:host(.spinner-lines-sharp) line,:host(.spinner-lines-sharp-small) line{stroke-width:4px}:host(.spinner-lines) line,:host(.spinner-lines-small) line,:host(.spinner-lines-sharp) line,:host(.spinner-lines-sharp-small) line{stroke-linecap:round;stroke:currentColor}:host(.spinner-lines) svg,:host(.spinner-lines-small) svg,:host(.spinner-lines-sharp) svg,:host(.spinner-lines-sharp-small) svg{-webkit-animation:spinner-fade-out 1s linear infinite;animation:spinner-fade-out 1s linear infinite}:host(.spinner-bubbles) svg{-webkit-animation:spinner-scale-out 1s linear infinite;animation:spinner-scale-out 1s linear infinite;fill:currentColor}:host(.spinner-circles) svg{-webkit-animation:spinner-fade-out 1s linear infinite;animation:spinner-fade-out 1s linear infinite;fill:currentColor}:host(.spinner-crescent) circle{fill:transparent;stroke-width:4px;stroke-dasharray:128px;stroke-dashoffset:82px;stroke:currentColor}:host(.spinner-crescent) svg{-webkit-animation:spinner-rotate 1s linear infinite;animation:spinner-rotate 1s linear infinite}:host(.spinner-dots) circle{stroke-width:0;fill:currentColor}:host(.spinner-dots) svg{-webkit-animation:spinner-dots 1s linear infinite;animation:spinner-dots 1s linear infinite}:host(.spinner-circular) svg{-webkit-animation:spinner-circular linear infinite;animation:spinner-circular linear infinite}:host(.spinner-circular) circle{-webkit-animation:spinner-circular-inner ease-in-out infinite;animation:spinner-circular-inner ease-in-out infinite;stroke:currentColor;stroke-dasharray:80px, 200px;stroke-dashoffset:0px;stroke-width:5.6;fill:none}:host(.spinner-paused),:host(.spinner-paused) svg,:host(.spinner-paused) circle{-webkit-animation-play-state:paused;animation-play-state:paused}@-webkit-keyframes spinner-fade-out{0%{opacity:1}100%{opacity:0}}@keyframes spinner-fade-out{0%{opacity:1}100%{opacity:0}}@-webkit-keyframes spinner-scale-out{0%{-webkit-transform:scale(1, 1);transform:scale(1, 1)}100%{-webkit-transform:scale(0, 0);transform:scale(0, 0)}}@keyframes spinner-scale-out{0%{-webkit-transform:scale(1, 1);transform:scale(1, 1)}100%{-webkit-transform:scale(0, 0);transform:scale(0, 0)}}@-webkit-keyframes spinner-rotate{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes spinner-rotate{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@-webkit-keyframes spinner-dots{0%{-webkit-transform:scale(1, 1);transform:scale(1, 1);opacity:0.9}50%{-webkit-transform:scale(0.4, 0.4);transform:scale(0.4, 0.4);opacity:0.3}100%{-webkit-transform:scale(1, 1);transform:scale(1, 1);opacity:0.9}}@keyframes spinner-dots{0%{-webkit-transform:scale(1, 1);transform:scale(1, 1);opacity:0.9}50%{-webkit-transform:scale(0.4, 0.4);transform:scale(0.4, 0.4);opacity:0.3}100%{-webkit-transform:scale(1, 1);transform:scale(1, 1);opacity:0.9}}@-webkit-keyframes spinner-circular{100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes spinner-circular{100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@-webkit-keyframes spinner-circular-inner{0%{stroke-dasharray:1px, 200px;stroke-dashoffset:0px}50%{stroke-dasharray:100px, 200px;stroke-dashoffset:-15px}100%{stroke-dasharray:100px, 200px;stroke-dashoffset:-125px}}@keyframes spinner-circular-inner{0%{stroke-dasharray:1px, 200px;stroke-dashoffset:0px}50%{stroke-dasharray:100px, 200px;stroke-dashoffset:-15px}100%{stroke-dasharray:100px, 200px;stroke-dashoffset:-125px}}";
  30721. var IonSpinnerStyle0 = spinnerCss;
  30722. class Spinner {
  30723. constructor(hostRef) {
  30724. registerInstance(this, hostRef);
  30725. this.color = undefined;
  30726. this.duration = undefined;
  30727. this.name = undefined;
  30728. this.paused = false;
  30729. }
  30730. getName() {
  30731. const spinnerName = this.name || config.get('spinner');
  30732. const mode = getIonMode$1(this);
  30733. if (spinnerName) {
  30734. return spinnerName;
  30735. }
  30736. return mode === 'ios' ? 'lines' : 'circular';
  30737. }
  30738. render() {
  30739. var _a;
  30740. const self = this;
  30741. const mode = getIonMode$1(self);
  30742. const spinnerName = self.getName();
  30743. const spinner = (_a = SPINNERS[spinnerName]) !== null && _a !== void 0 ? _a : SPINNERS['lines'];
  30744. const duration = typeof self.duration === 'number' && self.duration > 10 ? self.duration : spinner.dur;
  30745. const svgs = [];
  30746. if (spinner.circles !== undefined) {
  30747. for (let i = 0; i < spinner.circles; i++) {
  30748. svgs.push(buildCircle(spinner, duration, i, spinner.circles));
  30749. }
  30750. }
  30751. else if (spinner.lines !== undefined) {
  30752. for (let i = 0; i < spinner.lines; i++) {
  30753. svgs.push(buildLine(spinner, duration, i, spinner.lines));
  30754. }
  30755. }
  30756. return (hAsync(Host, { key: 'e0dfa8a3ee2a0469eb31323f506750bd77d65797', class: createColorClasses$1(self.color, {
  30757. [mode]: true,
  30758. [`spinner-${spinnerName}`]: true,
  30759. 'spinner-paused': self.paused || config.getBoolean('_testing'),
  30760. }), role: "progressbar", style: spinner.elmDuration ? { animationDuration: duration + 'ms' } : {} }, svgs));
  30761. }
  30762. static get style() { return IonSpinnerStyle0; }
  30763. static get cmpMeta() { return {
  30764. "$flags$": 9,
  30765. "$tagName$": "ion-spinner",
  30766. "$members$": {
  30767. "color": [513],
  30768. "duration": [2],
  30769. "name": [1],
  30770. "paused": [4]
  30771. },
  30772. "$listeners$": undefined,
  30773. "$lazyBundleId$": "-",
  30774. "$attrsToReflect$": [["color", "color"]]
  30775. }; }
  30776. }
  30777. const buildCircle = (spinner, duration, index, total) => {
  30778. const data = spinner.fn(duration, index, total);
  30779. data.style['animation-duration'] = duration + 'ms';
  30780. return (hAsync("svg", { viewBox: data.viewBox || '0 0 64 64', style: data.style }, hAsync("circle", { transform: data.transform || 'translate(32,32)', cx: data.cx, cy: data.cy, r: data.r, style: spinner.elmDuration ? { animationDuration: duration + 'ms' } : {} })));
  30781. };
  30782. const buildLine = (spinner, duration, index, total) => {
  30783. const data = spinner.fn(duration, index, total);
  30784. data.style['animation-duration'] = duration + 'ms';
  30785. return (hAsync("svg", { viewBox: data.viewBox || '0 0 64 64', style: data.style }, hAsync("line", { transform: "translate(32,32)", y1: data.y1, y2: data.y2 })));
  30786. };
  30787. const splitPaneIosCss = ":host{--side-width:100%;left:0;right:0;top:0;bottom:0;display:-ms-flexbox;display:flex;position:absolute;-ms-flex-direction:row;flex-direction:row;-ms-flex-wrap:nowrap;flex-wrap:nowrap;contain:strict}:host(.split-pane-visible) ::slotted(.split-pane-main){left:0;right:0;top:0;bottom:0;position:relative;-ms-flex:1;flex:1;-webkit-box-shadow:none;box-shadow:none;overflow:hidden;z-index:0}::slotted(.split-pane-side:not(ion-menu)){display:none}:host{--border:0.55px solid var(--ion-item-border-color, var(--ion-border-color, var(--ion-color-step-250, var(--ion-background-color-step-250, #c8c7cc))));--side-min-width:270px;--side-max-width:28%}";
  30788. var IonSplitPaneIosStyle0 = splitPaneIosCss;
  30789. const splitPaneMdCss = ":host{--side-width:100%;left:0;right:0;top:0;bottom:0;display:-ms-flexbox;display:flex;position:absolute;-ms-flex-direction:row;flex-direction:row;-ms-flex-wrap:nowrap;flex-wrap:nowrap;contain:strict}:host(.split-pane-visible) ::slotted(.split-pane-main){left:0;right:0;top:0;bottom:0;position:relative;-ms-flex:1;flex:1;-webkit-box-shadow:none;box-shadow:none;overflow:hidden;z-index:0}::slotted(.split-pane-side:not(ion-menu)){display:none}:host{--border:1px solid var(--ion-item-border-color, var(--ion-border-color, var(--ion-color-step-150, var(--ion-background-color-step-150, rgba(0, 0, 0, 0.13)))));--side-min-width:270px;--side-max-width:28%}";
  30790. var IonSplitPaneMdStyle0 = splitPaneMdCss;
  30791. const QUERY = {
  30792. xs: '(min-width: 0px)',
  30793. sm: '(min-width: 576px)',
  30794. md: '(min-width: 768px)',
  30795. lg: '(min-width: 992px)',
  30796. xl: '(min-width: 1200px)',
  30797. never: '',
  30798. };
  30799. class SplitPane {
  30800. constructor(hostRef) {
  30801. registerInstance(this, hostRef);
  30802. this.ionSplitPaneVisible = createEvent(this, "ionSplitPaneVisible", 7);
  30803. this.visible = false;
  30804. this.contentId = undefined;
  30805. this.disabled = false;
  30806. this.when = QUERY['lg'];
  30807. }
  30808. visibleChanged(visible) {
  30809. this.ionSplitPaneVisible.emit({ visible });
  30810. }
  30811. /**
  30812. * @internal
  30813. */
  30814. async isVisible() {
  30815. return Promise.resolve(this.visible);
  30816. }
  30817. async connectedCallback() {
  30818. // TODO: connectedCallback is fired in CE build
  30819. // before WC is defined. This needs to be fixed in Stencil.
  30820. if (typeof customElements !== 'undefined' && customElements != null) {
  30821. await customElements.whenDefined('ion-split-pane');
  30822. }
  30823. this.styleMainElement();
  30824. this.updateState();
  30825. }
  30826. disconnectedCallback() {
  30827. if (this.rmL) {
  30828. this.rmL();
  30829. this.rmL = undefined;
  30830. }
  30831. }
  30832. updateState() {
  30833. {
  30834. return;
  30835. }
  30836. }
  30837. /**
  30838. * Attempt to find the main content
  30839. * element inside of the split pane.
  30840. * If found, set it as the main node.
  30841. *
  30842. * We assume that the main node
  30843. * is available in the DOM on split
  30844. * pane load.
  30845. */
  30846. styleMainElement() {
  30847. {
  30848. return;
  30849. }
  30850. }
  30851. render() {
  30852. const mode = getIonMode$1(this);
  30853. return (hAsync(Host, { key: '098801b5a318e2fc6913fb0d9079b1552927b99b', class: {
  30854. [mode]: true,
  30855. // Used internally for styling
  30856. [`split-pane-${mode}`]: true,
  30857. 'split-pane-visible': this.visible,
  30858. } }, hAsync("slot", { key: '8cbc6a942ecba54fc3c62027d46917db067b65c8' })));
  30859. }
  30860. get el() { return getElement(this); }
  30861. static get watchers() { return {
  30862. "visible": ["visibleChanged"],
  30863. "disabled": ["updateState"],
  30864. "when": ["updateState"]
  30865. }; }
  30866. static get style() { return {
  30867. ios: IonSplitPaneIosStyle0,
  30868. md: IonSplitPaneMdStyle0
  30869. }; }
  30870. static get cmpMeta() { return {
  30871. "$flags$": 41,
  30872. "$tagName$": "ion-split-pane",
  30873. "$members$": {
  30874. "contentId": [513, "content-id"],
  30875. "disabled": [4],
  30876. "when": [8],
  30877. "visible": [32],
  30878. "isVisible": [64]
  30879. },
  30880. "$listeners$": undefined,
  30881. "$lazyBundleId$": "-",
  30882. "$attrsToReflect$": [["contentId", "content-id"]]
  30883. }; }
  30884. }
  30885. const tabCss = ":host(.tab-hidden){display:none !important}";
  30886. var IonTabStyle0 = tabCss;
  30887. class Tab {
  30888. constructor(hostRef) {
  30889. registerInstance(this, hostRef);
  30890. this.loaded = false;
  30891. this.active = false;
  30892. this.delegate = undefined;
  30893. this.tab = undefined;
  30894. this.component = undefined;
  30895. }
  30896. async componentWillLoad() {
  30897. if (this.active) {
  30898. await this.setActive();
  30899. }
  30900. }
  30901. /** Set the active component for the tab */
  30902. async setActive() {
  30903. await this.prepareLazyLoaded();
  30904. this.active = true;
  30905. }
  30906. changeActive(isActive) {
  30907. if (isActive) {
  30908. this.prepareLazyLoaded();
  30909. }
  30910. }
  30911. prepareLazyLoaded() {
  30912. if (!this.loaded && this.component != null) {
  30913. this.loaded = true;
  30914. try {
  30915. return attachComponent(this.delegate, this.el, this.component, ['ion-page']);
  30916. }
  30917. catch (e) {
  30918. printIonError('[ion-tab] - Exception in prepareLazyLoaded:', e);
  30919. }
  30920. }
  30921. return Promise.resolve(undefined);
  30922. }
  30923. render() {
  30924. const { tab, active, component } = this;
  30925. return (hAsync(Host, { key: 'c36c113e74e12b58459df9e3b546ad4856187e90', role: "tabpanel", "aria-hidden": !active ? 'true' : null, "aria-labelledby": `tab-button-${tab}`, class: {
  30926. 'ion-page': component === undefined,
  30927. 'tab-hidden': !active,
  30928. } }, hAsync("slot", { key: '0d7821dac70ba7a12edfb3331988f3df1566cc1a' })));
  30929. }
  30930. get el() { return getElement(this); }
  30931. static get watchers() { return {
  30932. "active": ["changeActive"]
  30933. }; }
  30934. static get style() { return IonTabStyle0; }
  30935. static get cmpMeta() { return {
  30936. "$flags$": 9,
  30937. "$tagName$": "ion-tab",
  30938. "$members$": {
  30939. "active": [1028],
  30940. "delegate": [16],
  30941. "tab": [1],
  30942. "component": [1],
  30943. "setActive": [64]
  30944. },
  30945. "$listeners$": undefined,
  30946. "$lazyBundleId$": "-",
  30947. "$attrsToReflect$": []
  30948. }; }
  30949. }
  30950. const tabBarIosCss = ":host{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;width:auto;padding-right:var(--ion-safe-area-right);padding-bottom:var(--ion-safe-area-bottom, 0);padding-left:var(--ion-safe-area-left);border-top:var(--border);background:var(--background);color:var(--color);text-align:center;contain:strict;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;z-index:10;-webkit-box-sizing:content-box !important;box-sizing:content-box !important}:host(.ion-color) ::slotted(ion-tab-button){--background-focused:var(--ion-color-shade);--color-selected:var(--ion-color-contrast)}:host(.ion-color) ::slotted(.tab-selected){color:var(--ion-color-contrast)}:host(.ion-color),:host(.ion-color) ::slotted(ion-tab-button){color:rgba(var(--ion-color-contrast-rgb), 0.7)}:host(.ion-color),:host(.ion-color) ::slotted(ion-tab-button){background:var(--ion-color-base)}:host(.ion-color) ::slotted(ion-tab-button.ion-focused),:host(.tab-bar-translucent) ::slotted(ion-tab-button.ion-focused){background:var(--background-focused)}:host(.tab-bar-translucent) ::slotted(ion-tab-button){background:transparent}:host([slot=top]){padding-top:var(--ion-safe-area-top, 0);padding-bottom:0;border-top:0;border-bottom:var(--border)}:host(.tab-bar-hidden){display:none !important}:host{--background:var(--ion-tab-bar-background, var(--ion-color-step-50, var(--ion-background-color-step-50, #f7f7f7)));--background-focused:var(--ion-tab-bar-background-focused, #e0e0e0);--border:0.55px solid var(--ion-tab-bar-border-color, var(--ion-border-color, var(--ion-color-step-150, var(--ion-background-color-step-150, rgba(0, 0, 0, 0.2)))));--color:var(--ion-tab-bar-color, var(--ion-color-step-600, var(--ion-text-color-step-400, #666666)));--color-selected:var(--ion-tab-bar-color-selected, var(--ion-color-primary, #0054e9));height:50px}@supports ((-webkit-backdrop-filter: blur(0)) or (backdrop-filter: blur(0))){:host(.tab-bar-translucent){--background:rgba(var(--ion-background-color-rgb, 255, 255, 255), 0.8);-webkit-backdrop-filter:saturate(210%) blur(20px);backdrop-filter:saturate(210%) blur(20px)}:host(.ion-color.tab-bar-translucent){background:rgba(var(--ion-color-base-rgb), 0.8)}:host(.tab-bar-translucent) ::slotted(ion-tab-button.ion-focused){background:rgba(var(--ion-background-color-rgb, 255, 255, 255), 0.6)}}";
  30951. var IonTabBarIosStyle0 = tabBarIosCss;
  30952. const tabBarMdCss = ":host{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;width:auto;padding-right:var(--ion-safe-area-right);padding-bottom:var(--ion-safe-area-bottom, 0);padding-left:var(--ion-safe-area-left);border-top:var(--border);background:var(--background);color:var(--color);text-align:center;contain:strict;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;z-index:10;-webkit-box-sizing:content-box !important;box-sizing:content-box !important}:host(.ion-color) ::slotted(ion-tab-button){--background-focused:var(--ion-color-shade);--color-selected:var(--ion-color-contrast)}:host(.ion-color) ::slotted(.tab-selected){color:var(--ion-color-contrast)}:host(.ion-color),:host(.ion-color) ::slotted(ion-tab-button){color:rgba(var(--ion-color-contrast-rgb), 0.7)}:host(.ion-color),:host(.ion-color) ::slotted(ion-tab-button){background:var(--ion-color-base)}:host(.ion-color) ::slotted(ion-tab-button.ion-focused),:host(.tab-bar-translucent) ::slotted(ion-tab-button.ion-focused){background:var(--background-focused)}:host(.tab-bar-translucent) ::slotted(ion-tab-button){background:transparent}:host([slot=top]){padding-top:var(--ion-safe-area-top, 0);padding-bottom:0;border-top:0;border-bottom:var(--border)}:host(.tab-bar-hidden){display:none !important}:host{--background:var(--ion-tab-bar-background, var(--ion-background-color, #fff));--background-focused:var(--ion-tab-bar-background-focused, #e0e0e0);--border:1px solid var(--ion-tab-bar-border-color, var(--ion-border-color, var(--ion-color-step-150, var(--ion-background-color-step-150, rgba(0, 0, 0, 0.07)))));--color:var(--ion-tab-bar-color, var(--ion-color-step-650, var(--ion-text-color-step-350, #595959)));--color-selected:var(--ion-tab-bar-color-selected, var(--ion-color-primary, #0054e9));height:56px}";
  30953. var IonTabBarMdStyle0 = tabBarMdCss;
  30954. /**
  30955. * @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
  30956. */
  30957. class TabBar {
  30958. constructor(hostRef) {
  30959. registerInstance(this, hostRef);
  30960. this.ionTabBarChanged = createEvent(this, "ionTabBarChanged", 7);
  30961. this.ionTabBarLoaded = createEvent(this, "ionTabBarLoaded", 7);
  30962. this.keyboardCtrl = null;
  30963. this.keyboardVisible = false;
  30964. this.color = undefined;
  30965. this.selectedTab = undefined;
  30966. this.translucent = false;
  30967. }
  30968. selectedTabChanged() {
  30969. if (this.selectedTab !== undefined) {
  30970. this.ionTabBarChanged.emit({
  30971. tab: this.selectedTab,
  30972. });
  30973. }
  30974. }
  30975. componentWillLoad() {
  30976. this.selectedTabChanged();
  30977. }
  30978. async connectedCallback() {
  30979. this.keyboardCtrl = await createKeyboardController(async (keyboardOpen, waitForResize) => {
  30980. /**
  30981. * If the keyboard is hiding, then we need to wait
  30982. * for the webview to resize. Otherwise, the tab bar
  30983. * will flicker before the webview resizes.
  30984. */
  30985. if (keyboardOpen === false && waitForResize !== undefined) {
  30986. await waitForResize;
  30987. }
  30988. this.keyboardVisible = keyboardOpen; // trigger re-render by updating state
  30989. });
  30990. }
  30991. disconnectedCallback() {
  30992. if (this.keyboardCtrl) {
  30993. this.keyboardCtrl.destroy();
  30994. }
  30995. }
  30996. componentDidLoad() {
  30997. this.ionTabBarLoaded.emit();
  30998. }
  30999. render() {
  31000. const { color, translucent, keyboardVisible } = this;
  31001. const mode = getIonMode$1(this);
  31002. const shouldHide = keyboardVisible && this.el.getAttribute('slot') !== 'top';
  31003. return (hAsync(Host, { key: '62303a7f9d8c98ffab51a5900c144c5117b9c543', role: "tablist", "aria-hidden": shouldHide ? 'true' : null, class: createColorClasses$1(color, {
  31004. [mode]: true,
  31005. 'tab-bar-translucent': translucent,
  31006. 'tab-bar-hidden': shouldHide,
  31007. }) }, hAsync("slot", { key: '5771a9828f748c2bd6b5e26758b9723c6b3de5ff' })));
  31008. }
  31009. get el() { return getElement(this); }
  31010. static get watchers() { return {
  31011. "selectedTab": ["selectedTabChanged"]
  31012. }; }
  31013. static get style() { return {
  31014. ios: IonTabBarIosStyle0,
  31015. md: IonTabBarMdStyle0
  31016. }; }
  31017. static get cmpMeta() { return {
  31018. "$flags$": 41,
  31019. "$tagName$": "ion-tab-bar",
  31020. "$members$": {
  31021. "color": [513],
  31022. "selectedTab": [1, "selected-tab"],
  31023. "translucent": [4],
  31024. "keyboardVisible": [32]
  31025. },
  31026. "$listeners$": undefined,
  31027. "$lazyBundleId$": "-",
  31028. "$attrsToReflect$": [["color", "color"]]
  31029. }; }
  31030. }
  31031. const tabButtonIosCss = ":host{--ripple-color:var(--color-selected);--background-focused-opacity:1;-ms-flex:1;flex:1;-ms-flex-direction:column;flex-direction:column;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;height:100%;outline:none;background:var(--background);color:var(--color)}.button-native{border-radius:inherit;margin-left:0;margin-right:0;margin-top:0;margin-bottom:0;-webkit-padding-start:var(--padding-start);padding-inline-start:var(--padding-start);-webkit-padding-end:var(--padding-end);padding-inline-end:var(--padding-end);padding-top:var(--padding-top);padding-bottom:var(--padding-bottom);font-family:inherit;font-size:inherit;font-style:inherit;font-weight:inherit;letter-spacing:inherit;text-decoration:inherit;text-indent:inherit;text-overflow:inherit;text-transform:inherit;text-align:inherit;white-space:inherit;color:inherit;display:-ms-flexbox;display:flex;position:relative;-ms-flex-direction:inherit;flex-direction:inherit;-ms-flex-align:inherit;align-items:inherit;-ms-flex-pack:inherit;justify-content:inherit;width:100%;height:100%;border:0;outline:none;background:transparent;text-decoration:none;cursor:pointer;overflow:hidden;-webkit-box-sizing:border-box;box-sizing:border-box;-webkit-user-drag:none}.button-native::after{left:0;right:0;top:0;bottom:0;position:absolute;content:\"\";opacity:0}.button-inner{display:-ms-flexbox;display:flex;position:relative;-ms-flex-flow:inherit;flex-flow:inherit;-ms-flex-align:inherit;align-items:inherit;-ms-flex-pack:inherit;justify-content:inherit;width:100%;height:100%;z-index:1}:host(.ion-focused) .button-native{color:var(--color-focused)}:host(.ion-focused) .button-native::after{background:var(--background-focused);opacity:var(--background-focused-opacity)}@media (any-hover: hover){a:hover{color:var(--color-selected)}}:host(.tab-selected){color:var(--color-selected)}:host(.tab-hidden){display:none !important}:host(.tab-disabled){pointer-events:none;opacity:0.4}::slotted(ion-label),::slotted(ion-icon){display:block;-ms-flex-item-align:center;align-self:center;max-width:100%;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;-webkit-box-sizing:border-box;box-sizing:border-box}::slotted(ion-label){-ms-flex-order:0;order:0}::slotted(ion-icon){-ms-flex-order:-1;order:-1;height:1em}:host(.tab-has-label-only) ::slotted(ion-label){white-space:normal}::slotted(ion-badge){-webkit-box-sizing:border-box;box-sizing:border-box;position:absolute;z-index:1}:host(.tab-layout-icon-start){-ms-flex-direction:row;flex-direction:row}:host(.tab-layout-icon-end){-ms-flex-direction:row-reverse;flex-direction:row-reverse}:host(.tab-layout-icon-bottom){-ms-flex-direction:column-reverse;flex-direction:column-reverse}:host(.tab-layout-icon-hide) ::slotted(ion-icon){display:none}:host(.tab-layout-label-hide) ::slotted(ion-label){display:none}ion-ripple-effect{color:var(--ripple-color)}:host{--padding-top:0;--padding-end:2px;--padding-bottom:0;--padding-start:2px;max-width:240px;font-size:10px}::slotted(ion-badge){-webkit-padding-start:6px;padding-inline-start:6px;-webkit-padding-end:6px;padding-inline-end:6px;padding-top:1px;padding-bottom:1px;top:4px;height:auto;font-size:12px;line-height:16px}::slotted(ion-badge){inset-inline-start:calc(50% + 6px)}::slotted(ion-icon){margin-top:2px;margin-bottom:2px;font-size:24px}::slotted(ion-icon::before){vertical-align:top}::slotted(ion-label){margin-top:0;margin-bottom:1px;min-height:11px;font-weight:500}:host(.tab-has-label-only) ::slotted(ion-label){margin-left:0;margin-right:0;margin-top:2px;margin-bottom:2px;font-size:12px;font-size:14px;line-height:1.1}:host(.tab-layout-icon-end) ::slotted(ion-label),:host(.tab-layout-icon-start) ::slotted(ion-label),:host(.tab-layout-icon-hide) ::slotted(ion-label){margin-top:2px;margin-bottom:2px;font-size:14px;line-height:1.1}:host(.tab-layout-icon-end) ::slotted(ion-icon),:host(.tab-layout-icon-start) ::slotted(ion-icon){min-width:24px;height:26px;margin-top:2px;margin-bottom:1px;font-size:24px}:host(.tab-layout-icon-bottom) ::slotted(ion-badge){inset-inline-start:calc(50% + 12px)}:host(.tab-layout-icon-bottom) ::slotted(ion-icon){margin-top:0;margin-bottom:1px}:host(.tab-layout-icon-bottom) ::slotted(ion-label){margin-top:4px}:host(.tab-layout-icon-start) ::slotted(ion-badge),:host(.tab-layout-icon-end) ::slotted(ion-badge){top:10px}:host(.tab-layout-icon-start) ::slotted(ion-badge),:host(.tab-layout-icon-end) ::slotted(ion-badge){inset-inline-start:calc(50% + 35px)}:host(.tab-layout-icon-hide) ::slotted(ion-badge),:host(.tab-has-label-only) ::slotted(ion-badge){top:10px}:host(.tab-layout-icon-hide) ::slotted(ion-badge),:host(.tab-has-label-only) ::slotted(ion-badge){inset-inline-start:calc(50% + 30px)}:host(.tab-layout-label-hide) ::slotted(ion-badge),:host(.tab-has-icon-only) ::slotted(ion-badge){top:10px}:host(.tab-layout-label-hide) ::slotted(ion-icon){margin-left:0;margin-right:0;margin-top:0;margin-bottom:0}:host(.tab-layout-label-hide) ::slotted(ion-icon),:host(.tab-has-icon-only) ::slotted(ion-icon){font-size:30px}";
  31032. var IonTabButtonIosStyle0 = tabButtonIosCss;
  31033. const tabButtonMdCss = ":host{--ripple-color:var(--color-selected);--background-focused-opacity:1;-ms-flex:1;flex:1;-ms-flex-direction:column;flex-direction:column;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;height:100%;outline:none;background:var(--background);color:var(--color)}.button-native{border-radius:inherit;margin-left:0;margin-right:0;margin-top:0;margin-bottom:0;-webkit-padding-start:var(--padding-start);padding-inline-start:var(--padding-start);-webkit-padding-end:var(--padding-end);padding-inline-end:var(--padding-end);padding-top:var(--padding-top);padding-bottom:var(--padding-bottom);font-family:inherit;font-size:inherit;font-style:inherit;font-weight:inherit;letter-spacing:inherit;text-decoration:inherit;text-indent:inherit;text-overflow:inherit;text-transform:inherit;text-align:inherit;white-space:inherit;color:inherit;display:-ms-flexbox;display:flex;position:relative;-ms-flex-direction:inherit;flex-direction:inherit;-ms-flex-align:inherit;align-items:inherit;-ms-flex-pack:inherit;justify-content:inherit;width:100%;height:100%;border:0;outline:none;background:transparent;text-decoration:none;cursor:pointer;overflow:hidden;-webkit-box-sizing:border-box;box-sizing:border-box;-webkit-user-drag:none}.button-native::after{left:0;right:0;top:0;bottom:0;position:absolute;content:\"\";opacity:0}.button-inner{display:-ms-flexbox;display:flex;position:relative;-ms-flex-flow:inherit;flex-flow:inherit;-ms-flex-align:inherit;align-items:inherit;-ms-flex-pack:inherit;justify-content:inherit;width:100%;height:100%;z-index:1}:host(.ion-focused) .button-native{color:var(--color-focused)}:host(.ion-focused) .button-native::after{background:var(--background-focused);opacity:var(--background-focused-opacity)}@media (any-hover: hover){a:hover{color:var(--color-selected)}}:host(.tab-selected){color:var(--color-selected)}:host(.tab-hidden){display:none !important}:host(.tab-disabled){pointer-events:none;opacity:0.4}::slotted(ion-label),::slotted(ion-icon){display:block;-ms-flex-item-align:center;align-self:center;max-width:100%;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;-webkit-box-sizing:border-box;box-sizing:border-box}::slotted(ion-label){-ms-flex-order:0;order:0}::slotted(ion-icon){-ms-flex-order:-1;order:-1;height:1em}:host(.tab-has-label-only) ::slotted(ion-label){white-space:normal}::slotted(ion-badge){-webkit-box-sizing:border-box;box-sizing:border-box;position:absolute;z-index:1}:host(.tab-layout-icon-start){-ms-flex-direction:row;flex-direction:row}:host(.tab-layout-icon-end){-ms-flex-direction:row-reverse;flex-direction:row-reverse}:host(.tab-layout-icon-bottom){-ms-flex-direction:column-reverse;flex-direction:column-reverse}:host(.tab-layout-icon-hide) ::slotted(ion-icon){display:none}:host(.tab-layout-label-hide) ::slotted(ion-label){display:none}ion-ripple-effect{color:var(--ripple-color)}:host{--padding-top:0;--padding-end:12px;--padding-bottom:0;--padding-start:12px;max-width:168px;font-size:12px;font-weight:normal;letter-spacing:0.03em}::slotted(ion-label){margin-left:0;margin-right:0;margin-top:2px;margin-bottom:2px;text-transform:none}::slotted(ion-icon){margin-left:0;margin-right:0;margin-top:16px;margin-bottom:16px;-webkit-transform-origin:center center;transform-origin:center center;font-size:22px}:host-context([dir=rtl]) ::slotted(ion-icon){-webkit-transform-origin:calc(100% - center) center;transform-origin:calc(100% - center) center}[dir=rtl] ::slotted(ion-icon){-webkit-transform-origin:calc(100% - center) center;transform-origin:calc(100% - center) center}@supports selector(:dir(rtl)){::slotted(ion-icon):dir(rtl){-webkit-transform-origin:calc(100% - center) center;transform-origin:calc(100% - center) center}}::slotted(ion-badge){border-radius:8px;-webkit-padding-start:2px;padding-inline-start:2px;-webkit-padding-end:2px;padding-inline-end:2px;padding-top:3px;padding-bottom:2px;top:8px;min-width:12px;font-size:8px;font-weight:normal}::slotted(ion-badge){inset-inline-start:calc(50% + 6px)}::slotted(ion-badge:empty){display:block;min-width:8px;height:8px}:host(.tab-layout-icon-top) ::slotted(ion-icon){margin-top:6px;margin-bottom:2px}:host(.tab-layout-icon-top) ::slotted(ion-label){margin-top:0;margin-bottom:6px}:host(.tab-layout-icon-bottom) ::slotted(ion-badge){top:8px}:host(.tab-layout-icon-bottom) ::slotted(ion-badge){inset-inline-start:70%}:host(.tab-layout-icon-bottom) ::slotted(ion-icon){margin-top:0;margin-bottom:6px}:host(.tab-layout-icon-bottom) ::slotted(ion-label){margin-top:6px;margin-bottom:0}:host(.tab-layout-icon-start) ::slotted(ion-badge),:host(.tab-layout-icon-end) ::slotted(ion-badge){top:16px}:host(.tab-layout-icon-start) ::slotted(ion-badge),:host(.tab-layout-icon-end) ::slotted(ion-badge){inset-inline-start:80%}:host(.tab-layout-icon-start) ::slotted(ion-icon){-webkit-margin-end:6px;margin-inline-end:6px}:host(.tab-layout-icon-end) ::slotted(ion-icon){-webkit-margin-start:6px;margin-inline-start:6px}:host(.tab-layout-icon-hide) ::slotted(ion-badge),:host(.tab-has-label-only) ::slotted(ion-badge){top:16px}:host(.tab-layout-icon-hide) ::slotted(ion-badge),:host(.tab-has-label-only) ::slotted(ion-badge){inset-inline-start:70%}:host(.tab-layout-icon-hide) ::slotted(ion-label),:host(.tab-has-label-only) ::slotted(ion-label){margin-top:0;margin-bottom:0}:host(.tab-layout-label-hide) ::slotted(ion-badge),:host(.tab-has-icon-only) ::slotted(ion-badge){top:16px}:host(.tab-layout-label-hide) ::slotted(ion-icon),:host(.tab-has-icon-only) ::slotted(ion-icon){margin-top:0;margin-bottom:0;font-size:24px}";
  31034. var IonTabButtonMdStyle0 = tabButtonMdCss;
  31035. /**
  31036. * @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
  31037. *
  31038. * @part native - The native HTML anchor element that wraps all child elements.
  31039. */
  31040. class TabButton {
  31041. constructor(hostRef) {
  31042. registerInstance(this, hostRef);
  31043. this.ionTabButtonClick = createEvent(this, "ionTabButtonClick", 7);
  31044. this.inheritedAttributes = {};
  31045. this.onKeyUp = (ev) => {
  31046. if (ev.key === 'Enter' || ev.key === ' ') {
  31047. this.selectTab(ev);
  31048. }
  31049. };
  31050. this.onClick = (ev) => {
  31051. this.selectTab(ev);
  31052. };
  31053. this.disabled = false;
  31054. this.download = undefined;
  31055. this.href = undefined;
  31056. this.rel = undefined;
  31057. this.layout = undefined;
  31058. this.selected = false;
  31059. this.tab = undefined;
  31060. this.target = undefined;
  31061. }
  31062. onTabBarChanged(ev) {
  31063. const dispatchedFrom = ev.target;
  31064. const parent = this.el.parentElement;
  31065. if (ev.composedPath().includes(parent) || (dispatchedFrom === null || dispatchedFrom === void 0 ? void 0 : dispatchedFrom.contains(this.el))) {
  31066. this.selected = this.tab === ev.detail.tab;
  31067. }
  31068. }
  31069. componentWillLoad() {
  31070. this.inheritedAttributes = Object.assign({}, inheritAttributes$1(this.el, ['aria-label']));
  31071. if (this.layout === undefined) {
  31072. this.layout = config.get('tabButtonLayout', 'icon-top');
  31073. }
  31074. }
  31075. selectTab(ev) {
  31076. if (this.tab !== undefined) {
  31077. if (!this.disabled) {
  31078. this.ionTabButtonClick.emit({
  31079. tab: this.tab,
  31080. href: this.href,
  31081. selected: this.selected,
  31082. });
  31083. }
  31084. ev.preventDefault();
  31085. }
  31086. }
  31087. get hasLabel() {
  31088. return !!this.el.querySelector('ion-label');
  31089. }
  31090. get hasIcon() {
  31091. return !!this.el.querySelector('ion-icon');
  31092. }
  31093. render() {
  31094. const { disabled, hasIcon, hasLabel, href, rel, target, layout, selected, tab, inheritedAttributes } = this;
  31095. const mode = getIonMode$1(this);
  31096. const attrs = {
  31097. download: this.download,
  31098. href,
  31099. rel,
  31100. target,
  31101. };
  31102. return (hAsync(Host, { key: 'a86d441d8df350fe991f2f948fc6b6ad007728f7', onClick: this.onClick, onKeyup: this.onKeyUp, id: tab !== undefined ? `tab-button-${tab}` : null, class: {
  31103. [mode]: true,
  31104. 'tab-selected': selected,
  31105. 'tab-disabled': disabled,
  31106. 'tab-has-label': hasLabel,
  31107. 'tab-has-icon': hasIcon,
  31108. 'tab-has-label-only': hasLabel && !hasIcon,
  31109. 'tab-has-icon-only': hasIcon && !hasLabel,
  31110. [`tab-layout-${layout}`]: true,
  31111. 'ion-activatable': true,
  31112. 'ion-selectable': true,
  31113. 'ion-focusable': true,
  31114. } }, hAsync("a", Object.assign({ key: '8dfe1ccff2cf21601c5aea7f7f877c0fbe384e09' }, attrs, { class: "button-native", part: "native", role: "tab", "aria-selected": selected ? 'true' : null, "aria-disabled": disabled ? 'true' : null, tabindex: disabled ? '-1' : undefined }, inheritedAttributes), hAsync("span", { key: '3f557cf6e96e22b9318b4aee19ede810eb7fb720', class: "button-inner" }, hAsync("slot", { key: '836dd090dbe3c2ea97dc263fca7d01dea6ea0eb6' })), mode === 'md' && hAsync("ion-ripple-effect", { key: '488a924fd04602c1b23e03d1a4c84dfa0f2ca03d', type: "unbounded" }))));
  31115. }
  31116. get el() { return getElement(this); }
  31117. static get style() { return {
  31118. ios: IonTabButtonIosStyle0,
  31119. md: IonTabButtonMdStyle0
  31120. }; }
  31121. static get cmpMeta() { return {
  31122. "$flags$": 41,
  31123. "$tagName$": "ion-tab-button",
  31124. "$members$": {
  31125. "disabled": [4],
  31126. "download": [1],
  31127. "href": [1],
  31128. "rel": [1],
  31129. "layout": [1025],
  31130. "selected": [1028],
  31131. "tab": [1],
  31132. "target": [1]
  31133. },
  31134. "$listeners$": [[8, "ionTabBarChanged", "onTabBarChanged"]],
  31135. "$lazyBundleId$": "-",
  31136. "$attrsToReflect$": []
  31137. }; }
  31138. }
  31139. const tabsCss = ":host{left:0;right:0;top:0;bottom:0;display:-ms-flexbox;display:flex;position:absolute;-ms-flex-direction:column;flex-direction:column;width:100%;height:100%;contain:layout size style;z-index:0}.tabs-inner{position:relative;-ms-flex:1;flex:1;contain:layout size style}";
  31140. var IonTabsStyle0 = tabsCss;
  31141. /**
  31142. * @slot - Content is placed between the named slots if provided without a slot.
  31143. * @slot top - Content is placed at the top of the screen.
  31144. * @slot bottom - Content is placed at the bottom of the screen.
  31145. */
  31146. class Tabs {
  31147. constructor(hostRef) {
  31148. registerInstance(this, hostRef);
  31149. this.ionNavWillLoad = createEvent(this, "ionNavWillLoad", 7);
  31150. this.ionTabsWillChange = createEvent(this, "ionTabsWillChange", 3);
  31151. this.ionTabsDidChange = createEvent(this, "ionTabsDidChange", 3);
  31152. this.transitioning = false;
  31153. this.onTabClicked = (ev) => {
  31154. const { href, tab } = ev.detail;
  31155. if (this.useRouter && href !== undefined) {
  31156. const router = document.querySelector('ion-router');
  31157. if (router) {
  31158. router.push(href);
  31159. }
  31160. }
  31161. else {
  31162. this.select(tab);
  31163. }
  31164. };
  31165. this.selectedTab = undefined;
  31166. this.useRouter = false;
  31167. }
  31168. async componentWillLoad() {
  31169. if (!this.useRouter) {
  31170. /**
  31171. * JavaScript and StencilJS use `ion-router`, while
  31172. * the other frameworks use `ion-router-outlet`.
  31173. *
  31174. * If either component is present then tabs will not use
  31175. * a basic tab-based navigation. It will use the history
  31176. * stack or URL updates associated with the router.
  31177. */
  31178. this.useRouter =
  31179. (!!this.el.querySelector('ion-router-outlet') || !!document.querySelector('ion-router')) &&
  31180. !this.el.closest('[no-router]');
  31181. }
  31182. if (!this.useRouter) {
  31183. const tabs = this.tabs;
  31184. if (tabs.length > 0) {
  31185. await this.select(tabs[0]);
  31186. }
  31187. }
  31188. this.ionNavWillLoad.emit();
  31189. }
  31190. componentWillRender() {
  31191. const tabBar = this.el.querySelector('ion-tab-bar');
  31192. if (tabBar) {
  31193. const tab = this.selectedTab ? this.selectedTab.tab : undefined;
  31194. tabBar.selectedTab = tab;
  31195. }
  31196. }
  31197. /**
  31198. * Select a tab by the value of its `tab` property or an element reference. This method is only available for vanilla JavaScript projects. The Angular, React, and Vue implementations of tabs are coupled to each framework's router.
  31199. *
  31200. * @param tab The tab instance to select. If passed a string, it should be the value of the tab's `tab` property.
  31201. */
  31202. async select(tab) {
  31203. const selectedTab = getTab(this.tabs, tab);
  31204. if (!this.shouldSwitch(selectedTab)) {
  31205. return false;
  31206. }
  31207. await this.setActive(selectedTab);
  31208. await this.notifyRouter();
  31209. this.tabSwitch();
  31210. return true;
  31211. }
  31212. /**
  31213. * Get a specific tab by the value of its `tab` property or an element reference. This method is only available for vanilla JavaScript projects. The Angular, React, and Vue implementations of tabs are coupled to each framework's router.
  31214. *
  31215. * @param tab The tab instance to select. If passed a string, it should be the value of the tab's `tab` property.
  31216. */
  31217. async getTab(tab) {
  31218. return getTab(this.tabs, tab);
  31219. }
  31220. /**
  31221. * Get the currently selected tab. This method is only available for vanilla JavaScript projects. The Angular, React, and Vue implementations of tabs are coupled to each framework's router.
  31222. */
  31223. getSelected() {
  31224. return Promise.resolve(this.selectedTab ? this.selectedTab.tab : undefined);
  31225. }
  31226. /** @internal */
  31227. async setRouteId(id) {
  31228. const selectedTab = getTab(this.tabs, id);
  31229. if (!this.shouldSwitch(selectedTab)) {
  31230. return { changed: false, element: this.selectedTab };
  31231. }
  31232. await this.setActive(selectedTab);
  31233. return {
  31234. changed: true,
  31235. element: this.selectedTab,
  31236. markVisible: () => this.tabSwitch(),
  31237. };
  31238. }
  31239. /** @internal */
  31240. async getRouteId() {
  31241. var _a;
  31242. const tabId = (_a = this.selectedTab) === null || _a === void 0 ? void 0 : _a.tab;
  31243. return tabId !== undefined ? { id: tabId, element: this.selectedTab } : undefined;
  31244. }
  31245. setActive(selectedTab) {
  31246. if (this.transitioning) {
  31247. return Promise.reject('transitioning already happening');
  31248. }
  31249. this.transitioning = true;
  31250. this.leavingTab = this.selectedTab;
  31251. this.selectedTab = selectedTab;
  31252. this.ionTabsWillChange.emit({ tab: selectedTab.tab });
  31253. selectedTab.active = true;
  31254. return Promise.resolve();
  31255. }
  31256. tabSwitch() {
  31257. const selectedTab = this.selectedTab;
  31258. const leavingTab = this.leavingTab;
  31259. this.leavingTab = undefined;
  31260. this.transitioning = false;
  31261. if (!selectedTab) {
  31262. return;
  31263. }
  31264. if (leavingTab !== selectedTab) {
  31265. if (leavingTab) {
  31266. leavingTab.active = false;
  31267. }
  31268. this.ionTabsDidChange.emit({ tab: selectedTab.tab });
  31269. }
  31270. }
  31271. notifyRouter() {
  31272. if (this.useRouter) {
  31273. const router = document.querySelector('ion-router');
  31274. if (router) {
  31275. return router.navChanged('forward');
  31276. }
  31277. }
  31278. return Promise.resolve(false);
  31279. }
  31280. shouldSwitch(selectedTab) {
  31281. const leavingTab = this.selectedTab;
  31282. return selectedTab !== undefined && selectedTab !== leavingTab && !this.transitioning;
  31283. }
  31284. get tabs() {
  31285. return Array.from(this.el.querySelectorAll('ion-tab'));
  31286. }
  31287. render() {
  31288. return (hAsync(Host, { key: '20b97196d78c1b3f3faf31618a8a2347e087f06b', onIonTabButtonClick: this.onTabClicked }, hAsync("slot", { key: 'b0823fbae6e47743cfd12c376b365ad7e32cec7c', name: "top" }), hAsync("div", { key: 'eaffd7e4d69ab9489a387e3bbb36e3bab72203a0', class: "tabs-inner" }, hAsync("slot", { key: '20bb66a2937e3ec473aa59c4075ce581b5411677' })), hAsync("slot", { key: '1529dd361f050f52074f51c73b3982ba827dc3a5', name: "bottom" })));
  31289. }
  31290. get el() { return getElement(this); }
  31291. static get style() { return IonTabsStyle0; }
  31292. static get cmpMeta() { return {
  31293. "$flags$": 9,
  31294. "$tagName$": "ion-tabs",
  31295. "$members$": {
  31296. "useRouter": [1028, "use-router"],
  31297. "selectedTab": [32],
  31298. "select": [64],
  31299. "getTab": [64],
  31300. "getSelected": [64],
  31301. "setRouteId": [64],
  31302. "getRouteId": [64]
  31303. },
  31304. "$listeners$": undefined,
  31305. "$lazyBundleId$": "-",
  31306. "$attrsToReflect$": []
  31307. }; }
  31308. }
  31309. const getTab = (tabs, tab) => {
  31310. const tabEl = typeof tab === 'string' ? tabs.find((t) => t.tab === tab) : tab;
  31311. if (!tabEl) {
  31312. printIonError(`[ion-tabs] - Tab with id: "${tabEl}" does not exist`);
  31313. }
  31314. return tabEl;
  31315. };
  31316. const textCss = ":host(.ion-color){color:var(--ion-color-base)}";
  31317. var IonTextStyle0 = textCss;
  31318. /**
  31319. * @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
  31320. */
  31321. class Text {
  31322. constructor(hostRef) {
  31323. registerInstance(this, hostRef);
  31324. this.color = undefined;
  31325. }
  31326. render() {
  31327. const mode = getIonMode$1(this);
  31328. return (hAsync(Host, { key: '0c2546ea3f24b0a6bfd606199441d0a4edfa4ca1', class: createColorClasses$1(this.color, {
  31329. [mode]: true,
  31330. }) }, hAsync("slot", { key: 'b7623ccb06f9461090a1f33e9f85886c7a4d5eff' })));
  31331. }
  31332. static get style() { return IonTextStyle0; }
  31333. static get cmpMeta() { return {
  31334. "$flags$": 9,
  31335. "$tagName$": "ion-text",
  31336. "$members$": {
  31337. "color": [513]
  31338. },
  31339. "$listeners$": undefined,
  31340. "$lazyBundleId$": "-",
  31341. "$attrsToReflect$": [["color", "color"]]
  31342. }; }
  31343. }
  31344. const textareaIosCss = ".sc-ion-textarea-ios-h{--background:initial;--color:initial;--placeholder-color:initial;--placeholder-font-style:initial;--placeholder-font-weight:initial;--placeholder-opacity:var(--ion-placeholder-opacity, 0.6);--padding-top:0;--padding-end:0;--padding-bottom:8px;--padding-start:0;--border-radius:0;--border-style:solid;--highlight-color-focused:var(--ion-color-primary, #0054e9);--highlight-color-valid:var(--ion-color-success, #2dd55b);--highlight-color-invalid:var(--ion-color-danger, #c5000f);--highlight-color:var(--highlight-color-focused);display:block;position:relative;width:100%;min-height:44px;color:var(--color);font-family:var(--ion-font-family, inherit);z-index:2;-webkit-box-sizing:border-box;box-sizing:border-box}.textarea-label-placement-floating.sc-ion-textarea-ios-h,.textarea-label-placement-stacked.sc-ion-textarea-ios-h{--padding-top:0px;min-height:56px}[cols].sc-ion-textarea-ios-h:not([auto-grow]){width:-webkit-fit-content;width:-moz-fit-content;width:fit-content}.ion-color.sc-ion-textarea-ios-h{--highlight-color-focused:var(--ion-color-base);background:initial}ion-item.sc-ion-textarea-ios-h,ion-item .sc-ion-textarea-ios-h{-ms-flex-item-align:baseline;align-self:baseline}ion-item[slot=start].sc-ion-textarea-ios-h,ion-item [slot=start].sc-ion-textarea-ios-h,ion-item[slot=end].sc-ion-textarea-ios-h,ion-item [slot=end].sc-ion-textarea-ios-h{width:auto}.native-textarea.sc-ion-textarea-ios{margin-left:0;margin-right:0;margin-top:0;margin-bottom:0;padding-left:0;padding-right:0;padding-top:0;padding-bottom:0;display:block;position:relative;-ms-flex:1;flex:1;width:100%;max-width:100%;max-height:100%;border:0;outline:none;background:transparent;white-space:pre-wrap;z-index:1;-webkit-box-sizing:border-box;box-sizing:border-box;resize:none;-webkit-appearance:none;-moz-appearance:none;appearance:none}.native-textarea.sc-ion-textarea-ios::-webkit-input-placeholder{padding-left:0;padding-right:0;padding-top:0;padding-bottom:0;color:var(--placeholder-color);font-family:inherit;font-style:var(--placeholder-font-style);font-weight:var(--placeholder-font-weight);opacity:var(--placeholder-opacity)}.native-textarea.sc-ion-textarea-ios::-moz-placeholder{padding-left:0;padding-right:0;padding-top:0;padding-bottom:0;color:var(--placeholder-color);font-family:inherit;font-style:var(--placeholder-font-style);font-weight:var(--placeholder-font-weight);opacity:var(--placeholder-opacity)}.native-textarea.sc-ion-textarea-ios:-ms-input-placeholder{padding-left:0;padding-right:0;padding-top:0;padding-bottom:0;color:var(--placeholder-color);font-family:inherit;font-style:var(--placeholder-font-style);font-weight:var(--placeholder-font-weight);opacity:var(--placeholder-opacity)}.native-textarea.sc-ion-textarea-ios::-ms-input-placeholder{padding-left:0;padding-right:0;padding-top:0;padding-bottom:0;color:var(--placeholder-color);font-family:inherit;font-style:var(--placeholder-font-style);font-weight:var(--placeholder-font-weight);opacity:var(--placeholder-opacity)}.native-textarea.sc-ion-textarea-ios::placeholder{padding-left:0;padding-right:0;padding-top:0;padding-bottom:0;color:var(--placeholder-color);font-family:inherit;font-style:var(--placeholder-font-style);font-weight:var(--placeholder-font-weight);opacity:var(--placeholder-opacity)}.native-textarea.sc-ion-textarea-ios{color:inherit;font-family:inherit;font-size:inherit;font-style:inherit;font-weight:inherit;letter-spacing:inherit;text-align:inherit;text-decoration:inherit;text-indent:inherit;text-overflow:inherit;text-transform:inherit;grid-area:1/1/2/2;word-break:break-word}.cloned-input.sc-ion-textarea-ios{top:0;bottom:0;position:absolute;pointer-events:none}.cloned-input.sc-ion-textarea-ios{inset-inline-start:0}.cloned-input.sc-ion-textarea-ios:disabled{opacity:1}[auto-grow].sc-ion-textarea-ios-h .cloned-input.sc-ion-textarea-ios{height:100%}[auto-grow].sc-ion-textarea-ios-h .native-textarea.sc-ion-textarea-ios{overflow:hidden}.textarea-wrapper.sc-ion-textarea-ios{-webkit-padding-start:var(--padding-start);padding-inline-start:var(--padding-start);-webkit-padding-end:var(--padding-end);padding-inline-end:var(--padding-end);padding-top:0px;padding-bottom:0px;border-radius:var(--border-radius);display:-ms-flexbox;display:flex;position:relative;-ms-flex-positive:1;flex-grow:1;-ms-flex-align:start;align-items:flex-start;height:inherit;min-height:inherit;-webkit-transition:background-color 15ms linear;transition:background-color 15ms linear;background:var(--background);line-height:normal}.native-wrapper.sc-ion-textarea-ios{position:relative;width:100%;height:100%}.has-focus.sc-ion-textarea-ios-h textarea.sc-ion-textarea-ios{caret-color:var(--highlight-color)}.native-wrapper.sc-ion-textarea-ios textarea.sc-ion-textarea-ios{-webkit-padding-start:0px;padding-inline-start:0px;-webkit-padding-end:0px;padding-inline-end:0px;padding-top:var(--padding-top);padding-bottom:var(--padding-bottom)}.native-wrapper.sc-ion-textarea-ios{display:grid;min-width:inherit;max-width:inherit;min-height:inherit;max-height:inherit;grid-auto-rows:100%}.native-wrapper.sc-ion-textarea-ios::after{white-space:pre-wrap;content:attr(data-replicated-value) \" \";visibility:hidden}.native-wrapper.sc-ion-textarea-ios::after{padding-left:0;padding-right:0;padding-top:var(--padding-top);padding-bottom:var(--padding-bottom);margin-left:0;margin-right:0;margin-top:0;margin-bottom:0;border-radius:var(--border-radius);color:inherit;font-family:inherit;font-size:inherit;font-style:inherit;font-weight:inherit;letter-spacing:inherit;text-align:inherit;text-decoration:inherit;text-indent:inherit;text-overflow:inherit;text-transform:inherit;grid-area:1/1/2/2;word-break:break-word}.textarea-wrapper-inner.sc-ion-textarea-ios{display:-ms-flexbox;display:flex;width:100%;min-height:inherit}.ion-touched.ion-invalid.sc-ion-textarea-ios-h{--highlight-color:var(--highlight-color-invalid)}.ion-valid.sc-ion-textarea-ios-h{--highlight-color:var(--highlight-color-valid)}.textarea-bottom.sc-ion-textarea-ios{-webkit-padding-start:var(--padding-start);padding-inline-start:var(--padding-start);-webkit-padding-end:var(--padding-end);padding-inline-end:var(--padding-end);padding-top:5px;padding-bottom:0;display:-ms-flexbox;display:flex;-ms-flex-pack:justify;justify-content:space-between;border-top:var(--border-width) var(--border-style) var(--border-color);font-size:0.75rem;white-space:normal}.has-focus.ion-valid.sc-ion-textarea-ios-h,.ion-touched.ion-invalid.sc-ion-textarea-ios-h{--border-color:var(--highlight-color)}.textarea-bottom.sc-ion-textarea-ios .error-text.sc-ion-textarea-ios{display:none;color:var(--highlight-color-invalid)}.textarea-bottom.sc-ion-textarea-ios .helper-text.sc-ion-textarea-ios{display:block;color:var(--ion-color-step-700, var(--ion-text-color-step-300, #4d4d4d))}.ion-touched.ion-invalid.sc-ion-textarea-ios-h .textarea-bottom.sc-ion-textarea-ios .error-text.sc-ion-textarea-ios{display:block}.ion-touched.ion-invalid.sc-ion-textarea-ios-h .textarea-bottom.sc-ion-textarea-ios .helper-text.sc-ion-textarea-ios{display:none}.textarea-bottom.sc-ion-textarea-ios .counter.sc-ion-textarea-ios{-webkit-margin-start:auto;margin-inline-start:auto;color:var(--ion-color-step-700, var(--ion-text-color-step-300, #4d4d4d));white-space:nowrap;-webkit-padding-start:16px;padding-inline-start:16px}.label-text-wrapper.sc-ion-textarea-ios{-webkit-padding-start:0px;padding-inline-start:0px;-webkit-padding-end:0px;padding-inline-end:0px;padding-top:var(--padding-top);padding-bottom:var(--padding-bottom);max-width:200px;-webkit-transition:color 150ms cubic-bezier(0.4, 0, 0.2, 1), -webkit-transform 150ms cubic-bezier(0.4, 0, 0.2, 1);transition:color 150ms cubic-bezier(0.4, 0, 0.2, 1), -webkit-transform 150ms cubic-bezier(0.4, 0, 0.2, 1);transition:color 150ms cubic-bezier(0.4, 0, 0.2, 1), transform 150ms cubic-bezier(0.4, 0, 0.2, 1);transition:color 150ms cubic-bezier(0.4, 0, 0.2, 1), transform 150ms cubic-bezier(0.4, 0, 0.2, 1), -webkit-transform 150ms cubic-bezier(0.4, 0, 0.2, 1);pointer-events:none}.label-text.sc-ion-textarea-ios,.sc-ion-textarea-ios-s>[slot=label]{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.label-text-wrapper-hidden.sc-ion-textarea-ios,.textarea-outline-notch-hidden.sc-ion-textarea-ios{display:none}.textarea-wrapper.sc-ion-textarea-ios textarea.sc-ion-textarea-ios{-webkit-transition:opacity 150ms cubic-bezier(0.4, 0, 0.2, 1);transition:opacity 150ms cubic-bezier(0.4, 0, 0.2, 1)}.textarea-label-placement-start.sc-ion-textarea-ios-h .textarea-wrapper.sc-ion-textarea-ios{-ms-flex-direction:row;flex-direction:row}.textarea-label-placement-start.sc-ion-textarea-ios-h .label-text-wrapper.sc-ion-textarea-ios{-webkit-margin-start:0;margin-inline-start:0;-webkit-margin-end:16px;margin-inline-end:16px;margin-top:0;margin-bottom:0}.textarea-label-placement-end.sc-ion-textarea-ios-h .textarea-wrapper.sc-ion-textarea-ios{-ms-flex-direction:row-reverse;flex-direction:row-reverse}.textarea-label-placement-end.sc-ion-textarea-ios-h .label-text-wrapper.sc-ion-textarea-ios{-webkit-margin-start:16px;margin-inline-start:16px;-webkit-margin-end:0;margin-inline-end:0;margin-top:0;margin-bottom:0}.textarea-label-placement-fixed.sc-ion-textarea-ios-h .label-text-wrapper.sc-ion-textarea-ios{-webkit-margin-start:0;margin-inline-start:0;-webkit-margin-end:16px;margin-inline-end:16px;margin-top:0;margin-bottom:0}.textarea-label-placement-fixed.sc-ion-textarea-ios-h .label-text.sc-ion-textarea-ios{-ms-flex:0 0 100px;flex:0 0 100px;width:100px;min-width:100px;max-width:200px}.textarea-label-placement-stacked.sc-ion-textarea-ios-h .textarea-wrapper.sc-ion-textarea-ios,.textarea-label-placement-floating.sc-ion-textarea-ios-h .textarea-wrapper.sc-ion-textarea-ios{-ms-flex-direction:column;flex-direction:column;-ms-flex-align:start;align-items:start}.textarea-label-placement-stacked.sc-ion-textarea-ios-h .label-text-wrapper.sc-ion-textarea-ios,.textarea-label-placement-floating.sc-ion-textarea-ios-h .label-text-wrapper.sc-ion-textarea-ios{-webkit-transform-origin:left top;transform-origin:left top;-webkit-padding-start:0px;padding-inline-start:0px;-webkit-padding-end:0px;padding-inline-end:0px;padding-top:0px;padding-bottom:0px;max-width:100%;z-index:2}[dir=rtl].sc-ion-textarea-ios-h -no-combinator.textarea-label-placement-stacked.sc-ion-textarea-ios-h .label-text-wrapper.sc-ion-textarea-ios,[dir=rtl] .sc-ion-textarea-ios-h -no-combinator.textarea-label-placement-stacked.sc-ion-textarea-ios-h .label-text-wrapper.sc-ion-textarea-ios,[dir=rtl].textarea-label-placement-stacked.sc-ion-textarea-ios-h .label-text-wrapper.sc-ion-textarea-ios,[dir=rtl] .textarea-label-placement-stacked.sc-ion-textarea-ios-h .label-text-wrapper.sc-ion-textarea-ios,[dir=rtl].sc-ion-textarea-ios-h -no-combinator.textarea-label-placement-floating.sc-ion-textarea-ios-h .label-text-wrapper.sc-ion-textarea-ios,[dir=rtl] .sc-ion-textarea-ios-h -no-combinator.textarea-label-placement-floating.sc-ion-textarea-ios-h .label-text-wrapper.sc-ion-textarea-ios,[dir=rtl].textarea-label-placement-floating.sc-ion-textarea-ios-h .label-text-wrapper.sc-ion-textarea-ios,[dir=rtl] .textarea-label-placement-floating.sc-ion-textarea-ios-h .label-text-wrapper.sc-ion-textarea-ios{-webkit-transform-origin:right top;transform-origin:right top}@supports selector(:dir(rtl)){.textarea-label-placement-stacked.sc-ion-textarea-ios-h:dir(rtl) .label-text-wrapper.sc-ion-textarea-ios,.textarea-label-placement-floating.sc-ion-textarea-ios-h:dir(rtl) .label-text-wrapper.sc-ion-textarea-ios{-webkit-transform-origin:right top;transform-origin:right top}}.textarea-label-placement-stacked.sc-ion-textarea-ios-h textarea.sc-ion-textarea-ios,.textarea-label-placement-floating.sc-ion-textarea-ios-h textarea.sc-ion-textarea-ios,.textarea-label-placement-stacked[auto-grow].sc-ion-textarea-ios-h .native-wrapper.sc-ion-textarea-ios::after,.textarea-label-placement-floating[auto-grow].sc-ion-textarea-ios-h .native-wrapper.sc-ion-textarea-ios::after{-webkit-margin-start:0px;margin-inline-start:0px;-webkit-margin-end:0px;margin-inline-end:0px;margin-top:8px;margin-bottom:0px}.sc-ion-textarea-ios-h.textarea-label-placement-stacked.sc-ion-textarea-ios-s>[slot=start],.sc-ion-textarea-ios-h.textarea-label-placement-stacked .sc-ion-textarea-ios-s>[slot=start],.sc-ion-textarea-ios-h.textarea-label-placement-stacked.sc-ion-textarea-ios-s>[slot=end],.sc-ion-textarea-ios-h.textarea-label-placement-stacked .sc-ion-textarea-ios-s>[slot=end],.sc-ion-textarea-ios-h.textarea-label-placement-floating.sc-ion-textarea-ios-s>[slot=start],.sc-ion-textarea-ios-h.textarea-label-placement-floating .sc-ion-textarea-ios-s>[slot=start],.sc-ion-textarea-ios-h.textarea-label-placement-floating.sc-ion-textarea-ios-s>[slot=end],.sc-ion-textarea-ios-h.textarea-label-placement-floating .sc-ion-textarea-ios-s>[slot=end]{margin-top:8px}.textarea-label-placement-floating.sc-ion-textarea-ios-h .label-text-wrapper.sc-ion-textarea-ios{-webkit-transform:translateY(100%) scale(1);transform:translateY(100%) scale(1)}.textarea-label-placement-floating.sc-ion-textarea-ios-h textarea.sc-ion-textarea-ios{opacity:0}.has-focus.textarea-label-placement-floating.sc-ion-textarea-ios-h textarea.sc-ion-textarea-ios,.has-value.textarea-label-placement-floating.sc-ion-textarea-ios-h textarea.sc-ion-textarea-ios{opacity:1}.label-floating.sc-ion-textarea-ios-h .label-text-wrapper.sc-ion-textarea-ios{-webkit-transform:translateY(50%) scale(0.75);transform:translateY(50%) scale(0.75);max-width:calc(100% / 0.75)}.start-slot-wrapper.sc-ion-textarea-ios,.end-slot-wrapper.sc-ion-textarea-ios{padding-left:0;padding-right:0;padding-top:var(--padding-top);padding-bottom:var(--padding-bottom);display:-ms-flexbox;display:flex;-ms-flex-negative:0;flex-shrink:0;-ms-flex-item-align:start;align-self:start}.sc-ion-textarea-ios-s>[slot=start],.sc-ion-textarea-ios-s>[slot=end]{margin-top:0}.sc-ion-textarea-ios-s>[slot=start]:last-of-type{-webkit-margin-end:16px;margin-inline-end:16px;-webkit-margin-start:0;margin-inline-start:0}.sc-ion-textarea-ios-s>[slot=end]:first-of-type{-webkit-margin-start:16px;margin-inline-start:16px;-webkit-margin-end:0;margin-inline-end:0}.sc-ion-textarea-ios-h{--border-width:0.55px;--border-color:var(--ion-item-border-color, var(--ion-border-color, var(--ion-color-step-250, var(--ion-background-color-step-250, #c8c7cc))));--padding-top:10px;--padding-end:0px;--padding-bottom:8px;--padding-start:0px;--highlight-height:0px;font-size:inherit}.textarea-disabled.sc-ion-textarea-ios-h{opacity:0.3}.sc-ion-textarea-ios-s>ion-button[slot=start].button-has-icon-only,.sc-ion-textarea-ios-s>ion-button[slot=end].button-has-icon-only{--border-radius:50%;--padding-start:0;--padding-end:0;--padding-top:0;--padding-bottom:0;aspect-ratio:1}";
  31345. var IonTextareaIosStyle0 = textareaIosCss;
  31346. const textareaMdCss = ".sc-ion-textarea-md-h{--background:initial;--color:initial;--placeholder-color:initial;--placeholder-font-style:initial;--placeholder-font-weight:initial;--placeholder-opacity:var(--ion-placeholder-opacity, 0.6);--padding-top:0;--padding-end:0;--padding-bottom:8px;--padding-start:0;--border-radius:0;--border-style:solid;--highlight-color-focused:var(--ion-color-primary, #0054e9);--highlight-color-valid:var(--ion-color-success, #2dd55b);--highlight-color-invalid:var(--ion-color-danger, #c5000f);--highlight-color:var(--highlight-color-focused);display:block;position:relative;width:100%;min-height:44px;color:var(--color);font-family:var(--ion-font-family, inherit);z-index:2;-webkit-box-sizing:border-box;box-sizing:border-box}.textarea-label-placement-floating.sc-ion-textarea-md-h,.textarea-label-placement-stacked.sc-ion-textarea-md-h{--padding-top:0px;min-height:56px}[cols].sc-ion-textarea-md-h:not([auto-grow]){width:-webkit-fit-content;width:-moz-fit-content;width:fit-content}.ion-color.sc-ion-textarea-md-h{--highlight-color-focused:var(--ion-color-base);background:initial}ion-item.sc-ion-textarea-md-h,ion-item .sc-ion-textarea-md-h{-ms-flex-item-align:baseline;align-self:baseline}ion-item[slot=start].sc-ion-textarea-md-h,ion-item [slot=start].sc-ion-textarea-md-h,ion-item[slot=end].sc-ion-textarea-md-h,ion-item [slot=end].sc-ion-textarea-md-h{width:auto}.native-textarea.sc-ion-textarea-md{margin-left:0;margin-right:0;margin-top:0;margin-bottom:0;padding-left:0;padding-right:0;padding-top:0;padding-bottom:0;display:block;position:relative;-ms-flex:1;flex:1;width:100%;max-width:100%;max-height:100%;border:0;outline:none;background:transparent;white-space:pre-wrap;z-index:1;-webkit-box-sizing:border-box;box-sizing:border-box;resize:none;-webkit-appearance:none;-moz-appearance:none;appearance:none}.native-textarea.sc-ion-textarea-md::-webkit-input-placeholder{padding-left:0;padding-right:0;padding-top:0;padding-bottom:0;color:var(--placeholder-color);font-family:inherit;font-style:var(--placeholder-font-style);font-weight:var(--placeholder-font-weight);opacity:var(--placeholder-opacity)}.native-textarea.sc-ion-textarea-md::-moz-placeholder{padding-left:0;padding-right:0;padding-top:0;padding-bottom:0;color:var(--placeholder-color);font-family:inherit;font-style:var(--placeholder-font-style);font-weight:var(--placeholder-font-weight);opacity:var(--placeholder-opacity)}.native-textarea.sc-ion-textarea-md:-ms-input-placeholder{padding-left:0;padding-right:0;padding-top:0;padding-bottom:0;color:var(--placeholder-color);font-family:inherit;font-style:var(--placeholder-font-style);font-weight:var(--placeholder-font-weight);opacity:var(--placeholder-opacity)}.native-textarea.sc-ion-textarea-md::-ms-input-placeholder{padding-left:0;padding-right:0;padding-top:0;padding-bottom:0;color:var(--placeholder-color);font-family:inherit;font-style:var(--placeholder-font-style);font-weight:var(--placeholder-font-weight);opacity:var(--placeholder-opacity)}.native-textarea.sc-ion-textarea-md::placeholder{padding-left:0;padding-right:0;padding-top:0;padding-bottom:0;color:var(--placeholder-color);font-family:inherit;font-style:var(--placeholder-font-style);font-weight:var(--placeholder-font-weight);opacity:var(--placeholder-opacity)}.native-textarea.sc-ion-textarea-md{color:inherit;font-family:inherit;font-size:inherit;font-style:inherit;font-weight:inherit;letter-spacing:inherit;text-align:inherit;text-decoration:inherit;text-indent:inherit;text-overflow:inherit;text-transform:inherit;grid-area:1/1/2/2;word-break:break-word}.cloned-input.sc-ion-textarea-md{top:0;bottom:0;position:absolute;pointer-events:none}.cloned-input.sc-ion-textarea-md{inset-inline-start:0}.cloned-input.sc-ion-textarea-md:disabled{opacity:1}[auto-grow].sc-ion-textarea-md-h .cloned-input.sc-ion-textarea-md{height:100%}[auto-grow].sc-ion-textarea-md-h .native-textarea.sc-ion-textarea-md{overflow:hidden}.textarea-wrapper.sc-ion-textarea-md{-webkit-padding-start:var(--padding-start);padding-inline-start:var(--padding-start);-webkit-padding-end:var(--padding-end);padding-inline-end:var(--padding-end);padding-top:0px;padding-bottom:0px;border-radius:var(--border-radius);display:-ms-flexbox;display:flex;position:relative;-ms-flex-positive:1;flex-grow:1;-ms-flex-align:start;align-items:flex-start;height:inherit;min-height:inherit;-webkit-transition:background-color 15ms linear;transition:background-color 15ms linear;background:var(--background);line-height:normal}.native-wrapper.sc-ion-textarea-md{position:relative;width:100%;height:100%}.has-focus.sc-ion-textarea-md-h textarea.sc-ion-textarea-md{caret-color:var(--highlight-color)}.native-wrapper.sc-ion-textarea-md textarea.sc-ion-textarea-md{-webkit-padding-start:0px;padding-inline-start:0px;-webkit-padding-end:0px;padding-inline-end:0px;padding-top:var(--padding-top);padding-bottom:var(--padding-bottom)}.native-wrapper.sc-ion-textarea-md{display:grid;min-width:inherit;max-width:inherit;min-height:inherit;max-height:inherit;grid-auto-rows:100%}.native-wrapper.sc-ion-textarea-md::after{white-space:pre-wrap;content:attr(data-replicated-value) \" \";visibility:hidden}.native-wrapper.sc-ion-textarea-md::after{padding-left:0;padding-right:0;padding-top:var(--padding-top);padding-bottom:var(--padding-bottom);margin-left:0;margin-right:0;margin-top:0;margin-bottom:0;border-radius:var(--border-radius);color:inherit;font-family:inherit;font-size:inherit;font-style:inherit;font-weight:inherit;letter-spacing:inherit;text-align:inherit;text-decoration:inherit;text-indent:inherit;text-overflow:inherit;text-transform:inherit;grid-area:1/1/2/2;word-break:break-word}.textarea-wrapper-inner.sc-ion-textarea-md{display:-ms-flexbox;display:flex;width:100%;min-height:inherit}.ion-touched.ion-invalid.sc-ion-textarea-md-h{--highlight-color:var(--highlight-color-invalid)}.ion-valid.sc-ion-textarea-md-h{--highlight-color:var(--highlight-color-valid)}.textarea-bottom.sc-ion-textarea-md{-webkit-padding-start:var(--padding-start);padding-inline-start:var(--padding-start);-webkit-padding-end:var(--padding-end);padding-inline-end:var(--padding-end);padding-top:5px;padding-bottom:0;display:-ms-flexbox;display:flex;-ms-flex-pack:justify;justify-content:space-between;border-top:var(--border-width) var(--border-style) var(--border-color);font-size:0.75rem;white-space:normal}.has-focus.ion-valid.sc-ion-textarea-md-h,.ion-touched.ion-invalid.sc-ion-textarea-md-h{--border-color:var(--highlight-color)}.textarea-bottom.sc-ion-textarea-md .error-text.sc-ion-textarea-md{display:none;color:var(--highlight-color-invalid)}.textarea-bottom.sc-ion-textarea-md .helper-text.sc-ion-textarea-md{display:block;color:var(--ion-color-step-700, var(--ion-text-color-step-300, #4d4d4d))}.ion-touched.ion-invalid.sc-ion-textarea-md-h .textarea-bottom.sc-ion-textarea-md .error-text.sc-ion-textarea-md{display:block}.ion-touched.ion-invalid.sc-ion-textarea-md-h .textarea-bottom.sc-ion-textarea-md .helper-text.sc-ion-textarea-md{display:none}.textarea-bottom.sc-ion-textarea-md .counter.sc-ion-textarea-md{-webkit-margin-start:auto;margin-inline-start:auto;color:var(--ion-color-step-700, var(--ion-text-color-step-300, #4d4d4d));white-space:nowrap;-webkit-padding-start:16px;padding-inline-start:16px}.label-text-wrapper.sc-ion-textarea-md{-webkit-padding-start:0px;padding-inline-start:0px;-webkit-padding-end:0px;padding-inline-end:0px;padding-top:var(--padding-top);padding-bottom:var(--padding-bottom);max-width:200px;-webkit-transition:color 150ms cubic-bezier(0.4, 0, 0.2, 1), -webkit-transform 150ms cubic-bezier(0.4, 0, 0.2, 1);transition:color 150ms cubic-bezier(0.4, 0, 0.2, 1), -webkit-transform 150ms cubic-bezier(0.4, 0, 0.2, 1);transition:color 150ms cubic-bezier(0.4, 0, 0.2, 1), transform 150ms cubic-bezier(0.4, 0, 0.2, 1);transition:color 150ms cubic-bezier(0.4, 0, 0.2, 1), transform 150ms cubic-bezier(0.4, 0, 0.2, 1), -webkit-transform 150ms cubic-bezier(0.4, 0, 0.2, 1);pointer-events:none}.label-text.sc-ion-textarea-md,.sc-ion-textarea-md-s>[slot=label]{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.label-text-wrapper-hidden.sc-ion-textarea-md,.textarea-outline-notch-hidden.sc-ion-textarea-md{display:none}.textarea-wrapper.sc-ion-textarea-md textarea.sc-ion-textarea-md{-webkit-transition:opacity 150ms cubic-bezier(0.4, 0, 0.2, 1);transition:opacity 150ms cubic-bezier(0.4, 0, 0.2, 1)}.textarea-label-placement-start.sc-ion-textarea-md-h .textarea-wrapper.sc-ion-textarea-md{-ms-flex-direction:row;flex-direction:row}.textarea-label-placement-start.sc-ion-textarea-md-h .label-text-wrapper.sc-ion-textarea-md{-webkit-margin-start:0;margin-inline-start:0;-webkit-margin-end:16px;margin-inline-end:16px;margin-top:0;margin-bottom:0}.textarea-label-placement-end.sc-ion-textarea-md-h .textarea-wrapper.sc-ion-textarea-md{-ms-flex-direction:row-reverse;flex-direction:row-reverse}.textarea-label-placement-end.sc-ion-textarea-md-h .label-text-wrapper.sc-ion-textarea-md{-webkit-margin-start:16px;margin-inline-start:16px;-webkit-margin-end:0;margin-inline-end:0;margin-top:0;margin-bottom:0}.textarea-label-placement-fixed.sc-ion-textarea-md-h .label-text-wrapper.sc-ion-textarea-md{-webkit-margin-start:0;margin-inline-start:0;-webkit-margin-end:16px;margin-inline-end:16px;margin-top:0;margin-bottom:0}.textarea-label-placement-fixed.sc-ion-textarea-md-h .label-text.sc-ion-textarea-md{-ms-flex:0 0 100px;flex:0 0 100px;width:100px;min-width:100px;max-width:200px}.textarea-label-placement-stacked.sc-ion-textarea-md-h .textarea-wrapper.sc-ion-textarea-md,.textarea-label-placement-floating.sc-ion-textarea-md-h .textarea-wrapper.sc-ion-textarea-md{-ms-flex-direction:column;flex-direction:column;-ms-flex-align:start;align-items:start}.textarea-label-placement-stacked.sc-ion-textarea-md-h .label-text-wrapper.sc-ion-textarea-md,.textarea-label-placement-floating.sc-ion-textarea-md-h .label-text-wrapper.sc-ion-textarea-md{-webkit-transform-origin:left top;transform-origin:left top;-webkit-padding-start:0px;padding-inline-start:0px;-webkit-padding-end:0px;padding-inline-end:0px;padding-top:0px;padding-bottom:0px;max-width:100%;z-index:2}[dir=rtl].sc-ion-textarea-md-h -no-combinator.textarea-label-placement-stacked.sc-ion-textarea-md-h .label-text-wrapper.sc-ion-textarea-md,[dir=rtl] .sc-ion-textarea-md-h -no-combinator.textarea-label-placement-stacked.sc-ion-textarea-md-h .label-text-wrapper.sc-ion-textarea-md,[dir=rtl].textarea-label-placement-stacked.sc-ion-textarea-md-h .label-text-wrapper.sc-ion-textarea-md,[dir=rtl] .textarea-label-placement-stacked.sc-ion-textarea-md-h .label-text-wrapper.sc-ion-textarea-md,[dir=rtl].sc-ion-textarea-md-h -no-combinator.textarea-label-placement-floating.sc-ion-textarea-md-h .label-text-wrapper.sc-ion-textarea-md,[dir=rtl] .sc-ion-textarea-md-h -no-combinator.textarea-label-placement-floating.sc-ion-textarea-md-h .label-text-wrapper.sc-ion-textarea-md,[dir=rtl].textarea-label-placement-floating.sc-ion-textarea-md-h .label-text-wrapper.sc-ion-textarea-md,[dir=rtl] .textarea-label-placement-floating.sc-ion-textarea-md-h .label-text-wrapper.sc-ion-textarea-md{-webkit-transform-origin:right top;transform-origin:right top}@supports selector(:dir(rtl)){.textarea-label-placement-stacked.sc-ion-textarea-md-h:dir(rtl) .label-text-wrapper.sc-ion-textarea-md,.textarea-label-placement-floating.sc-ion-textarea-md-h:dir(rtl) .label-text-wrapper.sc-ion-textarea-md{-webkit-transform-origin:right top;transform-origin:right top}}.textarea-label-placement-stacked.sc-ion-textarea-md-h textarea.sc-ion-textarea-md,.textarea-label-placement-floating.sc-ion-textarea-md-h textarea.sc-ion-textarea-md,.textarea-label-placement-stacked[auto-grow].sc-ion-textarea-md-h .native-wrapper.sc-ion-textarea-md::after,.textarea-label-placement-floating[auto-grow].sc-ion-textarea-md-h .native-wrapper.sc-ion-textarea-md::after{-webkit-margin-start:0px;margin-inline-start:0px;-webkit-margin-end:0px;margin-inline-end:0px;margin-top:8px;margin-bottom:0px}.sc-ion-textarea-md-h.textarea-label-placement-stacked.sc-ion-textarea-md-s>[slot=start],.sc-ion-textarea-md-h.textarea-label-placement-stacked .sc-ion-textarea-md-s>[slot=start],.sc-ion-textarea-md-h.textarea-label-placement-stacked.sc-ion-textarea-md-s>[slot=end],.sc-ion-textarea-md-h.textarea-label-placement-stacked .sc-ion-textarea-md-s>[slot=end],.sc-ion-textarea-md-h.textarea-label-placement-floating.sc-ion-textarea-md-s>[slot=start],.sc-ion-textarea-md-h.textarea-label-placement-floating .sc-ion-textarea-md-s>[slot=start],.sc-ion-textarea-md-h.textarea-label-placement-floating.sc-ion-textarea-md-s>[slot=end],.sc-ion-textarea-md-h.textarea-label-placement-floating .sc-ion-textarea-md-s>[slot=end]{margin-top:8px}.textarea-label-placement-floating.sc-ion-textarea-md-h .label-text-wrapper.sc-ion-textarea-md{-webkit-transform:translateY(100%) scale(1);transform:translateY(100%) scale(1)}.textarea-label-placement-floating.sc-ion-textarea-md-h textarea.sc-ion-textarea-md{opacity:0}.has-focus.textarea-label-placement-floating.sc-ion-textarea-md-h textarea.sc-ion-textarea-md,.has-value.textarea-label-placement-floating.sc-ion-textarea-md-h textarea.sc-ion-textarea-md{opacity:1}.label-floating.sc-ion-textarea-md-h .label-text-wrapper.sc-ion-textarea-md{-webkit-transform:translateY(50%) scale(0.75);transform:translateY(50%) scale(0.75);max-width:calc(100% / 0.75)}.start-slot-wrapper.sc-ion-textarea-md,.end-slot-wrapper.sc-ion-textarea-md{padding-left:0;padding-right:0;padding-top:var(--padding-top);padding-bottom:var(--padding-bottom);display:-ms-flexbox;display:flex;-ms-flex-negative:0;flex-shrink:0;-ms-flex-item-align:start;align-self:start}.sc-ion-textarea-md-s>[slot=start],.sc-ion-textarea-md-s>[slot=end]{margin-top:0}.sc-ion-textarea-md-s>[slot=start]:last-of-type{-webkit-margin-end:16px;margin-inline-end:16px;-webkit-margin-start:0;margin-inline-start:0}.sc-ion-textarea-md-s>[slot=end]:first-of-type{-webkit-margin-start:16px;margin-inline-start:16px;-webkit-margin-end:0;margin-inline-end:0}.textarea-fill-solid.sc-ion-textarea-md-h{--background:var(--ion-color-step-50, var(--ion-background-color-step-50, #f2f2f2));--border-color:var(--ion-color-step-500, var(--ion-background-color-step-500, gray));--border-radius:4px;--padding-start:16px;--padding-end:16px;min-height:56px}.textarea-fill-solid.sc-ion-textarea-md-h .textarea-wrapper.sc-ion-textarea-md{border-bottom:var(--border-width) var(--border-style) var(--border-color)}.has-focus.textarea-fill-solid.ion-valid.sc-ion-textarea-md-h,.textarea-fill-solid.ion-touched.ion-invalid.sc-ion-textarea-md-h{--border-color:var(--highlight-color)}.textarea-fill-solid.sc-ion-textarea-md-h .textarea-bottom.sc-ion-textarea-md{border-top:none}@media (any-hover: hover){.textarea-fill-solid.sc-ion-textarea-md-h:hover{--background:var(--ion-color-step-100, var(--ion-background-color-step-100, #e6e6e6));--border-color:var(--ion-color-step-750, var(--ion-background-color-step-750, #404040))}}.textarea-fill-solid.has-focus.sc-ion-textarea-md-h{--background:var(--ion-color-step-150, var(--ion-background-color-step-150, #d9d9d9));--border-color:var(--ion-color-step-750, var(--ion-background-color-step-750, #404040))}.textarea-fill-solid.sc-ion-textarea-md-h .textarea-wrapper.sc-ion-textarea-md{border-start-start-radius:var(--border-radius);border-start-end-radius:var(--border-radius);border-end-end-radius:0px;border-end-start-radius:0px}.label-floating.textarea-fill-solid.sc-ion-textarea-md-h .label-text-wrapper.sc-ion-textarea-md{max-width:calc(100% / 0.75)}.textarea-fill-outline.sc-ion-textarea-md-h{--border-color:var(--ion-color-step-300, var(--ion-background-color-step-300, #b3b3b3));--border-radius:4px;--padding-start:16px;--padding-end:16px;min-height:56px}.textarea-fill-outline.textarea-shape-round.sc-ion-textarea-md-h{--border-radius:28px;--padding-start:32px;--padding-end:32px}.has-focus.textarea-fill-outline.ion-valid.sc-ion-textarea-md-h,.textarea-fill-outline.ion-touched.ion-invalid.sc-ion-textarea-md-h{--border-color:var(--highlight-color)}@media (any-hover: hover){.textarea-fill-outline.sc-ion-textarea-md-h:hover{--border-color:var(--ion-color-step-750, var(--ion-background-color-step-750, #404040))}}.textarea-fill-outline.has-focus.sc-ion-textarea-md-h{--border-width:var(--highlight-height);--border-color:var(--highlight-color)}.textarea-fill-outline.sc-ion-textarea-md-h .textarea-bottom.sc-ion-textarea-md{border-top:none}.textarea-fill-outline.sc-ion-textarea-md-h .textarea-wrapper.sc-ion-textarea-md{border-bottom:none}.textarea-fill-outline.textarea-label-placement-stacked.sc-ion-textarea-md-h .label-text-wrapper.sc-ion-textarea-md,.textarea-fill-outline.textarea-label-placement-floating.sc-ion-textarea-md-h .label-text-wrapper.sc-ion-textarea-md{-webkit-transform-origin:left top;transform-origin:left top;position:absolute;max-width:calc(100% - var(--padding-start) - var(--padding-end))}[dir=rtl].sc-ion-textarea-md-h -no-combinator.textarea-fill-outline.textarea-label-placement-stacked.sc-ion-textarea-md-h .label-text-wrapper.sc-ion-textarea-md,[dir=rtl] .sc-ion-textarea-md-h -no-combinator.textarea-fill-outline.textarea-label-placement-stacked.sc-ion-textarea-md-h .label-text-wrapper.sc-ion-textarea-md,[dir=rtl].textarea-fill-outline.textarea-label-placement-stacked.sc-ion-textarea-md-h .label-text-wrapper.sc-ion-textarea-md,[dir=rtl] .textarea-fill-outline.textarea-label-placement-stacked.sc-ion-textarea-md-h .label-text-wrapper.sc-ion-textarea-md,[dir=rtl].sc-ion-textarea-md-h -no-combinator.textarea-fill-outline.textarea-label-placement-floating.sc-ion-textarea-md-h .label-text-wrapper.sc-ion-textarea-md,[dir=rtl] .sc-ion-textarea-md-h -no-combinator.textarea-fill-outline.textarea-label-placement-floating.sc-ion-textarea-md-h .label-text-wrapper.sc-ion-textarea-md,[dir=rtl].textarea-fill-outline.textarea-label-placement-floating.sc-ion-textarea-md-h .label-text-wrapper.sc-ion-textarea-md,[dir=rtl] .textarea-fill-outline.textarea-label-placement-floating.sc-ion-textarea-md-h .label-text-wrapper.sc-ion-textarea-md{-webkit-transform-origin:right top;transform-origin:right top}@supports selector(:dir(rtl)){.textarea-fill-outline.textarea-label-placement-stacked.sc-ion-textarea-md-h:dir(rtl) .label-text-wrapper.sc-ion-textarea-md,.textarea-fill-outline.textarea-label-placement-floating.sc-ion-textarea-md-h:dir(rtl) .label-text-wrapper.sc-ion-textarea-md{-webkit-transform-origin:right top;transform-origin:right top}}.textarea-fill-outline.sc-ion-textarea-md-h .label-text-wrapper.sc-ion-textarea-md{position:relative}.label-floating.textarea-fill-outline.sc-ion-textarea-md-h .label-text-wrapper.sc-ion-textarea-md{-webkit-transform:translateY(-32%) scale(0.75);transform:translateY(-32%) scale(0.75);margin-left:0;margin-right:0;margin-top:0;margin-bottom:0;max-width:calc(\n (100% - var(--padding-start) - var(--padding-end) - 8px) / 0.75\n )}.textarea-fill-outline.textarea-label-placement-stacked.sc-ion-textarea-md-h textarea.sc-ion-textarea-md,.textarea-fill-outline.textarea-label-placement-floating.sc-ion-textarea-md-h textarea.sc-ion-textarea-md,.textarea-fill-outline.textarea-label-placement-stacked[auto-grow].sc-ion-textarea-md-h .native-wrapper.sc-ion-textarea-md::after,.textarea-fill-outline.textarea-label-placement-floating[auto-grow].sc-ion-textarea-md-h .native-wrapper.sc-ion-textarea-md::after{-webkit-margin-start:0px;margin-inline-start:0px;-webkit-margin-end:0px;margin-inline-end:0px;margin-top:12px;margin-bottom:0px}.sc-ion-textarea-md-h.textarea-fill-outline.textarea-label-placement-stacked.sc-ion-textarea-md-s>[slot=start],.sc-ion-textarea-md-h.textarea-fill-outline.textarea-label-placement-stacked .sc-ion-textarea-md-s>[slot=start],.sc-ion-textarea-md-h.textarea-fill-outline.textarea-label-placement-stacked.sc-ion-textarea-md-s>[slot=end],.sc-ion-textarea-md-h.textarea-fill-outline.textarea-label-placement-stacked .sc-ion-textarea-md-s>[slot=end],.sc-ion-textarea-md-h.textarea-fill-outline.textarea-label-placement-floating.sc-ion-textarea-md-s>[slot=start],.sc-ion-textarea-md-h.textarea-fill-outline.textarea-label-placement-floating .sc-ion-textarea-md-s>[slot=start],.sc-ion-textarea-md-h.textarea-fill-outline.textarea-label-placement-floating.sc-ion-textarea-md-s>[slot=end],.sc-ion-textarea-md-h.textarea-fill-outline.textarea-label-placement-floating .sc-ion-textarea-md-s>[slot=end]{margin-top:12px}.textarea-fill-outline.sc-ion-textarea-md-h .textarea-outline-container.sc-ion-textarea-md{left:0;right:0;top:0;bottom:0;display:-ms-flexbox;display:flex;position:absolute;width:100%;height:100%}.textarea-fill-outline.sc-ion-textarea-md-h .textarea-outline-start.sc-ion-textarea-md,.textarea-fill-outline.sc-ion-textarea-md-h .textarea-outline-end.sc-ion-textarea-md{pointer-events:none}.textarea-fill-outline.sc-ion-textarea-md-h .textarea-outline-start.sc-ion-textarea-md,.textarea-fill-outline.sc-ion-textarea-md-h .textarea-outline-notch.sc-ion-textarea-md,.textarea-fill-outline.sc-ion-textarea-md-h .textarea-outline-end.sc-ion-textarea-md{border-top:var(--border-width) var(--border-style) var(--border-color);border-bottom:var(--border-width) var(--border-style) var(--border-color)}.textarea-fill-outline.sc-ion-textarea-md-h .textarea-outline-notch.sc-ion-textarea-md{max-width:calc(100% - var(--padding-start) - var(--padding-end))}.textarea-fill-outline.sc-ion-textarea-md-h .notch-spacer.sc-ion-textarea-md{-webkit-padding-end:8px;padding-inline-end:8px;font-size:calc(1em * 0.75);opacity:0;pointer-events:none;-webkit-box-sizing:content-box;box-sizing:content-box}.textarea-fill-outline.sc-ion-textarea-md-h .textarea-outline-start.sc-ion-textarea-md{border-start-start-radius:var(--border-radius);border-start-end-radius:0px;border-end-end-radius:0px;border-end-start-radius:var(--border-radius);-webkit-border-start:var(--border-width) var(--border-style) var(--border-color);border-inline-start:var(--border-width) var(--border-style) var(--border-color);width:calc(var(--padding-start) - 4px)}.textarea-fill-outline.sc-ion-textarea-md-h .textarea-outline-end.sc-ion-textarea-md{-webkit-border-end:var(--border-width) var(--border-style) var(--border-color);border-inline-end:var(--border-width) var(--border-style) var(--border-color);border-start-start-radius:0px;border-start-end-radius:var(--border-radius);border-end-end-radius:var(--border-radius);border-end-start-radius:0px;-ms-flex-positive:1;flex-grow:1}.label-floating.textarea-fill-outline.sc-ion-textarea-md-h .textarea-outline-notch.sc-ion-textarea-md{border-top:none}.sc-ion-textarea-md-h{--border-width:1px;--border-color:var(--ion-item-border-color, var(--ion-border-color, var(--ion-color-step-150, var(--ion-background-color-step-150, rgba(0, 0, 0, 0.13)))));--padding-top:18px;--padding-end:0px;--padding-bottom:8px;--padding-start:0px;--highlight-height:2px;font-size:inherit}.textarea-bottom.sc-ion-textarea-md .counter.sc-ion-textarea-md{letter-spacing:0.0333333333em}.textarea-label-placement-floating.has-focus.sc-ion-textarea-md-h .label-text-wrapper.sc-ion-textarea-md,.textarea-label-placement-stacked.has-focus.sc-ion-textarea-md-h .label-text-wrapper.sc-ion-textarea-md{color:var(--highlight-color)}.has-focus.textarea-label-placement-floating.ion-valid.sc-ion-textarea-md-h .label-text-wrapper.sc-ion-textarea-md,.textarea-label-placement-floating.ion-touched.ion-invalid.sc-ion-textarea-md-h .label-text-wrapper.sc-ion-textarea-md,.has-focus.textarea-label-placement-stacked.ion-valid.sc-ion-textarea-md-h .label-text-wrapper.sc-ion-textarea-md,.textarea-label-placement-stacked.ion-touched.ion-invalid.sc-ion-textarea-md-h .label-text-wrapper.sc-ion-textarea-md{color:var(--highlight-color)}.textarea-disabled.sc-ion-textarea-md-h{opacity:0.38}.textarea-highlight.sc-ion-textarea-md{bottom:-1px;position:absolute;width:100%;height:var(--highlight-height);-webkit-transform:scale(0);transform:scale(0);-webkit-transition:-webkit-transform 200ms;transition:-webkit-transform 200ms;transition:transform 200ms;transition:transform 200ms, -webkit-transform 200ms;background:var(--highlight-color)}.textarea-highlight.sc-ion-textarea-md{inset-inline-start:0}.has-focus.sc-ion-textarea-md-h .textarea-highlight.sc-ion-textarea-md{-webkit-transform:scale(1);transform:scale(1)}.in-item.sc-ion-textarea-md-h .textarea-highlight.sc-ion-textarea-md{bottom:0}.in-item.sc-ion-textarea-md-h .textarea-highlight.sc-ion-textarea-md{inset-inline-start:0}.textarea-shape-round.sc-ion-textarea-md-h{--border-radius:16px}.sc-ion-textarea-md-s>ion-button[slot=start].button-has-icon-only,.sc-ion-textarea-md-s>ion-button[slot=end].button-has-icon-only{--border-radius:50%;--padding-start:8px;--padding-end:8px;--padding-top:8px;--padding-bottom:8px;aspect-ratio:1;min-height:40px}";
  31347. var IonTextareaMdStyle0 = textareaMdCss;
  31348. /**
  31349. * @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
  31350. *
  31351. * @slot label - The label text to associate with the textarea. Use the `labelPlacement` property to control where the label is placed relative to the textarea. Use this if you need to render a label with custom HTML. (EXPERIMENTAL)
  31352. * @slot start - Content to display at the leading edge of the textarea. (EXPERIMENTAL)
  31353. * @slot end - Content to display at the trailing edge of the textarea. (EXPERIMENTAL)
  31354. */
  31355. class Textarea {
  31356. constructor(hostRef) {
  31357. registerInstance(this, hostRef);
  31358. this.ionChange = createEvent(this, "ionChange", 7);
  31359. this.ionInput = createEvent(this, "ionInput", 7);
  31360. this.ionBlur = createEvent(this, "ionBlur", 7);
  31361. this.ionFocus = createEvent(this, "ionFocus", 7);
  31362. this.inputId = `ion-textarea-${textareaIds++}`;
  31363. this.helperTextId = `${this.inputId}-helper-text`;
  31364. this.errorTextId = `${this.inputId}-error-text`;
  31365. /**
  31366. * `true` if the textarea was cleared as a result of the user typing
  31367. * with `clearOnEdit` enabled.
  31368. *
  31369. * Resets when the textarea loses focus.
  31370. */
  31371. this.didTextareaClearOnEdit = false;
  31372. this.inheritedAttributes = {};
  31373. // `Event` type is used instead of `InputEvent`
  31374. // since the types from Stencil are not derived
  31375. // from the element (e.g. textarea and input
  31376. // should be InputEvent, but all other elements
  31377. // should be Event).
  31378. this.onInput = (ev) => {
  31379. const input = ev.target;
  31380. if (input) {
  31381. this.value = input.value || '';
  31382. }
  31383. this.emitInputChange(ev);
  31384. };
  31385. this.onChange = (ev) => {
  31386. this.emitValueChange(ev);
  31387. };
  31388. this.onFocus = (ev) => {
  31389. this.hasFocus = true;
  31390. this.focusedValue = this.value;
  31391. this.ionFocus.emit(ev);
  31392. };
  31393. this.onBlur = (ev) => {
  31394. this.hasFocus = false;
  31395. if (this.focusedValue !== this.value) {
  31396. /**
  31397. * Emits the `ionChange` event when the textarea value
  31398. * is different than the value when the textarea was focused.
  31399. */
  31400. this.emitValueChange(ev);
  31401. }
  31402. this.didTextareaClearOnEdit = false;
  31403. this.ionBlur.emit(ev);
  31404. };
  31405. this.onKeyDown = (ev) => {
  31406. this.checkClearOnEdit(ev);
  31407. };
  31408. /**
  31409. * Stops propagation when the label is clicked,
  31410. * otherwise, two clicks will be triggered.
  31411. */
  31412. this.onLabelClick = (ev) => {
  31413. // Only stop propagation if the click was directly on the label
  31414. // and not on the input or other child elements
  31415. if (ev.target === ev.currentTarget) {
  31416. ev.stopPropagation();
  31417. }
  31418. };
  31419. this.hasFocus = false;
  31420. this.color = undefined;
  31421. this.autocapitalize = 'none';
  31422. this.autofocus = false;
  31423. this.clearOnEdit = false;
  31424. this.debounce = undefined;
  31425. this.disabled = false;
  31426. this.fill = undefined;
  31427. this.inputmode = undefined;
  31428. this.enterkeyhint = undefined;
  31429. this.maxlength = undefined;
  31430. this.minlength = undefined;
  31431. this.name = this.inputId;
  31432. this.placeholder = undefined;
  31433. this.readonly = false;
  31434. this.required = false;
  31435. this.spellcheck = false;
  31436. this.cols = undefined;
  31437. this.rows = undefined;
  31438. this.wrap = undefined;
  31439. this.autoGrow = false;
  31440. this.value = '';
  31441. this.counter = false;
  31442. this.counterFormatter = undefined;
  31443. this.errorText = undefined;
  31444. this.helperText = undefined;
  31445. this.label = undefined;
  31446. this.labelPlacement = 'start';
  31447. this.shape = undefined;
  31448. }
  31449. debounceChanged() {
  31450. const { ionInput, debounce, originalIonInput } = this;
  31451. /**
  31452. * If debounce is undefined, we have to manually revert the ionInput emitter in case
  31453. * debounce used to be set to a number. Otherwise, the event would stay debounced.
  31454. */
  31455. this.ionInput = debounce === undefined ? originalIonInput !== null && originalIonInput !== void 0 ? originalIonInput : ionInput : debounceEvent(ionInput, debounce);
  31456. }
  31457. /**
  31458. * Update the native input element when the value changes
  31459. */
  31460. valueChanged() {
  31461. const nativeInput = this.nativeInput;
  31462. const value = this.getValue();
  31463. if (nativeInput && nativeInput.value !== value) {
  31464. nativeInput.value = value;
  31465. }
  31466. this.runAutoGrow();
  31467. }
  31468. /**
  31469. * dir is a globally enumerated attribute.
  31470. * As a result, creating these as properties
  31471. * can have unintended side effects. Instead, we
  31472. * listen for attribute changes and inherit them
  31473. * to the inner `<textarea>` element.
  31474. */
  31475. onDirChanged(newValue) {
  31476. this.inheritedAttributes = Object.assign(Object.assign({}, this.inheritedAttributes), { dir: newValue });
  31477. }
  31478. /**
  31479. * This prevents the native input from emitting the click event.
  31480. * Instead, the click event from the ion-textarea is emitted.
  31481. */
  31482. onClickCapture(ev) {
  31483. const nativeInput = this.nativeInput;
  31484. if (nativeInput && ev.target === nativeInput) {
  31485. ev.stopPropagation();
  31486. this.el.click();
  31487. }
  31488. }
  31489. connectedCallback() {
  31490. const { el } = this;
  31491. this.slotMutationController = createSlotMutationController(el, ['label', 'start', 'end'], () => forceUpdate());
  31492. this.notchController = createNotchController(el, () => this.notchSpacerEl, () => this.labelSlot);
  31493. this.debounceChanged();
  31494. }
  31495. disconnectedCallback() {
  31496. if (this.slotMutationController) {
  31497. this.slotMutationController.destroy();
  31498. this.slotMutationController = undefined;
  31499. }
  31500. if (this.notchController) {
  31501. this.notchController.destroy();
  31502. this.notchController = undefined;
  31503. }
  31504. }
  31505. componentWillLoad() {
  31506. this.inheritedAttributes = Object.assign(Object.assign({}, inheritAriaAttributes(this.el)), inheritAttributes$1(this.el, ['data-form-type', 'title', 'tabindex', 'dir']));
  31507. }
  31508. componentDidLoad() {
  31509. this.originalIonInput = this.ionInput;
  31510. this.runAutoGrow();
  31511. }
  31512. componentDidRender() {
  31513. var _a;
  31514. (_a = this.notchController) === null || _a === void 0 ? void 0 : _a.calculateNotchWidth();
  31515. }
  31516. /**
  31517. * Sets focus on the native `textarea` in `ion-textarea`. Use this method instead of the global
  31518. * `textarea.focus()`.
  31519. *
  31520. * See [managing focus](/docs/developing/managing-focus) for more information.
  31521. */
  31522. async setFocus() {
  31523. if (this.nativeInput) {
  31524. this.nativeInput.focus();
  31525. }
  31526. }
  31527. /**
  31528. * Returns the native `<textarea>` element used under the hood.
  31529. */
  31530. async getInputElement() {
  31531. /**
  31532. * If this gets called in certain early lifecycle hooks (ex: Vue onMounted),
  31533. * nativeInput won't be defined yet with the custom elements build, so wait for it to load in.
  31534. */
  31535. if (!this.nativeInput) {
  31536. await new Promise((resolve) => componentOnReady(this.el, resolve));
  31537. }
  31538. return Promise.resolve(this.nativeInput);
  31539. }
  31540. /**
  31541. * Emits an `ionChange` event.
  31542. *
  31543. * This API should be called for user committed changes.
  31544. * This API should not be used for external value changes.
  31545. */
  31546. emitValueChange(event) {
  31547. const { value } = this;
  31548. // Checks for both null and undefined values
  31549. const newValue = value == null ? value : value.toString();
  31550. // Emitting a value change should update the internal state for tracking the focused value
  31551. this.focusedValue = newValue;
  31552. this.ionChange.emit({ value: newValue, event });
  31553. }
  31554. /**
  31555. * Emits an `ionInput` event.
  31556. */
  31557. emitInputChange(event) {
  31558. const { value } = this;
  31559. this.ionInput.emit({ value, event });
  31560. }
  31561. runAutoGrow() {
  31562. if (this.nativeInput && this.autoGrow) {
  31563. writeTask(() => {
  31564. var _a;
  31565. if (this.textareaWrapper) {
  31566. // Replicated value is an attribute to be used in the stylesheet
  31567. // to set the inner contents of a pseudo element.
  31568. this.textareaWrapper.dataset.replicatedValue = (_a = this.value) !== null && _a !== void 0 ? _a : '';
  31569. }
  31570. });
  31571. }
  31572. }
  31573. /**
  31574. * Check if we need to clear the text input if clearOnEdit is enabled
  31575. */
  31576. checkClearOnEdit(ev) {
  31577. if (!this.clearOnEdit) {
  31578. return;
  31579. }
  31580. /**
  31581. * The following keys do not modify the
  31582. * contents of the input. As a result, pressing
  31583. * them should not edit the textarea.
  31584. *
  31585. * We can't check to see if the value of the textarea
  31586. * was changed because we call checkClearOnEdit
  31587. * in a keydown listener, and the key has not yet
  31588. * been added to the textarea.
  31589. *
  31590. * Unlike ion-input, the "Enter" key does modify the
  31591. * textarea by adding a new line, so "Enter" is not
  31592. * included in the IGNORED_KEYS array.
  31593. */
  31594. const IGNORED_KEYS = ['Tab', 'Shift', 'Meta', 'Alt', 'Control'];
  31595. const pressedIgnoredKey = IGNORED_KEYS.includes(ev.key);
  31596. /**
  31597. * Clear the textarea if the control has not been previously cleared
  31598. * during focus.
  31599. */
  31600. if (!this.didTextareaClearOnEdit && this.hasValue() && !pressedIgnoredKey) {
  31601. this.value = '';
  31602. this.emitInputChange(ev);
  31603. }
  31604. /**
  31605. * Pressing an IGNORED_KEYS first and
  31606. * then an allowed key will cause the input to not
  31607. * be cleared.
  31608. */
  31609. if (!pressedIgnoredKey) {
  31610. this.didTextareaClearOnEdit = true;
  31611. }
  31612. }
  31613. hasValue() {
  31614. return this.getValue() !== '';
  31615. }
  31616. getValue() {
  31617. return this.value || '';
  31618. }
  31619. renderLabel() {
  31620. const { label } = this;
  31621. return (hAsync("div", { class: {
  31622. 'label-text-wrapper': true,
  31623. 'label-text-wrapper-hidden': !this.hasLabel,
  31624. } }, label === undefined ? hAsync("slot", { name: "label" }) : hAsync("div", { class: "label-text" }, label)));
  31625. }
  31626. /**
  31627. * Gets any content passed into the `label` slot,
  31628. * not the <slot> definition.
  31629. */
  31630. get labelSlot() {
  31631. return this.el.querySelector('[slot="label"]');
  31632. }
  31633. /**
  31634. * Returns `true` if label content is provided
  31635. * either by a prop or a content. If you want
  31636. * to get the plaintext value of the label use
  31637. * the `labelText` getter instead.
  31638. */
  31639. get hasLabel() {
  31640. return this.label !== undefined || this.labelSlot !== null;
  31641. }
  31642. /**
  31643. * Renders the border container when fill="outline".
  31644. */
  31645. renderLabelContainer() {
  31646. const mode = getIonMode$1(this);
  31647. const hasOutlineFill = mode === 'md' && this.fill === 'outline';
  31648. if (hasOutlineFill) {
  31649. /**
  31650. * The outline fill has a special outline
  31651. * that appears around the textarea and the label.
  31652. * Certain stacked and floating label placements cause the
  31653. * label to translate up and create a "cut out"
  31654. * inside of that border by using the notch-spacer element.
  31655. */
  31656. return [
  31657. hAsync("div", { class: "textarea-outline-container" }, hAsync("div", { class: "textarea-outline-start" }), hAsync("div", { class: {
  31658. 'textarea-outline-notch': true,
  31659. 'textarea-outline-notch-hidden': !this.hasLabel,
  31660. } }, hAsync("div", { class: "notch-spacer", "aria-hidden": "true", ref: (el) => (this.notchSpacerEl = el) }, this.label)), hAsync("div", { class: "textarea-outline-end" })),
  31661. this.renderLabel(),
  31662. ];
  31663. }
  31664. /**
  31665. * If not using the outline style,
  31666. * we can render just the label.
  31667. */
  31668. return this.renderLabel();
  31669. }
  31670. /**
  31671. * Renders the helper text or error text values
  31672. */
  31673. renderHintText() {
  31674. const { helperText, errorText, helperTextId, errorTextId } = this;
  31675. return [
  31676. hAsync("div", { id: helperTextId, class: "helper-text" }, helperText),
  31677. hAsync("div", { id: errorTextId, class: "error-text" }, errorText),
  31678. ];
  31679. }
  31680. getHintTextID() {
  31681. const { el, helperText, errorText, helperTextId, errorTextId } = this;
  31682. if (el.classList.contains('ion-touched') && el.classList.contains('ion-invalid') && errorText) {
  31683. return errorTextId;
  31684. }
  31685. if (helperText) {
  31686. return helperTextId;
  31687. }
  31688. return undefined;
  31689. }
  31690. renderCounter() {
  31691. const { counter, maxlength, counterFormatter, value } = this;
  31692. if (counter !== true || maxlength === undefined) {
  31693. return;
  31694. }
  31695. return hAsync("div", { class: "counter" }, getCounterText(value, maxlength, counterFormatter));
  31696. }
  31697. /**
  31698. * Responsible for rendering helper text,
  31699. * error text, and counter. This element should only
  31700. * be rendered if hint text is set or counter is enabled.
  31701. */
  31702. renderBottomContent() {
  31703. const { counter, helperText, errorText, maxlength } = this;
  31704. /**
  31705. * undefined and empty string values should
  31706. * be treated as not having helper/error text.
  31707. */
  31708. const hasHintText = !!helperText || !!errorText;
  31709. const hasCounter = counter === true && maxlength !== undefined;
  31710. if (!hasHintText && !hasCounter) {
  31711. return;
  31712. }
  31713. return (hAsync("div", { class: "textarea-bottom" }, this.renderHintText(), this.renderCounter()));
  31714. }
  31715. render() {
  31716. const { inputId, disabled, fill, shape, labelPlacement, el, hasFocus } = this;
  31717. const mode = getIonMode$1(this);
  31718. const value = this.getValue();
  31719. const inItem = hostContext('ion-item', this.el);
  31720. const shouldRenderHighlight = mode === 'md' && fill !== 'outline' && !inItem;
  31721. const hasValue = this.hasValue();
  31722. const hasStartEndSlots = el.querySelector('[slot="start"], [slot="end"]') !== null;
  31723. /**
  31724. * If the label is stacked, it should always sit above the textarea.
  31725. * For floating labels, the label should move above the textarea if
  31726. * the textarea has a value, is focused, or has anything in either
  31727. * the start or end slot.
  31728. *
  31729. * If there is content in the start slot, the label would overlap
  31730. * it if not forced to float. This is also applied to the end slot
  31731. * because with the default or solid fills, the textarea is not
  31732. * vertically centered in the container, but the label is. This
  31733. * causes the slots and label to appear vertically offset from each
  31734. * other when the label isn't floating above the input. This doesn't
  31735. * apply to the outline fill, but this was not accounted for to keep
  31736. * things consistent.
  31737. *
  31738. * TODO(FW-5592): Remove hasStartEndSlots condition
  31739. */
  31740. const labelShouldFloat = labelPlacement === 'stacked' || (labelPlacement === 'floating' && (hasValue || hasFocus || hasStartEndSlots));
  31741. return (hAsync(Host, { key: '7eb390b79de0d671a785bbb783f97e09169472f9', class: createColorClasses$1(this.color, {
  31742. [mode]: true,
  31743. 'has-value': hasValue,
  31744. 'has-focus': hasFocus,
  31745. 'label-floating': labelShouldFloat,
  31746. [`textarea-fill-${fill}`]: fill !== undefined,
  31747. [`textarea-shape-${shape}`]: shape !== undefined,
  31748. [`textarea-label-placement-${labelPlacement}`]: true,
  31749. 'textarea-disabled': disabled,
  31750. }) }, hAsync("label", { key: 'f5835d8d56fadbd24637fc063a84834064aefc6d', class: "textarea-wrapper", htmlFor: inputId, onClick: this.onLabelClick }, this.renderLabelContainer(), hAsync("div", { key: '7ca9391a0cdcf47991bd529bfd38d06a3f92d6ec', class: "textarea-wrapper-inner" }, hAsync("div", { key: '12e893e7c4b56f5e9f91ff81cdaf8d76f68988fe', class: "start-slot-wrapper" }, hAsync("slot", { key: 'd9ff42e8989eb1462747fe67575f6c3478f4f8b3', name: "start" })), hAsync("div", { key: '0b9f575368c9c4d990761c390c163825eb311963', class: "native-wrapper", ref: (el) => (this.textareaWrapper = el) }, hAsync("textarea", Object.assign({ key: '2c80fc07518265458f27201e15af9578e372fbcf', class: "native-textarea", ref: (el) => (this.nativeInput = el), id: inputId, disabled: disabled, autoCapitalize: this.autocapitalize, autoFocus: this.autofocus, enterKeyHint: this.enterkeyhint, inputMode: this.inputmode, minLength: this.minlength, maxLength: this.maxlength, name: this.name, placeholder: this.placeholder || '', readOnly: this.readonly, required: this.required, spellcheck: this.spellcheck, cols: this.cols, rows: this.rows, wrap: this.wrap, onInput: this.onInput, onChange: this.onChange, onBlur: this.onBlur, onFocus: this.onFocus, onKeyDown: this.onKeyDown, "aria-describedby": this.getHintTextID(), "aria-invalid": this.getHintTextID() === this.errorTextId }, this.inheritedAttributes), value)), hAsync("div", { key: '6647296719b79eb3ebe7146f9bfd77a6c37f6c30', class: "end-slot-wrapper" }, hAsync("slot", { key: 'ec3ec3feb6b35ffe11bdcab94b521922b2f7e91f', name: "end" }))), shouldRenderHighlight && hAsync("div", { key: '49e7dca783bc2eee320631859264772be876eaba', class: "textarea-highlight" })), this.renderBottomContent()));
  31751. }
  31752. get el() { return getElement(this); }
  31753. static get watchers() { return {
  31754. "debounce": ["debounceChanged"],
  31755. "value": ["valueChanged"],
  31756. "dir": ["onDirChanged"]
  31757. }; }
  31758. static get style() { return {
  31759. ios: IonTextareaIosStyle0,
  31760. md: IonTextareaMdStyle0
  31761. }; }
  31762. static get cmpMeta() { return {
  31763. "$flags$": 38,
  31764. "$tagName$": "ion-textarea",
  31765. "$members$": {
  31766. "color": [513],
  31767. "autocapitalize": [1],
  31768. "autofocus": [4],
  31769. "clearOnEdit": [4, "clear-on-edit"],
  31770. "debounce": [2],
  31771. "disabled": [4],
  31772. "fill": [1],
  31773. "inputmode": [1],
  31774. "enterkeyhint": [1],
  31775. "maxlength": [2],
  31776. "minlength": [2],
  31777. "name": [1],
  31778. "placeholder": [1],
  31779. "readonly": [4],
  31780. "required": [4],
  31781. "spellcheck": [4],
  31782. "cols": [514],
  31783. "rows": [2],
  31784. "wrap": [1],
  31785. "autoGrow": [516, "auto-grow"],
  31786. "value": [1025],
  31787. "counter": [4],
  31788. "counterFormatter": [16],
  31789. "errorText": [1, "error-text"],
  31790. "helperText": [1, "helper-text"],
  31791. "label": [1],
  31792. "labelPlacement": [1, "label-placement"],
  31793. "shape": [1],
  31794. "hasFocus": [32],
  31795. "setFocus": [64],
  31796. "getInputElement": [64]
  31797. },
  31798. "$listeners$": [[2, "click", "onClickCapture"]],
  31799. "$lazyBundleId$": "-",
  31800. "$attrsToReflect$": [["color", "color"], ["cols", "cols"], ["autoGrow", "auto-grow"]]
  31801. }; }
  31802. }
  31803. let textareaIds = 0;
  31804. const thumbnailCss = ":host{--size:48px;--border-radius:0;border-radius:var(--border-radius);display:block;width:var(--size);height:var(--size)}::slotted(ion-img),::slotted(img){border-radius:var(--border-radius);width:100%;height:100%;-o-object-fit:cover;object-fit:cover;overflow:hidden}";
  31805. var IonThumbnailStyle0 = thumbnailCss;
  31806. class Thumbnail {
  31807. constructor(hostRef) {
  31808. registerInstance(this, hostRef);
  31809. }
  31810. render() {
  31811. return (hAsync(Host, { key: '7f5fd6c056da2d82feb2c3c33f3e6dec898787f5', class: getIonMode$1(this) }, hAsync("slot", { key: 'd15fd2b6cdc03777edc1930be95ad838e1b376c8' })));
  31812. }
  31813. static get style() { return IonThumbnailStyle0; }
  31814. static get cmpMeta() { return {
  31815. "$flags$": 9,
  31816. "$tagName$": "ion-thumbnail",
  31817. "$members$": undefined,
  31818. "$listeners$": undefined,
  31819. "$lazyBundleId$": "-",
  31820. "$attrsToReflect$": []
  31821. }; }
  31822. }
  31823. /**
  31824. * Calculate the CSS top and bottom position of the toast, to be used
  31825. * as starting points for the animation keyframes.
  31826. *
  31827. * The default animations for both MD and iOS
  31828. * use translateY, which calculates from the
  31829. * top edge of the screen. This behavior impacts
  31830. * how we compute the offset when a toast has
  31831. * position='bottom' since we need to calculate from
  31832. * the bottom edge of the screen instead.
  31833. *
  31834. * @param position The value of the toast's position prop.
  31835. * @param positionAnchor The element the toast should be anchored to,
  31836. * if applicable.
  31837. * @param mode The toast component's mode (md, ios, etc).
  31838. * @param toast A reference to the toast element itself.
  31839. */
  31840. function getAnimationPosition(position, positionAnchor, mode, toast) {
  31841. /**
  31842. * Start with a predefined offset from the edge the toast will be
  31843. * positioned relative to, whether on the screen or anchor element.
  31844. */
  31845. let offset;
  31846. if (mode === 'md') {
  31847. offset = position === 'top' ? 8 : -8;
  31848. }
  31849. else {
  31850. offset = position === 'top' ? 10 : -10;
  31851. }
  31852. /**
  31853. * If positionAnchor is defined, add in the distance from the target
  31854. * screen edge to the target anchor edge. For position="top", the
  31855. * bottom anchor edge is targeted. For position="bottom", the top
  31856. * anchor edge is targeted.
  31857. */
  31858. if (positionAnchor && win$1) {
  31859. warnIfAnchorIsHidden(positionAnchor, toast);
  31860. const box = positionAnchor.getBoundingClientRect();
  31861. if (position === 'top') {
  31862. offset += box.bottom;
  31863. }
  31864. else if (position === 'bottom') {
  31865. /**
  31866. * Just box.top is the distance from the top edge of the screen
  31867. * to the top edge of the anchor. We want to calculate from the
  31868. * bottom edge of the screen instead.
  31869. */
  31870. offset -= win$1.innerHeight - box.top;
  31871. }
  31872. /**
  31873. * We don't include safe area here because that should already be
  31874. * accounted for when checking the position of the anchor.
  31875. */
  31876. return {
  31877. top: `${offset}px`,
  31878. bottom: `${offset}px`,
  31879. };
  31880. }
  31881. else {
  31882. return {
  31883. top: `calc(${offset}px + var(--ion-safe-area-top, 0px))`,
  31884. bottom: `calc(${offset}px - var(--ion-safe-area-bottom, 0px))`,
  31885. };
  31886. }
  31887. }
  31888. /**
  31889. * If the anchor element is hidden, getBoundingClientRect()
  31890. * will return all 0s for it, which can cause unexpected
  31891. * results in the position calculation when animating.
  31892. */
  31893. function warnIfAnchorIsHidden(positionAnchor, toast) {
  31894. if (positionAnchor.offsetParent === null) {
  31895. printIonWarning('[ion-toast] - The positionAnchor element for ion-toast was found in the DOM, but appears to be hidden. This may lead to unexpected positioning of the toast.', toast);
  31896. }
  31897. }
  31898. /**
  31899. * Returns the top offset required to place
  31900. * the toast in the middle of the screen.
  31901. * Only needed when position="toast".
  31902. * @param toastHeight - The height of the ion-toast element
  31903. * @param wrapperHeight - The height of the .toast-wrapper element
  31904. * inside the toast's shadow root.
  31905. */
  31906. const getOffsetForMiddlePosition = (toastHeight, wrapperHeight) => {
  31907. return Math.floor(toastHeight / 2 - wrapperHeight / 2);
  31908. };
  31909. /**
  31910. * iOS Toast Enter Animation
  31911. */
  31912. const iosEnterAnimation = (baseEl, opts) => {
  31913. const baseAnimation = createAnimation();
  31914. const wrapperAnimation = createAnimation();
  31915. const { position, top, bottom } = opts;
  31916. const root = getElementRoot(baseEl);
  31917. const wrapperEl = root.querySelector('.toast-wrapper');
  31918. wrapperAnimation.addElement(wrapperEl);
  31919. switch (position) {
  31920. case 'top':
  31921. wrapperAnimation.fromTo('transform', 'translateY(-100%)', `translateY(${top})`);
  31922. break;
  31923. case 'middle':
  31924. const topPosition = getOffsetForMiddlePosition(baseEl.clientHeight, wrapperEl.clientHeight);
  31925. wrapperEl.style.top = `${topPosition}px`;
  31926. wrapperAnimation.fromTo('opacity', 0.01, 1);
  31927. break;
  31928. default:
  31929. wrapperAnimation.fromTo('transform', 'translateY(100%)', `translateY(${bottom})`);
  31930. break;
  31931. }
  31932. return baseAnimation.easing('cubic-bezier(.155,1.105,.295,1.12)').duration(400).addAnimation(wrapperAnimation);
  31933. };
  31934. /**
  31935. * iOS Toast Leave Animation
  31936. */
  31937. const iosLeaveAnimation = (baseEl, opts) => {
  31938. const baseAnimation = createAnimation();
  31939. const wrapperAnimation = createAnimation();
  31940. const { position, top, bottom } = opts;
  31941. const root = getElementRoot(baseEl);
  31942. const wrapperEl = root.querySelector('.toast-wrapper');
  31943. wrapperAnimation.addElement(wrapperEl);
  31944. switch (position) {
  31945. case 'top':
  31946. wrapperAnimation.fromTo('transform', `translateY(${top})`, 'translateY(-100%)');
  31947. break;
  31948. case 'middle':
  31949. wrapperAnimation.fromTo('opacity', 0.99, 0);
  31950. break;
  31951. default:
  31952. wrapperAnimation.fromTo('transform', `translateY(${bottom})`, 'translateY(100%)');
  31953. break;
  31954. }
  31955. return baseAnimation.easing('cubic-bezier(.36,.66,.04,1)').duration(300).addAnimation(wrapperAnimation);
  31956. };
  31957. /**
  31958. * MD Toast Enter Animation
  31959. */
  31960. const mdEnterAnimation = (baseEl, opts) => {
  31961. const baseAnimation = createAnimation();
  31962. const wrapperAnimation = createAnimation();
  31963. const { position, top, bottom } = opts;
  31964. const root = getElementRoot(baseEl);
  31965. const wrapperEl = root.querySelector('.toast-wrapper');
  31966. wrapperAnimation.addElement(wrapperEl);
  31967. switch (position) {
  31968. case 'top':
  31969. wrapperEl.style.setProperty('transform', `translateY(${top})`);
  31970. wrapperAnimation.fromTo('opacity', 0.01, 1);
  31971. break;
  31972. case 'middle':
  31973. const topPosition = getOffsetForMiddlePosition(baseEl.clientHeight, wrapperEl.clientHeight);
  31974. wrapperEl.style.top = `${topPosition}px`;
  31975. wrapperAnimation.fromTo('opacity', 0.01, 1);
  31976. break;
  31977. default:
  31978. wrapperEl.style.setProperty('transform', `translateY(${bottom})`);
  31979. wrapperAnimation.fromTo('opacity', 0.01, 1);
  31980. break;
  31981. }
  31982. return baseAnimation.easing('cubic-bezier(.36,.66,.04,1)').duration(400).addAnimation(wrapperAnimation);
  31983. };
  31984. /**
  31985. * md Toast Leave Animation
  31986. */
  31987. const mdLeaveAnimation = (baseEl) => {
  31988. const baseAnimation = createAnimation();
  31989. const wrapperAnimation = createAnimation();
  31990. const root = getElementRoot(baseEl);
  31991. const wrapperEl = root.querySelector('.toast-wrapper');
  31992. wrapperAnimation.addElement(wrapperEl).fromTo('opacity', 0.99, 0);
  31993. return baseAnimation.easing('cubic-bezier(.36,.66,.04,1)').duration(300).addAnimation(wrapperAnimation);
  31994. };
  31995. /**
  31996. * Create a gesture that allows the Toast
  31997. * to be swiped to dismiss.
  31998. * @param el - The Toast element
  31999. * @param toastPosition - The last computed position of the Toast. This is computed in the "present" method.
  32000. * @param onDismiss - A callback to fire when the Toast was swiped to dismiss.
  32001. */
  32002. const createSwipeToDismissGesture = (el, toastPosition, onDismiss) => {
  32003. /**
  32004. * Users should swipe on the visible toast wrapper
  32005. * rather than on ion-toast which covers the entire screen.
  32006. * When testing the class instance the inner wrapper will not
  32007. * be defined. As a result, we use a placeholder element in those environments.
  32008. */
  32009. const wrapperEl = getElementRoot(el).querySelector('.toast-wrapper');
  32010. const hostElHeight = el.clientHeight;
  32011. const wrapperElBox = wrapperEl.getBoundingClientRect();
  32012. /**
  32013. * The maximum amount that
  32014. * the toast can be swiped. This should
  32015. * account for the wrapper element's height
  32016. * too so the toast can be swiped offscreen
  32017. * completely.
  32018. */
  32019. let MAX_SWIPE_DISTANCE = 0;
  32020. /**
  32021. * The step value at which a toast
  32022. * is eligible for dismissing via gesture.
  32023. */
  32024. const DISMISS_THRESHOLD = 0.5;
  32025. /**
  32026. * The middle position Toast starts 50% of the way
  32027. * through the animation, so we need to use this
  32028. * as the starting point for our step values.
  32029. */
  32030. const STEP_OFFSET = el.position === 'middle' ? 0.5 : 0;
  32031. /**
  32032. * When the Toast is at the top users will be
  32033. * swiping up. As a result, the delta values will be
  32034. * negative numbers which will result in negative steps
  32035. * and thresholds. As a result, we need to make those numbers
  32036. * positive.
  32037. */
  32038. const INVERSION_FACTOR = el.position === 'top' ? -1 : 1;
  32039. /**
  32040. * The top offset that places the
  32041. * toast in the middle of the screen.
  32042. * Only needed when position="middle".
  32043. */
  32044. const topPosition = getOffsetForMiddlePosition(hostElHeight, wrapperElBox.height);
  32045. const SWIPE_UP_DOWN_KEYFRAMES = [
  32046. { offset: 0, transform: `translateY(-${topPosition + wrapperElBox.height}px)` },
  32047. { offset: 0.5, transform: `translateY(0px)` },
  32048. { offset: 1, transform: `translateY(${topPosition + wrapperElBox.height}px)` },
  32049. ];
  32050. const swipeAnimation = createAnimation('toast-swipe-to-dismiss-animation')
  32051. .addElement(wrapperEl)
  32052. /**
  32053. * The specific value here does not actually
  32054. * matter. We just need this to be a positive
  32055. * value so the animation does not jump
  32056. * to the end when the user beings to drag.
  32057. */
  32058. .duration(100);
  32059. switch (el.position) {
  32060. case 'middle':
  32061. MAX_SWIPE_DISTANCE = hostElHeight + wrapperElBox.height;
  32062. swipeAnimation.keyframes(SWIPE_UP_DOWN_KEYFRAMES);
  32063. /**
  32064. * Toast can be swiped up or down but
  32065. * should start in the middle of the screen.
  32066. */
  32067. swipeAnimation.progressStart(true, 0.5);
  32068. break;
  32069. case 'top':
  32070. /**
  32071. * The bottom edge of the wrapper
  32072. * includes the distance between the top
  32073. * of the screen and the top of the wrapper
  32074. * as well as the wrapper height so the wrapper
  32075. * can be dragged fully offscreen.
  32076. */
  32077. MAX_SWIPE_DISTANCE = wrapperElBox.bottom;
  32078. swipeAnimation.keyframes([
  32079. { offset: 0, transform: `translateY(${toastPosition.top})` },
  32080. { offset: 1, transform: 'translateY(-100%)' },
  32081. ]);
  32082. swipeAnimation.progressStart(true, 0);
  32083. break;
  32084. case 'bottom':
  32085. default:
  32086. /**
  32087. * This computes the distance between the
  32088. * top of the wrapper and the bottom of the
  32089. * screen including the height of the wrapper
  32090. * element so it can be dragged fully offscreen.
  32091. */
  32092. MAX_SWIPE_DISTANCE = hostElHeight - wrapperElBox.top;
  32093. swipeAnimation.keyframes([
  32094. { offset: 0, transform: `translateY(${toastPosition.bottom})` },
  32095. { offset: 1, transform: 'translateY(100%)' },
  32096. ]);
  32097. swipeAnimation.progressStart(true, 0);
  32098. break;
  32099. }
  32100. const computeStep = (delta) => {
  32101. return (delta * INVERSION_FACTOR) / MAX_SWIPE_DISTANCE;
  32102. };
  32103. const onMove = (detail) => {
  32104. const step = STEP_OFFSET + computeStep(detail.deltaY);
  32105. swipeAnimation.progressStep(step);
  32106. };
  32107. const onEnd = (detail) => {
  32108. const velocity = detail.velocityY;
  32109. const threshold = ((detail.deltaY + velocity * 1000) / MAX_SWIPE_DISTANCE) * INVERSION_FACTOR;
  32110. /**
  32111. * Disable the gesture for the remainder of the animation.
  32112. * It will be re-enabled if the toast animates back to
  32113. * its initial presented position.
  32114. */
  32115. gesture.enable(false);
  32116. let shouldDismiss = true;
  32117. let playTo = 1;
  32118. let step = 0;
  32119. let remainingDistance = 0;
  32120. if (el.position === 'middle') {
  32121. /**
  32122. * A middle positioned Toast appears
  32123. * in the middle of the screen (at animation offset 0.5).
  32124. * As a result, the threshold will be calculated relative
  32125. * to this starting position. In other words at animation offset 0.5
  32126. * the threshold will be 0. We want the middle Toast to be eligible
  32127. * for dismiss when the user has swiped either half way up or down the
  32128. * screen. As a result, we divide DISMISS_THRESHOLD in half. We also
  32129. * consider when the threshold is a negative in the event the
  32130. * user drags up (since the deltaY will also be negative).
  32131. */
  32132. shouldDismiss = threshold >= DISMISS_THRESHOLD / 2 || threshold <= -DISMISS_THRESHOLD / 2;
  32133. /**
  32134. * Since we are replacing the keyframes
  32135. * below the animation always starts from
  32136. * the beginning of the new keyframes.
  32137. * Similarly, we are always playing to
  32138. * the end of the new keyframes.
  32139. */
  32140. playTo = 1;
  32141. step = 0;
  32142. /**
  32143. * The Toast should animate from wherever its
  32144. * current position is to the desired end state.
  32145. *
  32146. * To begin, we get the current position of the
  32147. * Toast for its starting state.
  32148. */
  32149. const wrapperElBox = wrapperEl.getBoundingClientRect();
  32150. const startOffset = wrapperElBox.top - topPosition;
  32151. const startPosition = `${startOffset}px`;
  32152. /**
  32153. * If the deltaY is negative then the user is swiping
  32154. * up, so the Toast should animate to the top of the screen.
  32155. * If the deltaY is positive then the user is swiping
  32156. * down, so the Toast should animate to the bottom of the screen.
  32157. * We also account for when the deltaY is 0, but realistically
  32158. * that should never happen because it means the user did not drag
  32159. * the toast.
  32160. */
  32161. const offsetFactor = detail.deltaY <= 0 ? -1 : 1;
  32162. const endOffset = (topPosition + wrapperElBox.height) * offsetFactor;
  32163. /**
  32164. * If the Toast should dismiss
  32165. * then we need to figure out which edge of
  32166. * the screen it should animate towards.
  32167. * By default, the Toast will come
  32168. * back to its default state in the
  32169. * middle of the screen.
  32170. */
  32171. const endPosition = shouldDismiss ? `${endOffset}px` : '0px';
  32172. const KEYFRAMES = [
  32173. { offset: 0, transform: `translateY(${startPosition})` },
  32174. { offset: 1, transform: `translateY(${endPosition})` },
  32175. ];
  32176. swipeAnimation.keyframes(KEYFRAMES);
  32177. /**
  32178. * Compute the remaining amount of pixels the
  32179. * toast needs to move to be fully dismissed.
  32180. */
  32181. remainingDistance = endOffset - startOffset;
  32182. }
  32183. else {
  32184. shouldDismiss = threshold >= DISMISS_THRESHOLD;
  32185. playTo = shouldDismiss ? 1 : 0;
  32186. step = computeStep(detail.deltaY);
  32187. /**
  32188. * Compute the remaining amount of pixels the
  32189. * toast needs to move to be fully dismissed.
  32190. */
  32191. const remainingStepAmount = shouldDismiss ? 1 - step : step;
  32192. remainingDistance = remainingStepAmount * MAX_SWIPE_DISTANCE;
  32193. }
  32194. /**
  32195. * The animation speed should depend on how quickly
  32196. * the user flicks the toast across the screen. However,
  32197. * it should be no slower than 200ms.
  32198. * We use Math.abs on the remainingDistance because that value
  32199. * can be negative when swiping up on a middle position toast.
  32200. */
  32201. const duration = Math.min(Math.abs(remainingDistance) / Math.abs(velocity), 200);
  32202. swipeAnimation
  32203. .onFinish(() => {
  32204. if (shouldDismiss) {
  32205. onDismiss();
  32206. swipeAnimation.destroy();
  32207. }
  32208. else {
  32209. if (el.position === 'middle') {
  32210. /**
  32211. * If the toast snapped back to
  32212. * the middle of the screen we need
  32213. * to reset the keyframes
  32214. * so the toast can be swiped
  32215. * up or down again.
  32216. */
  32217. swipeAnimation.keyframes(SWIPE_UP_DOWN_KEYFRAMES).progressStart(true, 0.5);
  32218. }
  32219. else {
  32220. swipeAnimation.progressStart(true, 0);
  32221. }
  32222. /**
  32223. * If the toast did not dismiss then
  32224. * the user should be able to swipe again.
  32225. */
  32226. gesture.enable(true);
  32227. }
  32228. /**
  32229. * This must be a one time callback
  32230. * otherwise a new callback will
  32231. * be added every time onEnd runs.
  32232. */
  32233. }, { oneTimeCallback: true })
  32234. .progressEnd(playTo, step, duration);
  32235. };
  32236. const gesture = createGesture({
  32237. el: wrapperEl,
  32238. gestureName: 'toast-swipe-to-dismiss',
  32239. gesturePriority: OVERLAY_GESTURE_PRIORITY,
  32240. /**
  32241. * Toast only supports vertical swipes.
  32242. * This needs to be updated if we later
  32243. * support horizontal swipes.
  32244. */
  32245. direction: 'y',
  32246. onMove,
  32247. onEnd,
  32248. });
  32249. return gesture;
  32250. };
  32251. const toastIosCss = ":host{--border-width:0;--border-style:none;--border-color:initial;--box-shadow:none;--min-width:auto;--width:auto;--min-height:auto;--height:auto;--max-height:auto;--white-space:normal;top:0;display:block;position:absolute;width:100%;height:100%;outline:none;color:var(--color);font-family:var(--ion-font-family, inherit);contain:strict;z-index:1001;pointer-events:none}:host{inset-inline-start:0}:host(.overlay-hidden){display:none}:host(.ion-color){--button-color:inherit;color:var(--ion-color-contrast)}:host(.ion-color) .toast-button-cancel{color:inherit}:host(.ion-color) .toast-wrapper{background:var(--ion-color-base)}.toast-wrapper{border-radius:var(--border-radius);width:var(--width);min-width:var(--min-width);max-width:var(--max-width);height:var(--height);min-height:var(--min-height);max-height:var(--max-height);border-width:var(--border-width);border-style:var(--border-style);border-color:var(--border-color);background:var(--background);-webkit-box-shadow:var(--box-shadow);box-shadow:var(--box-shadow);pointer-events:auto}.toast-wrapper{inset-inline-start:var(--start);inset-inline-end:var(--end)}.toast-wrapper.toast-top{-webkit-transform:translate3d(0, -100%, 0);transform:translate3d(0, -100%, 0);top:0}.toast-wrapper.toast-bottom{-webkit-transform:translate3d(0, 100%, 0);transform:translate3d(0, 100%, 0);bottom:0}.toast-container{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;height:inherit;min-height:inherit;max-height:inherit;contain:content}.toast-layout-stacked .toast-container{-ms-flex-wrap:wrap;flex-wrap:wrap}.toast-layout-baseline .toast-content{display:-ms-flexbox;display:flex;-ms-flex:1;flex:1;-ms-flex-direction:column;flex-direction:column;-ms-flex-pack:center;justify-content:center}.toast-icon{-webkit-margin-start:16px;margin-inline-start:16px}.toast-content{min-width:0}.toast-message{-ms-flex:1;flex:1;white-space:var(--white-space)}.toast-button-group{display:-ms-flexbox;display:flex}.toast-layout-stacked .toast-button-group{-ms-flex-pack:end;justify-content:end;width:100%}.toast-button{border:0;outline:none;color:var(--button-color);z-index:0}.toast-icon,.toast-button-icon{font-size:1.4em}.toast-button-inner{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center}@media (any-hover: hover){.toast-button:hover{cursor:pointer}}:host{--background:var(--ion-color-step-50, var(--ion-background-color-step-50, #f2f2f2));--border-radius:14px;--button-color:var(--ion-color-primary, #0054e9);--color:var(--ion-color-step-850, var(--ion-text-color-step-150, #262626));--max-width:700px;--max-height:478px;--start:10px;--end:10px;font-size:clamp(14px, 0.875rem, 43.4px)}.toast-wrapper{-webkit-margin-start:auto;margin-inline-start:auto;-webkit-margin-end:auto;margin-inline-end:auto;margin-top:auto;margin-bottom:auto;display:block;position:absolute;z-index:10}@supports ((-webkit-backdrop-filter: blur(0)) or (backdrop-filter: blur(0))){:host(.toast-translucent) .toast-wrapper{background:rgba(var(--ion-background-color-rgb, 255, 255, 255), 0.8);-webkit-backdrop-filter:saturate(180%) blur(20px);backdrop-filter:saturate(180%) blur(20px)}:host(.ion-color.toast-translucent) .toast-wrapper{background:rgba(var(--ion-color-base-rgb), 0.8)}}.toast-wrapper.toast-middle{opacity:0.01}.toast-content{-webkit-padding-start:15px;padding-inline-start:15px;-webkit-padding-end:15px;padding-inline-end:15px;padding-top:15px;padding-bottom:15px}.toast-header{margin-bottom:2px;font-weight:500}.toast-button{-webkit-padding-start:15px;padding-inline-start:15px;-webkit-padding-end:15px;padding-inline-end:15px;padding-top:10px;padding-bottom:10px;min-height:44px;-webkit-transition:background-color, opacity 100ms linear;transition:background-color, opacity 100ms linear;border:0;background-color:transparent;font-family:var(--ion-font-family);font-size:clamp(17px, 1.0625rem, 21.998px);font-weight:500;overflow:hidden}.toast-button.ion-activated{opacity:0.4}@media (any-hover: hover){.toast-button:hover{opacity:0.6}}";
  32252. var IonToastIosStyle0 = toastIosCss;
  32253. const toastMdCss = ":host{--border-width:0;--border-style:none;--border-color:initial;--box-shadow:none;--min-width:auto;--width:auto;--min-height:auto;--height:auto;--max-height:auto;--white-space:normal;top:0;display:block;position:absolute;width:100%;height:100%;outline:none;color:var(--color);font-family:var(--ion-font-family, inherit);contain:strict;z-index:1001;pointer-events:none}:host{inset-inline-start:0}:host(.overlay-hidden){display:none}:host(.ion-color){--button-color:inherit;color:var(--ion-color-contrast)}:host(.ion-color) .toast-button-cancel{color:inherit}:host(.ion-color) .toast-wrapper{background:var(--ion-color-base)}.toast-wrapper{border-radius:var(--border-radius);width:var(--width);min-width:var(--min-width);max-width:var(--max-width);height:var(--height);min-height:var(--min-height);max-height:var(--max-height);border-width:var(--border-width);border-style:var(--border-style);border-color:var(--border-color);background:var(--background);-webkit-box-shadow:var(--box-shadow);box-shadow:var(--box-shadow);pointer-events:auto}.toast-wrapper{inset-inline-start:var(--start);inset-inline-end:var(--end)}.toast-wrapper.toast-top{-webkit-transform:translate3d(0, -100%, 0);transform:translate3d(0, -100%, 0);top:0}.toast-wrapper.toast-bottom{-webkit-transform:translate3d(0, 100%, 0);transform:translate3d(0, 100%, 0);bottom:0}.toast-container{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;height:inherit;min-height:inherit;max-height:inherit;contain:content}.toast-layout-stacked .toast-container{-ms-flex-wrap:wrap;flex-wrap:wrap}.toast-layout-baseline .toast-content{display:-ms-flexbox;display:flex;-ms-flex:1;flex:1;-ms-flex-direction:column;flex-direction:column;-ms-flex-pack:center;justify-content:center}.toast-icon{-webkit-margin-start:16px;margin-inline-start:16px}.toast-content{min-width:0}.toast-message{-ms-flex:1;flex:1;white-space:var(--white-space)}.toast-button-group{display:-ms-flexbox;display:flex}.toast-layout-stacked .toast-button-group{-ms-flex-pack:end;justify-content:end;width:100%}.toast-button{border:0;outline:none;color:var(--button-color);z-index:0}.toast-icon,.toast-button-icon{font-size:1.4em}.toast-button-inner{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center}@media (any-hover: hover){.toast-button:hover{cursor:pointer}}:host{--background:var(--ion-color-step-800, var(--ion-background-color-step-800, #333333));--border-radius:4px;--box-shadow:0 3px 5px -1px rgba(0, 0, 0, 0.2), 0 6px 10px 0 rgba(0, 0, 0, 0.14), 0 1px 18px 0 rgba(0, 0, 0, 0.12);--button-color:var(--ion-color-primary, #0054e9);--color:var(--ion-color-step-50, var(--ion-text-color-step-950, #f2f2f2));--max-width:700px;--start:8px;--end:8px;font-size:0.875rem}.toast-wrapper{-webkit-margin-start:auto;margin-inline-start:auto;-webkit-margin-end:auto;margin-inline-end:auto;margin-top:auto;margin-bottom:auto;display:block;position:absolute;opacity:0.01;z-index:10}.toast-content{-webkit-padding-start:16px;padding-inline-start:16px;-webkit-padding-end:16px;padding-inline-end:16px;padding-top:14px;padding-bottom:14px}.toast-header{margin-bottom:2px;font-weight:500;line-height:1.25rem}.toast-message{line-height:1.25rem}.toast-layout-baseline .toast-button-group-start{-webkit-margin-start:8px;margin-inline-start:8px}.toast-layout-stacked .toast-button-group-start{-webkit-margin-end:8px;margin-inline-end:8px;margin-top:8px}.toast-layout-baseline .toast-button-group-end{-webkit-margin-end:8px;margin-inline-end:8px}.toast-layout-stacked .toast-button-group-end{-webkit-margin-end:8px;margin-inline-end:8px;margin-bottom:8px}.toast-button{-webkit-padding-start:15px;padding-inline-start:15px;-webkit-padding-end:15px;padding-inline-end:15px;padding-top:10px;padding-bottom:10px;position:relative;background-color:transparent;font-family:var(--ion-font-family);font-size:0.875rem;font-weight:500;letter-spacing:0.84px;text-transform:uppercase;overflow:hidden}.toast-button-cancel{color:var(--ion-color-step-100, var(--ion-text-color-step-900, #e6e6e6))}.toast-button-icon-only{border-radius:50%;-webkit-padding-start:9px;padding-inline-start:9px;-webkit-padding-end:9px;padding-inline-end:9px;padding-top:9px;padding-bottom:9px;width:36px;height:36px}@media (any-hover: hover){.toast-button:hover{background-color:rgba(var(--ion-color-primary-rgb, 0, 84, 233), 0.08)}.toast-button-cancel:hover{background-color:rgba(var(--ion-background-color-rgb, 255, 255, 255), 0.08)}}";
  32254. var IonToastMdStyle0 = toastMdCss;
  32255. // TODO(FW-2832): types
  32256. /**
  32257. * @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
  32258. *
  32259. * @part button - Any button element that is displayed inside of the toast.
  32260. * @part button cancel - Any button element with role "cancel" that is displayed inside of the toast.
  32261. * @part container - The element that wraps all child elements.
  32262. * @part header - The header text of the toast.
  32263. * @part message - The body text of the toast.
  32264. * @part icon - The icon that appears next to the toast content.
  32265. */
  32266. class Toast {
  32267. constructor(hostRef) {
  32268. registerInstance(this, hostRef);
  32269. this.didPresent = createEvent(this, "ionToastDidPresent", 7);
  32270. this.willPresent = createEvent(this, "ionToastWillPresent", 7);
  32271. this.willDismiss = createEvent(this, "ionToastWillDismiss", 7);
  32272. this.didDismiss = createEvent(this, "ionToastDidDismiss", 7);
  32273. this.didPresentShorthand = createEvent(this, "didPresent", 7);
  32274. this.willPresentShorthand = createEvent(this, "willPresent", 7);
  32275. this.willDismissShorthand = createEvent(this, "willDismiss", 7);
  32276. this.didDismissShorthand = createEvent(this, "didDismiss", 7);
  32277. this.delegateController = createDelegateController(this);
  32278. this.lockController = createLockController();
  32279. this.triggerController = createTriggerController();
  32280. this.customHTMLEnabled = config.get('innerHTMLTemplatesEnabled', ENABLE_HTML_CONTENT_DEFAULT);
  32281. this.presented = false;
  32282. this.dispatchCancelHandler = (ev) => {
  32283. const role = ev.detail.role;
  32284. if (isCancel(role)) {
  32285. const cancelButton = this.getButtons().find((b) => b.role === 'cancel');
  32286. this.callButtonHandler(cancelButton);
  32287. }
  32288. };
  32289. /**
  32290. * Create a new swipe gesture so Toast
  32291. * can be swiped to dismiss.
  32292. */
  32293. this.createSwipeGesture = (toastPosition) => {
  32294. const gesture = (this.gesture = createSwipeToDismissGesture(this.el, toastPosition, () => {
  32295. /**
  32296. * If the gesture completed then
  32297. * we should dismiss the toast.
  32298. */
  32299. this.dismiss(undefined, GESTURE);
  32300. }));
  32301. gesture.enable(true);
  32302. };
  32303. /**
  32304. * Destroy an existing swipe gesture
  32305. * so Toast can no longer be swiped to dismiss.
  32306. */
  32307. this.destroySwipeGesture = () => {
  32308. const { gesture } = this;
  32309. if (gesture === undefined) {
  32310. return;
  32311. }
  32312. gesture.destroy();
  32313. this.gesture = undefined;
  32314. };
  32315. /**
  32316. * Returns `true` if swipeGesture
  32317. * is configured to a value that enables the swipe behavior.
  32318. * Returns `false` otherwise.
  32319. */
  32320. this.prefersSwipeGesture = () => {
  32321. const { swipeGesture } = this;
  32322. return swipeGesture === 'vertical';
  32323. };
  32324. this.revealContentToScreenReader = false;
  32325. this.overlayIndex = undefined;
  32326. this.delegate = undefined;
  32327. this.hasController = false;
  32328. this.color = undefined;
  32329. this.enterAnimation = undefined;
  32330. this.leaveAnimation = undefined;
  32331. this.cssClass = undefined;
  32332. this.duration = config.getNumber('toastDuration', 0);
  32333. this.header = undefined;
  32334. this.layout = 'baseline';
  32335. this.message = undefined;
  32336. this.keyboardClose = false;
  32337. this.position = 'bottom';
  32338. this.positionAnchor = undefined;
  32339. this.buttons = undefined;
  32340. this.translucent = false;
  32341. this.animated = true;
  32342. this.icon = undefined;
  32343. this.htmlAttributes = undefined;
  32344. this.swipeGesture = undefined;
  32345. this.isOpen = false;
  32346. this.trigger = undefined;
  32347. }
  32348. swipeGestureChanged() {
  32349. /**
  32350. * If the Toast is presented, then we need to destroy
  32351. * any actives gestures before a new gesture is potentially
  32352. * created below.
  32353. *
  32354. * If the Toast is dismissed, then no gesture should be available
  32355. * since the Toast is not visible. This case should never
  32356. * happen since the "dismiss" method handles destroying
  32357. * any active swipe gestures, but we keep this code
  32358. * around to handle the first case.
  32359. */
  32360. this.destroySwipeGesture();
  32361. /**
  32362. * A new swipe gesture should only be created
  32363. * if the Toast is presented. If the Toast is not
  32364. * yet presented then the "present" method will
  32365. * handle calling the swipe gesture setup function.
  32366. */
  32367. if (this.presented && this.prefersSwipeGesture()) {
  32368. /**
  32369. * If the Toast is presented then
  32370. * lastPresentedPosition is defined.
  32371. */
  32372. this.createSwipeGesture(this.lastPresentedPosition);
  32373. }
  32374. }
  32375. onIsOpenChange(newValue, oldValue) {
  32376. if (newValue === true && oldValue === false) {
  32377. this.present();
  32378. }
  32379. else if (newValue === false && oldValue === true) {
  32380. this.dismiss();
  32381. }
  32382. }
  32383. triggerChanged() {
  32384. const { trigger, el, triggerController } = this;
  32385. if (trigger) {
  32386. triggerController.addClickListener(el, trigger);
  32387. }
  32388. }
  32389. connectedCallback() {
  32390. prepareOverlay(this.el);
  32391. this.triggerChanged();
  32392. }
  32393. disconnectedCallback() {
  32394. this.triggerController.removeClickListener();
  32395. }
  32396. componentWillLoad() {
  32397. var _a;
  32398. if (!((_a = this.htmlAttributes) === null || _a === void 0 ? void 0 : _a.id)) {
  32399. setOverlayId(this.el);
  32400. }
  32401. }
  32402. componentDidLoad() {
  32403. /**
  32404. * If toast was rendered with isOpen="true"
  32405. * then we should open toast immediately.
  32406. */
  32407. if (this.isOpen === true) {
  32408. raf(() => this.present());
  32409. }
  32410. /**
  32411. * When binding values in frameworks such as Angular
  32412. * it is possible for the value to be set after the Web Component
  32413. * initializes but before the value watcher is set up in Stencil.
  32414. * As a result, the watcher callback may not be fired.
  32415. * We work around this by manually calling the watcher
  32416. * callback when the component has loaded and the watcher
  32417. * is configured.
  32418. */
  32419. this.triggerChanged();
  32420. }
  32421. /**
  32422. * Present the toast overlay after it has been created.
  32423. */
  32424. async present() {
  32425. const unlock = await this.lockController.lock();
  32426. await this.delegateController.attachViewToDom();
  32427. const { el, position } = this;
  32428. const anchor = this.getAnchorElement();
  32429. const animationPosition = getAnimationPosition(position, anchor, getIonMode$1(this), el);
  32430. /**
  32431. * Cache the calculated position of the toast, so we can re-use it
  32432. * in the dismiss animation.
  32433. */
  32434. this.lastPresentedPosition = animationPosition;
  32435. await present(this, 'toastEnter', iosEnterAnimation, mdEnterAnimation, {
  32436. position,
  32437. top: animationPosition.top,
  32438. bottom: animationPosition.bottom,
  32439. });
  32440. /**
  32441. * Content is revealed to screen readers after
  32442. * the transition to avoid jank since this
  32443. * state updates will cause a re-render.
  32444. */
  32445. this.revealContentToScreenReader = true;
  32446. if (this.duration > 0) {
  32447. this.durationTimeout = setTimeout(() => this.dismiss(undefined, 'timeout'), this.duration);
  32448. }
  32449. /**
  32450. * If the Toast has a swipe gesture then we can
  32451. * create the gesture so users can swipe the
  32452. * presented Toast.
  32453. */
  32454. if (this.prefersSwipeGesture()) {
  32455. this.createSwipeGesture(animationPosition);
  32456. }
  32457. unlock();
  32458. }
  32459. /**
  32460. * Dismiss the toast overlay after it has been presented.
  32461. *
  32462. * @param data Any data to emit in the dismiss events.
  32463. * @param role The role of the element that is dismissing the toast.
  32464. * This can be useful in a button handler for determining which button was
  32465. * clicked to dismiss the toast.
  32466. * Some examples include: ``"cancel"`, `"destructive"`, "selected"`, and `"backdrop"`.
  32467. *
  32468. * This is a no-op if the overlay has not been presented yet. If you want
  32469. * to remove an overlay from the DOM that was never presented, use the
  32470. * [remove](https://developer.mozilla.org/en-US/docs/Web/API/Element/remove) method.
  32471. */
  32472. async dismiss(data, role) {
  32473. var _a, _b;
  32474. const unlock = await this.lockController.lock();
  32475. const { durationTimeout, position, lastPresentedPosition } = this;
  32476. if (durationTimeout) {
  32477. clearTimeout(durationTimeout);
  32478. }
  32479. const dismissed = await dismiss(this, data, role, 'toastLeave', iosLeaveAnimation, mdLeaveAnimation,
  32480. /**
  32481. * Fetch the cached position that was calculated back in the present
  32482. * animation. We always want to animate the dismiss from the same
  32483. * position the present stopped at, so the animation looks continuous.
  32484. */
  32485. {
  32486. position,
  32487. top: (_a = lastPresentedPosition === null || lastPresentedPosition === void 0 ? void 0 : lastPresentedPosition.top) !== null && _a !== void 0 ? _a : '',
  32488. bottom: (_b = lastPresentedPosition === null || lastPresentedPosition === void 0 ? void 0 : lastPresentedPosition.bottom) !== null && _b !== void 0 ? _b : '',
  32489. });
  32490. if (dismissed) {
  32491. this.delegateController.removeViewFromDom();
  32492. this.revealContentToScreenReader = false;
  32493. }
  32494. this.lastPresentedPosition = undefined;
  32495. /**
  32496. * If the Toast has a swipe gesture then we can
  32497. * safely destroy it now that it is dismissed.
  32498. */
  32499. this.destroySwipeGesture();
  32500. unlock();
  32501. return dismissed;
  32502. }
  32503. /**
  32504. * Returns a promise that resolves when the toast did dismiss.
  32505. */
  32506. onDidDismiss() {
  32507. return eventMethod(this.el, 'ionToastDidDismiss');
  32508. }
  32509. /**
  32510. * Returns a promise that resolves when the toast will dismiss.
  32511. */
  32512. onWillDismiss() {
  32513. return eventMethod(this.el, 'ionToastWillDismiss');
  32514. }
  32515. getButtons() {
  32516. const buttons = this.buttons
  32517. ? this.buttons.map((b) => {
  32518. return typeof b === 'string' ? { text: b } : b;
  32519. })
  32520. : [];
  32521. return buttons;
  32522. }
  32523. /**
  32524. * Returns the element specified by the positionAnchor prop,
  32525. * or undefined if prop's value is an ID string and the element
  32526. * is not found in the DOM.
  32527. */
  32528. getAnchorElement() {
  32529. const { position, positionAnchor, el } = this;
  32530. /**
  32531. * If positionAnchor is undefined then
  32532. * no anchor should be used when presenting the toast.
  32533. */
  32534. if (positionAnchor === undefined) {
  32535. return;
  32536. }
  32537. if (position === 'middle' && positionAnchor !== undefined) {
  32538. printIonWarning('[ion-toast] - The positionAnchor property is ignored when using position="middle".', this.el);
  32539. return undefined;
  32540. }
  32541. if (typeof positionAnchor === 'string') {
  32542. /**
  32543. * If the anchor is defined as an ID, find the element.
  32544. * We do this on every present so the toast doesn't need
  32545. * to account for the surrounding DOM changing since the
  32546. * last time it was presented.
  32547. */
  32548. const foundEl = document.getElementById(positionAnchor);
  32549. if (foundEl === null) {
  32550. printIonWarning(`[ion-toast] - An anchor element with an ID of "${positionAnchor}" was not found in the DOM.`, el);
  32551. return undefined;
  32552. }
  32553. return foundEl;
  32554. }
  32555. if (positionAnchor instanceof HTMLElement) {
  32556. return positionAnchor;
  32557. }
  32558. printIonWarning('[ion-toast] - Invalid positionAnchor value:', positionAnchor, el);
  32559. return undefined;
  32560. }
  32561. async buttonClick(button) {
  32562. const role = button.role;
  32563. if (isCancel(role)) {
  32564. return this.dismiss(undefined, role);
  32565. }
  32566. const shouldDismiss = await this.callButtonHandler(button);
  32567. if (shouldDismiss) {
  32568. return this.dismiss(undefined, role);
  32569. }
  32570. return Promise.resolve();
  32571. }
  32572. async callButtonHandler(button) {
  32573. if (button === null || button === void 0 ? void 0 : button.handler) {
  32574. // a handler has been provided, execute it
  32575. // pass the handler the values from the inputs
  32576. try {
  32577. const rtn = await safeCall(button.handler);
  32578. if (rtn === false) {
  32579. // if the return value of the handler is false then do not dismiss
  32580. return false;
  32581. }
  32582. }
  32583. catch (e) {
  32584. printIonError('[ion-toast] - Exception in callButtonHandler:', e);
  32585. }
  32586. }
  32587. return true;
  32588. }
  32589. renderButtons(buttons, side) {
  32590. if (buttons.length === 0) {
  32591. return;
  32592. }
  32593. const mode = getIonMode$1(this);
  32594. const buttonGroupsClasses = {
  32595. 'toast-button-group': true,
  32596. [`toast-button-group-${side}`]: true,
  32597. };
  32598. return (hAsync("div", { class: buttonGroupsClasses }, buttons.map((b) => (hAsync("button", Object.assign({}, b.htmlAttributes, { type: "button", class: buttonClass(b), tabIndex: 0, onClick: () => this.buttonClick(b), part: buttonPart(b) }), hAsync("div", { class: "toast-button-inner" }, b.icon && (hAsync("ion-icon", { "aria-hidden": "true", icon: b.icon, slot: b.text === undefined ? 'icon-only' : undefined, class: "toast-button-icon" })), b.text), mode === 'md' && (hAsync("ion-ripple-effect", { type: b.icon !== undefined && b.text === undefined ? 'unbounded' : 'bounded' })))))));
  32599. }
  32600. /**
  32601. * Render the `message` property.
  32602. * @param key - A key to give the element a stable identity. This is used to improve compatibility with screen readers.
  32603. * @param ariaHidden - If "true" then content will be hidden from screen readers.
  32604. */
  32605. renderToastMessage(key, ariaHidden = null) {
  32606. const { customHTMLEnabled, message } = this;
  32607. if (customHTMLEnabled) {
  32608. return (hAsync("div", { key: key, "aria-hidden": ariaHidden, class: "toast-message", part: "message", innerHTML: sanitizeDOMString(message) }));
  32609. }
  32610. return (hAsync("div", { key: key, "aria-hidden": ariaHidden, class: "toast-message", part: "message" }, message));
  32611. }
  32612. /**
  32613. * Render the `header` property.
  32614. * @param key - A key to give the element a stable identity. This is used to improve compatibility with screen readers.
  32615. * @param ariaHidden - If "true" then content will be hidden from screen readers.
  32616. */
  32617. renderHeader(key, ariaHidden = null) {
  32618. return (hAsync("div", { key: key, class: "toast-header", "aria-hidden": ariaHidden, part: "header" }, this.header));
  32619. }
  32620. render() {
  32621. const { layout, el, revealContentToScreenReader, header, message } = this;
  32622. const allButtons = this.getButtons();
  32623. const startButtons = allButtons.filter((b) => b.side === 'start');
  32624. const endButtons = allButtons.filter((b) => b.side !== 'start');
  32625. const mode = getIonMode$1(this);
  32626. const wrapperClass = {
  32627. 'toast-wrapper': true,
  32628. [`toast-${this.position}`]: true,
  32629. [`toast-layout-${layout}`]: true,
  32630. };
  32631. /**
  32632. * Stacked buttons are only meant to be
  32633. * used with one type of button.
  32634. */
  32635. if (layout === 'stacked' && startButtons.length > 0 && endButtons.length > 0) {
  32636. printIonWarning('[ion-toast] - This toast is using start and end buttons with the stacked toast layout. We recommend following the best practice of using either start or end buttons with the stacked toast layout.', el);
  32637. }
  32638. return (hAsync(Host, Object.assign({ key: 'a2216d860255c99337464370dcb12f6125871a50', tabindex: "-1" }, this.htmlAttributes, { style: {
  32639. zIndex: `${60000 + this.overlayIndex}`,
  32640. }, class: createColorClasses$1(this.color, Object.assign(Object.assign({ [mode]: true }, getClassMap(this.cssClass)), { 'overlay-hidden': true, 'toast-translucent': this.translucent })), onIonToastWillDismiss: this.dispatchCancelHandler }), hAsync("div", { key: 'd5adf8bc4c6c52431600033a76c4795689f9b412', class: wrapperClass }, hAsync("div", { key: 'ab694497ae37ceba123217eb48800129b9bebb84', class: "toast-container", part: "container" }, this.renderButtons(startButtons, 'start'), this.icon !== undefined && (hAsync("ion-icon", { key: '224854fa3989ce0eb69416cb5b0cc55fc9f131ea', class: "toast-icon", part: "icon", icon: this.icon, lazy: false, "aria-hidden": "true" })), hAsync("div", { key: 'c8e11fb5bdac202987f5c8613a0ebbd42bda946e', class: "toast-content", role: "status", "aria-atomic": "true", "aria-live": "polite" }, !revealContentToScreenReader && header !== undefined && this.renderHeader('oldHeader', 'true'), !revealContentToScreenReader && message !== undefined && this.renderToastMessage('oldMessage', 'true'), revealContentToScreenReader && header !== undefined && this.renderHeader('header'), revealContentToScreenReader && message !== undefined && this.renderToastMessage('header')), this.renderButtons(endButtons, 'end')))));
  32641. }
  32642. get el() { return getElement(this); }
  32643. static get watchers() { return {
  32644. "swipeGesture": ["swipeGestureChanged"],
  32645. "isOpen": ["onIsOpenChange"],
  32646. "trigger": ["triggerChanged"]
  32647. }; }
  32648. static get style() { return {
  32649. ios: IonToastIosStyle0,
  32650. md: IonToastMdStyle0
  32651. }; }
  32652. static get cmpMeta() { return {
  32653. "$flags$": 41,
  32654. "$tagName$": "ion-toast",
  32655. "$members$": {
  32656. "overlayIndex": [2, "overlay-index"],
  32657. "delegate": [16],
  32658. "hasController": [4, "has-controller"],
  32659. "color": [513],
  32660. "enterAnimation": [16],
  32661. "leaveAnimation": [16],
  32662. "cssClass": [1, "css-class"],
  32663. "duration": [2],
  32664. "header": [1],
  32665. "layout": [1],
  32666. "message": [1],
  32667. "keyboardClose": [4, "keyboard-close"],
  32668. "position": [1],
  32669. "positionAnchor": [1, "position-anchor"],
  32670. "buttons": [16],
  32671. "translucent": [4],
  32672. "animated": [4],
  32673. "icon": [1],
  32674. "htmlAttributes": [16],
  32675. "swipeGesture": [1, "swipe-gesture"],
  32676. "isOpen": [4, "is-open"],
  32677. "trigger": [1],
  32678. "revealContentToScreenReader": [32],
  32679. "present": [64],
  32680. "dismiss": [64],
  32681. "onDidDismiss": [64],
  32682. "onWillDismiss": [64]
  32683. },
  32684. "$listeners$": undefined,
  32685. "$lazyBundleId$": "-",
  32686. "$attrsToReflect$": [["color", "color"]]
  32687. }; }
  32688. }
  32689. const buttonClass = (button) => {
  32690. return {
  32691. 'toast-button': true,
  32692. 'toast-button-icon-only': button.icon !== undefined && button.text === undefined,
  32693. [`toast-button-${button.role}`]: button.role !== undefined,
  32694. 'ion-focusable': true,
  32695. 'ion-activatable': true,
  32696. };
  32697. };
  32698. const buttonPart = (button) => {
  32699. return isCancel(button.role) ? 'button cancel' : 'button';
  32700. };
  32701. const toggleIosCss = ":host{-webkit-box-sizing:content-box !important;box-sizing:content-box !important;display:inline-block;position:relative;max-width:100%;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;z-index:2}:host(.in-item){-ms-flex:1 1 0px;flex:1 1 0;width:100%;height:100%}:host([slot=start]),:host([slot=end]){-ms-flex:initial;flex:initial;width:auto}:host(.ion-focused) input{border:2px solid #5e9ed6}:host(.toggle-disabled){pointer-events:none}input{display:none}.toggle-wrapper{display:-ms-flexbox;display:flex;position:relative;-ms-flex-positive:1;flex-grow:1;-ms-flex-align:center;align-items:center;-ms-flex-pack:justify;justify-content:space-between;height:inherit;-webkit-transition:background-color 15ms linear;transition:background-color 15ms linear;cursor:inherit}.label-text-wrapper{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}:host(.in-item) .label-text-wrapper{margin-top:10px;margin-bottom:10px}:host(.in-item.toggle-label-placement-stacked) .label-text-wrapper{margin-top:10px;margin-bottom:16px}:host(.in-item.toggle-label-placement-stacked) .native-wrapper{margin-bottom:10px}.label-text-wrapper-hidden{display:none}.native-wrapper{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center}.toggle-bottom{padding-top:4px;display:-ms-flexbox;display:flex;-ms-flex-pack:justify;justify-content:space-between;font-size:0.75rem;white-space:normal}:host(.toggle-label-placement-stacked) .toggle-bottom{font-size:1rem}.toggle-bottom .error-text{display:none;color:var(--ion-color-danger, #c5000f)}.toggle-bottom .helper-text{display:block;color:var(--ion-color-step-700, var(--ion-text-color-step-300, #4d4d4d))}:host(.ion-touched.ion-invalid) .toggle-bottom .error-text{display:block}:host(.ion-touched.ion-invalid) .toggle-bottom .helper-text{display:none}:host(.toggle-label-placement-start) .toggle-wrapper{-ms-flex-direction:row;flex-direction:row}:host(.toggle-label-placement-start) .label-text-wrapper{-webkit-margin-start:0;margin-inline-start:0;-webkit-margin-end:16px;margin-inline-end:16px}:host(.toggle-label-placement-end) .toggle-wrapper{-ms-flex-direction:row-reverse;flex-direction:row-reverse;-ms-flex-pack:start;justify-content:start}:host(.toggle-label-placement-end) .label-text-wrapper{-webkit-margin-start:16px;margin-inline-start:16px;-webkit-margin-end:0;margin-inline-end:0}:host(.toggle-label-placement-fixed) .label-text-wrapper{-webkit-margin-start:0;margin-inline-start:0;-webkit-margin-end:16px;margin-inline-end:16px}:host(.toggle-label-placement-fixed) .label-text-wrapper{-ms-flex:0 0 100px;flex:0 0 100px;width:100px;min-width:100px;max-width:200px}:host(.toggle-label-placement-stacked) .toggle-wrapper{-ms-flex-direction:column;flex-direction:column;text-align:center}:host(.toggle-label-placement-stacked) .label-text-wrapper{-webkit-transform:scale(0.75);transform:scale(0.75);margin-left:0;margin-right:0;margin-bottom:16px;max-width:calc(100% / 0.75)}:host(.toggle-label-placement-stacked.toggle-alignment-start) .label-text-wrapper{-webkit-transform-origin:left top;transform-origin:left top}:host-context([dir=rtl]):host(.toggle-label-placement-stacked.toggle-alignment-start) .label-text-wrapper,:host-context([dir=rtl]).toggle-label-placement-stacked.toggle-alignment-start .label-text-wrapper{-webkit-transform-origin:right top;transform-origin:right top}@supports selector(:dir(rtl)){:host(.toggle-label-placement-stacked.toggle-alignment-start:dir(rtl)) .label-text-wrapper{-webkit-transform-origin:right top;transform-origin:right top}}:host(.toggle-label-placement-stacked.toggle-alignment-center) .label-text-wrapper{-webkit-transform-origin:center top;transform-origin:center top}:host-context([dir=rtl]):host(.toggle-label-placement-stacked.toggle-alignment-center) .label-text-wrapper,:host-context([dir=rtl]).toggle-label-placement-stacked.toggle-alignment-center .label-text-wrapper{-webkit-transform-origin:calc(100% - center) top;transform-origin:calc(100% - center) top}@supports selector(:dir(rtl)){:host(.toggle-label-placement-stacked.toggle-alignment-center:dir(rtl)) .label-text-wrapper{-webkit-transform-origin:calc(100% - center) top;transform-origin:calc(100% - center) top}}:host(.toggle-justify-space-between) .toggle-wrapper{-ms-flex-pack:justify;justify-content:space-between}:host(.toggle-justify-start) .toggle-wrapper{-ms-flex-pack:start;justify-content:start}:host(.toggle-justify-end) .toggle-wrapper{-ms-flex-pack:end;justify-content:end}:host(.toggle-alignment-start) .toggle-wrapper{-ms-flex-align:start;align-items:start}:host(.toggle-alignment-center) .toggle-wrapper{-ms-flex-align:center;align-items:center}:host(.toggle-justify-space-between),:host(.toggle-justify-start),:host(.toggle-justify-end),:host(.toggle-alignment-start),:host(.toggle-alignment-center){display:block}.toggle-icon-wrapper{display:-ms-flexbox;display:flex;position:relative;-ms-flex-align:center;align-items:center;width:100%;height:100%;-webkit-transition:var(--handle-transition);transition:var(--handle-transition);will-change:transform}.toggle-icon{border-radius:var(--border-radius);display:block;position:relative;width:100%;height:100%;background:var(--track-background);overflow:inherit}:host(.toggle-checked) .toggle-icon{background:var(--track-background-checked)}.toggle-inner{border-radius:var(--handle-border-radius);position:absolute;left:var(--handle-spacing);width:var(--handle-width);height:var(--handle-height);max-height:var(--handle-max-height);-webkit-transition:var(--handle-transition);transition:var(--handle-transition);background:var(--handle-background);-webkit-box-shadow:var(--handle-box-shadow);box-shadow:var(--handle-box-shadow);contain:strict}:host(.toggle-ltr) .toggle-inner{left:var(--handle-spacing)}:host(.toggle-rtl) .toggle-inner{right:var(--handle-spacing)}:host(.toggle-ltr.toggle-checked) .toggle-icon-wrapper{-webkit-transform:translate3d(calc(100% - var(--handle-width)), 0, 0);transform:translate3d(calc(100% - var(--handle-width)), 0, 0)}:host(.toggle-rtl.toggle-checked) .toggle-icon-wrapper{-webkit-transform:translate3d(calc(-100% + var(--handle-width)), 0, 0);transform:translate3d(calc(-100% + var(--handle-width)), 0, 0)}:host(.toggle-checked) .toggle-inner{background:var(--handle-background-checked)}:host(.toggle-ltr.toggle-checked) .toggle-inner{-webkit-transform:translate3d(calc(var(--handle-spacing) * -2), 0, 0);transform:translate3d(calc(var(--handle-spacing) * -2), 0, 0)}:host(.toggle-rtl.toggle-checked) .toggle-inner{-webkit-transform:translate3d(calc(var(--handle-spacing) * 2), 0, 0);transform:translate3d(calc(var(--handle-spacing) * 2), 0, 0)}:host{--track-background:rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.088);--track-background-checked:var(--ion-color-primary, #0054e9);--border-radius:15.5px;--handle-background:#ffffff;--handle-background-checked:#ffffff;--handle-border-radius:25.5px;--handle-box-shadow:0 3px 4px rgba(0, 0, 0, 0.06), 0 3px 8px rgba(0, 0, 0, 0.06);--handle-height:calc(31px - (2px * 2));--handle-max-height:calc(100% - var(--handle-spacing) * 2);--handle-width:calc(31px - (2px * 2));--handle-spacing:2px;--handle-transition:transform 300ms, width 120ms ease-in-out 80ms, left 110ms ease-in-out 80ms, right 110ms ease-in-out 80ms}.native-wrapper .toggle-icon{width:51px;height:31px;overflow:hidden}:host(.ion-color.toggle-checked) .toggle-icon{background:var(--ion-color-base)}:host(.toggle-activated) .toggle-switch-icon{opacity:0}.toggle-icon{-webkit-transform:translate3d(0, 0, 0);transform:translate3d(0, 0, 0);-webkit-transition:background-color 300ms;transition:background-color 300ms}.toggle-inner{will-change:transform}.toggle-switch-icon{position:absolute;top:50%;width:11px;height:11px;-webkit-transform:translateY(-50%);transform:translateY(-50%);-webkit-transition:opacity 300ms, color 300ms;transition:opacity 300ms, color 300ms}.toggle-switch-icon{position:absolute;color:var(--ion-color-dark, #222428)}:host(.toggle-ltr) .toggle-switch-icon{right:6px}:host(.toggle-rtl) .toggle-switch-icon{right:initial;left:6px;}:host(.toggle-checked) .toggle-switch-icon.toggle-switch-icon-checked{color:var(--ion-color-contrast, #fff)}:host(.toggle-checked) .toggle-switch-icon:not(.toggle-switch-icon-checked){opacity:0}.toggle-switch-icon-checked{position:absolute;width:15px;height:15px;-webkit-transform:translateY(-50%) rotate(90deg);transform:translateY(-50%) rotate(90deg)}:host(.toggle-ltr) .toggle-switch-icon-checked{right:initial;left:4px;}:host(.toggle-rtl) .toggle-switch-icon-checked{right:4px}:host(.toggle-activated) .toggle-icon::before,:host(.toggle-checked) .toggle-icon::before{-webkit-transform:scale3d(0, 0, 0);transform:scale3d(0, 0, 0)}:host(.toggle-activated.toggle-checked) .toggle-inner::before{-webkit-transform:scale3d(0, 0, 0);transform:scale3d(0, 0, 0)}:host(.toggle-activated) .toggle-inner{width:calc(var(--handle-width) + 6px)}:host(.toggle-ltr.toggle-activated.toggle-checked) .toggle-icon-wrapper{-webkit-transform:translate3d(calc(100% - var(--handle-width) - 6px), 0, 0);transform:translate3d(calc(100% - var(--handle-width) - 6px), 0, 0)}:host(.toggle-rtl.toggle-activated.toggle-checked) .toggle-icon-wrapper{-webkit-transform:translate3d(calc(-100% + var(--handle-width) + 6px), 0, 0);transform:translate3d(calc(-100% + var(--handle-width) + 6px), 0, 0)}:host(.toggle-disabled){opacity:0.3}";
  32702. var IonToggleIosStyle0 = toggleIosCss;
  32703. const toggleMdCss = ":host{-webkit-box-sizing:content-box !important;box-sizing:content-box !important;display:inline-block;position:relative;max-width:100%;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;z-index:2}:host(.in-item){-ms-flex:1 1 0px;flex:1 1 0;width:100%;height:100%}:host([slot=start]),:host([slot=end]){-ms-flex:initial;flex:initial;width:auto}:host(.ion-focused) input{border:2px solid #5e9ed6}:host(.toggle-disabled){pointer-events:none}input{display:none}.toggle-wrapper{display:-ms-flexbox;display:flex;position:relative;-ms-flex-positive:1;flex-grow:1;-ms-flex-align:center;align-items:center;-ms-flex-pack:justify;justify-content:space-between;height:inherit;-webkit-transition:background-color 15ms linear;transition:background-color 15ms linear;cursor:inherit}.label-text-wrapper{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}:host(.in-item) .label-text-wrapper{margin-top:10px;margin-bottom:10px}:host(.in-item.toggle-label-placement-stacked) .label-text-wrapper{margin-top:10px;margin-bottom:16px}:host(.in-item.toggle-label-placement-stacked) .native-wrapper{margin-bottom:10px}.label-text-wrapper-hidden{display:none}.native-wrapper{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center}.toggle-bottom{padding-top:4px;display:-ms-flexbox;display:flex;-ms-flex-pack:justify;justify-content:space-between;font-size:0.75rem;white-space:normal}:host(.toggle-label-placement-stacked) .toggle-bottom{font-size:1rem}.toggle-bottom .error-text{display:none;color:var(--ion-color-danger, #c5000f)}.toggle-bottom .helper-text{display:block;color:var(--ion-color-step-700, var(--ion-text-color-step-300, #4d4d4d))}:host(.ion-touched.ion-invalid) .toggle-bottom .error-text{display:block}:host(.ion-touched.ion-invalid) .toggle-bottom .helper-text{display:none}:host(.toggle-label-placement-start) .toggle-wrapper{-ms-flex-direction:row;flex-direction:row}:host(.toggle-label-placement-start) .label-text-wrapper{-webkit-margin-start:0;margin-inline-start:0;-webkit-margin-end:16px;margin-inline-end:16px}:host(.toggle-label-placement-end) .toggle-wrapper{-ms-flex-direction:row-reverse;flex-direction:row-reverse;-ms-flex-pack:start;justify-content:start}:host(.toggle-label-placement-end) .label-text-wrapper{-webkit-margin-start:16px;margin-inline-start:16px;-webkit-margin-end:0;margin-inline-end:0}:host(.toggle-label-placement-fixed) .label-text-wrapper{-webkit-margin-start:0;margin-inline-start:0;-webkit-margin-end:16px;margin-inline-end:16px}:host(.toggle-label-placement-fixed) .label-text-wrapper{-ms-flex:0 0 100px;flex:0 0 100px;width:100px;min-width:100px;max-width:200px}:host(.toggle-label-placement-stacked) .toggle-wrapper{-ms-flex-direction:column;flex-direction:column;text-align:center}:host(.toggle-label-placement-stacked) .label-text-wrapper{-webkit-transform:scale(0.75);transform:scale(0.75);margin-left:0;margin-right:0;margin-bottom:16px;max-width:calc(100% / 0.75)}:host(.toggle-label-placement-stacked.toggle-alignment-start) .label-text-wrapper{-webkit-transform-origin:left top;transform-origin:left top}:host-context([dir=rtl]):host(.toggle-label-placement-stacked.toggle-alignment-start) .label-text-wrapper,:host-context([dir=rtl]).toggle-label-placement-stacked.toggle-alignment-start .label-text-wrapper{-webkit-transform-origin:right top;transform-origin:right top}@supports selector(:dir(rtl)){:host(.toggle-label-placement-stacked.toggle-alignment-start:dir(rtl)) .label-text-wrapper{-webkit-transform-origin:right top;transform-origin:right top}}:host(.toggle-label-placement-stacked.toggle-alignment-center) .label-text-wrapper{-webkit-transform-origin:center top;transform-origin:center top}:host-context([dir=rtl]):host(.toggle-label-placement-stacked.toggle-alignment-center) .label-text-wrapper,:host-context([dir=rtl]).toggle-label-placement-stacked.toggle-alignment-center .label-text-wrapper{-webkit-transform-origin:calc(100% - center) top;transform-origin:calc(100% - center) top}@supports selector(:dir(rtl)){:host(.toggle-label-placement-stacked.toggle-alignment-center:dir(rtl)) .label-text-wrapper{-webkit-transform-origin:calc(100% - center) top;transform-origin:calc(100% - center) top}}:host(.toggle-justify-space-between) .toggle-wrapper{-ms-flex-pack:justify;justify-content:space-between}:host(.toggle-justify-start) .toggle-wrapper{-ms-flex-pack:start;justify-content:start}:host(.toggle-justify-end) .toggle-wrapper{-ms-flex-pack:end;justify-content:end}:host(.toggle-alignment-start) .toggle-wrapper{-ms-flex-align:start;align-items:start}:host(.toggle-alignment-center) .toggle-wrapper{-ms-flex-align:center;align-items:center}:host(.toggle-justify-space-between),:host(.toggle-justify-start),:host(.toggle-justify-end),:host(.toggle-alignment-start),:host(.toggle-alignment-center){display:block}.toggle-icon-wrapper{display:-ms-flexbox;display:flex;position:relative;-ms-flex-align:center;align-items:center;width:100%;height:100%;-webkit-transition:var(--handle-transition);transition:var(--handle-transition);will-change:transform}.toggle-icon{border-radius:var(--border-radius);display:block;position:relative;width:100%;height:100%;background:var(--track-background);overflow:inherit}:host(.toggle-checked) .toggle-icon{background:var(--track-background-checked)}.toggle-inner{border-radius:var(--handle-border-radius);position:absolute;left:var(--handle-spacing);width:var(--handle-width);height:var(--handle-height);max-height:var(--handle-max-height);-webkit-transition:var(--handle-transition);transition:var(--handle-transition);background:var(--handle-background);-webkit-box-shadow:var(--handle-box-shadow);box-shadow:var(--handle-box-shadow);contain:strict}:host(.toggle-ltr) .toggle-inner{left:var(--handle-spacing)}:host(.toggle-rtl) .toggle-inner{right:var(--handle-spacing)}:host(.toggle-ltr.toggle-checked) .toggle-icon-wrapper{-webkit-transform:translate3d(calc(100% - var(--handle-width)), 0, 0);transform:translate3d(calc(100% - var(--handle-width)), 0, 0)}:host(.toggle-rtl.toggle-checked) .toggle-icon-wrapper{-webkit-transform:translate3d(calc(-100% + var(--handle-width)), 0, 0);transform:translate3d(calc(-100% + var(--handle-width)), 0, 0)}:host(.toggle-checked) .toggle-inner{background:var(--handle-background-checked)}:host(.toggle-ltr.toggle-checked) .toggle-inner{-webkit-transform:translate3d(calc(var(--handle-spacing) * -2), 0, 0);transform:translate3d(calc(var(--handle-spacing) * -2), 0, 0)}:host(.toggle-rtl.toggle-checked) .toggle-inner{-webkit-transform:translate3d(calc(var(--handle-spacing) * 2), 0, 0);transform:translate3d(calc(var(--handle-spacing) * 2), 0, 0)}:host{--track-background:rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.39);--track-background-checked:rgba(var(--ion-color-primary-rgb, 0, 84, 233), 0.5);--border-radius:14px;--handle-background:#ffffff;--handle-background-checked:var(--ion-color-primary, #0054e9);--handle-border-radius:50%;--handle-box-shadow:0 3px 1px -2px rgba(0, 0, 0, 0.2), 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 1px 5px 0 rgba(0, 0, 0, 0.12);--handle-width:20px;--handle-height:20px;--handle-max-height:calc(100% + 6px);--handle-spacing:0;--handle-transition:transform 160ms cubic-bezier(0.4, 0, 0.2, 1), background-color 160ms cubic-bezier(0.4, 0, 0.2, 1)}.native-wrapper .toggle-icon{width:36px;height:14px}:host(.ion-color.toggle-checked) .toggle-icon{background:rgba(var(--ion-color-base-rgb), 0.5)}:host(.ion-color.toggle-checked) .toggle-inner{background:var(--ion-color-base)}:host(.toggle-checked) .toggle-inner{color:var(--ion-color-contrast, #fff)}.toggle-icon{-webkit-transition:background-color 160ms;transition:background-color 160ms}.toggle-inner{will-change:background-color, transform;display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;color:#000}.toggle-inner .toggle-switch-icon{-webkit-padding-start:1px;padding-inline-start:1px;-webkit-padding-end:1px;padding-inline-end:1px;padding-top:1px;padding-bottom:1px;width:100%;height:100%}:host(.toggle-disabled){opacity:0.38}";
  32704. var IonToggleMdStyle0 = toggleMdCss;
  32705. /**
  32706. * @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
  32707. *
  32708. * @slot - The label text to associate with the toggle. Use the "labelPlacement" property to control where the label is placed relative to the toggle.
  32709. *
  32710. * @part track - The background track of the toggle.
  32711. * @part handle - The toggle handle, or knob, used to change the checked state.
  32712. * @part label - The label text describing the toggle.
  32713. * @part supporting-text - Supporting text displayed beneath the toggle label.
  32714. * @part helper-text - Supporting text displayed beneath the toggle label when the toggle is valid.
  32715. * @part error-text - Supporting text displayed beneath the toggle label when the toggle is invalid and touched.
  32716. */
  32717. class Toggle {
  32718. constructor(hostRef) {
  32719. registerInstance(this, hostRef);
  32720. this.ionChange = createEvent(this, "ionChange", 7);
  32721. this.ionFocus = createEvent(this, "ionFocus", 7);
  32722. this.ionBlur = createEvent(this, "ionBlur", 7);
  32723. this.inputId = `ion-tg-${toggleIds++}`;
  32724. this.inputLabelId = `${this.inputId}-lbl`;
  32725. this.helperTextId = `${this.inputId}-helper-text`;
  32726. this.errorTextId = `${this.inputId}-error-text`;
  32727. this.lastDrag = 0;
  32728. this.inheritedAttributes = {};
  32729. this.didLoad = false;
  32730. this.setupGesture = async () => {
  32731. const { toggleTrack } = this;
  32732. if (toggleTrack) {
  32733. this.gesture = (await Promise.resolve().then(function () { return index; })).createGesture({
  32734. el: toggleTrack,
  32735. gestureName: 'toggle',
  32736. gesturePriority: 100,
  32737. threshold: 5,
  32738. passive: false,
  32739. onStart: () => this.onStart(),
  32740. onMove: (ev) => this.onMove(ev),
  32741. onEnd: (ev) => this.onEnd(ev),
  32742. });
  32743. this.disabledChanged();
  32744. }
  32745. };
  32746. this.onKeyDown = (ev) => {
  32747. if (ev.key === ' ') {
  32748. ev.preventDefault();
  32749. if (!this.disabled) {
  32750. this.toggleChecked();
  32751. }
  32752. }
  32753. };
  32754. this.onClick = (ev) => {
  32755. if (this.disabled) {
  32756. return;
  32757. }
  32758. ev.preventDefault();
  32759. if (this.lastDrag + 300 < Date.now()) {
  32760. this.toggleChecked();
  32761. }
  32762. };
  32763. /**
  32764. * Stops propagation when the display label is clicked,
  32765. * otherwise, two clicks will be triggered.
  32766. */
  32767. this.onDivLabelClick = (ev) => {
  32768. ev.stopPropagation();
  32769. };
  32770. this.onFocus = () => {
  32771. this.ionFocus.emit();
  32772. };
  32773. this.onBlur = () => {
  32774. this.ionBlur.emit();
  32775. };
  32776. this.getSwitchLabelIcon = (mode, checked) => {
  32777. if (mode === 'md') {
  32778. return checked ? checkmarkOutline : removeOutline;
  32779. }
  32780. return checked ? removeOutline : ellipseOutline;
  32781. };
  32782. this.activated = false;
  32783. this.color = undefined;
  32784. this.name = this.inputId;
  32785. this.checked = false;
  32786. this.disabled = false;
  32787. this.errorText = undefined;
  32788. this.helperText = undefined;
  32789. this.value = 'on';
  32790. this.enableOnOffLabels = config.get('toggleOnOffLabels');
  32791. this.labelPlacement = 'start';
  32792. this.justify = undefined;
  32793. this.alignment = undefined;
  32794. this.required = false;
  32795. }
  32796. disabledChanged() {
  32797. if (this.gesture) {
  32798. this.gesture.enable(!this.disabled);
  32799. }
  32800. }
  32801. toggleChecked() {
  32802. const { checked, value } = this;
  32803. const isNowChecked = !checked;
  32804. this.checked = isNowChecked;
  32805. this.setFocus();
  32806. this.ionChange.emit({
  32807. checked: isNowChecked,
  32808. value,
  32809. });
  32810. }
  32811. async connectedCallback() {
  32812. /**
  32813. * If we have not yet rendered
  32814. * ion-toggle, then toggleTrack is not defined.
  32815. * But if we are moving ion-toggle via appendChild,
  32816. * then toggleTrack will be defined.
  32817. */
  32818. if (this.didLoad) {
  32819. this.setupGesture();
  32820. }
  32821. }
  32822. componentDidLoad() {
  32823. this.setupGesture();
  32824. this.didLoad = true;
  32825. }
  32826. disconnectedCallback() {
  32827. if (this.gesture) {
  32828. this.gesture.destroy();
  32829. this.gesture = undefined;
  32830. }
  32831. }
  32832. componentWillLoad() {
  32833. this.inheritedAttributes = Object.assign({}, inheritAriaAttributes(this.el));
  32834. }
  32835. onStart() {
  32836. this.activated = true;
  32837. // touch-action does not work in iOS
  32838. this.setFocus();
  32839. }
  32840. onMove(detail) {
  32841. if (shouldToggle(isRTL$1(this.el), this.checked, detail.deltaX, -10)) {
  32842. this.toggleChecked();
  32843. hapticSelection();
  32844. }
  32845. }
  32846. onEnd(ev) {
  32847. this.activated = false;
  32848. this.lastDrag = Date.now();
  32849. ev.event.preventDefault();
  32850. ev.event.stopImmediatePropagation();
  32851. }
  32852. getValue() {
  32853. return this.value || '';
  32854. }
  32855. setFocus() {
  32856. if (this.focusEl) {
  32857. this.focusEl.focus();
  32858. }
  32859. }
  32860. renderOnOffSwitchLabels(mode, checked) {
  32861. const icon = this.getSwitchLabelIcon(mode, checked);
  32862. return (hAsync("ion-icon", { class: {
  32863. 'toggle-switch-icon': true,
  32864. 'toggle-switch-icon-checked': checked,
  32865. }, icon: icon, "aria-hidden": "true" }));
  32866. }
  32867. renderToggleControl() {
  32868. const mode = getIonMode$1(this);
  32869. const { enableOnOffLabels, checked } = this;
  32870. return (hAsync("div", { class: "toggle-icon", part: "track", ref: (el) => (this.toggleTrack = el) }, enableOnOffLabels &&
  32871. mode === 'ios' && [this.renderOnOffSwitchLabels(mode, true), this.renderOnOffSwitchLabels(mode, false)], hAsync("div", { class: "toggle-icon-wrapper" }, hAsync("div", { class: "toggle-inner", part: "handle" }, enableOnOffLabels && mode === 'md' && this.renderOnOffSwitchLabels(mode, checked)))));
  32872. }
  32873. get hasLabel() {
  32874. return this.el.textContent !== '';
  32875. }
  32876. getHintTextID() {
  32877. const { el, helperText, errorText, helperTextId, errorTextId } = this;
  32878. if (el.classList.contains('ion-touched') && el.classList.contains('ion-invalid') && errorText) {
  32879. return errorTextId;
  32880. }
  32881. if (helperText) {
  32882. return helperTextId;
  32883. }
  32884. return undefined;
  32885. }
  32886. /**
  32887. * Responsible for rendering helper text and error text.
  32888. * This element should only be rendered if hint text is set.
  32889. */
  32890. renderHintText() {
  32891. const { helperText, errorText, helperTextId, errorTextId } = this;
  32892. /**
  32893. * undefined and empty string values should
  32894. * be treated as not having helper/error text.
  32895. */
  32896. const hasHintText = !!helperText || !!errorText;
  32897. if (!hasHintText) {
  32898. return;
  32899. }
  32900. return (hAsync("div", { class: "toggle-bottom" }, hAsync("div", { id: helperTextId, class: "helper-text", part: "supporting-text helper-text" }, helperText), hAsync("div", { id: errorTextId, class: "error-text", part: "supporting-text error-text" }, errorText)));
  32901. }
  32902. render() {
  32903. const { activated, alignment, checked, color, disabled, el, errorTextId, hasLabel, inheritedAttributes, inputId, inputLabelId, justify, labelPlacement, name, required, } = this;
  32904. const mode = getIonMode$1(this);
  32905. const value = this.getValue();
  32906. const rtl = isRTL$1(el) ? 'rtl' : 'ltr';
  32907. renderHiddenInput(true, el, name, checked ? value : '', disabled);
  32908. return (hAsync(Host, { key: 'd9dad2132e9d6cf8e9844fefa009402e1a637ef8', role: "switch", "aria-checked": `${checked}`, "aria-describedby": this.getHintTextID(), "aria-invalid": this.getHintTextID() === errorTextId, onClick: this.onClick, "aria-labelledby": hasLabel ? inputLabelId : null, "aria-label": inheritedAttributes['aria-label'] || null, "aria-disabled": disabled ? 'true' : null, tabindex: disabled ? undefined : 0, onKeyDown: this.onKeyDown, class: createColorClasses$1(color, {
  32909. [mode]: true,
  32910. 'in-item': hostContext('ion-item', el),
  32911. 'toggle-activated': activated,
  32912. 'toggle-checked': checked,
  32913. 'toggle-disabled': disabled,
  32914. [`toggle-justify-${justify}`]: justify !== undefined,
  32915. [`toggle-alignment-${alignment}`]: alignment !== undefined,
  32916. [`toggle-label-placement-${labelPlacement}`]: true,
  32917. [`toggle-${rtl}`]: true,
  32918. }) }, hAsync("label", { key: '4becda2f40a735e941ecaba26f14231271e38197', class: "toggle-wrapper", htmlFor: inputId }, hAsync("input", Object.assign({ key: 'c1946dd6aa23dee3562915a7165e012c48b79890', type: "checkbox", role: "switch", "aria-checked": `${checked}`, checked: checked, disabled: disabled, id: inputId, onFocus: () => this.onFocus(), onBlur: () => this.onBlur(), ref: (focusEl) => (this.focusEl = focusEl), required: required }, inheritedAttributes)), hAsync("div", { key: '2493dc0aa587f5f9d9a7d0a388f92928f2db0cf3', class: {
  32919. 'label-text-wrapper': true,
  32920. 'label-text-wrapper-hidden': !hasLabel,
  32921. }, part: "label", id: inputLabelId, onClick: this.onDivLabelClick }, hAsync("slot", { key: '798220850b311a26b081914d5c774b757bde2992' }), this.renderHintText()), hAsync("div", { key: '3c6142c9697b60646f286f6fd59f54609377f7d0', class: "native-wrapper" }, this.renderToggleControl()))));
  32922. }
  32923. get el() { return getElement(this); }
  32924. static get watchers() { return {
  32925. "disabled": ["disabledChanged"]
  32926. }; }
  32927. static get style() { return {
  32928. ios: IonToggleIosStyle0,
  32929. md: IonToggleMdStyle0
  32930. }; }
  32931. static get cmpMeta() { return {
  32932. "$flags$": 41,
  32933. "$tagName$": "ion-toggle",
  32934. "$members$": {
  32935. "color": [513],
  32936. "name": [1],
  32937. "checked": [1028],
  32938. "disabled": [4],
  32939. "errorText": [1, "error-text"],
  32940. "helperText": [1, "helper-text"],
  32941. "value": [1],
  32942. "enableOnOffLabels": [4, "enable-on-off-labels"],
  32943. "labelPlacement": [1, "label-placement"],
  32944. "justify": [1],
  32945. "alignment": [1],
  32946. "required": [4],
  32947. "activated": [32]
  32948. },
  32949. "$listeners$": undefined,
  32950. "$lazyBundleId$": "-",
  32951. "$attrsToReflect$": [["color", "color"]]
  32952. }; }
  32953. }
  32954. const shouldToggle = (rtl, checked, deltaX, margin) => {
  32955. if (checked) {
  32956. return (!rtl && margin > deltaX) || (rtl && -margin < deltaX);
  32957. }
  32958. else {
  32959. return (!rtl && -margin < deltaX) || (rtl && margin > deltaX);
  32960. }
  32961. };
  32962. let toggleIds = 0;
  32963. const toolbarIosCss = ":host{--border-width:0;--border-style:solid;--opacity:1;--opacity-scale:1;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;display:block;position:relative;width:100%;padding-right:var(--ion-safe-area-right);padding-left:var(--ion-safe-area-left);color:var(--color);font-family:var(--ion-font-family, inherit);contain:content;z-index:10;-webkit-box-sizing:border-box;box-sizing:border-box}:host(.ion-color){color:var(--ion-color-contrast)}:host(.ion-color) .toolbar-background{background:var(--ion-color-base)}.toolbar-container{-webkit-padding-start:var(--padding-start);padding-inline-start:var(--padding-start);-webkit-padding-end:var(--padding-end);padding-inline-end:var(--padding-end);padding-top:var(--padding-top);padding-bottom:var(--padding-bottom);display:-ms-flexbox;display:flex;position:relative;-ms-flex-direction:row;flex-direction:row;-ms-flex-align:center;align-items:center;-ms-flex-pack:justify;justify-content:space-between;width:100%;min-height:var(--min-height);contain:content;overflow:hidden;z-index:10;-webkit-box-sizing:border-box;box-sizing:border-box}.toolbar-background{left:0;right:0;top:0;bottom:0;position:absolute;-webkit-transform:translateZ(0);transform:translateZ(0);border-width:var(--border-width);border-style:var(--border-style);border-color:var(--border-color);background:var(--background);contain:strict;opacity:calc(var(--opacity) * var(--opacity-scale));z-index:-1;pointer-events:none}::slotted(ion-progress-bar){left:0;right:0;bottom:0;position:absolute}:host{--background:var(--ion-toolbar-background, var(--ion-color-step-50, var(--ion-background-color-step-50, #f7f7f7)));--color:var(--ion-toolbar-color, var(--ion-text-color, #000));--border-color:var(--ion-toolbar-border-color, var(--ion-border-color, var(--ion-color-step-150, var(--ion-background-color-step-150, rgba(0, 0, 0, 0.2)))));--padding-top:3px;--padding-bottom:3px;--padding-start:4px;--padding-end:4px;--min-height:44px}.toolbar-content{-ms-flex:1;flex:1;-ms-flex-order:4;order:4;min-width:0}:host(.toolbar-segment) .toolbar-content{display:-ms-inline-flexbox;display:inline-flex}:host(.toolbar-searchbar) .toolbar-container{padding-top:0;padding-bottom:0}:host(.toolbar-searchbar) ::slotted(*){-ms-flex-item-align:start;align-self:start}:host(.toolbar-searchbar) ::slotted(ion-chip){margin-top:3px}::slotted(ion-buttons){min-height:38px}::slotted([slot=start]){-ms-flex-order:2;order:2}::slotted([slot=secondary]){-ms-flex-order:3;order:3}::slotted([slot=primary]){-ms-flex-order:5;order:5;text-align:end}::slotted([slot=end]){-ms-flex-order:6;order:6;text-align:end}:host(.toolbar-title-large) .toolbar-container{-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-align:start;align-items:flex-start}:host(.toolbar-title-large) .toolbar-content ion-title{-ms-flex:1;flex:1;-ms-flex-order:8;order:8;min-width:100%}";
  32964. var IonToolbarIosStyle0 = toolbarIosCss;
  32965. const toolbarMdCss = ":host{--border-width:0;--border-style:solid;--opacity:1;--opacity-scale:1;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;display:block;position:relative;width:100%;padding-right:var(--ion-safe-area-right);padding-left:var(--ion-safe-area-left);color:var(--color);font-family:var(--ion-font-family, inherit);contain:content;z-index:10;-webkit-box-sizing:border-box;box-sizing:border-box}:host(.ion-color){color:var(--ion-color-contrast)}:host(.ion-color) .toolbar-background{background:var(--ion-color-base)}.toolbar-container{-webkit-padding-start:var(--padding-start);padding-inline-start:var(--padding-start);-webkit-padding-end:var(--padding-end);padding-inline-end:var(--padding-end);padding-top:var(--padding-top);padding-bottom:var(--padding-bottom);display:-ms-flexbox;display:flex;position:relative;-ms-flex-direction:row;flex-direction:row;-ms-flex-align:center;align-items:center;-ms-flex-pack:justify;justify-content:space-between;width:100%;min-height:var(--min-height);contain:content;overflow:hidden;z-index:10;-webkit-box-sizing:border-box;box-sizing:border-box}.toolbar-background{left:0;right:0;top:0;bottom:0;position:absolute;-webkit-transform:translateZ(0);transform:translateZ(0);border-width:var(--border-width);border-style:var(--border-style);border-color:var(--border-color);background:var(--background);contain:strict;opacity:calc(var(--opacity) * var(--opacity-scale));z-index:-1;pointer-events:none}::slotted(ion-progress-bar){left:0;right:0;bottom:0;position:absolute}:host{--background:var(--ion-toolbar-background, var(--ion-background-color, #fff));--color:var(--ion-toolbar-color, var(--ion-text-color, #424242));--border-color:var(--ion-toolbar-border-color, var(--ion-border-color, var(--ion-color-step-150, var(--ion-background-color-step-150, #c1c4cd))));--padding-top:0;--padding-bottom:0;--padding-start:0;--padding-end:0;--min-height:56px}.toolbar-content{-ms-flex:1;flex:1;-ms-flex-order:3;order:3;min-width:0;max-width:100%}::slotted(.buttons-first-slot){-webkit-margin-start:4px;margin-inline-start:4px}::slotted(.buttons-last-slot){-webkit-margin-end:4px;margin-inline-end:4px}::slotted([slot=start]){-ms-flex-order:2;order:2}::slotted([slot=secondary]){-ms-flex-order:4;order:4}::slotted([slot=primary]){-ms-flex-order:5;order:5;text-align:end}::slotted([slot=end]){-ms-flex-order:6;order:6;text-align:end}";
  32966. var IonToolbarMdStyle0 = toolbarMdCss;
  32967. /**
  32968. * @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
  32969. *
  32970. * @slot - Content is placed between the named slots if provided without a slot.
  32971. * @slot start - Content is placed to the left of the toolbar text in LTR, and to the right in RTL.
  32972. * @slot secondary - Content is placed to the left of the toolbar text in `ios` mode, and directly to the right in `md` mode.
  32973. * @slot primary - Content is placed to the right of the toolbar text in `ios` mode, and to the far right in `md` mode.
  32974. * @slot end - Content is placed to the right of the toolbar text in LTR, and to the left in RTL.
  32975. *
  32976. * @part background - The background of the toolbar, covering the entire area behind the toolbar content.
  32977. * @part container - The container that wraps all toolbar content, including the default slot and named slot content.
  32978. * @part content - The container for the default slot, wrapping content provided without a named slot.
  32979. */
  32980. class Toolbar {
  32981. constructor(hostRef) {
  32982. registerInstance(this, hostRef);
  32983. this.childrenStyles = new Map();
  32984. this.color = undefined;
  32985. }
  32986. componentWillLoad() {
  32987. const buttons = Array.from(this.el.querySelectorAll('ion-buttons'));
  32988. const firstButtons = buttons.find((button) => {
  32989. return button.slot === 'start';
  32990. });
  32991. if (firstButtons) {
  32992. firstButtons.classList.add('buttons-first-slot');
  32993. }
  32994. const buttonsReversed = buttons.reverse();
  32995. const lastButtons = buttonsReversed.find((button) => button.slot === 'end') ||
  32996. buttonsReversed.find((button) => button.slot === 'primary') ||
  32997. buttonsReversed.find((button) => button.slot === 'secondary');
  32998. if (lastButtons) {
  32999. lastButtons.classList.add('buttons-last-slot');
  33000. }
  33001. }
  33002. childrenStyle(ev) {
  33003. ev.stopPropagation();
  33004. const tagName = ev.target.tagName;
  33005. const updatedStyles = ev.detail;
  33006. const newStyles = {};
  33007. const childStyles = this.childrenStyles.get(tagName) || {};
  33008. let hasStyleChange = false;
  33009. Object.keys(updatedStyles).forEach((key) => {
  33010. const childKey = `toolbar-${key}`;
  33011. const newValue = updatedStyles[key];
  33012. if (newValue !== childStyles[childKey]) {
  33013. hasStyleChange = true;
  33014. }
  33015. if (newValue) {
  33016. newStyles[childKey] = true;
  33017. }
  33018. });
  33019. if (hasStyleChange) {
  33020. this.childrenStyles.set(tagName, newStyles);
  33021. }
  33022. }
  33023. render() {
  33024. const mode = getIonMode$1(this);
  33025. const childStyles = {};
  33026. this.childrenStyles.forEach((value) => {
  33027. Object.assign(childStyles, value);
  33028. });
  33029. return (hAsync(Host, { key: '402afe7ce0c97883cedd0e48a5a0492a9bfe76ae', class: Object.assign(Object.assign({}, childStyles), createColorClasses$1(this.color, {
  33030. [mode]: true,
  33031. 'in-toolbar': hostContext('ion-toolbar', this.el),
  33032. })) }, hAsync("div", { key: '2465a6dc8d507ec650538378d1be2abd399c58ad', class: "toolbar-background", part: "background" }), hAsync("div", { key: '6075096afd12303b961e4fe9ad345ef2887573af', class: "toolbar-container", part: "container" }, hAsync("slot", { key: '8b7eec1148cfeb339d87cdf9273f2104703e7601', name: "start" }), hAsync("slot", { key: 'b102d3926cade24faf78b7af78ad5e192c4c0308', name: "secondary" }), hAsync("div", { key: 'c6ab2e978328324c6f9e7892024cbcd8b8987067', class: "toolbar-content", part: "content" }, hAsync("slot", { key: '86f8952c4355a9df5b4bbb95e9d0cafefd272d5b' })), hAsync("slot", { key: '501e43431da6b9dd35b47b79222f948d445f7a78', name: "primary" }), hAsync("slot", { key: '84bf1a15a5e52e8e94df9f479c4ce18004f5ab57', name: "end" }))));
  33033. }
  33034. get el() { return getElement(this); }
  33035. static get style() { return {
  33036. ios: IonToolbarIosStyle0,
  33037. md: IonToolbarMdStyle0
  33038. }; }
  33039. static get cmpMeta() { return {
  33040. "$flags$": 41,
  33041. "$tagName$": "ion-toolbar",
  33042. "$members$": {
  33043. "color": [513]
  33044. },
  33045. "$listeners$": [[0, "ionStyle", "childrenStyle"]],
  33046. "$lazyBundleId$": "-",
  33047. "$attrsToReflect$": [["color", "color"]]
  33048. }; }
  33049. }
  33050. const titleIosCss = ":host{--color:initial;display:-ms-flexbox;display:flex;-ms-flex:1;flex:1;-ms-flex-align:center;align-items:center;-webkit-transform:translateZ(0);transform:translateZ(0);color:var(--color)}:host(.ion-color){color:var(--ion-color-base)}.toolbar-title{display:block;width:100%;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;pointer-events:auto}:host(.title-small) .toolbar-title{white-space:normal}:host{top:0;-webkit-padding-start:90px;padding-inline-start:90px;-webkit-padding-end:90px;padding-inline-end:90px;padding-top:var(--padding-top);padding-bottom:var(--padding-bottom);position:absolute;width:100%;height:100%;-webkit-transform:translateZ(0);transform:translateZ(0);font-size:min(1.0625rem, 20.4px);font-weight:600;text-align:center;-webkit-box-sizing:border-box;box-sizing:border-box;pointer-events:none}:host{inset-inline-start:0}:host(.title-small){-webkit-padding-start:9px;padding-inline-start:9px;-webkit-padding-end:9px;padding-inline-end:9px;padding-top:6px;padding-bottom:16px;position:relative;font-size:min(0.8125rem, 23.4px);font-weight:normal}:host(.title-large){-webkit-padding-start:12px;padding-inline-start:12px;-webkit-padding-end:12px;padding-inline-end:12px;padding-top:2px;padding-bottom:4px;-webkit-transform-origin:left center;transform-origin:left center;position:static;-ms-flex-align:end;align-items:flex-end;min-width:100%;font-size:min(2.125rem, 61.2px);font-weight:700;text-align:start}:host(.title-large.title-rtl){-webkit-transform-origin:right center;transform-origin:right center}:host(.title-large.ion-cloned-element){--color:var(--ion-text-color, #000);font-family:var(--ion-font-family)}:host(.title-large) .toolbar-title{-webkit-transform-origin:inherit;transform-origin:inherit;width:auto}:host-context([dir=rtl]):host(.title-large) .toolbar-title,:host-context([dir=rtl]).title-large .toolbar-title{-webkit-transform-origin:calc(100% - inherit);transform-origin:calc(100% - inherit)}@supports selector(:dir(rtl)){:host(.title-large:dir(rtl)) .toolbar-title{-webkit-transform-origin:calc(100% - inherit);transform-origin:calc(100% - inherit)}}";
  33051. var IonTitleIosStyle0 = titleIosCss;
  33052. const titleMdCss = ":host{--color:initial;display:-ms-flexbox;display:flex;-ms-flex:1;flex:1;-ms-flex-align:center;align-items:center;-webkit-transform:translateZ(0);transform:translateZ(0);color:var(--color)}:host(.ion-color){color:var(--ion-color-base)}.toolbar-title{display:block;width:100%;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;pointer-events:auto}:host(.title-small) .toolbar-title{white-space:normal}:host{-webkit-padding-start:20px;padding-inline-start:20px;-webkit-padding-end:20px;padding-inline-end:20px;padding-top:0;padding-bottom:0;font-size:1.25rem;font-weight:500;letter-spacing:0.0125em}:host(.title-small){width:100%;height:100%;font-size:0.9375rem;font-weight:normal}";
  33053. var IonTitleMdStyle0 = titleMdCss;
  33054. class ToolbarTitle {
  33055. constructor(hostRef) {
  33056. registerInstance(this, hostRef);
  33057. this.ionStyle = createEvent(this, "ionStyle", 7);
  33058. this.color = undefined;
  33059. this.size = undefined;
  33060. }
  33061. sizeChanged() {
  33062. this.emitStyle();
  33063. }
  33064. connectedCallback() {
  33065. this.emitStyle();
  33066. }
  33067. emitStyle() {
  33068. const size = this.getSize();
  33069. this.ionStyle.emit({
  33070. [`title-${size}`]: true,
  33071. });
  33072. }
  33073. getSize() {
  33074. return this.size !== undefined ? this.size : 'default';
  33075. }
  33076. render() {
  33077. const mode = getIonMode$1(this);
  33078. const size = this.getSize();
  33079. return (hAsync(Host, { key: '3f7b19c99961dbb86c0a925218332528b22e6880', class: createColorClasses$1(this.color, {
  33080. [mode]: true,
  33081. [`title-${size}`]: true,
  33082. 'title-rtl': document.dir === 'rtl',
  33083. }) }, hAsync("div", { key: '12054fbdd60e40a15875e442c20143766fc34fc3', class: "toolbar-title" }, hAsync("slot", { key: '9f14fb14a67d4bd1e4536a4d64a637fbe5a151c7' }))));
  33084. }
  33085. get el() { return getElement(this); }
  33086. static get watchers() { return {
  33087. "size": ["sizeChanged"]
  33088. }; }
  33089. static get style() { return {
  33090. ios: IonTitleIosStyle0,
  33091. md: IonTitleMdStyle0
  33092. }; }
  33093. static get cmpMeta() { return {
  33094. "$flags$": 41,
  33095. "$tagName$": "ion-title",
  33096. "$members$": {
  33097. "color": [513],
  33098. "size": [1]
  33099. },
  33100. "$listeners$": undefined,
  33101. "$lazyBundleId$": "-",
  33102. "$attrsToReflect$": [["color", "color"]]
  33103. }; }
  33104. }
  33105. registerComponents([
  33106. Accordion,
  33107. AccordionGroup,
  33108. ActionSheet,
  33109. Alert,
  33110. App,
  33111. Avatar,
  33112. BackButton,
  33113. Backdrop,
  33114. Badge,
  33115. Breadcrumb,
  33116. Breadcrumbs,
  33117. Button,
  33118. Buttons,
  33119. Card,
  33120. CardContent,
  33121. CardHeader,
  33122. CardSubtitle,
  33123. CardTitle,
  33124. Checkbox,
  33125. Chip,
  33126. Col,
  33127. Content,
  33128. Datetime,
  33129. DatetimeButton,
  33130. Fab,
  33131. FabButton,
  33132. FabList,
  33133. Footer,
  33134. Grid,
  33135. Header,
  33136. Icon,
  33137. Img,
  33138. InfiniteScroll,
  33139. InfiniteScrollContent,
  33140. Input,
  33141. InputPasswordToggle,
  33142. Item,
  33143. ItemDivider,
  33144. ItemGroup,
  33145. ItemOption,
  33146. ItemOptions,
  33147. ItemSliding,
  33148. Label,
  33149. List,
  33150. ListHeader,
  33151. Loading,
  33152. Menu,
  33153. MenuButton,
  33154. MenuToggle,
  33155. Modal,
  33156. Nav,
  33157. NavLink,
  33158. Note,
  33159. Picker$1,
  33160. Picker,
  33161. PickerColumn,
  33162. PickerColumnCmp,
  33163. PickerColumnOption,
  33164. Popover,
  33165. ProgressBar,
  33166. Radio,
  33167. RadioGroup,
  33168. Range,
  33169. Refresher,
  33170. RefresherContent,
  33171. Reorder,
  33172. ReorderGroup,
  33173. RippleEffect,
  33174. Route,
  33175. RouteRedirect,
  33176. Router,
  33177. RouterLink,
  33178. RouterOutlet,
  33179. Row,
  33180. Searchbar,
  33181. Segment,
  33182. SegmentButton,
  33183. SegmentContent,
  33184. SegmentView,
  33185. Select,
  33186. SelectModal,
  33187. SelectOption,
  33188. SelectPopover,
  33189. SkeletonText,
  33190. Spinner,
  33191. SplitPane,
  33192. Tab,
  33193. TabBar,
  33194. TabButton,
  33195. Tabs,
  33196. Text,
  33197. Textarea,
  33198. Thumbnail,
  33199. Toast,
  33200. Toggle,
  33201. Toolbar,
  33202. ToolbarTitle,
  33203. ]);
  33204. const DURATION = 540;
  33205. // TODO(FW-2832): types
  33206. const getClonedElement = (tagName) => {
  33207. return document.querySelector(`${tagName}.ion-cloned-element`);
  33208. };
  33209. const shadow = (el) => {
  33210. return el.shadowRoot || el;
  33211. };
  33212. const getLargeTitle = (refEl) => {
  33213. const tabs = refEl.tagName === 'ION-TABS' ? refEl : refEl.querySelector('ion-tabs');
  33214. const query = 'ion-content ion-header:not(.header-collapse-condense-inactive) ion-title.title-large';
  33215. if (tabs != null) {
  33216. const activeTab = tabs.querySelector('ion-tab:not(.tab-hidden), .ion-page:not(.ion-page-hidden)');
  33217. return activeTab != null ? activeTab.querySelector(query) : null;
  33218. }
  33219. return refEl.querySelector(query);
  33220. };
  33221. const getBackButton = (refEl, backDirection) => {
  33222. const tabs = refEl.tagName === 'ION-TABS' ? refEl : refEl.querySelector('ion-tabs');
  33223. let buttonsList = [];
  33224. if (tabs != null) {
  33225. const activeTab = tabs.querySelector('ion-tab:not(.tab-hidden), .ion-page:not(.ion-page-hidden)');
  33226. if (activeTab != null) {
  33227. buttonsList = activeTab.querySelectorAll('ion-buttons');
  33228. }
  33229. }
  33230. else {
  33231. buttonsList = refEl.querySelectorAll('ion-buttons');
  33232. }
  33233. for (const buttons of buttonsList) {
  33234. const parentHeader = buttons.closest('ion-header');
  33235. const activeHeader = parentHeader && !parentHeader.classList.contains('header-collapse-condense-inactive');
  33236. const backButton = buttons.querySelector('ion-back-button');
  33237. const buttonsCollapse = buttons.classList.contains('buttons-collapse');
  33238. const startSlot = buttons.slot === 'start' || buttons.slot === '';
  33239. if (backButton !== null && startSlot && ((buttonsCollapse && activeHeader && backDirection) || !buttonsCollapse)) {
  33240. return backButton;
  33241. }
  33242. }
  33243. return null;
  33244. };
  33245. const createLargeTitleTransition = (rootAnimation, rtl, backDirection, enteringEl, leavingEl) => {
  33246. const enteringBackButton = getBackButton(enteringEl, backDirection);
  33247. const leavingLargeTitle = getLargeTitle(leavingEl);
  33248. const enteringLargeTitle = getLargeTitle(enteringEl);
  33249. const leavingBackButton = getBackButton(leavingEl, backDirection);
  33250. const shouldAnimationForward = enteringBackButton !== null && leavingLargeTitle !== null && !backDirection;
  33251. const shouldAnimationBackward = enteringLargeTitle !== null && leavingBackButton !== null && backDirection;
  33252. if (shouldAnimationForward) {
  33253. const leavingLargeTitleBox = leavingLargeTitle.getBoundingClientRect();
  33254. const enteringBackButtonBox = enteringBackButton.getBoundingClientRect();
  33255. const enteringBackButtonTextEl = shadow(enteringBackButton).querySelector('.button-text');
  33256. // Text element not rendered if developers pass text="" to the back button
  33257. const enteringBackButtonTextBox = enteringBackButtonTextEl === null || enteringBackButtonTextEl === void 0 ? void 0 : enteringBackButtonTextEl.getBoundingClientRect();
  33258. const leavingLargeTitleTextEl = shadow(leavingLargeTitle).querySelector('.toolbar-title');
  33259. const leavingLargeTitleTextBox = leavingLargeTitleTextEl.getBoundingClientRect();
  33260. animateLargeTitle(rootAnimation, rtl, backDirection, leavingLargeTitle, leavingLargeTitleBox, leavingLargeTitleTextBox, enteringBackButtonBox, enteringBackButtonTextEl, enteringBackButtonTextBox);
  33261. animateBackButton(rootAnimation, rtl, backDirection, enteringBackButton, enteringBackButtonBox, enteringBackButtonTextEl, enteringBackButtonTextBox, leavingLargeTitle, leavingLargeTitleTextBox);
  33262. }
  33263. else if (shouldAnimationBackward) {
  33264. const enteringLargeTitleBox = enteringLargeTitle.getBoundingClientRect();
  33265. const leavingBackButtonBox = leavingBackButton.getBoundingClientRect();
  33266. const leavingBackButtonTextEl = shadow(leavingBackButton).querySelector('.button-text');
  33267. // Text element not rendered if developers pass text="" to the back button
  33268. const leavingBackButtonTextBox = leavingBackButtonTextEl === null || leavingBackButtonTextEl === void 0 ? void 0 : leavingBackButtonTextEl.getBoundingClientRect();
  33269. const enteringLargeTitleTextEl = shadow(enteringLargeTitle).querySelector('.toolbar-title');
  33270. const enteringLargeTitleTextBox = enteringLargeTitleTextEl.getBoundingClientRect();
  33271. animateLargeTitle(rootAnimation, rtl, backDirection, enteringLargeTitle, enteringLargeTitleBox, enteringLargeTitleTextBox, leavingBackButtonBox, leavingBackButtonTextEl, leavingBackButtonTextBox);
  33272. animateBackButton(rootAnimation, rtl, backDirection, leavingBackButton, leavingBackButtonBox, leavingBackButtonTextEl, leavingBackButtonTextBox, enteringLargeTitle, enteringLargeTitleTextBox);
  33273. }
  33274. return {
  33275. forward: shouldAnimationForward,
  33276. backward: shouldAnimationBackward,
  33277. };
  33278. };
  33279. const animateBackButton = (rootAnimation, rtl, backDirection, backButtonEl, backButtonBox, backButtonTextEl, backButtonTextBox, largeTitleEl, largeTitleTextBox) => {
  33280. var _a, _b;
  33281. const BACK_BUTTON_START_OFFSET = rtl ? `calc(100% - ${backButtonBox.right + 4}px)` : `${backButtonBox.left - 4}px`;
  33282. const TEXT_ORIGIN_X = rtl ? 'right' : 'left';
  33283. const ICON_ORIGIN_X = rtl ? 'left' : 'right';
  33284. const CONTAINER_ORIGIN_X = rtl ? 'right' : 'left';
  33285. let WIDTH_SCALE = 1;
  33286. let HEIGHT_SCALE = 1;
  33287. let TEXT_START_SCALE = `scale(${HEIGHT_SCALE})`;
  33288. const TEXT_END_SCALE = 'scale(1)';
  33289. if (backButtonTextEl && backButtonTextBox) {
  33290. /**
  33291. * When the title and back button texts match then they should overlap during the
  33292. * page transition. If the texts do not match up then the back button text scale
  33293. * adjusts to not perfectly match the large title text otherwise the proportions
  33294. * will be incorrect. When the texts match we scale both the width and height to
  33295. * account for font weight differences between the title and back button.
  33296. */
  33297. const doTitleAndButtonTextsMatch = ((_a = backButtonTextEl.textContent) === null || _a === void 0 ? void 0 : _a.trim()) === ((_b = largeTitleEl.textContent) === null || _b === void 0 ? void 0 : _b.trim());
  33298. WIDTH_SCALE = largeTitleTextBox.width / backButtonTextBox.width;
  33299. /**
  33300. * Subtract an offset to account for slight sizing/padding differences between the
  33301. * title and the back button.
  33302. */
  33303. HEIGHT_SCALE = (largeTitleTextBox.height - LARGE_TITLE_SIZE_OFFSET) / backButtonTextBox.height;
  33304. /**
  33305. * Even though we set TEXT_START_SCALE to HEIGHT_SCALE above, we potentially need
  33306. * to re-compute this here since the HEIGHT_SCALE may have changed.
  33307. */
  33308. TEXT_START_SCALE = doTitleAndButtonTextsMatch ? `scale(${WIDTH_SCALE}, ${HEIGHT_SCALE})` : `scale(${HEIGHT_SCALE})`;
  33309. }
  33310. const backButtonIconEl = shadow(backButtonEl).querySelector('ion-icon');
  33311. const backButtonIconBox = backButtonIconEl.getBoundingClientRect();
  33312. /**
  33313. * We need to offset the container by the icon dimensions
  33314. * so that the back button text aligns with the large title
  33315. * text. Otherwise, the back button icon will align with the
  33316. * large title text but the back button text will not.
  33317. */
  33318. const CONTAINER_START_TRANSLATE_X = rtl
  33319. ? `${backButtonIconBox.width / 2 - (backButtonIconBox.right - backButtonBox.right)}px`
  33320. : `${backButtonBox.left - backButtonIconBox.width / 2}px`;
  33321. const CONTAINER_END_TRANSLATE_X = rtl ? `-${window.innerWidth - backButtonBox.right}px` : `${backButtonBox.left}px`;
  33322. /**
  33323. * Back button container should be
  33324. * aligned to the top of the title container
  33325. * so the texts overlap as the back button
  33326. * text begins to fade in.
  33327. */
  33328. const CONTAINER_START_TRANSLATE_Y = `${largeTitleTextBox.top}px`;
  33329. /**
  33330. * The cloned back button should align exactly with the
  33331. * real back button on the entering page otherwise there will
  33332. * be a layout shift.
  33333. */
  33334. const CONTAINER_END_TRANSLATE_Y = `${backButtonBox.top}px`;
  33335. /**
  33336. * In the forward direction, the cloned back button
  33337. * container should translate from over the large title
  33338. * to over the back button. In the backward direction,
  33339. * it should translate from over the back button to over
  33340. * the large title.
  33341. */
  33342. const FORWARD_CONTAINER_KEYFRAMES = [
  33343. { offset: 0, transform: `translate3d(${CONTAINER_START_TRANSLATE_X}, ${CONTAINER_START_TRANSLATE_Y}, 0)` },
  33344. { offset: 1, transform: `translate3d(${CONTAINER_END_TRANSLATE_X}, ${CONTAINER_END_TRANSLATE_Y}, 0)` },
  33345. ];
  33346. const BACKWARD_CONTAINER_KEYFRAMES = [
  33347. { offset: 0, transform: `translate3d(${CONTAINER_END_TRANSLATE_X}, ${CONTAINER_END_TRANSLATE_Y}, 0)` },
  33348. { offset: 1, transform: `translate3d(${CONTAINER_START_TRANSLATE_X}, ${CONTAINER_START_TRANSLATE_Y}, 0)` },
  33349. ];
  33350. const CONTAINER_KEYFRAMES = backDirection ? BACKWARD_CONTAINER_KEYFRAMES : FORWARD_CONTAINER_KEYFRAMES;
  33351. /**
  33352. * In the forward direction, the text in the cloned back button
  33353. * should start to be (roughly) the size of the large title
  33354. * and then scale down to be the size of the actual back button.
  33355. * The text should also translate, but that translate is handled
  33356. * by the container keyframes.
  33357. */
  33358. const FORWARD_TEXT_KEYFRAMES = [
  33359. { offset: 0, opacity: 0, transform: TEXT_START_SCALE },
  33360. { offset: 1, opacity: 1, transform: TEXT_END_SCALE },
  33361. ];
  33362. const BACKWARD_TEXT_KEYFRAMES = [
  33363. { offset: 0, opacity: 1, transform: TEXT_END_SCALE },
  33364. { offset: 1, opacity: 0, transform: TEXT_START_SCALE },
  33365. ];
  33366. const TEXT_KEYFRAMES = backDirection ? BACKWARD_TEXT_KEYFRAMES : FORWARD_TEXT_KEYFRAMES;
  33367. /**
  33368. * The icon should scale in/out in the second
  33369. * half of the animation. The icon should also
  33370. * translate, but that translate is handled by the
  33371. * container keyframes.
  33372. */
  33373. const FORWARD_ICON_KEYFRAMES = [
  33374. { offset: 0, opacity: 0, transform: 'scale(0.6)' },
  33375. { offset: 0.6, opacity: 0, transform: 'scale(0.6)' },
  33376. { offset: 1, opacity: 1, transform: 'scale(1)' },
  33377. ];
  33378. const BACKWARD_ICON_KEYFRAMES = [
  33379. { offset: 0, opacity: 1, transform: 'scale(1)' },
  33380. { offset: 0.2, opacity: 0, transform: 'scale(0.6)' },
  33381. { offset: 1, opacity: 0, transform: 'scale(0.6)' },
  33382. ];
  33383. const ICON_KEYFRAMES = backDirection ? BACKWARD_ICON_KEYFRAMES : FORWARD_ICON_KEYFRAMES;
  33384. const enteringBackButtonTextAnimation = createAnimation();
  33385. const enteringBackButtonIconAnimation = createAnimation();
  33386. const enteringBackButtonAnimation = createAnimation();
  33387. const clonedBackButtonEl = getClonedElement('ion-back-button');
  33388. const clonedBackButtonTextEl = shadow(clonedBackButtonEl).querySelector('.button-text');
  33389. const clonedBackButtonIconEl = shadow(clonedBackButtonEl).querySelector('ion-icon');
  33390. clonedBackButtonEl.text = backButtonEl.text;
  33391. clonedBackButtonEl.mode = backButtonEl.mode;
  33392. clonedBackButtonEl.icon = backButtonEl.icon;
  33393. clonedBackButtonEl.color = backButtonEl.color;
  33394. clonedBackButtonEl.disabled = backButtonEl.disabled;
  33395. clonedBackButtonEl.style.setProperty('display', 'block');
  33396. clonedBackButtonEl.style.setProperty('position', 'fixed');
  33397. enteringBackButtonIconAnimation.addElement(clonedBackButtonIconEl);
  33398. enteringBackButtonTextAnimation.addElement(clonedBackButtonTextEl);
  33399. enteringBackButtonAnimation.addElement(clonedBackButtonEl);
  33400. enteringBackButtonAnimation
  33401. .beforeStyles({
  33402. position: 'absolute',
  33403. top: '0px',
  33404. [CONTAINER_ORIGIN_X]: '0px',
  33405. })
  33406. /**
  33407. * The write hooks must be set on this animation as it is guaranteed to run. Other
  33408. * animations such as the back button text animation will not run if the back button
  33409. * has no visible text.
  33410. */
  33411. .beforeAddWrite(() => {
  33412. backButtonEl.style.setProperty('display', 'none');
  33413. clonedBackButtonEl.style.setProperty(TEXT_ORIGIN_X, BACK_BUTTON_START_OFFSET);
  33414. })
  33415. .afterAddWrite(() => {
  33416. backButtonEl.style.setProperty('display', '');
  33417. clonedBackButtonEl.style.setProperty('display', 'none');
  33418. clonedBackButtonEl.style.removeProperty(TEXT_ORIGIN_X);
  33419. })
  33420. .keyframes(CONTAINER_KEYFRAMES);
  33421. enteringBackButtonTextAnimation
  33422. .beforeStyles({
  33423. 'transform-origin': `${TEXT_ORIGIN_X} top`,
  33424. })
  33425. .keyframes(TEXT_KEYFRAMES);
  33426. enteringBackButtonIconAnimation
  33427. .beforeStyles({
  33428. 'transform-origin': `${ICON_ORIGIN_X} center`,
  33429. })
  33430. .keyframes(ICON_KEYFRAMES);
  33431. rootAnimation.addAnimation([
  33432. enteringBackButtonTextAnimation,
  33433. enteringBackButtonIconAnimation,
  33434. enteringBackButtonAnimation,
  33435. ]);
  33436. };
  33437. const animateLargeTitle = (rootAnimation, rtl, backDirection, largeTitleEl, largeTitleBox, largeTitleTextBox, backButtonBox, backButtonTextEl, backButtonTextBox) => {
  33438. var _a, _b;
  33439. /**
  33440. * The horizontal transform origin for the large title
  33441. */
  33442. const ORIGIN_X = rtl ? 'right' : 'left';
  33443. const TITLE_START_OFFSET = rtl ? `calc(100% - ${largeTitleBox.right}px)` : `${largeTitleBox.left}px`;
  33444. /**
  33445. * The cloned large should align exactly with the
  33446. * real large title on the leaving page otherwise there will
  33447. * be a layout shift.
  33448. */
  33449. const START_TRANSLATE_X = '0px';
  33450. const START_TRANSLATE_Y = `${largeTitleBox.top}px`;
  33451. /**
  33452. * How much to offset the large title translation by.
  33453. * This accounts for differences in sizing between the large
  33454. * title and the back button due to padding and font weight.
  33455. */
  33456. const LARGE_TITLE_TRANSLATION_OFFSET = 8;
  33457. let END_TRANSLATE_X = rtl
  33458. ? `-${window.innerWidth - backButtonBox.right - LARGE_TITLE_TRANSLATION_OFFSET}px`
  33459. : `${backButtonBox.x + LARGE_TITLE_TRANSLATION_OFFSET}px`;
  33460. /**
  33461. * How much to scale the large title up/down by.
  33462. */
  33463. let HEIGHT_SCALE = 0.5;
  33464. /**
  33465. * The large title always starts full size.
  33466. */
  33467. const START_SCALE = 'scale(1)';
  33468. /**
  33469. * By default, we don't worry about having the large title scaled to perfectly
  33470. * match the back button because we don't know if the back button's text matches
  33471. * the large title's text.
  33472. */
  33473. let END_SCALE = `scale(${HEIGHT_SCALE})`;
  33474. // Text element not rendered if developers pass text="" to the back button
  33475. if (backButtonTextEl && backButtonTextBox) {
  33476. /**
  33477. * The scaled title should (roughly) overlap the back button. This ensures that
  33478. * the back button and title overlap during the animation. Note that since both
  33479. * elements either fade in or fade out over the course of the animation, neither
  33480. * element will be fully visible on top of the other. As a result, the overlap
  33481. * does not need to be perfect, so approximate values are acceptable here.
  33482. */
  33483. END_TRANSLATE_X = rtl
  33484. ? `-${window.innerWidth - backButtonTextBox.right - LARGE_TITLE_TRANSLATION_OFFSET}px`
  33485. : `${backButtonTextBox.x - LARGE_TITLE_TRANSLATION_OFFSET}px`;
  33486. /**
  33487. * In the forward direction, the large title should start at its normal size and
  33488. * then scale down to be (roughly) the size of the back button on the other view.
  33489. * In the backward direction, the large title should start at (roughly) the size
  33490. * of the back button and then scale up to its original size.
  33491. * Note that since both elements either fade in or fade out over the course of the
  33492. * animation, neither element will be fully visible on top of the other. As a result,
  33493. * the overlap does not need to be perfect, so approximate values are acceptable here.
  33494. */
  33495. /**
  33496. * When the title and back button texts match then they should overlap during the
  33497. * page transition. If the texts do not match up then the large title text scale
  33498. * adjusts to not perfectly match the back button text otherwise the proportions
  33499. * will be incorrect. When the texts match we scale both the width and height to
  33500. * account for font weight differences between the title and back button.
  33501. */
  33502. const doTitleAndButtonTextsMatch = ((_a = backButtonTextEl.textContent) === null || _a === void 0 ? void 0 : _a.trim()) === ((_b = largeTitleEl.textContent) === null || _b === void 0 ? void 0 : _b.trim());
  33503. const WIDTH_SCALE = backButtonTextBox.width / largeTitleTextBox.width;
  33504. HEIGHT_SCALE = backButtonTextBox.height / (largeTitleTextBox.height - LARGE_TITLE_SIZE_OFFSET);
  33505. /**
  33506. * Even though we set TEXT_START_SCALE to HEIGHT_SCALE above, we potentially need
  33507. * to re-compute this here since the HEIGHT_SCALE may have changed.
  33508. */
  33509. END_SCALE = doTitleAndButtonTextsMatch ? `scale(${WIDTH_SCALE}, ${HEIGHT_SCALE})` : `scale(${HEIGHT_SCALE})`;
  33510. }
  33511. /**
  33512. * The midpoints of the back button and the title should align such that the back
  33513. * button and title appear to be centered with each other.
  33514. */
  33515. const backButtonMidPoint = backButtonBox.top + backButtonBox.height / 2;
  33516. const titleMidPoint = (largeTitleBox.height * HEIGHT_SCALE) / 2;
  33517. const END_TRANSLATE_Y = `${backButtonMidPoint - titleMidPoint}px`;
  33518. const BACKWARDS_KEYFRAMES = [
  33519. { offset: 0, opacity: 0, transform: `translate3d(${END_TRANSLATE_X}, ${END_TRANSLATE_Y}, 0) ${END_SCALE}` },
  33520. { offset: 0.1, opacity: 0 },
  33521. { offset: 1, opacity: 1, transform: `translate3d(${START_TRANSLATE_X}, ${START_TRANSLATE_Y}, 0) ${START_SCALE}` },
  33522. ];
  33523. const FORWARDS_KEYFRAMES = [
  33524. {
  33525. offset: 0,
  33526. opacity: 0.99,
  33527. transform: `translate3d(${START_TRANSLATE_X}, ${START_TRANSLATE_Y}, 0) ${START_SCALE}`,
  33528. },
  33529. { offset: 0.6, opacity: 0 },
  33530. { offset: 1, opacity: 0, transform: `translate3d(${END_TRANSLATE_X}, ${END_TRANSLATE_Y}, 0) ${END_SCALE}` },
  33531. ];
  33532. const KEYFRAMES = backDirection ? BACKWARDS_KEYFRAMES : FORWARDS_KEYFRAMES;
  33533. const clonedTitleEl = getClonedElement('ion-title');
  33534. const clonedLargeTitleAnimation = createAnimation();
  33535. clonedTitleEl.innerText = largeTitleEl.innerText;
  33536. clonedTitleEl.size = largeTitleEl.size;
  33537. clonedTitleEl.color = largeTitleEl.color;
  33538. clonedLargeTitleAnimation.addElement(clonedTitleEl);
  33539. clonedLargeTitleAnimation
  33540. .beforeStyles({
  33541. 'transform-origin': `${ORIGIN_X} top`,
  33542. /**
  33543. * Since font size changes will cause
  33544. * the dimension of the large title to change
  33545. * we need to set the cloned title height
  33546. * equal to that of the original large title height.
  33547. */
  33548. height: `${largeTitleBox.height}px`,
  33549. display: '',
  33550. position: 'relative',
  33551. [ORIGIN_X]: TITLE_START_OFFSET,
  33552. })
  33553. .beforeAddWrite(() => {
  33554. largeTitleEl.style.setProperty('opacity', '0');
  33555. })
  33556. .afterAddWrite(() => {
  33557. largeTitleEl.style.setProperty('opacity', '');
  33558. clonedTitleEl.style.setProperty('display', 'none');
  33559. })
  33560. .keyframes(KEYFRAMES);
  33561. rootAnimation.addAnimation(clonedLargeTitleAnimation);
  33562. };
  33563. const iosTransitionAnimation = (navEl, opts) => {
  33564. var _a;
  33565. try {
  33566. const EASING = 'cubic-bezier(0.32,0.72,0,1)';
  33567. const OPACITY = 'opacity';
  33568. const TRANSFORM = 'transform';
  33569. const CENTER = '0%';
  33570. const OFF_OPACITY = 0.8;
  33571. const isRTL = navEl.ownerDocument.dir === 'rtl';
  33572. const OFF_RIGHT = isRTL ? '-99.5%' : '99.5%';
  33573. const OFF_LEFT = isRTL ? '33%' : '-33%';
  33574. const enteringEl = opts.enteringEl;
  33575. const leavingEl = opts.leavingEl;
  33576. const backDirection = opts.direction === 'back';
  33577. const contentEl = enteringEl.querySelector(':scope > ion-content');
  33578. const headerEls = enteringEl.querySelectorAll(':scope > ion-header > *:not(ion-toolbar), :scope > ion-footer > *');
  33579. const enteringToolBarEls = enteringEl.querySelectorAll(':scope > ion-header > ion-toolbar');
  33580. const rootAnimation = createAnimation();
  33581. const enteringContentAnimation = createAnimation();
  33582. rootAnimation
  33583. .addElement(enteringEl)
  33584. .duration(((_a = opts.duration) !== null && _a !== void 0 ? _a : 0) || DURATION)
  33585. .easing(opts.easing || EASING)
  33586. .fill('both')
  33587. .beforeRemoveClass('ion-page-invisible');
  33588. // eslint-disable-next-line @typescript-eslint/prefer-optional-chain
  33589. if (leavingEl && navEl !== null && navEl !== undefined) {
  33590. const navDecorAnimation = createAnimation();
  33591. navDecorAnimation.addElement(navEl);
  33592. rootAnimation.addAnimation(navDecorAnimation);
  33593. }
  33594. if (!contentEl && enteringToolBarEls.length === 0 && headerEls.length === 0) {
  33595. enteringContentAnimation.addElement(enteringEl.querySelector(':scope > .ion-page, :scope > ion-nav, :scope > ion-tabs')); // REVIEW
  33596. }
  33597. else {
  33598. enteringContentAnimation.addElement(contentEl); // REVIEW
  33599. enteringContentAnimation.addElement(headerEls);
  33600. }
  33601. rootAnimation.addAnimation(enteringContentAnimation);
  33602. if (backDirection) {
  33603. enteringContentAnimation
  33604. .beforeClearStyles([OPACITY])
  33605. .fromTo('transform', `translateX(${OFF_LEFT})`, `translateX(${CENTER})`)
  33606. .fromTo(OPACITY, OFF_OPACITY, 1);
  33607. }
  33608. else {
  33609. // entering content, forward direction
  33610. enteringContentAnimation
  33611. .beforeClearStyles([OPACITY])
  33612. .fromTo('transform', `translateX(${OFF_RIGHT})`, `translateX(${CENTER})`);
  33613. }
  33614. if (contentEl) {
  33615. const enteringTransitionEffectEl = shadow(contentEl).querySelector('.transition-effect');
  33616. if (enteringTransitionEffectEl) {
  33617. const enteringTransitionCoverEl = enteringTransitionEffectEl.querySelector('.transition-cover');
  33618. const enteringTransitionShadowEl = enteringTransitionEffectEl.querySelector('.transition-shadow');
  33619. const enteringTransitionEffect = createAnimation();
  33620. const enteringTransitionCover = createAnimation();
  33621. const enteringTransitionShadow = createAnimation();
  33622. enteringTransitionEffect
  33623. .addElement(enteringTransitionEffectEl)
  33624. .beforeStyles({ opacity: '1', display: 'block' })
  33625. .afterStyles({ opacity: '', display: '' });
  33626. enteringTransitionCover
  33627. .addElement(enteringTransitionCoverEl) // REVIEW
  33628. .beforeClearStyles([OPACITY])
  33629. .fromTo(OPACITY, 0, 0.1);
  33630. enteringTransitionShadow
  33631. .addElement(enteringTransitionShadowEl) // REVIEW
  33632. .beforeClearStyles([OPACITY])
  33633. .fromTo(OPACITY, 0.03, 0.7);
  33634. enteringTransitionEffect.addAnimation([enteringTransitionCover, enteringTransitionShadow]);
  33635. enteringContentAnimation.addAnimation([enteringTransitionEffect]);
  33636. }
  33637. }
  33638. const enteringContentHasLargeTitle = enteringEl.querySelector('ion-header.header-collapse-condense');
  33639. const { forward, backward } = createLargeTitleTransition(rootAnimation, isRTL, backDirection, enteringEl, leavingEl);
  33640. enteringToolBarEls.forEach((enteringToolBarEl) => {
  33641. const enteringToolBar = createAnimation();
  33642. enteringToolBar.addElement(enteringToolBarEl);
  33643. rootAnimation.addAnimation(enteringToolBar);
  33644. const enteringTitle = createAnimation();
  33645. enteringTitle.addElement(enteringToolBarEl.querySelector('ion-title')); // REVIEW
  33646. const enteringToolBarButtons = createAnimation();
  33647. const buttons = Array.from(enteringToolBarEl.querySelectorAll('ion-buttons,[menuToggle]'));
  33648. const parentHeader = enteringToolBarEl.closest('ion-header');
  33649. const inactiveHeader = parentHeader === null || parentHeader === void 0 ? void 0 : parentHeader.classList.contains('header-collapse-condense-inactive');
  33650. let buttonsToAnimate;
  33651. if (backDirection) {
  33652. buttonsToAnimate = buttons.filter((button) => {
  33653. const isCollapseButton = button.classList.contains('buttons-collapse');
  33654. return (isCollapseButton && !inactiveHeader) || !isCollapseButton;
  33655. });
  33656. }
  33657. else {
  33658. buttonsToAnimate = buttons.filter((button) => !button.classList.contains('buttons-collapse'));
  33659. }
  33660. enteringToolBarButtons.addElement(buttonsToAnimate);
  33661. const enteringToolBarItems = createAnimation();
  33662. enteringToolBarItems.addElement(enteringToolBarEl.querySelectorAll(':scope > *:not(ion-title):not(ion-buttons):not([menuToggle])'));
  33663. const enteringToolBarBg = createAnimation();
  33664. enteringToolBarBg.addElement(shadow(enteringToolBarEl).querySelector('.toolbar-background')); // REVIEW
  33665. const enteringBackButton = createAnimation();
  33666. const backButtonEl = enteringToolBarEl.querySelector('ion-back-button');
  33667. if (backButtonEl) {
  33668. enteringBackButton.addElement(backButtonEl);
  33669. }
  33670. enteringToolBar.addAnimation([
  33671. enteringTitle,
  33672. enteringToolBarButtons,
  33673. enteringToolBarItems,
  33674. enteringToolBarBg,
  33675. enteringBackButton,
  33676. ]);
  33677. enteringToolBarButtons.fromTo(OPACITY, 0.01, 1);
  33678. enteringToolBarItems.fromTo(OPACITY, 0.01, 1);
  33679. if (backDirection) {
  33680. if (!inactiveHeader) {
  33681. enteringTitle
  33682. .fromTo('transform', `translateX(${OFF_LEFT})`, `translateX(${CENTER})`)
  33683. .fromTo(OPACITY, 0.01, 1);
  33684. }
  33685. enteringToolBarItems.fromTo('transform', `translateX(${OFF_LEFT})`, `translateX(${CENTER})`);
  33686. // back direction, entering page has a back button
  33687. enteringBackButton.fromTo(OPACITY, 0.01, 1);
  33688. }
  33689. else {
  33690. // entering toolbar, forward direction
  33691. if (!enteringContentHasLargeTitle) {
  33692. enteringTitle
  33693. .fromTo('transform', `translateX(${OFF_RIGHT})`, `translateX(${CENTER})`)
  33694. .fromTo(OPACITY, 0.01, 1);
  33695. }
  33696. enteringToolBarItems.fromTo('transform', `translateX(${OFF_RIGHT})`, `translateX(${CENTER})`);
  33697. enteringToolBarBg.beforeClearStyles([OPACITY, 'transform']);
  33698. const translucentHeader = parentHeader === null || parentHeader === void 0 ? void 0 : parentHeader.translucent;
  33699. if (!translucentHeader) {
  33700. enteringToolBarBg.fromTo(OPACITY, 0.01, 'var(--opacity)');
  33701. }
  33702. else {
  33703. enteringToolBarBg.fromTo('transform', isRTL ? 'translateX(-100%)' : 'translateX(100%)', 'translateX(0px)');
  33704. }
  33705. // forward direction, entering page has a back button
  33706. if (!forward) {
  33707. enteringBackButton.fromTo(OPACITY, 0.01, 1);
  33708. }
  33709. if (backButtonEl && !forward) {
  33710. const enteringBackBtnText = createAnimation();
  33711. enteringBackBtnText
  33712. .addElement(shadow(backButtonEl).querySelector('.button-text')) // REVIEW
  33713. .fromTo(`transform`, isRTL ? 'translateX(-100px)' : 'translateX(100px)', 'translateX(0px)');
  33714. enteringToolBar.addAnimation(enteringBackBtnText);
  33715. }
  33716. }
  33717. });
  33718. // setup leaving view
  33719. if (leavingEl) {
  33720. const leavingContent = createAnimation();
  33721. const leavingContentEl = leavingEl.querySelector(':scope > ion-content');
  33722. const leavingToolBarEls = leavingEl.querySelectorAll(':scope > ion-header > ion-toolbar');
  33723. const leavingHeaderEls = leavingEl.querySelectorAll(':scope > ion-header > *:not(ion-toolbar), :scope > ion-footer > *');
  33724. if (!leavingContentEl && leavingToolBarEls.length === 0 && leavingHeaderEls.length === 0) {
  33725. leavingContent.addElement(leavingEl.querySelector(':scope > .ion-page, :scope > ion-nav, :scope > ion-tabs')); // REVIEW
  33726. }
  33727. else {
  33728. leavingContent.addElement(leavingContentEl); // REVIEW
  33729. leavingContent.addElement(leavingHeaderEls);
  33730. }
  33731. rootAnimation.addAnimation(leavingContent);
  33732. if (backDirection) {
  33733. // leaving content, back direction
  33734. leavingContent
  33735. .beforeClearStyles([OPACITY])
  33736. .fromTo('transform', `translateX(${CENTER})`, isRTL ? 'translateX(-100%)' : 'translateX(100%)');
  33737. const leavingPage = getIonPageElement(leavingEl);
  33738. rootAnimation.afterAddWrite(() => {
  33739. if (rootAnimation.getDirection() === 'normal') {
  33740. leavingPage.style.setProperty('display', 'none');
  33741. }
  33742. });
  33743. }
  33744. else {
  33745. // leaving content, forward direction
  33746. leavingContent
  33747. .fromTo('transform', `translateX(${CENTER})`, `translateX(${OFF_LEFT})`)
  33748. .fromTo(OPACITY, 1, OFF_OPACITY);
  33749. }
  33750. if (leavingContentEl) {
  33751. const leavingTransitionEffectEl = shadow(leavingContentEl).querySelector('.transition-effect');
  33752. if (leavingTransitionEffectEl) {
  33753. const leavingTransitionCoverEl = leavingTransitionEffectEl.querySelector('.transition-cover');
  33754. const leavingTransitionShadowEl = leavingTransitionEffectEl.querySelector('.transition-shadow');
  33755. const leavingTransitionEffect = createAnimation();
  33756. const leavingTransitionCover = createAnimation();
  33757. const leavingTransitionShadow = createAnimation();
  33758. leavingTransitionEffect
  33759. .addElement(leavingTransitionEffectEl)
  33760. .beforeStyles({ opacity: '1', display: 'block' })
  33761. .afterStyles({ opacity: '', display: '' });
  33762. leavingTransitionCover
  33763. .addElement(leavingTransitionCoverEl) // REVIEW
  33764. .beforeClearStyles([OPACITY])
  33765. .fromTo(OPACITY, 0.1, 0);
  33766. leavingTransitionShadow
  33767. .addElement(leavingTransitionShadowEl) // REVIEW
  33768. .beforeClearStyles([OPACITY])
  33769. .fromTo(OPACITY, 0.7, 0.03);
  33770. leavingTransitionEffect.addAnimation([leavingTransitionCover, leavingTransitionShadow]);
  33771. leavingContent.addAnimation([leavingTransitionEffect]);
  33772. }
  33773. }
  33774. leavingToolBarEls.forEach((leavingToolBarEl) => {
  33775. const leavingToolBar = createAnimation();
  33776. leavingToolBar.addElement(leavingToolBarEl);
  33777. const leavingTitle = createAnimation();
  33778. leavingTitle.addElement(leavingToolBarEl.querySelector('ion-title')); // REVIEW
  33779. const leavingToolBarButtons = createAnimation();
  33780. const buttons = leavingToolBarEl.querySelectorAll('ion-buttons,[menuToggle]');
  33781. const parentHeader = leavingToolBarEl.closest('ion-header');
  33782. const inactiveHeader = parentHeader === null || parentHeader === void 0 ? void 0 : parentHeader.classList.contains('header-collapse-condense-inactive');
  33783. const buttonsToAnimate = Array.from(buttons).filter((button) => {
  33784. const isCollapseButton = button.classList.contains('buttons-collapse');
  33785. return (isCollapseButton && !inactiveHeader) || !isCollapseButton;
  33786. });
  33787. leavingToolBarButtons.addElement(buttonsToAnimate);
  33788. const leavingToolBarItems = createAnimation();
  33789. const leavingToolBarItemEls = leavingToolBarEl.querySelectorAll(':scope > *:not(ion-title):not(ion-buttons):not([menuToggle])');
  33790. if (leavingToolBarItemEls.length > 0) {
  33791. leavingToolBarItems.addElement(leavingToolBarItemEls);
  33792. }
  33793. const leavingToolBarBg = createAnimation();
  33794. leavingToolBarBg.addElement(shadow(leavingToolBarEl).querySelector('.toolbar-background')); // REVIEW
  33795. const leavingBackButton = createAnimation();
  33796. const backButtonEl = leavingToolBarEl.querySelector('ion-back-button');
  33797. if (backButtonEl) {
  33798. leavingBackButton.addElement(backButtonEl);
  33799. }
  33800. leavingToolBar.addAnimation([
  33801. leavingTitle,
  33802. leavingToolBarButtons,
  33803. leavingToolBarItems,
  33804. leavingBackButton,
  33805. leavingToolBarBg,
  33806. ]);
  33807. rootAnimation.addAnimation(leavingToolBar);
  33808. // fade out leaving toolbar items
  33809. leavingBackButton.fromTo(OPACITY, 0.99, 0);
  33810. leavingToolBarButtons.fromTo(OPACITY, 0.99, 0);
  33811. leavingToolBarItems.fromTo(OPACITY, 0.99, 0);
  33812. if (backDirection) {
  33813. if (!inactiveHeader) {
  33814. // leaving toolbar, back direction
  33815. leavingTitle
  33816. .fromTo('transform', `translateX(${CENTER})`, isRTL ? 'translateX(-100%)' : 'translateX(100%)')
  33817. .fromTo(OPACITY, 0.99, 0);
  33818. }
  33819. leavingToolBarItems.fromTo('transform', `translateX(${CENTER})`, isRTL ? 'translateX(-100%)' : 'translateX(100%)');
  33820. leavingToolBarBg.beforeClearStyles([OPACITY, 'transform']);
  33821. // leaving toolbar, back direction, and there's no entering toolbar
  33822. // should just slide out, no fading out
  33823. const translucentHeader = parentHeader === null || parentHeader === void 0 ? void 0 : parentHeader.translucent;
  33824. if (!translucentHeader) {
  33825. leavingToolBarBg.fromTo(OPACITY, 'var(--opacity)', 0);
  33826. }
  33827. else {
  33828. leavingToolBarBg.fromTo('transform', 'translateX(0px)', isRTL ? 'translateX(-100%)' : 'translateX(100%)');
  33829. }
  33830. if (backButtonEl && !backward) {
  33831. const leavingBackBtnText = createAnimation();
  33832. leavingBackBtnText
  33833. .addElement(shadow(backButtonEl).querySelector('.button-text')) // REVIEW
  33834. .fromTo('transform', `translateX(${CENTER})`, `translateX(${(isRTL ? -124 : 124) + 'px'})`);
  33835. leavingToolBar.addAnimation(leavingBackBtnText);
  33836. }
  33837. }
  33838. else {
  33839. // leaving toolbar, forward direction
  33840. if (!inactiveHeader) {
  33841. leavingTitle
  33842. .fromTo('transform', `translateX(${CENTER})`, `translateX(${OFF_LEFT})`)
  33843. .fromTo(OPACITY, 0.99, 0)
  33844. .afterClearStyles([TRANSFORM, OPACITY]);
  33845. }
  33846. leavingToolBarItems
  33847. .fromTo('transform', `translateX(${CENTER})`, `translateX(${OFF_LEFT})`)
  33848. .afterClearStyles([TRANSFORM, OPACITY]);
  33849. leavingBackButton.afterClearStyles([OPACITY]);
  33850. leavingTitle.afterClearStyles([OPACITY]);
  33851. leavingToolBarButtons.afterClearStyles([OPACITY]);
  33852. }
  33853. });
  33854. }
  33855. return rootAnimation;
  33856. }
  33857. catch (err) {
  33858. throw err;
  33859. }
  33860. };
  33861. /**
  33862. * The scale of the back button during the animation
  33863. * is computed based on the scale of the large title
  33864. * and vice versa. However, we need to account for slight
  33865. * variations in the size of the large title due to
  33866. * padding and font weight. This value should be used to subtract
  33867. * a small amount from the large title height when computing scales
  33868. * to get more accurate scale results.
  33869. */
  33870. const LARGE_TITLE_SIZE_OFFSET = 10;
  33871. var ios_transition = /*#__PURE__*/Object.freeze({
  33872. __proto__: null,
  33873. shadow: shadow,
  33874. iosTransitionAnimation: iosTransitionAnimation
  33875. });
  33876. const mdTransitionAnimation = (_, opts) => {
  33877. var _a, _b, _c;
  33878. const OFF_BOTTOM = '40px';
  33879. const CENTER = '0px';
  33880. const backDirection = opts.direction === 'back';
  33881. const enteringEl = opts.enteringEl;
  33882. const leavingEl = opts.leavingEl;
  33883. const ionPageElement = getIonPageElement(enteringEl);
  33884. const enteringToolbarEle = ionPageElement.querySelector('ion-toolbar');
  33885. const rootTransition = createAnimation();
  33886. rootTransition.addElement(ionPageElement).fill('both').beforeRemoveClass('ion-page-invisible');
  33887. // animate the component itself
  33888. if (backDirection) {
  33889. rootTransition.duration(((_a = opts.duration) !== null && _a !== void 0 ? _a : 0) || 200).easing('cubic-bezier(0.47,0,0.745,0.715)');
  33890. }
  33891. else {
  33892. rootTransition
  33893. .duration(((_b = opts.duration) !== null && _b !== void 0 ? _b : 0) || 280)
  33894. .easing('cubic-bezier(0.36,0.66,0.04,1)')
  33895. .fromTo('transform', `translateY(${OFF_BOTTOM})`, `translateY(${CENTER})`)
  33896. .fromTo('opacity', 0.01, 1);
  33897. }
  33898. // Animate toolbar if it's there
  33899. if (enteringToolbarEle) {
  33900. const enteringToolBar = createAnimation();
  33901. enteringToolBar.addElement(enteringToolbarEle);
  33902. rootTransition.addAnimation(enteringToolBar);
  33903. }
  33904. // setup leaving view
  33905. if (leavingEl && backDirection) {
  33906. // leaving content
  33907. rootTransition.duration(((_c = opts.duration) !== null && _c !== void 0 ? _c : 0) || 200).easing('cubic-bezier(0.47,0,0.745,0.715)');
  33908. const leavingPage = createAnimation();
  33909. leavingPage
  33910. .addElement(getIonPageElement(leavingEl))
  33911. .onFinish((currentStep) => {
  33912. if (currentStep === 1 && leavingPage.elements.length > 0) {
  33913. leavingPage.elements[0].style.setProperty('display', 'none');
  33914. }
  33915. })
  33916. .fromTo('transform', `translateY(${CENTER})`, `translateY(${OFF_BOTTOM})`)
  33917. .fromTo('opacity', 1, 0);
  33918. rootTransition.addAnimation(leavingPage);
  33919. }
  33920. return rootTransition;
  33921. };
  33922. var md_transition = /*#__PURE__*/Object.freeze({
  33923. __proto__: null,
  33924. mdTransitionAnimation: mdTransitionAnimation
  33925. });
  33926. const createSwipeBackGesture = (el, canStartHandler, onStartHandler, onMoveHandler, onEndHandler) => {
  33927. const win = el.ownerDocument.defaultView;
  33928. let rtl = isRTL$1(el);
  33929. /**
  33930. * Determine if a gesture is near the edge
  33931. * of the screen. If true, then the swipe
  33932. * to go back gesture should proceed.
  33933. */
  33934. const isAtEdge = (detail) => {
  33935. const threshold = 50;
  33936. const { startX } = detail;
  33937. if (rtl) {
  33938. return startX >= win.innerWidth - threshold;
  33939. }
  33940. return startX <= threshold;
  33941. };
  33942. const getDeltaX = (detail) => {
  33943. return rtl ? -detail.deltaX : detail.deltaX;
  33944. };
  33945. const getVelocityX = (detail) => {
  33946. return rtl ? -detail.velocityX : detail.velocityX;
  33947. };
  33948. const canStart = (detail) => {
  33949. /**
  33950. * The user's locale can change mid-session,
  33951. * so we need to check text direction at
  33952. * the beginning of every gesture.
  33953. */
  33954. rtl = isRTL$1(el);
  33955. return isAtEdge(detail) && canStartHandler();
  33956. };
  33957. const onMove = (detail) => {
  33958. // set the transition animation's progress
  33959. const delta = getDeltaX(detail);
  33960. const stepValue = delta / win.innerWidth;
  33961. onMoveHandler(stepValue);
  33962. };
  33963. const onEnd = (detail) => {
  33964. // the swipe back gesture has ended
  33965. const delta = getDeltaX(detail);
  33966. const width = win.innerWidth;
  33967. const stepValue = delta / width;
  33968. const velocity = getVelocityX(detail);
  33969. const z = width / 2.0;
  33970. const shouldComplete = velocity >= 0 && (velocity > 0.2 || delta > z);
  33971. const missing = shouldComplete ? 1 - stepValue : stepValue;
  33972. const missingDistance = missing * width;
  33973. let realDur = 0;
  33974. if (missingDistance > 5) {
  33975. const dur = missingDistance / Math.abs(velocity);
  33976. realDur = Math.min(dur, 540);
  33977. }
  33978. onEndHandler(shouldComplete, stepValue <= 0 ? 0.01 : clamp(0, stepValue, 0.9999), realDur);
  33979. };
  33980. return createGesture({
  33981. el,
  33982. gestureName: 'goback-swipe',
  33983. /**
  33984. * Swipe to go back should have priority over other horizontal swipe
  33985. * gestures. These gestures have a priority of 100 which is why 101 was chosen here.
  33986. */
  33987. gesturePriority: 101,
  33988. threshold: 10,
  33989. canStart,
  33990. onStart: onStartHandler,
  33991. onMove,
  33992. onEnd,
  33993. });
  33994. };
  33995. var swipeBack = /*#__PURE__*/Object.freeze({
  33996. __proto__: null,
  33997. createSwipeBackGesture: createSwipeBackGesture
  33998. });
  33999. exports.hydrateApp = hydrateApp;
  34000. /*hydrateAppClosure end*/
  34001. hydrateApp(window, $stencilHydrateOpts, $stencilHydrateResults, $stencilAfterHydrate, $stencilHydrateResolve);
  34002. }
  34003. hydrateAppClosure($stencilWindow);
  34004. }
  34005. /*
  34006. Stencil Hydrate Runner v4.20.0 | MIT Licensed | https://stenciljs.com
  34007. */
  34008. var __defProp = Object.defineProperty;
  34009. var __export = (target, all) => {
  34010. for (var name in all)
  34011. __defProp(target, name, { get: all[name], enumerable: true });
  34012. };
  34013. // src/runtime/runtime-constants.ts
  34014. var CONTENT_REF_ID = "r";
  34015. var ORG_LOCATION_ID = "o";
  34016. var SLOT_NODE_ID = "s";
  34017. var TEXT_NODE_ID = "t";
  34018. var XLINK_NS = "http://www.w3.org/1999/xlink";
  34019. // src/mock-doc/attribute.ts
  34020. var attrHandler = {
  34021. get(obj, prop) {
  34022. if (prop in obj) {
  34023. return obj[prop];
  34024. }
  34025. if (typeof prop !== "symbol" && !isNaN(prop)) {
  34026. return obj.__items[prop];
  34027. }
  34028. return void 0;
  34029. }
  34030. };
  34031. var createAttributeProxy = (caseInsensitive) => new Proxy(new MockAttributeMap(caseInsensitive), attrHandler);
  34032. var MockAttributeMap = class {
  34033. constructor(caseInsensitive = false) {
  34034. this.caseInsensitive = caseInsensitive;
  34035. this.__items = [];
  34036. }
  34037. get length() {
  34038. return this.__items.length;
  34039. }
  34040. item(index) {
  34041. return this.__items[index] || null;
  34042. }
  34043. setNamedItem(attr) {
  34044. attr.namespaceURI = null;
  34045. this.setNamedItemNS(attr);
  34046. }
  34047. setNamedItemNS(attr) {
  34048. if (attr != null && attr.value != null) {
  34049. attr.value = String(attr.value);
  34050. }
  34051. const existingAttr = this.__items.find((a) => a.name === attr.name && a.namespaceURI === attr.namespaceURI);
  34052. if (existingAttr != null) {
  34053. existingAttr.value = attr.value;
  34054. } else {
  34055. this.__items.push(attr);
  34056. }
  34057. }
  34058. getNamedItem(attrName) {
  34059. if (this.caseInsensitive) {
  34060. attrName = attrName.toLowerCase();
  34061. }
  34062. return this.getNamedItemNS(null, attrName);
  34063. }
  34064. getNamedItemNS(namespaceURI, attrName) {
  34065. namespaceURI = getNamespaceURI(namespaceURI);
  34066. return this.__items.find((attr) => attr.name === attrName && getNamespaceURI(attr.namespaceURI) === namespaceURI) || null;
  34067. }
  34068. removeNamedItem(attr) {
  34069. this.removeNamedItemNS(attr);
  34070. }
  34071. removeNamedItemNS(attr) {
  34072. for (let i = 0, ii = this.__items.length; i < ii; i++) {
  34073. if (this.__items[i].name === attr.name && this.__items[i].namespaceURI === attr.namespaceURI) {
  34074. this.__items.splice(i, 1);
  34075. break;
  34076. }
  34077. }
  34078. }
  34079. [Symbol.iterator]() {
  34080. let i = 0;
  34081. return {
  34082. next: () => ({
  34083. done: i === this.length,
  34084. value: this.item(i++)
  34085. })
  34086. };
  34087. }
  34088. get [Symbol.toStringTag]() {
  34089. return "MockAttributeMap";
  34090. }
  34091. };
  34092. function getNamespaceURI(namespaceURI) {
  34093. return namespaceURI === XLINK_NS ? null : namespaceURI;
  34094. }
  34095. function cloneAttributes(srcAttrs, sortByName = false) {
  34096. const dstAttrs = new MockAttributeMap(srcAttrs.caseInsensitive);
  34097. if (srcAttrs != null) {
  34098. const attrLen = srcAttrs.length;
  34099. if (sortByName && attrLen > 1) {
  34100. const sortedAttrs = [];
  34101. for (let i = 0; i < attrLen; i++) {
  34102. const srcAttr = srcAttrs.item(i);
  34103. const dstAttr = new MockAttr(srcAttr.name, srcAttr.value, srcAttr.namespaceURI);
  34104. sortedAttrs.push(dstAttr);
  34105. }
  34106. sortedAttrs.sort(sortAttributes).forEach((attr) => {
  34107. dstAttrs.setNamedItemNS(attr);
  34108. });
  34109. } else {
  34110. for (let i = 0; i < attrLen; i++) {
  34111. const srcAttr = srcAttrs.item(i);
  34112. const dstAttr = new MockAttr(srcAttr.name, srcAttr.value, srcAttr.namespaceURI);
  34113. dstAttrs.setNamedItemNS(dstAttr);
  34114. }
  34115. }
  34116. }
  34117. return dstAttrs;
  34118. }
  34119. function sortAttributes(a, b) {
  34120. if (a.name < b.name) return -1;
  34121. if (a.name > b.name) return 1;
  34122. return 0;
  34123. }
  34124. var MockAttr = class {
  34125. constructor(attrName, attrValue, namespaceURI = null) {
  34126. this._name = attrName;
  34127. this._value = String(attrValue);
  34128. this._namespaceURI = namespaceURI;
  34129. }
  34130. get name() {
  34131. return this._name;
  34132. }
  34133. set name(value) {
  34134. this._name = value;
  34135. }
  34136. get value() {
  34137. return this._value;
  34138. }
  34139. set value(value) {
  34140. this._value = String(value);
  34141. }
  34142. get nodeName() {
  34143. return this._name;
  34144. }
  34145. set nodeName(value) {
  34146. this._name = value;
  34147. }
  34148. get nodeValue() {
  34149. return this._value;
  34150. }
  34151. set nodeValue(value) {
  34152. this._value = String(value);
  34153. }
  34154. get namespaceURI() {
  34155. return this._namespaceURI;
  34156. }
  34157. set namespaceURI(namespaceURI) {
  34158. this._namespaceURI = namespaceURI;
  34159. }
  34160. };
  34161. // src/mock-doc/class-list.ts
  34162. var MockClassList = class {
  34163. constructor(elm) {
  34164. this.elm = elm;
  34165. }
  34166. add(...classNames) {
  34167. const clsNames = getItems(this.elm);
  34168. let updated = false;
  34169. classNames.forEach((className) => {
  34170. className = String(className);
  34171. validateClass(className);
  34172. if (clsNames.includes(className) === false) {
  34173. clsNames.push(className);
  34174. updated = true;
  34175. }
  34176. });
  34177. if (updated) {
  34178. this.elm.setAttributeNS(null, "class", clsNames.join(" "));
  34179. }
  34180. }
  34181. remove(...classNames) {
  34182. const clsNames = getItems(this.elm);
  34183. let updated = false;
  34184. classNames.forEach((className) => {
  34185. className = String(className);
  34186. validateClass(className);
  34187. const index = clsNames.indexOf(className);
  34188. if (index > -1) {
  34189. clsNames.splice(index, 1);
  34190. updated = true;
  34191. }
  34192. });
  34193. if (updated) {
  34194. this.elm.setAttributeNS(null, "class", clsNames.filter((c) => c.length > 0).join(" "));
  34195. }
  34196. }
  34197. contains(className) {
  34198. className = String(className);
  34199. return getItems(this.elm).includes(className);
  34200. }
  34201. toggle(className) {
  34202. className = String(className);
  34203. if (this.contains(className) === true) {
  34204. this.remove(className);
  34205. } else {
  34206. this.add(className);
  34207. }
  34208. }
  34209. get length() {
  34210. return getItems(this.elm).length;
  34211. }
  34212. item(index) {
  34213. return getItems(this.elm)[index];
  34214. }
  34215. toString() {
  34216. return getItems(this.elm).join(" ");
  34217. }
  34218. };
  34219. function validateClass(className) {
  34220. if (className === "") {
  34221. throw new Error("The token provided must not be empty.");
  34222. }
  34223. if (/\s/.test(className)) {
  34224. throw new Error(
  34225. `The token provided ('${className}') contains HTML space characters, which are not valid in tokens.`
  34226. );
  34227. }
  34228. }
  34229. function getItems(elm) {
  34230. const className = elm.getAttribute("class");
  34231. if (typeof className === "string" && className.length > 0) {
  34232. return className.trim().split(" ").filter((c) => c.length > 0);
  34233. }
  34234. return [];
  34235. }
  34236. // src/mock-doc/css-style-declaration.ts
  34237. var MockCSSStyleDeclaration = class {
  34238. constructor() {
  34239. this._styles = /* @__PURE__ */ new Map();
  34240. }
  34241. setProperty(prop, value) {
  34242. prop = jsCaseToCssCase(prop);
  34243. if (value == null || value === "") {
  34244. this._styles.delete(prop);
  34245. } else {
  34246. this._styles.set(prop, String(value));
  34247. }
  34248. }
  34249. getPropertyValue(prop) {
  34250. prop = jsCaseToCssCase(prop);
  34251. return String(this._styles.get(prop) || "");
  34252. }
  34253. removeProperty(prop) {
  34254. prop = jsCaseToCssCase(prop);
  34255. this._styles.delete(prop);
  34256. }
  34257. get length() {
  34258. return this._styles.size;
  34259. }
  34260. get cssText() {
  34261. const cssText = [];
  34262. this._styles.forEach((value, prop) => {
  34263. cssText.push(`${prop}: ${value};`);
  34264. });
  34265. return cssText.join(" ").trim();
  34266. }
  34267. set cssText(cssText) {
  34268. if (cssText == null || cssText === "") {
  34269. this._styles.clear();
  34270. return;
  34271. }
  34272. cssText.split(";").forEach((rule) => {
  34273. rule = rule.trim();
  34274. if (rule.length > 0) {
  34275. const splt = rule.split(":");
  34276. if (splt.length > 1) {
  34277. const prop = splt[0].trim();
  34278. const value = splt.slice(1).join(":").trim();
  34279. if (prop !== "" && value !== "") {
  34280. this._styles.set(jsCaseToCssCase(prop), value);
  34281. }
  34282. }
  34283. }
  34284. });
  34285. }
  34286. };
  34287. function createCSSStyleDeclaration() {
  34288. return new Proxy(new MockCSSStyleDeclaration(), cssProxyHandler);
  34289. }
  34290. var cssProxyHandler = {
  34291. get(cssStyle, prop) {
  34292. if (prop in cssStyle) {
  34293. return cssStyle[prop];
  34294. }
  34295. prop = cssCaseToJsCase(prop);
  34296. return cssStyle.getPropertyValue(prop);
  34297. },
  34298. set(cssStyle, prop, value) {
  34299. if (prop in cssStyle) {
  34300. cssStyle[prop] = value;
  34301. } else {
  34302. cssStyle.setProperty(prop, value);
  34303. }
  34304. return true;
  34305. }
  34306. };
  34307. function cssCaseToJsCase(str) {
  34308. if (str.length > 1 && str.includes("-") === true) {
  34309. str = str.toLowerCase().split("-").map((segment) => segment.charAt(0).toUpperCase() + segment.slice(1)).join("");
  34310. str = str.slice(0, 1).toLowerCase() + str.slice(1);
  34311. }
  34312. return str;
  34313. }
  34314. function jsCaseToCssCase(str) {
  34315. if (str.length > 1 && str.includes("-") === false && /[A-Z]/.test(str) === true) {
  34316. str = str.replace(/([A-Z])/g, (g) => " " + g[0]).trim().replace(/ /g, "-").toLowerCase();
  34317. }
  34318. return str;
  34319. }
  34320. // src/mock-doc/custom-element-registry.ts
  34321. var MockCustomElementRegistry = class {
  34322. constructor(win) {
  34323. this.win = win;
  34324. }
  34325. define(tagName, cstr, options) {
  34326. if (tagName.toLowerCase() !== tagName) {
  34327. throw new Error(
  34328. `Failed to execute 'define' on 'CustomElementRegistry': "${tagName}" is not a valid custom element name`
  34329. );
  34330. }
  34331. if (this.__registry == null) {
  34332. this.__registry = /* @__PURE__ */ new Map();
  34333. }
  34334. this.__registry.set(tagName, { cstr, options });
  34335. if (this.__whenDefined != null) {
  34336. const whenDefinedResolveFns = this.__whenDefined.get(tagName);
  34337. if (whenDefinedResolveFns != null) {
  34338. whenDefinedResolveFns.forEach((whenDefinedResolveFn) => {
  34339. whenDefinedResolveFn();
  34340. });
  34341. whenDefinedResolveFns.length = 0;
  34342. this.__whenDefined.delete(tagName);
  34343. }
  34344. }
  34345. const doc = this.win.document;
  34346. if (doc != null) {
  34347. const hosts = doc.querySelectorAll(tagName);
  34348. hosts.forEach((host) => {
  34349. if (upgradedElements.has(host) === false) {
  34350. tempDisableCallbacks.add(doc);
  34351. const upgradedCmp = createCustomElement(this, doc, tagName);
  34352. for (let i = 0; i < host.childNodes.length; i++) {
  34353. const childNode = host.childNodes[i];
  34354. childNode.remove();
  34355. upgradedCmp.appendChild(childNode);
  34356. }
  34357. tempDisableCallbacks.delete(doc);
  34358. if (proxyElements.has(host)) {
  34359. proxyElements.set(host, upgradedCmp);
  34360. }
  34361. }
  34362. fireConnectedCallback(host);
  34363. });
  34364. }
  34365. }
  34366. get(tagName) {
  34367. if (this.__registry != null) {
  34368. const def = this.__registry.get(tagName.toLowerCase());
  34369. if (def != null) {
  34370. return def.cstr;
  34371. }
  34372. }
  34373. return void 0;
  34374. }
  34375. getName(cstr) {
  34376. for (const [tagName, def] of this.__registry.entries()) {
  34377. if (def.cstr === cstr) {
  34378. return tagName;
  34379. }
  34380. }
  34381. return void 0;
  34382. }
  34383. upgrade(_rootNode) {
  34384. }
  34385. clear() {
  34386. if (this.__registry != null) {
  34387. this.__registry.clear();
  34388. }
  34389. if (this.__whenDefined != null) {
  34390. this.__whenDefined.clear();
  34391. }
  34392. }
  34393. whenDefined(tagName) {
  34394. tagName = tagName.toLowerCase();
  34395. if (this.__registry != null && this.__registry.has(tagName) === true) {
  34396. return Promise.resolve(this.__registry.get(tagName).cstr);
  34397. }
  34398. return new Promise((resolve) => {
  34399. if (this.__whenDefined == null) {
  34400. this.__whenDefined = /* @__PURE__ */ new Map();
  34401. }
  34402. let whenDefinedResolveFns = this.__whenDefined.get(tagName);
  34403. if (whenDefinedResolveFns == null) {
  34404. whenDefinedResolveFns = [];
  34405. this.__whenDefined.set(tagName, whenDefinedResolveFns);
  34406. }
  34407. whenDefinedResolveFns.push(resolve);
  34408. });
  34409. }
  34410. };
  34411. function createCustomElement(customElements, ownerDocument, tagName) {
  34412. const Cstr = customElements.get(tagName);
  34413. if (Cstr != null) {
  34414. const cmp = new Cstr(ownerDocument);
  34415. cmp.nodeName = tagName.toUpperCase();
  34416. upgradedElements.add(cmp);
  34417. return cmp;
  34418. }
  34419. const host = new Proxy(
  34420. {},
  34421. {
  34422. get(obj, prop) {
  34423. const elm2 = proxyElements.get(host);
  34424. if (elm2 != null) {
  34425. return elm2[prop];
  34426. }
  34427. return obj[prop];
  34428. },
  34429. set(obj, prop, val) {
  34430. const elm2 = proxyElements.get(host);
  34431. if (elm2 != null) {
  34432. elm2[prop] = val;
  34433. } else {
  34434. obj[prop] = val;
  34435. }
  34436. return true;
  34437. },
  34438. has(obj, prop) {
  34439. const elm2 = proxyElements.get(host);
  34440. if (prop in elm2) {
  34441. return true;
  34442. }
  34443. if (prop in obj) {
  34444. return true;
  34445. }
  34446. return false;
  34447. }
  34448. }
  34449. );
  34450. const elm = new MockHTMLElement(ownerDocument, tagName);
  34451. proxyElements.set(host, elm);
  34452. return host;
  34453. }
  34454. var proxyElements = /* @__PURE__ */ new WeakMap();
  34455. var upgradedElements = /* @__PURE__ */ new WeakSet();
  34456. function connectNode(ownerDocument, node) {
  34457. node.ownerDocument = ownerDocument;
  34458. if (node.nodeType === 1 /* ELEMENT_NODE */) {
  34459. if (ownerDocument != null && node.nodeName.includes("-")) {
  34460. const win = ownerDocument.defaultView;
  34461. if (win != null && typeof node.connectedCallback === "function" && node.isConnected) {
  34462. fireConnectedCallback(node);
  34463. }
  34464. const shadowRoot = node.shadowRoot;
  34465. if (shadowRoot != null) {
  34466. shadowRoot.childNodes.forEach((childNode) => {
  34467. connectNode(ownerDocument, childNode);
  34468. });
  34469. }
  34470. }
  34471. node.childNodes.forEach((childNode) => {
  34472. connectNode(ownerDocument, childNode);
  34473. });
  34474. } else {
  34475. node.childNodes.forEach((childNode) => {
  34476. childNode.ownerDocument = ownerDocument;
  34477. });
  34478. }
  34479. }
  34480. function fireConnectedCallback(node) {
  34481. if (typeof node.connectedCallback === "function") {
  34482. if (tempDisableCallbacks.has(node.ownerDocument) === false) {
  34483. try {
  34484. node.connectedCallback();
  34485. } catch (e) {
  34486. console.error(e);
  34487. }
  34488. }
  34489. }
  34490. }
  34491. function disconnectNode(node) {
  34492. if (node.nodeType === 1 /* ELEMENT_NODE */) {
  34493. if (node.nodeName.includes("-") === true && typeof node.disconnectedCallback === "function") {
  34494. if (tempDisableCallbacks.has(node.ownerDocument) === false) {
  34495. try {
  34496. node.disconnectedCallback();
  34497. } catch (e) {
  34498. console.error(e);
  34499. }
  34500. }
  34501. }
  34502. node.childNodes.forEach(disconnectNode);
  34503. }
  34504. }
  34505. function attributeChanged(node, attrName, oldValue, newValue) {
  34506. attrName = attrName.toLowerCase();
  34507. const observedAttributes = node.constructor.observedAttributes;
  34508. if (Array.isArray(observedAttributes) === true && observedAttributes.some((obs) => obs.toLowerCase() === attrName) === true) {
  34509. try {
  34510. node.attributeChangedCallback(attrName, oldValue, newValue);
  34511. } catch (e) {
  34512. console.error(e);
  34513. }
  34514. }
  34515. }
  34516. function checkAttributeChanged(node) {
  34517. return node.nodeName.includes("-") === true && typeof node.attributeChangedCallback === "function";
  34518. }
  34519. var tempDisableCallbacks = /* @__PURE__ */ new Set();
  34520. // src/mock-doc/dataset.ts
  34521. function dataset(elm) {
  34522. const ds = {};
  34523. const attributes = elm.attributes;
  34524. const attrLen = attributes.length;
  34525. for (let i = 0; i < attrLen; i++) {
  34526. const attr = attributes.item(i);
  34527. const nodeName = attr.nodeName;
  34528. if (nodeName.startsWith("data-")) {
  34529. ds[dashToPascalCase(nodeName)] = attr.nodeValue;
  34530. }
  34531. }
  34532. return new Proxy(ds, {
  34533. get(_obj, camelCaseProp) {
  34534. return ds[camelCaseProp];
  34535. },
  34536. set(_obj, camelCaseProp, value) {
  34537. const dataAttr = toDataAttribute(camelCaseProp);
  34538. elm.setAttribute(dataAttr, value);
  34539. return true;
  34540. }
  34541. });
  34542. }
  34543. function toDataAttribute(str) {
  34544. return "data-" + String(str).replace(/([A-Z0-9])/g, (g) => " " + g[0]).trim().replace(/ /g, "-").toLowerCase();
  34545. }
  34546. function dashToPascalCase(str) {
  34547. str = String(str).slice(5);
  34548. return str.split("-").map((segment, index) => {
  34549. if (index === 0) {
  34550. return segment.charAt(0).toLowerCase() + segment.slice(1);
  34551. }
  34552. return segment.charAt(0).toUpperCase() + segment.slice(1);
  34553. }).join("");
  34554. }
  34555. // src/mock-doc/event.ts
  34556. var MockEvent = class {
  34557. constructor(type, eventInitDict) {
  34558. this.bubbles = false;
  34559. this.cancelBubble = false;
  34560. this.cancelable = false;
  34561. this.composed = false;
  34562. this.currentTarget = null;
  34563. this.defaultPrevented = false;
  34564. this.srcElement = null;
  34565. this.target = null;
  34566. if (typeof type !== "string") {
  34567. throw new Error(`Event type required`);
  34568. }
  34569. this.type = type;
  34570. this.timeStamp = Date.now();
  34571. if (eventInitDict != null) {
  34572. Object.assign(this, eventInitDict);
  34573. }
  34574. }
  34575. preventDefault() {
  34576. this.defaultPrevented = true;
  34577. }
  34578. stopPropagation() {
  34579. this.cancelBubble = true;
  34580. }
  34581. stopImmediatePropagation() {
  34582. this.cancelBubble = true;
  34583. }
  34584. /**
  34585. * @ref https://developer.mozilla.org/en-US/docs/Web/API/Event/composedPath
  34586. * @returns a composed path of the event
  34587. */
  34588. composedPath() {
  34589. const composedPath = [];
  34590. let currentElement = this.target;
  34591. while (currentElement) {
  34592. composedPath.push(currentElement);
  34593. if (!currentElement.parentElement && currentElement.nodeName === "#document" /* DOCUMENT_NODE */) {
  34594. composedPath.push(currentElement.defaultView);
  34595. break;
  34596. }
  34597. if (currentElement.parentElement == null && currentElement.tagName === "HTML") {
  34598. currentElement = currentElement.ownerDocument;
  34599. } else {
  34600. currentElement = currentElement.parentElement;
  34601. }
  34602. }
  34603. return composedPath;
  34604. }
  34605. };
  34606. var MockCustomEvent = class extends MockEvent {
  34607. constructor(type, customEventInitDic) {
  34608. super(type);
  34609. this.detail = null;
  34610. if (customEventInitDic != null) {
  34611. Object.assign(this, customEventInitDic);
  34612. }
  34613. }
  34614. };
  34615. var MockKeyboardEvent = class extends MockEvent {
  34616. constructor(type, keyboardEventInitDic) {
  34617. super(type);
  34618. this.code = "";
  34619. this.key = "";
  34620. this.altKey = false;
  34621. this.ctrlKey = false;
  34622. this.metaKey = false;
  34623. this.shiftKey = false;
  34624. this.location = 0;
  34625. this.repeat = false;
  34626. if (keyboardEventInitDic != null) {
  34627. Object.assign(this, keyboardEventInitDic);
  34628. }
  34629. }
  34630. };
  34631. var MockMouseEvent = class extends MockEvent {
  34632. constructor(type, mouseEventInitDic) {
  34633. super(type);
  34634. this.screenX = 0;
  34635. this.screenY = 0;
  34636. this.clientX = 0;
  34637. this.clientY = 0;
  34638. this.ctrlKey = false;
  34639. this.shiftKey = false;
  34640. this.altKey = false;
  34641. this.metaKey = false;
  34642. this.button = 0;
  34643. this.buttons = 0;
  34644. this.relatedTarget = null;
  34645. if (mouseEventInitDic != null) {
  34646. Object.assign(this, mouseEventInitDic);
  34647. }
  34648. }
  34649. };
  34650. var MockUIEvent = class extends MockEvent {
  34651. constructor(type, uiEventInitDic) {
  34652. super(type);
  34653. this.detail = null;
  34654. this.view = null;
  34655. if (uiEventInitDic != null) {
  34656. Object.assign(this, uiEventInitDic);
  34657. }
  34658. }
  34659. };
  34660. var MockFocusEvent = class extends MockUIEvent {
  34661. constructor(type, focusEventInitDic) {
  34662. super(type);
  34663. this.relatedTarget = null;
  34664. if (focusEventInitDic != null) {
  34665. Object.assign(this, focusEventInitDic);
  34666. }
  34667. }
  34668. };
  34669. var MockEventListener = class {
  34670. constructor(type, handler) {
  34671. this.type = type;
  34672. this.handler = handler;
  34673. }
  34674. };
  34675. function addEventListener(elm, type, handler) {
  34676. const target = elm;
  34677. if (target.__listeners == null) {
  34678. target.__listeners = [];
  34679. }
  34680. target.__listeners.push(new MockEventListener(type, handler));
  34681. }
  34682. function removeEventListener(elm, type, handler) {
  34683. const target = elm;
  34684. if (target != null && Array.isArray(target.__listeners) === true) {
  34685. const elmListener = target.__listeners.find((e) => e.type === type && e.handler === handler);
  34686. if (elmListener != null) {
  34687. const index = target.__listeners.indexOf(elmListener);
  34688. target.__listeners.splice(index, 1);
  34689. }
  34690. }
  34691. }
  34692. function resetEventListeners(target) {
  34693. if (target != null && target.__listeners != null) {
  34694. target.__listeners = null;
  34695. }
  34696. }
  34697. function triggerEventListener(elm, ev) {
  34698. if (elm == null || ev.cancelBubble === true) {
  34699. return;
  34700. }
  34701. const target = elm;
  34702. ev.currentTarget = elm;
  34703. if (Array.isArray(target.__listeners) === true) {
  34704. const listeners = target.__listeners.filter((e) => e.type === ev.type);
  34705. listeners.forEach((listener) => {
  34706. try {
  34707. listener.handler.call(target, ev);
  34708. } catch (err2) {
  34709. console.error(err2);
  34710. }
  34711. });
  34712. }
  34713. if (ev.bubbles === false) {
  34714. return;
  34715. }
  34716. if (elm.nodeName === "#document" /* DOCUMENT_NODE */) {
  34717. triggerEventListener(elm.defaultView, ev);
  34718. } else if (elm.parentElement == null && elm.tagName === "HTML") {
  34719. triggerEventListener(elm.ownerDocument, ev);
  34720. } else {
  34721. triggerEventListener(elm.parentElement, ev);
  34722. }
  34723. }
  34724. function dispatchEvent(currentTarget, ev) {
  34725. ev.target = currentTarget;
  34726. triggerEventListener(currentTarget, ev);
  34727. return true;
  34728. }
  34729. // node_modules/parse5/dist/common/unicode.js
  34730. var UNDEFINED_CODE_POINTS = /* @__PURE__ */ new Set([
  34731. 65534,
  34732. 65535,
  34733. 131070,
  34734. 131071,
  34735. 196606,
  34736. 196607,
  34737. 262142,
  34738. 262143,
  34739. 327678,
  34740. 327679,
  34741. 393214,
  34742. 393215,
  34743. 458750,
  34744. 458751,
  34745. 524286,
  34746. 524287,
  34747. 589822,
  34748. 589823,
  34749. 655358,
  34750. 655359,
  34751. 720894,
  34752. 720895,
  34753. 786430,
  34754. 786431,
  34755. 851966,
  34756. 851967,
  34757. 917502,
  34758. 917503,
  34759. 983038,
  34760. 983039,
  34761. 1048574,
  34762. 1048575,
  34763. 1114110,
  34764. 1114111
  34765. ]);
  34766. var REPLACEMENT_CHARACTER = "\uFFFD";
  34767. var CODE_POINTS;
  34768. (function(CODE_POINTS2) {
  34769. CODE_POINTS2[CODE_POINTS2["EOF"] = -1] = "EOF";
  34770. CODE_POINTS2[CODE_POINTS2["NULL"] = 0] = "NULL";
  34771. CODE_POINTS2[CODE_POINTS2["TABULATION"] = 9] = "TABULATION";
  34772. CODE_POINTS2[CODE_POINTS2["CARRIAGE_RETURN"] = 13] = "CARRIAGE_RETURN";
  34773. CODE_POINTS2[CODE_POINTS2["LINE_FEED"] = 10] = "LINE_FEED";
  34774. CODE_POINTS2[CODE_POINTS2["FORM_FEED"] = 12] = "FORM_FEED";
  34775. CODE_POINTS2[CODE_POINTS2["SPACE"] = 32] = "SPACE";
  34776. CODE_POINTS2[CODE_POINTS2["EXCLAMATION_MARK"] = 33] = "EXCLAMATION_MARK";
  34777. CODE_POINTS2[CODE_POINTS2["QUOTATION_MARK"] = 34] = "QUOTATION_MARK";
  34778. CODE_POINTS2[CODE_POINTS2["NUMBER_SIGN"] = 35] = "NUMBER_SIGN";
  34779. CODE_POINTS2[CODE_POINTS2["AMPERSAND"] = 38] = "AMPERSAND";
  34780. CODE_POINTS2[CODE_POINTS2["APOSTROPHE"] = 39] = "APOSTROPHE";
  34781. CODE_POINTS2[CODE_POINTS2["HYPHEN_MINUS"] = 45] = "HYPHEN_MINUS";
  34782. CODE_POINTS2[CODE_POINTS2["SOLIDUS"] = 47] = "SOLIDUS";
  34783. CODE_POINTS2[CODE_POINTS2["DIGIT_0"] = 48] = "DIGIT_0";
  34784. CODE_POINTS2[CODE_POINTS2["DIGIT_9"] = 57] = "DIGIT_9";
  34785. CODE_POINTS2[CODE_POINTS2["SEMICOLON"] = 59] = "SEMICOLON";
  34786. CODE_POINTS2[CODE_POINTS2["LESS_THAN_SIGN"] = 60] = "LESS_THAN_SIGN";
  34787. CODE_POINTS2[CODE_POINTS2["EQUALS_SIGN"] = 61] = "EQUALS_SIGN";
  34788. CODE_POINTS2[CODE_POINTS2["GREATER_THAN_SIGN"] = 62] = "GREATER_THAN_SIGN";
  34789. CODE_POINTS2[CODE_POINTS2["QUESTION_MARK"] = 63] = "QUESTION_MARK";
  34790. CODE_POINTS2[CODE_POINTS2["LATIN_CAPITAL_A"] = 65] = "LATIN_CAPITAL_A";
  34791. CODE_POINTS2[CODE_POINTS2["LATIN_CAPITAL_F"] = 70] = "LATIN_CAPITAL_F";
  34792. CODE_POINTS2[CODE_POINTS2["LATIN_CAPITAL_X"] = 88] = "LATIN_CAPITAL_X";
  34793. CODE_POINTS2[CODE_POINTS2["LATIN_CAPITAL_Z"] = 90] = "LATIN_CAPITAL_Z";
  34794. CODE_POINTS2[CODE_POINTS2["RIGHT_SQUARE_BRACKET"] = 93] = "RIGHT_SQUARE_BRACKET";
  34795. CODE_POINTS2[CODE_POINTS2["GRAVE_ACCENT"] = 96] = "GRAVE_ACCENT";
  34796. CODE_POINTS2[CODE_POINTS2["LATIN_SMALL_A"] = 97] = "LATIN_SMALL_A";
  34797. CODE_POINTS2[CODE_POINTS2["LATIN_SMALL_F"] = 102] = "LATIN_SMALL_F";
  34798. CODE_POINTS2[CODE_POINTS2["LATIN_SMALL_X"] = 120] = "LATIN_SMALL_X";
  34799. CODE_POINTS2[CODE_POINTS2["LATIN_SMALL_Z"] = 122] = "LATIN_SMALL_Z";
  34800. CODE_POINTS2[CODE_POINTS2["REPLACEMENT_CHARACTER"] = 65533] = "REPLACEMENT_CHARACTER";
  34801. })(CODE_POINTS = CODE_POINTS || (CODE_POINTS = {}));
  34802. var SEQUENCES = {
  34803. DASH_DASH: "--",
  34804. CDATA_START: "[CDATA[",
  34805. DOCTYPE: "doctype",
  34806. SCRIPT: "script",
  34807. PUBLIC: "public",
  34808. SYSTEM: "system"
  34809. };
  34810. function isSurrogate(cp) {
  34811. return cp >= 55296 && cp <= 57343;
  34812. }
  34813. function isSurrogatePair(cp) {
  34814. return cp >= 56320 && cp <= 57343;
  34815. }
  34816. function getSurrogatePairCodePoint(cp1, cp2) {
  34817. return (cp1 - 55296) * 1024 + 9216 + cp2;
  34818. }
  34819. function isControlCodePoint(cp) {
  34820. return cp !== 32 && cp !== 10 && cp !== 13 && cp !== 9 && cp !== 12 && cp >= 1 && cp <= 31 || cp >= 127 && cp <= 159;
  34821. }
  34822. function isUndefinedCodePoint(cp) {
  34823. return cp >= 64976 && cp <= 65007 || UNDEFINED_CODE_POINTS.has(cp);
  34824. }
  34825. // node_modules/parse5/dist/common/error-codes.js
  34826. var ERR;
  34827. (function(ERR2) {
  34828. ERR2["controlCharacterInInputStream"] = "control-character-in-input-stream";
  34829. ERR2["noncharacterInInputStream"] = "noncharacter-in-input-stream";
  34830. ERR2["surrogateInInputStream"] = "surrogate-in-input-stream";
  34831. ERR2["nonVoidHtmlElementStartTagWithTrailingSolidus"] = "non-void-html-element-start-tag-with-trailing-solidus";
  34832. ERR2["endTagWithAttributes"] = "end-tag-with-attributes";
  34833. ERR2["endTagWithTrailingSolidus"] = "end-tag-with-trailing-solidus";
  34834. ERR2["unexpectedSolidusInTag"] = "unexpected-solidus-in-tag";
  34835. ERR2["unexpectedNullCharacter"] = "unexpected-null-character";
  34836. ERR2["unexpectedQuestionMarkInsteadOfTagName"] = "unexpected-question-mark-instead-of-tag-name";
  34837. ERR2["invalidFirstCharacterOfTagName"] = "invalid-first-character-of-tag-name";
  34838. ERR2["unexpectedEqualsSignBeforeAttributeName"] = "unexpected-equals-sign-before-attribute-name";
  34839. ERR2["missingEndTagName"] = "missing-end-tag-name";
  34840. ERR2["unexpectedCharacterInAttributeName"] = "unexpected-character-in-attribute-name";
  34841. ERR2["unknownNamedCharacterReference"] = "unknown-named-character-reference";
  34842. ERR2["missingSemicolonAfterCharacterReference"] = "missing-semicolon-after-character-reference";
  34843. ERR2["unexpectedCharacterAfterDoctypeSystemIdentifier"] = "unexpected-character-after-doctype-system-identifier";
  34844. ERR2["unexpectedCharacterInUnquotedAttributeValue"] = "unexpected-character-in-unquoted-attribute-value";
  34845. ERR2["eofBeforeTagName"] = "eof-before-tag-name";
  34846. ERR2["eofInTag"] = "eof-in-tag";
  34847. ERR2["missingAttributeValue"] = "missing-attribute-value";
  34848. ERR2["missingWhitespaceBetweenAttributes"] = "missing-whitespace-between-attributes";
  34849. ERR2["missingWhitespaceAfterDoctypePublicKeyword"] = "missing-whitespace-after-doctype-public-keyword";
  34850. ERR2["missingWhitespaceBetweenDoctypePublicAndSystemIdentifiers"] = "missing-whitespace-between-doctype-public-and-system-identifiers";
  34851. ERR2["missingWhitespaceAfterDoctypeSystemKeyword"] = "missing-whitespace-after-doctype-system-keyword";
  34852. ERR2["missingQuoteBeforeDoctypePublicIdentifier"] = "missing-quote-before-doctype-public-identifier";
  34853. ERR2["missingQuoteBeforeDoctypeSystemIdentifier"] = "missing-quote-before-doctype-system-identifier";
  34854. ERR2["missingDoctypePublicIdentifier"] = "missing-doctype-public-identifier";
  34855. ERR2["missingDoctypeSystemIdentifier"] = "missing-doctype-system-identifier";
  34856. ERR2["abruptDoctypePublicIdentifier"] = "abrupt-doctype-public-identifier";
  34857. ERR2["abruptDoctypeSystemIdentifier"] = "abrupt-doctype-system-identifier";
  34858. ERR2["cdataInHtmlContent"] = "cdata-in-html-content";
  34859. ERR2["incorrectlyOpenedComment"] = "incorrectly-opened-comment";
  34860. ERR2["eofInScriptHtmlCommentLikeText"] = "eof-in-script-html-comment-like-text";
  34861. ERR2["eofInDoctype"] = "eof-in-doctype";
  34862. ERR2["nestedComment"] = "nested-comment";
  34863. ERR2["abruptClosingOfEmptyComment"] = "abrupt-closing-of-empty-comment";
  34864. ERR2["eofInComment"] = "eof-in-comment";
  34865. ERR2["incorrectlyClosedComment"] = "incorrectly-closed-comment";
  34866. ERR2["eofInCdata"] = "eof-in-cdata";
  34867. ERR2["absenceOfDigitsInNumericCharacterReference"] = "absence-of-digits-in-numeric-character-reference";
  34868. ERR2["nullCharacterReference"] = "null-character-reference";
  34869. ERR2["surrogateCharacterReference"] = "surrogate-character-reference";
  34870. ERR2["characterReferenceOutsideUnicodeRange"] = "character-reference-outside-unicode-range";
  34871. ERR2["controlCharacterReference"] = "control-character-reference";
  34872. ERR2["noncharacterCharacterReference"] = "noncharacter-character-reference";
  34873. ERR2["missingWhitespaceBeforeDoctypeName"] = "missing-whitespace-before-doctype-name";
  34874. ERR2["missingDoctypeName"] = "missing-doctype-name";
  34875. ERR2["invalidCharacterSequenceAfterDoctypeName"] = "invalid-character-sequence-after-doctype-name";
  34876. ERR2["duplicateAttribute"] = "duplicate-attribute";
  34877. ERR2["nonConformingDoctype"] = "non-conforming-doctype";
  34878. ERR2["missingDoctype"] = "missing-doctype";
  34879. ERR2["misplacedDoctype"] = "misplaced-doctype";
  34880. ERR2["endTagWithoutMatchingOpenElement"] = "end-tag-without-matching-open-element";
  34881. ERR2["closingOfElementWithOpenChildElements"] = "closing-of-element-with-open-child-elements";
  34882. ERR2["disallowedContentInNoscriptInHead"] = "disallowed-content-in-noscript-in-head";
  34883. ERR2["openElementsLeftAfterEof"] = "open-elements-left-after-eof";
  34884. ERR2["abandonedHeadElementChild"] = "abandoned-head-element-child";
  34885. ERR2["misplacedStartTagForHeadElement"] = "misplaced-start-tag-for-head-element";
  34886. ERR2["nestedNoscriptInHead"] = "nested-noscript-in-head";
  34887. ERR2["eofInElementThatCanContainOnlyText"] = "eof-in-element-that-can-contain-only-text";
  34888. })(ERR = ERR || (ERR = {}));
  34889. // node_modules/parse5/dist/tokenizer/preprocessor.js
  34890. var DEFAULT_BUFFER_WATERLINE = 1 << 16;
  34891. var Preprocessor = class {
  34892. constructor(handler) {
  34893. this.handler = handler;
  34894. this.html = "";
  34895. this.pos = -1;
  34896. this.lastGapPos = -2;
  34897. this.gapStack = [];
  34898. this.skipNextNewLine = false;
  34899. this.lastChunkWritten = false;
  34900. this.endOfChunkHit = false;
  34901. this.bufferWaterline = DEFAULT_BUFFER_WATERLINE;
  34902. this.isEol = false;
  34903. this.lineStartPos = 0;
  34904. this.droppedBufferSize = 0;
  34905. this.line = 1;
  34906. this.lastErrOffset = -1;
  34907. }
  34908. /** The column on the current line. If we just saw a gap (eg. a surrogate pair), return the index before. */
  34909. get col() {
  34910. return this.pos - this.lineStartPos + Number(this.lastGapPos !== this.pos);
  34911. }
  34912. get offset() {
  34913. return this.droppedBufferSize + this.pos;
  34914. }
  34915. getError(code) {
  34916. const { line, col, offset } = this;
  34917. return {
  34918. code,
  34919. startLine: line,
  34920. endLine: line,
  34921. startCol: col,
  34922. endCol: col,
  34923. startOffset: offset,
  34924. endOffset: offset
  34925. };
  34926. }
  34927. _err(code) {
  34928. if (this.handler.onParseError && this.lastErrOffset !== this.offset) {
  34929. this.lastErrOffset = this.offset;
  34930. this.handler.onParseError(this.getError(code));
  34931. }
  34932. }
  34933. _addGap() {
  34934. this.gapStack.push(this.lastGapPos);
  34935. this.lastGapPos = this.pos;
  34936. }
  34937. _processSurrogate(cp) {
  34938. if (this.pos !== this.html.length - 1) {
  34939. const nextCp = this.html.charCodeAt(this.pos + 1);
  34940. if (isSurrogatePair(nextCp)) {
  34941. this.pos++;
  34942. this._addGap();
  34943. return getSurrogatePairCodePoint(cp, nextCp);
  34944. }
  34945. } else if (!this.lastChunkWritten) {
  34946. this.endOfChunkHit = true;
  34947. return CODE_POINTS.EOF;
  34948. }
  34949. this._err(ERR.surrogateInInputStream);
  34950. return cp;
  34951. }
  34952. willDropParsedChunk() {
  34953. return this.pos > this.bufferWaterline;
  34954. }
  34955. dropParsedChunk() {
  34956. if (this.willDropParsedChunk()) {
  34957. this.html = this.html.substring(this.pos);
  34958. this.lineStartPos -= this.pos;
  34959. this.droppedBufferSize += this.pos;
  34960. this.pos = 0;
  34961. this.lastGapPos = -2;
  34962. this.gapStack.length = 0;
  34963. }
  34964. }
  34965. write(chunk, isLastChunk) {
  34966. if (this.html.length > 0) {
  34967. this.html += chunk;
  34968. } else {
  34969. this.html = chunk;
  34970. }
  34971. this.endOfChunkHit = false;
  34972. this.lastChunkWritten = isLastChunk;
  34973. }
  34974. insertHtmlAtCurrentPos(chunk) {
  34975. this.html = this.html.substring(0, this.pos + 1) + chunk + this.html.substring(this.pos + 1);
  34976. this.endOfChunkHit = false;
  34977. }
  34978. startsWith(pattern, caseSensitive) {
  34979. if (this.pos + pattern.length > this.html.length) {
  34980. this.endOfChunkHit = !this.lastChunkWritten;
  34981. return false;
  34982. }
  34983. if (caseSensitive) {
  34984. return this.html.startsWith(pattern, this.pos);
  34985. }
  34986. for (let i = 0; i < pattern.length; i++) {
  34987. const cp = this.html.charCodeAt(this.pos + i) | 32;
  34988. if (cp !== pattern.charCodeAt(i)) {
  34989. return false;
  34990. }
  34991. }
  34992. return true;
  34993. }
  34994. peek(offset) {
  34995. const pos = this.pos + offset;
  34996. if (pos >= this.html.length) {
  34997. this.endOfChunkHit = !this.lastChunkWritten;
  34998. return CODE_POINTS.EOF;
  34999. }
  35000. const code = this.html.charCodeAt(pos);
  35001. return code === CODE_POINTS.CARRIAGE_RETURN ? CODE_POINTS.LINE_FEED : code;
  35002. }
  35003. advance() {
  35004. this.pos++;
  35005. if (this.isEol) {
  35006. this.isEol = false;
  35007. this.line++;
  35008. this.lineStartPos = this.pos;
  35009. }
  35010. if (this.pos >= this.html.length) {
  35011. this.endOfChunkHit = !this.lastChunkWritten;
  35012. return CODE_POINTS.EOF;
  35013. }
  35014. let cp = this.html.charCodeAt(this.pos);
  35015. if (cp === CODE_POINTS.CARRIAGE_RETURN) {
  35016. this.isEol = true;
  35017. this.skipNextNewLine = true;
  35018. return CODE_POINTS.LINE_FEED;
  35019. }
  35020. if (cp === CODE_POINTS.LINE_FEED) {
  35021. this.isEol = true;
  35022. if (this.skipNextNewLine) {
  35023. this.line--;
  35024. this.skipNextNewLine = false;
  35025. this._addGap();
  35026. return this.advance();
  35027. }
  35028. }
  35029. this.skipNextNewLine = false;
  35030. if (isSurrogate(cp)) {
  35031. cp = this._processSurrogate(cp);
  35032. }
  35033. const isCommonValidRange = this.handler.onParseError === null || cp > 31 && cp < 127 || cp === CODE_POINTS.LINE_FEED || cp === CODE_POINTS.CARRIAGE_RETURN || cp > 159 && cp < 64976;
  35034. if (!isCommonValidRange) {
  35035. this._checkForProblematicCharacters(cp);
  35036. }
  35037. return cp;
  35038. }
  35039. _checkForProblematicCharacters(cp) {
  35040. if (isControlCodePoint(cp)) {
  35041. this._err(ERR.controlCharacterInInputStream);
  35042. } else if (isUndefinedCodePoint(cp)) {
  35043. this._err(ERR.noncharacterInInputStream);
  35044. }
  35045. }
  35046. retreat(count) {
  35047. this.pos -= count;
  35048. while (this.pos < this.lastGapPos) {
  35049. this.lastGapPos = this.gapStack.pop();
  35050. this.pos--;
  35051. }
  35052. this.isEol = false;
  35053. }
  35054. };
  35055. // node_modules/parse5/dist/common/token.js
  35056. var token_exports = {};
  35057. __export(token_exports, {
  35058. TokenType: () => TokenType,
  35059. getTokenAttr: () => getTokenAttr
  35060. });
  35061. var TokenType;
  35062. (function(TokenType2) {
  35063. TokenType2[TokenType2["CHARACTER"] = 0] = "CHARACTER";
  35064. TokenType2[TokenType2["NULL_CHARACTER"] = 1] = "NULL_CHARACTER";
  35065. TokenType2[TokenType2["WHITESPACE_CHARACTER"] = 2] = "WHITESPACE_CHARACTER";
  35066. TokenType2[TokenType2["START_TAG"] = 3] = "START_TAG";
  35067. TokenType2[TokenType2["END_TAG"] = 4] = "END_TAG";
  35068. TokenType2[TokenType2["COMMENT"] = 5] = "COMMENT";
  35069. TokenType2[TokenType2["DOCTYPE"] = 6] = "DOCTYPE";
  35070. TokenType2[TokenType2["EOF"] = 7] = "EOF";
  35071. TokenType2[TokenType2["HIBERNATION"] = 8] = "HIBERNATION";
  35072. })(TokenType = TokenType || (TokenType = {}));
  35073. function getTokenAttr(token, attrName) {
  35074. for (let i = token.attrs.length - 1; i >= 0; i--) {
  35075. if (token.attrs[i].name === attrName) {
  35076. return token.attrs[i].value;
  35077. }
  35078. }
  35079. return null;
  35080. }
  35081. // node_modules/entities/lib/esm/generated/decode-data-html.js
  35082. var decode_data_html_default = new Uint16Array(
  35083. // prettier-ignore
  35084. '\u1D41<\xD5\u0131\u028A\u049D\u057B\u05D0\u0675\u06DE\u07A2\u07D6\u080F\u0A4A\u0A91\u0DA1\u0E6D\u0F09\u0F26\u10CA\u1228\u12E1\u1415\u149D\u14C3\u14DF\u1525\0\0\0\0\0\0\u156B\u16CD\u198D\u1C12\u1DDD\u1F7E\u2060\u21B0\u228D\u23C0\u23FB\u2442\u2824\u2912\u2D08\u2E48\u2FCE\u3016\u32BA\u3639\u37AC\u38FE\u3A28\u3A71\u3AE0\u3B2E\u0800EMabcfglmnoprstu\\bfms\x7F\x84\x8B\x90\x95\x98\xA6\xB3\xB9\xC8\xCFlig\u803B\xC6\u40C6P\u803B&\u4026cute\u803B\xC1\u40C1reve;\u4102\u0100iyx}rc\u803B\xC2\u40C2;\u4410r;\uC000\u{1D504}rave\u803B\xC0\u40C0pha;\u4391acr;\u4100d;\u6A53\u0100gp\x9D\xA1on;\u4104f;\uC000\u{1D538}plyFunction;\u6061ing\u803B\xC5\u40C5\u0100cs\xBE\xC3r;\uC000\u{1D49C}ign;\u6254ilde\u803B\xC3\u40C3ml\u803B\xC4\u40C4\u0400aceforsu\xE5\xFB\xFE\u0117\u011C\u0122\u0127\u012A\u0100cr\xEA\xF2kslash;\u6216\u0176\xF6\xF8;\u6AE7ed;\u6306y;\u4411\u0180crt\u0105\u010B\u0114ause;\u6235noullis;\u612Ca;\u4392r;\uC000\u{1D505}pf;\uC000\u{1D539}eve;\u42D8c\xF2\u0113mpeq;\u624E\u0700HOacdefhilorsu\u014D\u0151\u0156\u0180\u019E\u01A2\u01B5\u01B7\u01BA\u01DC\u0215\u0273\u0278\u027Ecy;\u4427PY\u803B\xA9\u40A9\u0180cpy\u015D\u0162\u017Aute;\u4106\u0100;i\u0167\u0168\u62D2talDifferentialD;\u6145leys;\u612D\u0200aeio\u0189\u018E\u0194\u0198ron;\u410Cdil\u803B\xC7\u40C7rc;\u4108nint;\u6230ot;\u410A\u0100dn\u01A7\u01ADilla;\u40B8terDot;\u40B7\xF2\u017Fi;\u43A7rcle\u0200DMPT\u01C7\u01CB\u01D1\u01D6ot;\u6299inus;\u6296lus;\u6295imes;\u6297o\u0100cs\u01E2\u01F8kwiseContourIntegral;\u6232eCurly\u0100DQ\u0203\u020FoubleQuote;\u601Duote;\u6019\u0200lnpu\u021E\u0228\u0247\u0255on\u0100;e\u0225\u0226\u6237;\u6A74\u0180git\u022F\u0236\u023Aruent;\u6261nt;\u622FourIntegral;\u622E\u0100fr\u024C\u024E;\u6102oduct;\u6210nterClockwiseContourIntegral;\u6233oss;\u6A2Fcr;\uC000\u{1D49E}p\u0100;C\u0284\u0285\u62D3ap;\u624D\u0580DJSZacefios\u02A0\u02AC\u02B0\u02B4\u02B8\u02CB\u02D7\u02E1\u02E6\u0333\u048D\u0100;o\u0179\u02A5trahd;\u6911cy;\u4402cy;\u4405cy;\u440F\u0180grs\u02BF\u02C4\u02C7ger;\u6021r;\u61A1hv;\u6AE4\u0100ay\u02D0\u02D5ron;\u410E;\u4414l\u0100;t\u02DD\u02DE\u6207a;\u4394r;\uC000\u{1D507}\u0100af\u02EB\u0327\u0100cm\u02F0\u0322ritical\u0200ADGT\u0300\u0306\u0316\u031Ccute;\u40B4o\u0174\u030B\u030D;\u42D9bleAcute;\u42DDrave;\u4060ilde;\u42DCond;\u62C4ferentialD;\u6146\u0470\u033D\0\0\0\u0342\u0354\0\u0405f;\uC000\u{1D53B}\u0180;DE\u0348\u0349\u034D\u40A8ot;\u60DCqual;\u6250ble\u0300CDLRUV\u0363\u0372\u0382\u03CF\u03E2\u03F8ontourIntegra\xEC\u0239o\u0274\u0379\0\0\u037B\xBB\u0349nArrow;\u61D3\u0100eo\u0387\u03A4ft\u0180ART\u0390\u0396\u03A1rrow;\u61D0ightArrow;\u61D4e\xE5\u02CAng\u0100LR\u03AB\u03C4eft\u0100AR\u03B3\u03B9rrow;\u67F8ightArrow;\u67FAightArrow;\u67F9ight\u0100AT\u03D8\u03DErrow;\u61D2ee;\u62A8p\u0241\u03E9\0\0\u03EFrrow;\u61D1ownArrow;\u61D5erticalBar;\u6225n\u0300ABLRTa\u0412\u042A\u0430\u045E\u047F\u037Crrow\u0180;BU\u041D\u041E\u0422\u6193ar;\u6913pArrow;\u61F5reve;\u4311eft\u02D2\u043A\0\u0446\0\u0450ightVector;\u6950eeVector;\u695Eector\u0100;B\u0459\u045A\u61BDar;\u6956ight\u01D4\u0467\0\u0471eeVector;\u695Fector\u0100;B\u047A\u047B\u61C1ar;\u6957ee\u0100;A\u0486\u0487\u62A4rrow;\u61A7\u0100ct\u0492\u0497r;\uC000\u{1D49F}rok;\u4110\u0800NTacdfglmopqstux\u04BD\u04C0\u04C4\u04CB\u04DE\u04E2\u04E7\u04EE\u04F5\u0521\u052F\u0536\u0552\u055D\u0560\u0565G;\u414AH\u803B\xD0\u40D0cute\u803B\xC9\u40C9\u0180aiy\u04D2\u04D7\u04DCron;\u411Arc\u803B\xCA\u40CA;\u442Dot;\u4116r;\uC000\u{1D508}rave\u803B\xC8\u40C8ement;\u6208\u0100ap\u04FA\u04FEcr;\u4112ty\u0253\u0506\0\0\u0512mallSquare;\u65FBerySmallSquare;\u65AB\u0100gp\u0526\u052Aon;\u4118f;\uC000\u{1D53C}silon;\u4395u\u0100ai\u053C\u0549l\u0100;T\u0542\u0543\u6A75ilde;\u6242librium;\u61CC\u0100ci\u0557\u055Ar;\u6130m;\u6A73a;\u4397ml\u803B\xCB\u40CB\u0100ip\u056A\u056Fsts;\u6203onentialE;\u6147\u0280cfios\u0585\u0588\u058D\u05B2\u05CCy;\u4424r;\uC000\u{1D509}lled\u0253\u0597\0\0\u05A3mallSquare;\u65FCerySmallSquare;\u65AA\u0370\u05BA\0\u05BF\0\0\u05C4f;\uC000\u{1D53D}All;\u6200riertrf;\u6131c\xF2\u05CB\u0600JTabcdfgorst\u05E8\u05EC\u05EF\u05FA\u0600\u0612\u0616\u061B\u061D\u0623\u066C\u0672cy;\u4403\u803B>\u403Emma\u0100;d\u05F7\u05F8\u4393;\u43DCreve;\u411E\u0180eiy\u0607\u060C\u0610dil;\u4122rc;\u411C;\u4413ot;\u4120r;\uC000\u{1D50A};\u62D9pf;\uC000\u{1D53E}eater\u0300EFGLST\u0635\u0644\u064E\u0656\u065B\u0666qual\u0100;L\u063E\u063F\u6265ess;\u62DBullEqual;\u6267reater;\u6AA2ess;\u6277lantEqual;\u6A7Eilde;\u6273cr;\uC000\u{1D4A2};\u626B\u0400Aacfiosu\u0685\u068B\u0696\u069B\u069E\u06AA\u06BE\u06CARDcy;\u442A\u0100ct\u0690\u0694ek;\u42C7;\u405Eirc;\u4124r;\u610ClbertSpace;\u610B\u01F0\u06AF\0\u06B2f;\u610DizontalLine;\u6500\u0100ct\u06C3\u06C5\xF2\u06A9rok;\u4126mp\u0144\u06D0\u06D8ownHum\xF0\u012Fqual;\u624F\u0700EJOacdfgmnostu\u06FA\u06FE\u0703\u0707\u070E\u071A\u071E\u0721\u0728\u0744\u0778\u078B\u078F\u0795cy;\u4415lig;\u4132cy;\u4401cute\u803B\xCD\u40CD\u0100iy\u0713\u0718rc\u803B\xCE\u40CE;\u4418ot;\u4130r;\u6111rave\u803B\xCC\u40CC\u0180;ap\u0720\u072F\u073F\u0100cg\u0734\u0737r;\u412AinaryI;\u6148lie\xF3\u03DD\u01F4\u0749\0\u0762\u0100;e\u074D\u074E\u622C\u0100gr\u0753\u0758ral;\u622Bsection;\u62C2isible\u0100CT\u076C\u0772omma;\u6063imes;\u6062\u0180gpt\u077F\u0783\u0788on;\u412Ef;\uC000\u{1D540}a;\u4399cr;\u6110ilde;\u4128\u01EB\u079A\0\u079Ecy;\u4406l\u803B\xCF\u40CF\u0280cfosu\u07AC\u07B7\u07BC\u07C2\u07D0\u0100iy\u07B1\u07B5rc;\u4134;\u4419r;\uC000\u{1D50D}pf;\uC000\u{1D541}\u01E3\u07C7\0\u07CCr;\uC000\u{1D4A5}rcy;\u4408kcy;\u4404\u0380HJacfos\u07E4\u07E8\u07EC\u07F1\u07FD\u0802\u0808cy;\u4425cy;\u440Cppa;\u439A\u0100ey\u07F6\u07FBdil;\u4136;\u441Ar;\uC000\u{1D50E}pf;\uC000\u{1D542}cr;\uC000\u{1D4A6}\u0580JTaceflmost\u0825\u0829\u082C\u0850\u0863\u09B3\u09B8\u09C7\u09CD\u0A37\u0A47cy;\u4409\u803B<\u403C\u0280cmnpr\u0837\u083C\u0841\u0844\u084Dute;\u4139bda;\u439Bg;\u67EAlacetrf;\u6112r;\u619E\u0180aey\u0857\u085C\u0861ron;\u413Ddil;\u413B;\u441B\u0100fs\u0868\u0970t\u0500ACDFRTUVar\u087E\u08A9\u08B1\u08E0\u08E6\u08FC\u092F\u095B\u0390\u096A\u0100nr\u0883\u088FgleBracket;\u67E8row\u0180;BR\u0899\u089A\u089E\u6190ar;\u61E4ightArrow;\u61C6eiling;\u6308o\u01F5\u08B7\0\u08C3bleBracket;\u67E6n\u01D4\u08C8\0\u08D2eeVector;\u6961ector\u0100;B\u08DB\u08DC\u61C3ar;\u6959loor;\u630Aight\u0100AV\u08EF\u08F5rrow;\u6194ector;\u694E\u0100er\u0901\u0917e\u0180;AV\u0909\u090A\u0910\u62A3rrow;\u61A4ector;\u695Aiangle\u0180;BE\u0924\u0925\u0929\u62B2ar;\u69CFqual;\u62B4p\u0180DTV\u0937\u0942\u094CownVector;\u6951eeVector;\u6960ector\u0100;B\u0956\u0957\u61BFar;\u6958ector\u0100;B\u0965\u0966\u61BCar;\u6952ight\xE1\u039Cs\u0300EFGLST\u097E\u098B\u0995\u099D\u09A2\u09ADqualGreater;\u62DAullEqual;\u6266reater;\u6276ess;\u6AA1lantEqual;\u6A7Dilde;\u6272r;\uC000\u{1D50F}\u0100;e\u09BD\u09BE\u62D8ftarrow;\u61DAidot;\u413F\u0180npw\u09D4\u0A16\u0A1Bg\u0200LRlr\u09DE\u09F7\u0A02\u0A10eft\u0100AR\u09E6\u09ECrrow;\u67F5ightArrow;\u67F7ightArrow;\u67F6eft\u0100ar\u03B3\u0A0Aight\xE1\u03BFight\xE1\u03CAf;\uC000\u{1D543}er\u0100LR\u0A22\u0A2CeftArrow;\u6199ightArrow;\u6198\u0180cht\u0A3E\u0A40\u0A42\xF2\u084C;\u61B0rok;\u4141;\u626A\u0400acefiosu\u0A5A\u0A5D\u0A60\u0A77\u0A7C\u0A85\u0A8B\u0A8Ep;\u6905y;\u441C\u0100dl\u0A65\u0A6FiumSpace;\u605Flintrf;\u6133r;\uC000\u{1D510}nusPlus;\u6213pf;\uC000\u{1D544}c\xF2\u0A76;\u439C\u0480Jacefostu\u0AA3\u0AA7\u0AAD\u0AC0\u0B14\u0B19\u0D91\u0D97\u0D9Ecy;\u440Acute;\u4143\u0180aey\u0AB4\u0AB9\u0ABEron;\u4147dil;\u4145;\u441D\u0180gsw\u0AC7\u0AF0\u0B0Eative\u0180MTV\u0AD3\u0ADF\u0AE8ediumSpace;\u600Bhi\u0100cn\u0AE6\u0AD8\xEB\u0AD9eryThi\xEE\u0AD9ted\u0100GL\u0AF8\u0B06reaterGreate\xF2\u0673essLes\xF3\u0A48Line;\u400Ar;\uC000\u{1D511}\u0200Bnpt\u0B22\u0B28\u0B37\u0B3Areak;\u6060BreakingSpace;\u40A0f;\u6115\u0680;CDEGHLNPRSTV\u0B55\u0B56\u0B6A\u0B7C\u0BA1\u0BEB\u0C04\u0C5E\u0C84\u0CA6\u0CD8\u0D61\u0D85\u6AEC\u0100ou\u0B5B\u0B64ngruent;\u6262pCap;\u626DoubleVerticalBar;\u6226\u0180lqx\u0B83\u0B8A\u0B9Bement;\u6209ual\u0100;T\u0B92\u0B93\u6260ilde;\uC000\u2242\u0338ists;\u6204reater\u0380;EFGLST\u0BB6\u0BB7\u0BBD\u0BC9\u0BD3\u0BD8\u0BE5\u626Fqual;\u6271ullEqual;\uC000\u2267\u0338reater;\uC000\u226B\u0338ess;\u6279lantEqual;\uC000\u2A7E\u0338ilde;\u6275ump\u0144\u0BF2\u0BFDownHump;\uC000\u224E\u0338qual;\uC000\u224F\u0338e\u0100fs\u0C0A\u0C27tTriangle\u0180;BE\u0C1A\u0C1B\u0C21\u62EAar;\uC000\u29CF\u0338qual;\u62ECs\u0300;EGLST\u0C35\u0C36\u0C3C\u0C44\u0C4B\u0C58\u626Equal;\u6270reater;\u6278ess;\uC000\u226A\u0338lantEqual;\uC000\u2A7D\u0338ilde;\u6274ested\u0100GL\u0C68\u0C79reaterGreater;\uC000\u2AA2\u0338essLess;\uC000\u2AA1\u0338recedes\u0180;ES\u0C92\u0C93\u0C9B\u6280qual;\uC000\u2AAF\u0338lantEqual;\u62E0\u0100ei\u0CAB\u0CB9verseElement;\u620CghtTriangle\u0180;BE\u0CCB\u0CCC\u0CD2\u62EBar;\uC000\u29D0\u0338qual;\u62ED\u0100qu\u0CDD\u0D0CuareSu\u0100bp\u0CE8\u0CF9set\u0100;E\u0CF0\u0CF3\uC000\u228F\u0338qual;\u62E2erset\u0100;E\u0D03\u0D06\uC000\u2290\u0338qual;\u62E3\u0180bcp\u0D13\u0D24\u0D4Eset\u0100;E\u0D1B\u0D1E\uC000\u2282\u20D2qual;\u6288ceeds\u0200;EST\u0D32\u0D33\u0D3B\u0D46\u6281qual;\uC000\u2AB0\u0338lantEqual;\u62E1ilde;\uC000\u227F\u0338erset\u0100;E\u0D58\u0D5B\uC000\u2283\u20D2qual;\u6289ilde\u0200;EFT\u0D6E\u0D6F\u0D75\u0D7F\u6241qual;\u6244ullEqual;\u6247ilde;\u6249erticalBar;\u6224cr;\uC000\u{1D4A9}ilde\u803B\xD1\u40D1;\u439D\u0700Eacdfgmoprstuv\u0DBD\u0DC2\u0DC9\u0DD5\u0DDB\u0DE0\u0DE7\u0DFC\u0E02\u0E20\u0E22\u0E32\u0E3F\u0E44lig;\u4152cute\u803B\xD3\u40D3\u0100iy\u0DCE\u0DD3rc\u803B\xD4\u40D4;\u441Eblac;\u4150r;\uC000\u{1D512}rave\u803B\xD2\u40D2\u0180aei\u0DEE\u0DF2\u0DF6cr;\u414Cga;\u43A9cron;\u439Fpf;\uC000\u{1D546}enCurly\u0100DQ\u0E0E\u0E1AoubleQuote;\u601Cuote;\u6018;\u6A54\u0100cl\u0E27\u0E2Cr;\uC000\u{1D4AA}ash\u803B\xD8\u40D8i\u016C\u0E37\u0E3Cde\u803B\xD5\u40D5es;\u6A37ml\u803B\xD6\u40D6er\u0100BP\u0E4B\u0E60\u0100ar\u0E50\u0E53r;\u603Eac\u0100ek\u0E5A\u0E5C;\u63DEet;\u63B4arenthesis;\u63DC\u0480acfhilors\u0E7F\u0E87\u0E8A\u0E8F\u0E92\u0E94\u0E9D\u0EB0\u0EFCrtialD;\u6202y;\u441Fr;\uC000\u{1D513}i;\u43A6;\u43A0usMinus;\u40B1\u0100ip\u0EA2\u0EADncareplan\xE5\u069Df;\u6119\u0200;eio\u0EB9\u0EBA\u0EE0\u0EE4\u6ABBcedes\u0200;EST\u0EC8\u0EC9\u0ECF\u0EDA\u627Aqual;\u6AAFlantEqual;\u627Cilde;\u627Eme;\u6033\u0100dp\u0EE9\u0EEEuct;\u620Fortion\u0100;a\u0225\u0EF9l;\u621D\u0100ci\u0F01\u0F06r;\uC000\u{1D4AB};\u43A8\u0200Ufos\u0F11\u0F16\u0F1B\u0F1FOT\u803B"\u4022r;\uC000\u{1D514}pf;\u611Acr;\uC000\u{1D4AC}\u0600BEacefhiorsu\u0F3E\u0F43\u0F47\u0F60\u0F73\u0FA7\u0FAA\u0FAD\u1096\u10A9\u10B4\u10BEarr;\u6910G\u803B\xAE\u40AE\u0180cnr\u0F4E\u0F53\u0F56ute;\u4154g;\u67EBr\u0100;t\u0F5C\u0F5D\u61A0l;\u6916\u0180aey\u0F67\u0F6C\u0F71ron;\u4158dil;\u4156;\u4420\u0100;v\u0F78\u0F79\u611Cerse\u0100EU\u0F82\u0F99\u0100lq\u0F87\u0F8Eement;\u620Builibrium;\u61CBpEquilibrium;\u696Fr\xBB\u0F79o;\u43A1ght\u0400ACDFTUVa\u0FC1\u0FEB\u0FF3\u1022\u1028\u105B\u1087\u03D8\u0100nr\u0FC6\u0FD2gleBracket;\u67E9row\u0180;BL\u0FDC\u0FDD\u0FE1\u6192ar;\u61E5eftArrow;\u61C4eiling;\u6309o\u01F5\u0FF9\0\u1005bleBracket;\u67E7n\u01D4\u100A\0\u1014eeVector;\u695Dector\u0100;B\u101D\u101E\u61C2ar;\u6955loor;\u630B\u0100er\u102D\u1043e\u0180;AV\u1035\u1036\u103C\u62A2rrow;\u61A6ector;\u695Biangle\u0180;BE\u1050\u1051\u1055\u62B3ar;\u69D0qual;\u62B5p\u0180DTV\u1063\u106E\u1078ownVector;\u694FeeVector;\u695Cector\u0100;B\u1082\u1083\u61BEar;\u6954ector\u0100;B\u1091\u1092\u61C0ar;\u6953\u0100pu\u109B\u109Ef;\u611DndImplies;\u6970ightarrow;\u61DB\u0100ch\u10B9\u10BCr;\u611B;\u61B1leDelayed;\u69F4\u0680HOacfhimoqstu\u10E4\u10F1\u10F7\u10FD\u1119\u111E\u1151\u1156\u1161\u1167\u11B5\u11BB\u11BF\u0100Cc\u10E9\u10EEHcy;\u4429y;\u4428FTcy;\u442Ccute;\u415A\u0280;aeiy\u1108\u1109\u110E\u1113\u1117\u6ABCron;\u4160dil;\u415Erc;\u415C;\u4421r;\uC000\u{1D516}ort\u0200DLRU\u112A\u1134\u113E\u1149ownArrow\xBB\u041EeftArrow\xBB\u089AightArrow\xBB\u0FDDpArrow;\u6191gma;\u43A3allCircle;\u6218pf;\uC000\u{1D54A}\u0272\u116D\0\0\u1170t;\u621Aare\u0200;ISU\u117B\u117C\u1189\u11AF\u65A1ntersection;\u6293u\u0100bp\u118F\u119Eset\u0100;E\u1197\u1198\u628Fqual;\u6291erset\u0100;E\u11A8\u11A9\u6290qual;\u6292nion;\u6294cr;\uC000\u{1D4AE}ar;\u62C6\u0200bcmp\u11C8\u11DB\u1209\u120B\u0100;s\u11CD\u11CE\u62D0et\u0100;E\u11CD\u11D5qual;\u6286\u0100ch\u11E0\u1205eeds\u0200;EST\u11ED\u11EE\u11F4\u11FF\u627Bqual;\u6AB0lantEqual;\u627Dilde;\u627FTh\xE1\u0F8C;\u6211\u0180;es\u1212\u1213\u1223\u62D1rset\u0100;E\u121C\u121D\u6283qual;\u6287et\xBB\u1213\u0580HRSacfhiors\u123E\u1244\u1249\u1255\u125E\u1271\u1276\u129F\u12C2\u12C8\u12D1ORN\u803B\xDE\u40DEADE;\u6122\u0100Hc\u124E\u1252cy;\u440By;\u4426\u0100bu\u125A\u125C;\u4009;\u43A4\u0180aey\u1265\u126A\u126Fron;\u4164dil;\u4162;\u4422r;\uC000\u{1D517}\u0100ei\u127B\u1289\u01F2\u1280\0\u1287efore;\u6234a;\u4398\u0100cn\u128E\u1298kSpace;\uC000\u205F\u200ASpace;\u6009lde\u0200;EFT\u12AB\u12AC\u12B2\u12BC\u623Cqual;\u6243ullEqual;\u6245ilde;\u6248pf;\uC000\u{1D54B}ipleDot;\u60DB\u0100ct\u12D6\u12DBr;\uC000\u{1D4AF}rok;\u4166\u0AE1\u12F7\u130E\u131A\u1326\0\u132C\u1331\0\0\0\0\0\u1338\u133D\u1377\u1385\0\u13FF\u1404\u140A\u1410\u0100cr\u12FB\u1301ute\u803B\xDA\u40DAr\u0100;o\u1307\u1308\u619Fcir;\u6949r\u01E3\u1313\0\u1316y;\u440Eve;\u416C\u0100iy\u131E\u1323rc\u803B\xDB\u40DB;\u4423blac;\u4170r;\uC000\u{1D518}rave\u803B\xD9\u40D9acr;\u416A\u0100di\u1341\u1369er\u0100BP\u1348\u135D\u0100ar\u134D\u1350r;\u405Fac\u0100ek\u1357\u1359;\u63DFet;\u63B5arenthesis;\u63DDon\u0100;P\u1370\u1371\u62C3lus;\u628E\u0100gp\u137B\u137Fon;\u4172f;\uC000\u{1D54C}\u0400ADETadps\u1395\u13AE\u13B8\u13C4\u03E8\u13D2\u13D7\u13F3rrow\u0180;BD\u1150\u13A0\u13A4ar;\u6912ownArrow;\u61C5ownArrow;\u6195quilibrium;\u696Eee\u0100;A\u13CB\u13CC\u62A5rrow;\u61A5own\xE1\u03F3er\u0100LR\u13DE\u13E8eftArrow;\u6196ightArrow;\u6197i\u0100;l\u13F9\u13FA\u43D2on;\u43A5ing;\u416Ecr;\uC000\u{1D4B0}ilde;\u4168ml\u803B\xDC\u40DC\u0480Dbcdefosv\u1427\u142C\u1430\u1433\u143E\u1485\u148A\u1490\u1496ash;\u62ABar;\u6AEBy;\u4412ash\u0100;l\u143B\u143C\u62A9;\u6AE6\u0100er\u1443\u1445;\u62C1\u0180bty\u144C\u1450\u147Aar;\u6016\u0100;i\u144F\u1455cal\u0200BLST\u1461\u1465\u146A\u1474ar;\u6223ine;\u407Ceparator;\u6758ilde;\u6240ThinSpace;\u600Ar;\uC000\u{1D519}pf;\uC000\u{1D54D}cr;\uC000\u{1D4B1}dash;\u62AA\u0280cefos\u14A7\u14AC\u14B1\u14B6\u14BCirc;\u4174dge;\u62C0r;\uC000\u{1D51A}pf;\uC000\u{1D54E}cr;\uC000\u{1D4B2}\u0200fios\u14CB\u14D0\u14D2\u14D8r;\uC000\u{1D51B};\u439Epf;\uC000\u{1D54F}cr;\uC000\u{1D4B3}\u0480AIUacfosu\u14F1\u14F5\u14F9\u14FD\u1504\u150F\u1514\u151A\u1520cy;\u442Fcy;\u4407cy;\u442Ecute\u803B\xDD\u40DD\u0100iy\u1509\u150Drc;\u4176;\u442Br;\uC000\u{1D51C}pf;\uC000\u{1D550}cr;\uC000\u{1D4B4}ml;\u4178\u0400Hacdefos\u1535\u1539\u153F\u154B\u154F\u155D\u1560\u1564cy;\u4416cute;\u4179\u0100ay\u1544\u1549ron;\u417D;\u4417ot;\u417B\u01F2\u1554\0\u155BoWidt\xE8\u0AD9a;\u4396r;\u6128pf;\u6124cr;\uC000\u{1D4B5}\u0BE1\u1583\u158A\u1590\0\u15B0\u15B6\u15BF\0\0\0\0\u15C6\u15DB\u15EB\u165F\u166D\0\u1695\u169B\u16B2\u16B9\0\u16BEcute\u803B\xE1\u40E1reve;\u4103\u0300;Ediuy\u159C\u159D\u15A1\u15A3\u15A8\u15AD\u623E;\uC000\u223E\u0333;\u623Frc\u803B\xE2\u40E2te\u80BB\xB4\u0306;\u4430lig\u803B\xE6\u40E6\u0100;r\xB2\u15BA;\uC000\u{1D51E}rave\u803B\xE0\u40E0\u0100ep\u15CA\u15D6\u0100fp\u15CF\u15D4sym;\u6135\xE8\u15D3ha;\u43B1\u0100ap\u15DFc\u0100cl\u15E4\u15E7r;\u4101g;\u6A3F\u0264\u15F0\0\0\u160A\u0280;adsv\u15FA\u15FB\u15FF\u1601\u1607\u6227nd;\u6A55;\u6A5Clope;\u6A58;\u6A5A\u0380;elmrsz\u1618\u1619\u161B\u161E\u163F\u164F\u1659\u6220;\u69A4e\xBB\u1619sd\u0100;a\u1625\u1626\u6221\u0461\u1630\u1632\u1634\u1636\u1638\u163A\u163C\u163E;\u69A8;\u69A9;\u69AA;\u69AB;\u69AC;\u69AD;\u69AE;\u69AFt\u0100;v\u1645\u1646\u621Fb\u0100;d\u164C\u164D\u62BE;\u699D\u0100pt\u1654\u1657h;\u6222\xBB\xB9arr;\u637C\u0100gp\u1663\u1667on;\u4105f;\uC000\u{1D552}\u0380;Eaeiop\u12C1\u167B\u167D\u1682\u1684\u1687\u168A;\u6A70cir;\u6A6F;\u624Ad;\u624Bs;\u4027rox\u0100;e\u12C1\u1692\xF1\u1683ing\u803B\xE5\u40E5\u0180cty\u16A1\u16A6\u16A8r;\uC000\u{1D4B6};\u402Amp\u0100;e\u12C1\u16AF\xF1\u0288ilde\u803B\xE3\u40E3ml\u803B\xE4\u40E4\u0100ci\u16C2\u16C8onin\xF4\u0272nt;\u6A11\u0800Nabcdefiklnoprsu\u16ED\u16F1\u1730\u173C\u1743\u1748\u1778\u177D\u17E0\u17E6\u1839\u1850\u170D\u193D\u1948\u1970ot;\u6AED\u0100cr\u16F6\u171Ek\u0200ceps\u1700\u1705\u170D\u1713ong;\u624Cpsilon;\u43F6rime;\u6035im\u0100;e\u171A\u171B\u623Dq;\u62CD\u0176\u1722\u1726ee;\u62BDed\u0100;g\u172C\u172D\u6305e\xBB\u172Drk\u0100;t\u135C\u1737brk;\u63B6\u0100oy\u1701\u1741;\u4431quo;\u601E\u0280cmprt\u1753\u175B\u1761\u1764\u1768aus\u0100;e\u010A\u0109ptyv;\u69B0s\xE9\u170Cno\xF5\u0113\u0180ahw\u176F\u1771\u1773;\u43B2;\u6136een;\u626Cr;\uC000\u{1D51F}g\u0380costuvw\u178D\u179D\u17B3\u17C1\u17D5\u17DB\u17DE\u0180aiu\u1794\u1796\u179A\xF0\u0760rc;\u65EFp\xBB\u1371\u0180dpt\u17A4\u17A8\u17ADot;\u6A00lus;\u6A01imes;\u6A02\u0271\u17B9\0\0\u17BEcup;\u6A06ar;\u6605riangle\u0100du\u17CD\u17D2own;\u65BDp;\u65B3plus;\u6A04e\xE5\u1444\xE5\u14ADarow;\u690D\u0180ako\u17ED\u1826\u1835\u0100cn\u17F2\u1823k\u0180lst\u17FA\u05AB\u1802ozenge;\u69EBriangle\u0200;dlr\u1812\u1813\u1818\u181D\u65B4own;\u65BEeft;\u65C2ight;\u65B8k;\u6423\u01B1\u182B\0\u1833\u01B2\u182F\0\u1831;\u6592;\u65914;\u6593ck;\u6588\u0100eo\u183E\u184D\u0100;q\u1843\u1846\uC000=\u20E5uiv;\uC000\u2261\u20E5t;\u6310\u0200ptwx\u1859\u185E\u1867\u186Cf;\uC000\u{1D553}\u0100;t\u13CB\u1863om\xBB\u13CCtie;\u62C8\u0600DHUVbdhmptuv\u1885\u1896\u18AA\u18BB\u18D7\u18DB\u18EC\u18FF\u1905\u190A\u1910\u1921\u0200LRlr\u188E\u1890\u1892\u1894;\u6557;\u6554;\u6556;\u6553\u0280;DUdu\u18A1\u18A2\u18A4\u18A6\u18A8\u6550;\u6566;\u6569;\u6564;\u6567\u0200LRlr\u18B3\u18B5\u18B7\u18B9;\u655D;\u655A;\u655C;\u6559\u0380;HLRhlr\u18CA\u18CB\u18CD\u18CF\u18D1\u18D3\u18D5\u6551;\u656C;\u6563;\u6560;\u656B;\u6562;\u655Fox;\u69C9\u0200LRlr\u18E4\u18E6\u18E8\u18EA;\u6555;\u6552;\u6510;\u650C\u0280;DUdu\u06BD\u18F7\u18F9\u18FB\u18FD;\u6565;\u6568;\u652C;\u6534inus;\u629Flus;\u629Eimes;\u62A0\u0200LRlr\u1919\u191B\u191D\u191F;\u655B;\u6558;\u6518;\u6514\u0380;HLRhlr\u1930\u1931\u1933\u1935\u1937\u1939\u193B\u6502;\u656A;\u6561;\u655E;\u653C;\u6524;\u651C\u0100ev\u0123\u1942bar\u803B\xA6\u40A6\u0200ceio\u1951\u1956\u195A\u1960r;\uC000\u{1D4B7}mi;\u604Fm\u0100;e\u171A\u171Cl\u0180;bh\u1968\u1969\u196B\u405C;\u69C5sub;\u67C8\u016C\u1974\u197El\u0100;e\u1979\u197A\u6022t\xBB\u197Ap\u0180;Ee\u012F\u1985\u1987;\u6AAE\u0100;q\u06DC\u06DB\u0CE1\u19A7\0\u19E8\u1A11\u1A15\u1A32\0\u1A37\u1A50\0\0\u1AB4\0\0\u1AC1\0\0\u1B21\u1B2E\u1B4D\u1B52\0\u1BFD\0\u1C0C\u0180cpr\u19AD\u19B2\u19DDute;\u4107\u0300;abcds\u19BF\u19C0\u19C4\u19CA\u19D5\u19D9\u6229nd;\u6A44rcup;\u6A49\u0100au\u19CF\u19D2p;\u6A4Bp;\u6A47ot;\u6A40;\uC000\u2229\uFE00\u0100eo\u19E2\u19E5t;\u6041\xEE\u0693\u0200aeiu\u19F0\u19FB\u1A01\u1A05\u01F0\u19F5\0\u19F8s;\u6A4Don;\u410Ddil\u803B\xE7\u40E7rc;\u4109ps\u0100;s\u1A0C\u1A0D\u6A4Cm;\u6A50ot;\u410B\u0180dmn\u1A1B\u1A20\u1A26il\u80BB\xB8\u01ADptyv;\u69B2t\u8100\xA2;e\u1A2D\u1A2E\u40A2r\xE4\u01B2r;\uC000\u{1D520}\u0180cei\u1A3D\u1A40\u1A4Dy;\u4447ck\u0100;m\u1A47\u1A48\u6713ark\xBB\u1A48;\u43C7r\u0380;Ecefms\u1A5F\u1A60\u1A62\u1A6B\u1AA4\u1AAA\u1AAE\u65CB;\u69C3\u0180;el\u1A69\u1A6A\u1A6D\u42C6q;\u6257e\u0261\u1A74\0\0\u1A88rrow\u0100lr\u1A7C\u1A81eft;\u61BAight;\u61BB\u0280RSacd\u1A92\u1A94\u1A96\u1A9A\u1A9F\xBB\u0F47;\u64C8st;\u629Birc;\u629Aash;\u629Dnint;\u6A10id;\u6AEFcir;\u69C2ubs\u0100;u\u1ABB\u1ABC\u6663it\xBB\u1ABC\u02EC\u1AC7\u1AD4\u1AFA\0\u1B0Aon\u0100;e\u1ACD\u1ACE\u403A\u0100;q\xC7\xC6\u026D\u1AD9\0\0\u1AE2a\u0100;t\u1ADE\u1ADF\u402C;\u4040\u0180;fl\u1AE8\u1AE9\u1AEB\u6201\xEE\u1160e\u0100mx\u1AF1\u1AF6ent\xBB\u1AE9e\xF3\u024D\u01E7\u1AFE\0\u1B07\u0100;d\u12BB\u1B02ot;\u6A6Dn\xF4\u0246\u0180fry\u1B10\u1B14\u1B17;\uC000\u{1D554}o\xE4\u0254\u8100\xA9;s\u0155\u1B1Dr;\u6117\u0100ao\u1B25\u1B29rr;\u61B5ss;\u6717\u0100cu\u1B32\u1B37r;\uC000\u{1D4B8}\u0100bp\u1B3C\u1B44\u0100;e\u1B41\u1B42\u6ACF;\u6AD1\u0100;e\u1B49\u1B4A\u6AD0;\u6AD2dot;\u62EF\u0380delprvw\u1B60\u1B6C\u1B77\u1B82\u1BAC\u1BD4\u1BF9arr\u0100lr\u1B68\u1B6A;\u6938;\u6935\u0270\u1B72\0\0\u1B75r;\u62DEc;\u62DFarr\u0100;p\u1B7F\u1B80\u61B6;\u693D\u0300;bcdos\u1B8F\u1B90\u1B96\u1BA1\u1BA5\u1BA8\u622Arcap;\u6A48\u0100au\u1B9B\u1B9Ep;\u6A46p;\u6A4Aot;\u628Dr;\u6A45;\uC000\u222A\uFE00\u0200alrv\u1BB5\u1BBF\u1BDE\u1BE3rr\u0100;m\u1BBC\u1BBD\u61B7;\u693Cy\u0180evw\u1BC7\u1BD4\u1BD8q\u0270\u1BCE\0\0\u1BD2re\xE3\u1B73u\xE3\u1B75ee;\u62CEedge;\u62CFen\u803B\xA4\u40A4earrow\u0100lr\u1BEE\u1BF3eft\xBB\u1B80ight\xBB\u1BBDe\xE4\u1BDD\u0100ci\u1C01\u1C07onin\xF4\u01F7nt;\u6231lcty;\u632D\u0980AHabcdefhijlorstuwz\u1C38\u1C3B\u1C3F\u1C5D\u1C69\u1C75\u1C8A\u1C9E\u1CAC\u1CB7\u1CFB\u1CFF\u1D0D\u1D7B\u1D91\u1DAB\u1DBB\u1DC6\u1DCDr\xF2\u0381ar;\u6965\u0200glrs\u1C48\u1C4D\u1C52\u1C54ger;\u6020eth;\u6138\xF2\u1133h\u0100;v\u1C5A\u1C5B\u6010\xBB\u090A\u016B\u1C61\u1C67arow;\u690Fa\xE3\u0315\u0100ay\u1C6E\u1C73ron;\u410F;\u4434\u0180;ao\u0332\u1C7C\u1C84\u0100gr\u02BF\u1C81r;\u61CAtseq;\u6A77\u0180glm\u1C91\u1C94\u1C98\u803B\xB0\u40B0ta;\u43B4ptyv;\u69B1\u0100ir\u1CA3\u1CA8sht;\u697F;\uC000\u{1D521}ar\u0100lr\u1CB3\u1CB5\xBB\u08DC\xBB\u101E\u0280aegsv\u1CC2\u0378\u1CD6\u1CDC\u1CE0m\u0180;os\u0326\u1CCA\u1CD4nd\u0100;s\u0326\u1CD1uit;\u6666amma;\u43DDin;\u62F2\u0180;io\u1CE7\u1CE8\u1CF8\u40F7de\u8100\xF7;o\u1CE7\u1CF0ntimes;\u62C7n\xF8\u1CF7cy;\u4452c\u026F\u1D06\0\0\u1D0Arn;\u631Eop;\u630D\u0280lptuw\u1D18\u1D1D\u1D22\u1D49\u1D55lar;\u4024f;\uC000\u{1D555}\u0280;emps\u030B\u1D2D\u1D37\u1D3D\u1D42q\u0100;d\u0352\u1D33ot;\u6251inus;\u6238lus;\u6214quare;\u62A1blebarwedg\xE5\xFAn\u0180adh\u112E\u1D5D\u1D67ownarrow\xF3\u1C83arpoon\u0100lr\u1D72\u1D76ef\xF4\u1CB4igh\xF4\u1CB6\u0162\u1D7F\u1D85karo\xF7\u0F42\u026F\u1D8A\0\0\u1D8Ern;\u631Fop;\u630C\u0180cot\u1D98\u1DA3\u1DA6\u0100ry\u1D9D\u1DA1;\uC000\u{1D4B9};\u4455l;\u69F6rok;\u4111\u0100dr\u1DB0\u1DB4ot;\u62F1i\u0100;f\u1DBA\u1816\u65BF\u0100ah\u1DC0\u1DC3r\xF2\u0429a\xF2\u0FA6angle;\u69A6\u0100ci\u1DD2\u1DD5y;\u445Fgrarr;\u67FF\u0900Dacdefglmnopqrstux\u1E01\u1E09\u1E19\u1E38\u0578\u1E3C\u1E49\u1E61\u1E7E\u1EA5\u1EAF\u1EBD\u1EE1\u1F2A\u1F37\u1F44\u1F4E\u1F5A\u0100Do\u1E06\u1D34o\xF4\u1C89\u0100cs\u1E0E\u1E14ute\u803B\xE9\u40E9ter;\u6A6E\u0200aioy\u1E22\u1E27\u1E31\u1E36ron;\u411Br\u0100;c\u1E2D\u1E2E\u6256\u803B\xEA\u40EAlon;\u6255;\u444Dot;\u4117\u0100Dr\u1E41\u1E45ot;\u6252;\uC000\u{1D522}\u0180;rs\u1E50\u1E51\u1E57\u6A9Aave\u803B\xE8\u40E8\u0100;d\u1E5C\u1E5D\u6A96ot;\u6A98\u0200;ils\u1E6A\u1E6B\u1E72\u1E74\u6A99nters;\u63E7;\u6113\u0100;d\u1E79\u1E7A\u6A95ot;\u6A97\u0180aps\u1E85\u1E89\u1E97cr;\u4113ty\u0180;sv\u1E92\u1E93\u1E95\u6205et\xBB\u1E93p\u01001;\u1E9D\u1EA4\u0133\u1EA1\u1EA3;\u6004;\u6005\u6003\u0100gs\u1EAA\u1EAC;\u414Bp;\u6002\u0100gp\u1EB4\u1EB8on;\u4119f;\uC000\u{1D556}\u0180als\u1EC4\u1ECE\u1ED2r\u0100;s\u1ECA\u1ECB\u62D5l;\u69E3us;\u6A71i\u0180;lv\u1EDA\u1EDB\u1EDF\u43B5on\xBB\u1EDB;\u43F5\u0200csuv\u1EEA\u1EF3\u1F0B\u1F23\u0100io\u1EEF\u1E31rc\xBB\u1E2E\u0269\u1EF9\0\0\u1EFB\xED\u0548ant\u0100gl\u1F02\u1F06tr\xBB\u1E5Dess\xBB\u1E7A\u0180aei\u1F12\u1F16\u1F1Als;\u403Dst;\u625Fv\u0100;D\u0235\u1F20D;\u6A78parsl;\u69E5\u0100Da\u1F2F\u1F33ot;\u6253rr;\u6971\u0180cdi\u1F3E\u1F41\u1EF8r;\u612Fo\xF4\u0352\u0100ah\u1F49\u1F4B;\u43B7\u803B\xF0\u40F0\u0100mr\u1F53\u1F57l\u803B\xEB\u40EBo;\u60AC\u0180cip\u1F61\u1F64\u1F67l;\u4021s\xF4\u056E\u0100eo\u1F6C\u1F74ctatio\xEE\u0559nential\xE5\u0579\u09E1\u1F92\0\u1F9E\0\u1FA1\u1FA7\0\0\u1FC6\u1FCC\0\u1FD3\0\u1FE6\u1FEA\u2000\0\u2008\u205Allingdotse\xF1\u1E44y;\u4444male;\u6640\u0180ilr\u1FAD\u1FB3\u1FC1lig;\u8000\uFB03\u0269\u1FB9\0\0\u1FBDg;\u8000\uFB00ig;\u8000\uFB04;\uC000\u{1D523}lig;\u8000\uFB01lig;\uC000fj\u0180alt\u1FD9\u1FDC\u1FE1t;\u666Dig;\u8000\uFB02ns;\u65B1of;\u4192\u01F0\u1FEE\0\u1FF3f;\uC000\u{1D557}\u0100ak\u05BF\u1FF7\u0100;v\u1FFC\u1FFD\u62D4;\u6AD9artint;\u6A0D\u0100ao\u200C\u2055\u0100cs\u2011\u2052\u03B1\u201A\u2030\u2038\u2045\u2048\0\u2050\u03B2\u2022\u2025\u2027\u202A\u202C\0\u202E\u803B\xBD\u40BD;\u6153\u803B\xBC\u40BC;\u6155;\u6159;\u615B\u01B3\u2034\0\u2036;\u6154;\u6156\u02B4\u203E\u2041\0\0\u2043\u803B\xBE\u40BE;\u6157;\u615C5;\u6158\u01B6\u204C\0\u204E;\u615A;\u615D8;\u615El;\u6044wn;\u6322cr;\uC000\u{1D4BB}\u0880Eabcdefgijlnorstv\u2082\u2089\u209F\u20A5\u20B0\u20B4\u20F0\u20F5\u20FA\u20FF\u2103\u2112\u2138\u0317\u213E\u2152\u219E\u0100;l\u064D\u2087;\u6A8C\u0180cmp\u2090\u2095\u209Dute;\u41F5ma\u0100;d\u209C\u1CDA\u43B3;\u6A86reve;\u411F\u0100iy\u20AA\u20AErc;\u411D;\u4433ot;\u4121\u0200;lqs\u063E\u0642\u20BD\u20C9\u0180;qs\u063E\u064C\u20C4lan\xF4\u0665\u0200;cdl\u0665\u20D2\u20D5\u20E5c;\u6AA9ot\u0100;o\u20DC\u20DD\u6A80\u0100;l\u20E2\u20E3\u6A82;\u6A84\u0100;e\u20EA\u20ED\uC000\u22DB\uFE00s;\u6A94r;\uC000\u{1D524}\u0100;g\u0673\u061Bmel;\u6137cy;\u4453\u0200;Eaj\u065A\u210C\u210E\u2110;\u6A92;\u6AA5;\u6AA4\u0200Eaes\u211B\u211D\u2129\u2134;\u6269p\u0100;p\u2123\u2124\u6A8Arox\xBB\u2124\u0100;q\u212E\u212F\u6A88\u0100;q\u212E\u211Bim;\u62E7pf;\uC000\u{1D558}\u0100ci\u2143\u2146r;\u610Am\u0180;el\u066B\u214E\u2150;\u6A8E;\u6A90\u8300>;cdlqr\u05EE\u2160\u216A\u216E\u2173\u2179\u0100ci\u2165\u2167;\u6AA7r;\u6A7Aot;\u62D7Par;\u6995uest;\u6A7C\u0280adels\u2184\u216A\u2190\u0656\u219B\u01F0\u2189\0\u218Epro\xF8\u209Er;\u6978q\u0100lq\u063F\u2196les\xF3\u2088i\xED\u066B\u0100en\u21A3\u21ADrtneqq;\uC000\u2269\uFE00\xC5\u21AA\u0500Aabcefkosy\u21C4\u21C7\u21F1\u21F5\u21FA\u2218\u221D\u222F\u2268\u227Dr\xF2\u03A0\u0200ilmr\u21D0\u21D4\u21D7\u21DBrs\xF0\u1484f\xBB\u2024il\xF4\u06A9\u0100dr\u21E0\u21E4cy;\u444A\u0180;cw\u08F4\u21EB\u21EFir;\u6948;\u61ADar;\u610Firc;\u4125\u0180alr\u2201\u220E\u2213rts\u0100;u\u2209\u220A\u6665it\xBB\u220Alip;\u6026con;\u62B9r;\uC000\u{1D525}s\u0100ew\u2223\u2229arow;\u6925arow;\u6926\u0280amopr\u223A\u223E\u2243\u225E\u2263rr;\u61FFtht;\u623Bk\u0100lr\u2249\u2253eftarrow;\u61A9ightarrow;\u61AAf;\uC000\u{1D559}bar;\u6015\u0180clt\u226F\u2274\u2278r;\uC000\u{1D4BD}as\xE8\u21F4rok;\u4127\u0100bp\u2282\u2287ull;\u6043hen\xBB\u1C5B\u0AE1\u22A3\0\u22AA\0\u22B8\u22C5\u22CE\0\u22D5\u22F3\0\0\u22F8\u2322\u2367\u2362\u237F\0\u2386\u23AA\u23B4cute\u803B\xED\u40ED\u0180;iy\u0771\u22B0\u22B5rc\u803B\xEE\u40EE;\u4438\u0100cx\u22BC\u22BFy;\u4435cl\u803B\xA1\u40A1\u0100fr\u039F\u22C9;\uC000\u{1D526}rave\u803B\xEC\u40EC\u0200;ino\u073E\u22DD\u22E9\u22EE\u0100in\u22E2\u22E6nt;\u6A0Ct;\u622Dfin;\u69DCta;\u6129lig;\u4133\u0180aop\u22FE\u231A\u231D\u0180cgt\u2305\u2308\u2317r;\u412B\u0180elp\u071F\u230F\u2313in\xE5\u078Ear\xF4\u0720h;\u4131f;\u62B7ed;\u41B5\u0280;cfot\u04F4\u232C\u2331\u233D\u2341are;\u6105in\u0100;t\u2338\u2339\u621Eie;\u69DDdo\xF4\u2319\u0280;celp\u0757\u234C\u2350\u235B\u2361al;\u62BA\u0100gr\u2355\u2359er\xF3\u1563\xE3\u234Darhk;\u6A17rod;\u6A3C\u0200cgpt\u236F\u2372\u2376\u237By;\u4451on;\u412Ff;\uC000\u{1D55A}a;\u43B9uest\u803B\xBF\u40BF\u0100ci\u238A\u238Fr;\uC000\u{1D4BE}n\u0280;Edsv\u04F4\u239B\u239D\u23A1\u04F3;\u62F9ot;\u62F5\u0100;v\u23A6\u23A7\u62F4;\u62F3\u0100;i\u0777\u23AElde;\u4129\u01EB\u23B8\0\u23BCcy;\u4456l\u803B\xEF\u40EF\u0300cfmosu\u23CC\u23D7\u23DC\u23E1\u23E7\u23F5\u0100iy\u23D1\u23D5rc;\u4135;\u4439r;\uC000\u{1D527}ath;\u4237pf;\uC000\u{1D55B}\u01E3\u23EC\0\u23F1r;\uC000\u{1D4BF}rcy;\u4458kcy;\u4454\u0400acfghjos\u240B\u2416\u2422\u2427\u242D\u2431\u2435\u243Bppa\u0100;v\u2413\u2414\u43BA;\u43F0\u0100ey\u241B\u2420dil;\u4137;\u443Ar;\uC000\u{1D528}reen;\u4138cy;\u4445cy;\u445Cpf;\uC000\u{1D55C}cr;\uC000\u{1D4C0}\u0B80ABEHabcdefghjlmnoprstuv\u2470\u2481\u2486\u248D\u2491\u250E\u253D\u255A\u2580\u264E\u265E\u2665\u2679\u267D\u269A\u26B2\u26D8\u275D\u2768\u278B\u27C0\u2801\u2812\u0180art\u2477\u247A\u247Cr\xF2\u09C6\xF2\u0395ail;\u691Barr;\u690E\u0100;g\u0994\u248B;\u6A8Bar;\u6962\u0963\u24A5\0\u24AA\0\u24B1\0\0\0\0\0\u24B5\u24BA\0\u24C6\u24C8\u24CD\0\u24F9ute;\u413Amptyv;\u69B4ra\xEE\u084Cbda;\u43BBg\u0180;dl\u088E\u24C1\u24C3;\u6991\xE5\u088E;\u6A85uo\u803B\xAB\u40ABr\u0400;bfhlpst\u0899\u24DE\u24E6\u24E9\u24EB\u24EE\u24F1\u24F5\u0100;f\u089D\u24E3s;\u691Fs;\u691D\xEB\u2252p;\u61ABl;\u6939im;\u6973l;\u61A2\u0180;ae\u24FF\u2500\u2504\u6AABil;\u6919\u0100;s\u2509\u250A\u6AAD;\uC000\u2AAD\uFE00\u0180abr\u2515\u2519\u251Drr;\u690Crk;\u6772\u0100ak\u2522\u252Cc\u0100ek\u2528\u252A;\u407B;\u405B\u0100es\u2531\u2533;\u698Bl\u0100du\u2539\u253B;\u698F;\u698D\u0200aeuy\u2546\u254B\u2556\u2558ron;\u413E\u0100di\u2550\u2554il;\u413C\xEC\u08B0\xE2\u2529;\u443B\u0200cqrs\u2563\u2566\u256D\u257Da;\u6936uo\u0100;r\u0E19\u1746\u0100du\u2572\u2577har;\u6967shar;\u694Bh;\u61B2\u0280;fgqs\u258B\u258C\u0989\u25F3\u25FF\u6264t\u0280ahlrt\u2598\u25A4\u25B7\u25C2\u25E8rrow\u0100;t\u0899\u25A1a\xE9\u24F6arpoon\u0100du\u25AF\u25B4own\xBB\u045Ap\xBB\u0966eftarrows;\u61C7ight\u0180ahs\u25CD\u25D6\u25DErrow\u0100;s\u08F4\u08A7arpoon\xF3\u0F98quigarro\xF7\u21F0hreetimes;\u62CB\u0180;qs\u258B\u0993\u25FAlan\xF4\u09AC\u0280;cdgs\u09AC\u260A\u260D\u261D\u2628c;\u6AA8ot\u0100;o\u2614\u2615\u6A7F\u0100;r\u261A\u261B\u6A81;\u6A83\u0100;e\u2622\u2625\uC000\u22DA\uFE00s;\u6A93\u0280adegs\u2633\u2639\u263D\u2649\u264Bppro\xF8\u24C6ot;\u62D6q\u0100gq\u2643\u2645\xF4\u0989gt\xF2\u248C\xF4\u099Bi\xED\u09B2\u0180ilr\u2655\u08E1\u265Asht;\u697C;\uC000\u{1D529}\u0100;E\u099C\u2663;\u6A91\u0161\u2669\u2676r\u0100du\u25B2\u266E\u0100;l\u0965\u2673;\u696Alk;\u6584cy;\u4459\u0280;acht\u0A48\u2688\u268B\u2691\u2696r\xF2\u25C1orne\xF2\u1D08ard;\u696Bri;\u65FA\u0100io\u269F\u26A4dot;\u4140ust\u0100;a\u26AC\u26AD\u63B0che\xBB\u26AD\u0200Eaes\u26BB\u26BD\u26C9\u26D4;\u6268p\u0100;p\u26C3\u26C4\u6A89rox\xBB\u26C4\u0100;q\u26CE\u26CF\u6A87\u0100;q\u26CE\u26BBim;\u62E6\u0400abnoptwz\u26E9\u26F4\u26F7\u271A\u272F\u2741\u2747\u2750\u0100nr\u26EE\u26F1g;\u67ECr;\u61FDr\xEB\u08C1g\u0180lmr\u26FF\u270D\u2714eft\u0100ar\u09E6\u2707ight\xE1\u09F2apsto;\u67FCight\xE1\u09FDparrow\u0100lr\u2725\u2729ef\xF4\u24EDight;\u61AC\u0180afl\u2736\u2739\u273Dr;\u6985;\uC000\u{1D55D}us;\u6A2Dimes;\u6A34\u0161\u274B\u274Fst;\u6217\xE1\u134E\u0180;ef\u2757\u2758\u1800\u65CAnge\xBB\u2758ar\u0100;l\u2764\u2765\u4028t;\u6993\u0280achmt\u2773\u2776\u277C\u2785\u2787r\xF2\u08A8orne\xF2\u1D8Car\u0100;d\u0F98\u2783;\u696D;\u600Eri;\u62BF\u0300achiqt\u2798\u279D\u0A40\u27A2\u27AE\u27BBquo;\u6039r;\uC000\u{1D4C1}m\u0180;eg\u09B2\u27AA\u27AC;\u6A8D;\u6A8F\u0100bu\u252A\u27B3o\u0100;r\u0E1F\u27B9;\u601Arok;\u4142\u8400<;cdhilqr\u082B\u27D2\u2639\u27DC\u27E0\u27E5\u27EA\u27F0\u0100ci\u27D7\u27D9;\u6AA6r;\u6A79re\xE5\u25F2mes;\u62C9arr;\u6976uest;\u6A7B\u0100Pi\u27F5\u27F9ar;\u6996\u0180;ef\u2800\u092D\u181B\u65C3r\u0100du\u2807\u280Dshar;\u694Ahar;\u6966\u0100en\u2817\u2821rtneqq;\uC000\u2268\uFE00\xC5\u281E\u0700Dacdefhilnopsu\u2840\u2845\u2882\u288E\u2893\u28A0\u28A5\u28A8\u28DA\u28E2\u28E4\u0A83\u28F3\u2902Dot;\u623A\u0200clpr\u284E\u2852\u2863\u287Dr\u803B\xAF\u40AF\u0100et\u2857\u2859;\u6642\u0100;e\u285E\u285F\u6720se\xBB\u285F\u0100;s\u103B\u2868to\u0200;dlu\u103B\u2873\u2877\u287Bow\xEE\u048Cef\xF4\u090F\xF0\u13D1ker;\u65AE\u0100oy\u2887\u288Cmma;\u6A29;\u443Cash;\u6014asuredangle\xBB\u1626r;\uC000\u{1D52A}o;\u6127\u0180cdn\u28AF\u28B4\u28C9ro\u803B\xB5\u40B5\u0200;acd\u1464\u28BD\u28C0\u28C4s\xF4\u16A7ir;\u6AF0ot\u80BB\xB7\u01B5us\u0180;bd\u28D2\u1903\u28D3\u6212\u0100;u\u1D3C\u28D8;\u6A2A\u0163\u28DE\u28E1p;\u6ADB\xF2\u2212\xF0\u0A81\u0100dp\u28E9\u28EEels;\u62A7f;\uC000\u{1D55E}\u0100ct\u28F8\u28FDr;\uC000\u{1D4C2}pos\xBB\u159D\u0180;lm\u2909\u290A\u290D\u43BCtimap;\u62B8\u0C00GLRVabcdefghijlmoprstuvw\u2942\u2953\u297E\u2989\u2998\u29DA\u29E9\u2A15\u2A1A\u2A58\u2A5D\u2A83\u2A95\u2AA4\u2AA8\u2B04\u2B07\u2B44\u2B7F\u2BAE\u2C34\u2C67\u2C7C\u2CE9\u0100gt\u2947\u294B;\uC000\u22D9\u0338\u0100;v\u2950\u0BCF\uC000\u226B\u20D2\u0180elt\u295A\u2972\u2976ft\u0100ar\u2961\u2967rrow;\u61CDightarrow;\u61CE;\uC000\u22D8\u0338\u0100;v\u297B\u0C47\uC000\u226A\u20D2ightarrow;\u61CF\u0100Dd\u298E\u2993ash;\u62AFash;\u62AE\u0280bcnpt\u29A3\u29A7\u29AC\u29B1\u29CCla\xBB\u02DEute;\u4144g;\uC000\u2220\u20D2\u0280;Eiop\u0D84\u29BC\u29C0\u29C5\u29C8;\uC000\u2A70\u0338d;\uC000\u224B\u0338s;\u4149ro\xF8\u0D84ur\u0100;a\u29D3\u29D4\u666El\u0100;s\u29D3\u0B38\u01F3\u29DF\0\u29E3p\u80BB\xA0\u0B37mp\u0100;e\u0BF9\u0C00\u0280aeouy\u29F4\u29FE\u2A03\u2A10\u2A13\u01F0\u29F9\0\u29FB;\u6A43on;\u4148dil;\u4146ng\u0100;d\u0D7E\u2A0Aot;\uC000\u2A6D\u0338p;\u6A42;\u443Dash;\u6013\u0380;Aadqsx\u0B92\u2A29\u2A2D\u2A3B\u2A41\u2A45\u2A50rr;\u61D7r\u0100hr\u2A33\u2A36k;\u6924\u0100;o\u13F2\u13F0ot;\uC000\u2250\u0338ui\xF6\u0B63\u0100ei\u2A4A\u2A4Ear;\u6928\xED\u0B98ist\u0100;s\u0BA0\u0B9Fr;\uC000\u{1D52B}\u0200Eest\u0BC5\u2A66\u2A79\u2A7C\u0180;qs\u0BBC\u2A6D\u0BE1\u0180;qs\u0BBC\u0BC5\u2A74lan\xF4\u0BE2i\xED\u0BEA\u0100;r\u0BB6\u2A81\xBB\u0BB7\u0180Aap\u2A8A\u2A8D\u2A91r\xF2\u2971rr;\u61AEar;\u6AF2\u0180;sv\u0F8D\u2A9C\u0F8C\u0100;d\u2AA1\u2AA2\u62FC;\u62FAcy;\u445A\u0380AEadest\u2AB7\u2ABA\u2ABE\u2AC2\u2AC5\u2AF6\u2AF9r\xF2\u2966;\uC000\u2266\u0338rr;\u619Ar;\u6025\u0200;fqs\u0C3B\u2ACE\u2AE3\u2AEFt\u0100ar\u2AD4\u2AD9rro\xF7\u2AC1ightarro\xF7\u2A90\u0180;qs\u0C3B\u2ABA\u2AEAlan\xF4\u0C55\u0100;s\u0C55\u2AF4\xBB\u0C36i\xED\u0C5D\u0100;r\u0C35\u2AFEi\u0100;e\u0C1A\u0C25i\xE4\u0D90\u0100pt\u2B0C\u2B11f;\uC000\u{1D55F}\u8180\xAC;in\u2B19\u2B1A\u2B36\u40ACn\u0200;Edv\u0B89\u2B24\u2B28\u2B2E;\uC000\u22F9\u0338ot;\uC000\u22F5\u0338\u01E1\u0B89\u2B33\u2B35;\u62F7;\u62F6i\u0100;v\u0CB8\u2B3C\u01E1\u0CB8\u2B41\u2B43;\u62FE;\u62FD\u0180aor\u2B4B\u2B63\u2B69r\u0200;ast\u0B7B\u2B55\u2B5A\u2B5Flle\xEC\u0B7Bl;\uC000\u2AFD\u20E5;\uC000\u2202\u0338lint;\u6A14\u0180;ce\u0C92\u2B70\u2B73u\xE5\u0CA5\u0100;c\u0C98\u2B78\u0100;e\u0C92\u2B7D\xF1\u0C98\u0200Aait\u2B88\u2B8B\u2B9D\u2BA7r\xF2\u2988rr\u0180;cw\u2B94\u2B95\u2B99\u619B;\uC000\u2933\u0338;\uC000\u219D\u0338ghtarrow\xBB\u2B95ri\u0100;e\u0CCB\u0CD6\u0380chimpqu\u2BBD\u2BCD\u2BD9\u2B04\u0B78\u2BE4\u2BEF\u0200;cer\u0D32\u2BC6\u0D37\u2BC9u\xE5\u0D45;\uC000\u{1D4C3}ort\u026D\u2B05\0\0\u2BD6ar\xE1\u2B56m\u0100;e\u0D6E\u2BDF\u0100;q\u0D74\u0D73su\u0100bp\u2BEB\u2BED\xE5\u0CF8\xE5\u0D0B\u0180bcp\u2BF6\u2C11\u2C19\u0200;Ees\u2BFF\u2C00\u0D22\u2C04\u6284;\uC000\u2AC5\u0338et\u0100;e\u0D1B\u2C0Bq\u0100;q\u0D23\u2C00c\u0100;e\u0D32\u2C17\xF1\u0D38\u0200;Ees\u2C22\u2C23\u0D5F\u2C27\u6285;\uC000\u2AC6\u0338et\u0100;e\u0D58\u2C2Eq\u0100;q\u0D60\u2C23\u0200gilr\u2C3D\u2C3F\u2C45\u2C47\xEC\u0BD7lde\u803B\xF1\u40F1\xE7\u0C43iangle\u0100lr\u2C52\u2C5Ceft\u0100;e\u0C1A\u2C5A\xF1\u0C26ight\u0100;e\u0CCB\u2C65\xF1\u0CD7\u0100;m\u2C6C\u2C6D\u43BD\u0180;es\u2C74\u2C75\u2C79\u4023ro;\u6116p;\u6007\u0480DHadgilrs\u2C8F\u2C94\u2C99\u2C9E\u2CA3\u2CB0\u2CB6\u2CD3\u2CE3ash;\u62ADarr;\u6904p;\uC000\u224D\u20D2ash;\u62AC\u0100et\u2CA8\u2CAC;\uC000\u2265\u20D2;\uC000>\u20D2nfin;\u69DE\u0180Aet\u2CBD\u2CC1\u2CC5rr;\u6902;\uC000\u2264\u20D2\u0100;r\u2CCA\u2CCD\uC000<\u20D2ie;\uC000\u22B4\u20D2\u0100At\u2CD8\u2CDCrr;\u6903rie;\uC000\u22B5\u20D2im;\uC000\u223C\u20D2\u0180Aan\u2CF0\u2CF4\u2D02rr;\u61D6r\u0100hr\u2CFA\u2CFDk;\u6923\u0100;o\u13E7\u13E5ear;\u6927\u1253\u1A95\0\0\0\0\0\0\0\0\0\0\0\0\0\u2D2D\0\u2D38\u2D48\u2D60\u2D65\u2D72\u2D84\u1B07\0\0\u2D8D\u2DAB\0\u2DC8\u2DCE\0\u2DDC\u2E19\u2E2B\u2E3E\u2E43\u0100cs\u2D31\u1A97ute\u803B\xF3\u40F3\u0100iy\u2D3C\u2D45r\u0100;c\u1A9E\u2D42\u803B\xF4\u40F4;\u443E\u0280abios\u1AA0\u2D52\u2D57\u01C8\u2D5Alac;\u4151v;\u6A38old;\u69BClig;\u4153\u0100cr\u2D69\u2D6Dir;\u69BF;\uC000\u{1D52C}\u036F\u2D79\0\0\u2D7C\0\u2D82n;\u42DBave\u803B\xF2\u40F2;\u69C1\u0100bm\u2D88\u0DF4ar;\u69B5\u0200acit\u2D95\u2D98\u2DA5\u2DA8r\xF2\u1A80\u0100ir\u2D9D\u2DA0r;\u69BEoss;\u69BBn\xE5\u0E52;\u69C0\u0180aei\u2DB1\u2DB5\u2DB9cr;\u414Dga;\u43C9\u0180cdn\u2DC0\u2DC5\u01CDron;\u43BF;\u69B6pf;\uC000\u{1D560}\u0180ael\u2DD4\u2DD7\u01D2r;\u69B7rp;\u69B9\u0380;adiosv\u2DEA\u2DEB\u2DEE\u2E08\u2E0D\u2E10\u2E16\u6228r\xF2\u1A86\u0200;efm\u2DF7\u2DF8\u2E02\u2E05\u6A5Dr\u0100;o\u2DFE\u2DFF\u6134f\xBB\u2DFF\u803B\xAA\u40AA\u803B\xBA\u40BAgof;\u62B6r;\u6A56lope;\u6A57;\u6A5B\u0180clo\u2E1F\u2E21\u2E27\xF2\u2E01ash\u803B\xF8\u40F8l;\u6298i\u016C\u2E2F\u2E34de\u803B\xF5\u40F5es\u0100;a\u01DB\u2E3As;\u6A36ml\u803B\xF6\u40F6bar;\u633D\u0AE1\u2E5E\0\u2E7D\0\u2E80\u2E9D\0\u2EA2\u2EB9\0\0\u2ECB\u0E9C\0\u2F13\0\0\u2F2B\u2FBC\0\u2FC8r\u0200;ast\u0403\u2E67\u2E72\u0E85\u8100\xB6;l\u2E6D\u2E6E\u40B6le\xEC\u0403\u0269\u2E78\0\0\u2E7Bm;\u6AF3;\u6AFDy;\u443Fr\u0280cimpt\u2E8B\u2E8F\u2E93\u1865\u2E97nt;\u4025od;\u402Eil;\u6030enk;\u6031r;\uC000\u{1D52D}\u0180imo\u2EA8\u2EB0\u2EB4\u0100;v\u2EAD\u2EAE\u43C6;\u43D5ma\xF4\u0A76ne;\u660E\u0180;tv\u2EBF\u2EC0\u2EC8\u43C0chfork\xBB\u1FFD;\u43D6\u0100au\u2ECF\u2EDFn\u0100ck\u2ED5\u2EDDk\u0100;h\u21F4\u2EDB;\u610E\xF6\u21F4s\u0480;abcdemst\u2EF3\u2EF4\u1908\u2EF9\u2EFD\u2F04\u2F06\u2F0A\u2F0E\u402Bcir;\u6A23ir;\u6A22\u0100ou\u1D40\u2F02;\u6A25;\u6A72n\u80BB\xB1\u0E9Dim;\u6A26wo;\u6A27\u0180ipu\u2F19\u2F20\u2F25ntint;\u6A15f;\uC000\u{1D561}nd\u803B\xA3\u40A3\u0500;Eaceinosu\u0EC8\u2F3F\u2F41\u2F44\u2F47\u2F81\u2F89\u2F92\u2F7E\u2FB6;\u6AB3p;\u6AB7u\xE5\u0ED9\u0100;c\u0ECE\u2F4C\u0300;acens\u0EC8\u2F59\u2F5F\u2F66\u2F68\u2F7Eppro\xF8\u2F43urlye\xF1\u0ED9\xF1\u0ECE\u0180aes\u2F6F\u2F76\u2F7Approx;\u6AB9qq;\u6AB5im;\u62E8i\xED\u0EDFme\u0100;s\u2F88\u0EAE\u6032\u0180Eas\u2F78\u2F90\u2F7A\xF0\u2F75\u0180dfp\u0EEC\u2F99\u2FAF\u0180als\u2FA0\u2FA5\u2FAAlar;\u632Eine;\u6312urf;\u6313\u0100;t\u0EFB\u2FB4\xEF\u0EFBrel;\u62B0\u0100ci\u2FC0\u2FC5r;\uC000\u{1D4C5};\u43C8ncsp;\u6008\u0300fiopsu\u2FDA\u22E2\u2FDF\u2FE5\u2FEB\u2FF1r;\uC000\u{1D52E}pf;\uC000\u{1D562}rime;\u6057cr;\uC000\u{1D4C6}\u0180aeo\u2FF8\u3009\u3013t\u0100ei\u2FFE\u3005rnion\xF3\u06B0nt;\u6A16st\u0100;e\u3010\u3011\u403F\xF1\u1F19\xF4\u0F14\u0A80ABHabcdefhilmnoprstux\u3040\u3051\u3055\u3059\u30E0\u310E\u312B\u3147\u3162\u3172\u318E\u3206\u3215\u3224\u3229\u3258\u326E\u3272\u3290\u32B0\u32B7\u0180art\u3047\u304A\u304Cr\xF2\u10B3\xF2\u03DDail;\u691Car\xF2\u1C65ar;\u6964\u0380cdenqrt\u3068\u3075\u3078\u307F\u308F\u3094\u30CC\u0100eu\u306D\u3071;\uC000\u223D\u0331te;\u4155i\xE3\u116Emptyv;\u69B3g\u0200;del\u0FD1\u3089\u308B\u308D;\u6992;\u69A5\xE5\u0FD1uo\u803B\xBB\u40BBr\u0580;abcfhlpstw\u0FDC\u30AC\u30AF\u30B7\u30B9\u30BC\u30BE\u30C0\u30C3\u30C7\u30CAp;\u6975\u0100;f\u0FE0\u30B4s;\u6920;\u6933s;\u691E\xEB\u225D\xF0\u272El;\u6945im;\u6974l;\u61A3;\u619D\u0100ai\u30D1\u30D5il;\u691Ao\u0100;n\u30DB\u30DC\u6236al\xF3\u0F1E\u0180abr\u30E7\u30EA\u30EEr\xF2\u17E5rk;\u6773\u0100ak\u30F3\u30FDc\u0100ek\u30F9\u30FB;\u407D;\u405D\u0100es\u3102\u3104;\u698Cl\u0100du\u310A\u310C;\u698E;\u6990\u0200aeuy\u3117\u311C\u3127\u3129ron;\u4159\u0100di\u3121\u3125il;\u4157\xEC\u0FF2\xE2\u30FA;\u4440\u0200clqs\u3134\u3137\u313D\u3144a;\u6937dhar;\u6969uo\u0100;r\u020E\u020Dh;\u61B3\u0180acg\u314E\u315F\u0F44l\u0200;ips\u0F78\u3158\u315B\u109Cn\xE5\u10BBar\xF4\u0FA9t;\u65AD\u0180ilr\u3169\u1023\u316Esht;\u697D;\uC000\u{1D52F}\u0100ao\u3177\u3186r\u0100du\u317D\u317F\xBB\u047B\u0100;l\u1091\u3184;\u696C\u0100;v\u318B\u318C\u43C1;\u43F1\u0180gns\u3195\u31F9\u31FCht\u0300ahlrst\u31A4\u31B0\u31C2\u31D8\u31E4\u31EErrow\u0100;t\u0FDC\u31ADa\xE9\u30C8arpoon\u0100du\u31BB\u31BFow\xEE\u317Ep\xBB\u1092eft\u0100ah\u31CA\u31D0rrow\xF3\u0FEAarpoon\xF3\u0551ightarrows;\u61C9quigarro\xF7\u30CBhreetimes;\u62CCg;\u42DAingdotse\xF1\u1F32\u0180ahm\u320D\u3210\u3213r\xF2\u0FEAa\xF2\u0551;\u600Foust\u0100;a\u321E\u321F\u63B1che\xBB\u321Fmid;\u6AEE\u0200abpt\u3232\u323D\u3240\u3252\u0100nr\u3237\u323Ag;\u67EDr;\u61FEr\xEB\u1003\u0180afl\u3247\u324A\u324Er;\u6986;\uC000\u{1D563}us;\u6A2Eimes;\u6A35\u0100ap\u325D\u3267r\u0100;g\u3263\u3264\u4029t;\u6994olint;\u6A12ar\xF2\u31E3\u0200achq\u327B\u3280\u10BC\u3285quo;\u603Ar;\uC000\u{1D4C7}\u0100bu\u30FB\u328Ao\u0100;r\u0214\u0213\u0180hir\u3297\u329B\u32A0re\xE5\u31F8mes;\u62CAi\u0200;efl\u32AA\u1059\u1821\u32AB\u65B9tri;\u69CEluhar;\u6968;\u611E\u0D61\u32D5\u32DB\u32DF\u332C\u3338\u3371\0\u337A\u33A4\0\0\u33EC\u33F0\0\u3428\u3448\u345A\u34AD\u34B1\u34CA\u34F1\0\u3616\0\0\u3633cute;\u415Bqu\xEF\u27BA\u0500;Eaceinpsy\u11ED\u32F3\u32F5\u32FF\u3302\u330B\u330F\u331F\u3326\u3329;\u6AB4\u01F0\u32FA\0\u32FC;\u6AB8on;\u4161u\xE5\u11FE\u0100;d\u11F3\u3307il;\u415Frc;\u415D\u0180Eas\u3316\u3318\u331B;\u6AB6p;\u6ABAim;\u62E9olint;\u6A13i\xED\u1204;\u4441ot\u0180;be\u3334\u1D47\u3335\u62C5;\u6A66\u0380Aacmstx\u3346\u334A\u3357\u335B\u335E\u3363\u336Drr;\u61D8r\u0100hr\u3350\u3352\xEB\u2228\u0100;o\u0A36\u0A34t\u803B\xA7\u40A7i;\u403Bwar;\u6929m\u0100in\u3369\xF0nu\xF3\xF1t;\u6736r\u0100;o\u3376\u2055\uC000\u{1D530}\u0200acoy\u3382\u3386\u3391\u33A0rp;\u666F\u0100hy\u338B\u338Fcy;\u4449;\u4448rt\u026D\u3399\0\0\u339Ci\xE4\u1464ara\xEC\u2E6F\u803B\xAD\u40AD\u0100gm\u33A8\u33B4ma\u0180;fv\u33B1\u33B2\u33B2\u43C3;\u43C2\u0400;deglnpr\u12AB\u33C5\u33C9\u33CE\u33D6\u33DE\u33E1\u33E6ot;\u6A6A\u0100;q\u12B1\u12B0\u0100;E\u33D3\u33D4\u6A9E;\u6AA0\u0100;E\u33DB\u33DC\u6A9D;\u6A9Fe;\u6246lus;\u6A24arr;\u6972ar\xF2\u113D\u0200aeit\u33F8\u3408\u340F\u3417\u0100ls\u33FD\u3404lsetm\xE9\u336Ahp;\u6A33parsl;\u69E4\u0100dl\u1463\u3414e;\u6323\u0100;e\u341C\u341D\u6AAA\u0100;s\u3422\u3423\u6AAC;\uC000\u2AAC\uFE00\u0180flp\u342E\u3433\u3442tcy;\u444C\u0100;b\u3438\u3439\u402F\u0100;a\u343E\u343F\u69C4r;\u633Ff;\uC000\u{1D564}a\u0100dr\u344D\u0402es\u0100;u\u3454\u3455\u6660it\xBB\u3455\u0180csu\u3460\u3479\u349F\u0100au\u3465\u346Fp\u0100;s\u1188\u346B;\uC000\u2293\uFE00p\u0100;s\u11B4\u3475;\uC000\u2294\uFE00u\u0100bp\u347F\u348F\u0180;es\u1197\u119C\u3486et\u0100;e\u1197\u348D\xF1\u119D\u0180;es\u11A8\u11AD\u3496et\u0100;e\u11A8\u349D\xF1\u11AE\u0180;af\u117B\u34A6\u05B0r\u0165\u34AB\u05B1\xBB\u117Car\xF2\u1148\u0200cemt\u34B9\u34BE\u34C2\u34C5r;\uC000\u{1D4C8}tm\xEE\xF1i\xEC\u3415ar\xE6\u11BE\u0100ar\u34CE\u34D5r\u0100;f\u34D4\u17BF\u6606\u0100an\u34DA\u34EDight\u0100ep\u34E3\u34EApsilo\xEE\u1EE0h\xE9\u2EAFs\xBB\u2852\u0280bcmnp\u34FB\u355E\u1209\u358B\u358E\u0480;Edemnprs\u350E\u350F\u3511\u3515\u351E\u3523\u352C\u3531\u3536\u6282;\u6AC5ot;\u6ABD\u0100;d\u11DA\u351Aot;\u6AC3ult;\u6AC1\u0100Ee\u3528\u352A;\u6ACB;\u628Alus;\u6ABFarr;\u6979\u0180eiu\u353D\u3552\u3555t\u0180;en\u350E\u3545\u354Bq\u0100;q\u11DA\u350Feq\u0100;q\u352B\u3528m;\u6AC7\u0100bp\u355A\u355C;\u6AD5;\u6AD3c\u0300;acens\u11ED\u356C\u3572\u3579\u357B\u3326ppro\xF8\u32FAurlye\xF1\u11FE\xF1\u11F3\u0180aes\u3582\u3588\u331Bppro\xF8\u331Aq\xF1\u3317g;\u666A\u0680123;Edehlmnps\u35A9\u35AC\u35AF\u121C\u35B2\u35B4\u35C0\u35C9\u35D5\u35DA\u35DF\u35E8\u35ED\u803B\xB9\u40B9\u803B\xB2\u40B2\u803B\xB3\u40B3;\u6AC6\u0100os\u35B9\u35BCt;\u6ABEub;\u6AD8\u0100;d\u1222\u35C5ot;\u6AC4s\u0100ou\u35CF\u35D2l;\u67C9b;\u6AD7arr;\u697Bult;\u6AC2\u0100Ee\u35E4\u35E6;\u6ACC;\u628Blus;\u6AC0\u0180eiu\u35F4\u3609\u360Ct\u0180;en\u121C\u35FC\u3602q\u0100;q\u1222\u35B2eq\u0100;q\u35E7\u35E4m;\u6AC8\u0100bp\u3611\u3613;\u6AD4;\u6AD6\u0180Aan\u361C\u3620\u362Drr;\u61D9r\u0100hr\u3626\u3628\xEB\u222E\u0100;o\u0A2B\u0A29war;\u692Alig\u803B\xDF\u40DF\u0BE1\u3651\u365D\u3660\u12CE\u3673\u3679\0\u367E\u36C2\0\0\0\0\0\u36DB\u3703\0\u3709\u376C\0\0\0\u3787\u0272\u3656\0\0\u365Bget;\u6316;\u43C4r\xEB\u0E5F\u0180aey\u3666\u366B\u3670ron;\u4165dil;\u4163;\u4442lrec;\u6315r;\uC000\u{1D531}\u0200eiko\u3686\u369D\u36B5\u36BC\u01F2\u368B\0\u3691e\u01004f\u1284\u1281a\u0180;sv\u3698\u3699\u369B\u43B8ym;\u43D1\u0100cn\u36A2\u36B2k\u0100as\u36A8\u36AEppro\xF8\u12C1im\xBB\u12ACs\xF0\u129E\u0100as\u36BA\u36AE\xF0\u12C1rn\u803B\xFE\u40FE\u01EC\u031F\u36C6\u22E7es\u8180\xD7;bd\u36CF\u36D0\u36D8\u40D7\u0100;a\u190F\u36D5r;\u6A31;\u6A30\u0180eps\u36E1\u36E3\u3700\xE1\u2A4D\u0200;bcf\u0486\u36EC\u36F0\u36F4ot;\u6336ir;\u6AF1\u0100;o\u36F9\u36FC\uC000\u{1D565}rk;\u6ADA\xE1\u3362rime;\u6034\u0180aip\u370F\u3712\u3764d\xE5\u1248\u0380adempst\u3721\u374D\u3740\u3751\u3757\u375C\u375Fngle\u0280;dlqr\u3730\u3731\u3736\u3740\u3742\u65B5own\xBB\u1DBBeft\u0100;e\u2800\u373E\xF1\u092E;\u625Cight\u0100;e\u32AA\u374B\xF1\u105Aot;\u65ECinus;\u6A3Alus;\u6A39b;\u69CDime;\u6A3Bezium;\u63E2\u0180cht\u3772\u377D\u3781\u0100ry\u3777\u377B;\uC000\u{1D4C9};\u4446cy;\u445Brok;\u4167\u0100io\u378B\u378Ex\xF4\u1777head\u0100lr\u3797\u37A0eftarro\xF7\u084Fightarrow\xBB\u0F5D\u0900AHabcdfghlmoprstuw\u37D0\u37D3\u37D7\u37E4\u37F0\u37FC\u380E\u381C\u3823\u3834\u3851\u385D\u386B\u38A9\u38CC\u38D2\u38EA\u38F6r\xF2\u03EDar;\u6963\u0100cr\u37DC\u37E2ute\u803B\xFA\u40FA\xF2\u1150r\u01E3\u37EA\0\u37EDy;\u445Eve;\u416D\u0100iy\u37F5\u37FArc\u803B\xFB\u40FB;\u4443\u0180abh\u3803\u3806\u380Br\xF2\u13ADlac;\u4171a\xF2\u13C3\u0100ir\u3813\u3818sht;\u697E;\uC000\u{1D532}rave\u803B\xF9\u40F9\u0161\u3827\u3831r\u0100lr\u382C\u382E\xBB\u0957\xBB\u1083lk;\u6580\u0100ct\u3839\u384D\u026F\u383F\0\0\u384Arn\u0100;e\u3845\u3846\u631Cr\xBB\u3846op;\u630Fri;\u65F8\u0100al\u3856\u385Acr;\u416B\u80BB\xA8\u0349\u0100gp\u3862\u3866on;\u4173f;\uC000\u{1D566}\u0300adhlsu\u114B\u3878\u387D\u1372\u3891\u38A0own\xE1\u13B3arpoon\u0100lr\u3888\u388Cef\xF4\u382Digh\xF4\u382Fi\u0180;hl\u3899\u389A\u389C\u43C5\xBB\u13FAon\xBB\u389Aparrows;\u61C8\u0180cit\u38B0\u38C4\u38C8\u026F\u38B6\0\0\u38C1rn\u0100;e\u38BC\u38BD\u631Dr\xBB\u38BDop;\u630Eng;\u416Fri;\u65F9cr;\uC000\u{1D4CA}\u0180dir\u38D9\u38DD\u38E2ot;\u62F0lde;\u4169i\u0100;f\u3730\u38E8\xBB\u1813\u0100am\u38EF\u38F2r\xF2\u38A8l\u803B\xFC\u40FCangle;\u69A7\u0780ABDacdeflnoprsz\u391C\u391F\u3929\u392D\u39B5\u39B8\u39BD\u39DF\u39E4\u39E8\u39F3\u39F9\u39FD\u3A01\u3A20r\xF2\u03F7ar\u0100;v\u3926\u3927\u6AE8;\u6AE9as\xE8\u03E1\u0100nr\u3932\u3937grt;\u699C\u0380eknprst\u34E3\u3946\u394B\u3952\u395D\u3964\u3996app\xE1\u2415othin\xE7\u1E96\u0180hir\u34EB\u2EC8\u3959op\xF4\u2FB5\u0100;h\u13B7\u3962\xEF\u318D\u0100iu\u3969\u396Dgm\xE1\u33B3\u0100bp\u3972\u3984setneq\u0100;q\u397D\u3980\uC000\u228A\uFE00;\uC000\u2ACB\uFE00setneq\u0100;q\u398F\u3992\uC000\u228B\uFE00;\uC000\u2ACC\uFE00\u0100hr\u399B\u399Fet\xE1\u369Ciangle\u0100lr\u39AA\u39AFeft\xBB\u0925ight\xBB\u1051y;\u4432ash\xBB\u1036\u0180elr\u39C4\u39D2\u39D7\u0180;be\u2DEA\u39CB\u39CFar;\u62BBq;\u625Alip;\u62EE\u0100bt\u39DC\u1468a\xF2\u1469r;\uC000\u{1D533}tr\xE9\u39AEsu\u0100bp\u39EF\u39F1\xBB\u0D1C\xBB\u0D59pf;\uC000\u{1D567}ro\xF0\u0EFBtr\xE9\u39B4\u0100cu\u3A06\u3A0Br;\uC000\u{1D4CB}\u0100bp\u3A10\u3A18n\u0100Ee\u3980\u3A16\xBB\u397En\u0100Ee\u3992\u3A1E\xBB\u3990igzag;\u699A\u0380cefoprs\u3A36\u3A3B\u3A56\u3A5B\u3A54\u3A61\u3A6Airc;\u4175\u0100di\u3A40\u3A51\u0100bg\u3A45\u3A49ar;\u6A5Fe\u0100;q\u15FA\u3A4F;\u6259erp;\u6118r;\uC000\u{1D534}pf;\uC000\u{1D568}\u0100;e\u1479\u3A66at\xE8\u1479cr;\uC000\u{1D4CC}\u0AE3\u178E\u3A87\0\u3A8B\0\u3A90\u3A9B\0\0\u3A9D\u3AA8\u3AAB\u3AAF\0\0\u3AC3\u3ACE\0\u3AD8\u17DC\u17DFtr\xE9\u17D1r;\uC000\u{1D535}\u0100Aa\u3A94\u3A97r\xF2\u03C3r\xF2\u09F6;\u43BE\u0100Aa\u3AA1\u3AA4r\xF2\u03B8r\xF2\u09EBa\xF0\u2713is;\u62FB\u0180dpt\u17A4\u3AB5\u3ABE\u0100fl\u3ABA\u17A9;\uC000\u{1D569}im\xE5\u17B2\u0100Aa\u3AC7\u3ACAr\xF2\u03CEr\xF2\u0A01\u0100cq\u3AD2\u17B8r;\uC000\u{1D4CD}\u0100pt\u17D6\u3ADCr\xE9\u17D4\u0400acefiosu\u3AF0\u3AFD\u3B08\u3B0C\u3B11\u3B15\u3B1B\u3B21c\u0100uy\u3AF6\u3AFBte\u803B\xFD\u40FD;\u444F\u0100iy\u3B02\u3B06rc;\u4177;\u444Bn\u803B\xA5\u40A5r;\uC000\u{1D536}cy;\u4457pf;\uC000\u{1D56A}cr;\uC000\u{1D4CE}\u0100cm\u3B26\u3B29y;\u444El\u803B\xFF\u40FF\u0500acdefhiosw\u3B42\u3B48\u3B54\u3B58\u3B64\u3B69\u3B6D\u3B74\u3B7A\u3B80cute;\u417A\u0100ay\u3B4D\u3B52ron;\u417E;\u4437ot;\u417C\u0100et\u3B5D\u3B61tr\xE6\u155Fa;\u43B6r;\uC000\u{1D537}cy;\u4436grarr;\u61DDpf;\uC000\u{1D56B}cr;\uC000\u{1D4CF}\u0100jn\u3B85\u3B87;\u600Dj;\u600C'.split("").map((c) => c.charCodeAt(0))
  35085. );
  35086. // node_modules/entities/lib/esm/generated/decode-data-xml.js
  35087. var decode_data_xml_default = new Uint16Array(
  35088. // prettier-ignore
  35089. "\u0200aglq \x1B\u026D\0\0p;\u4026os;\u4027t;\u403Et;\u403Cuot;\u4022".split("").map((c) => c.charCodeAt(0))
  35090. );
  35091. // node_modules/entities/lib/esm/decode_codepoint.js
  35092. var _a;
  35093. var decodeMap = /* @__PURE__ */ new Map([
  35094. [0, 65533],
  35095. // C1 Unicode control character reference replacements
  35096. [128, 8364],
  35097. [130, 8218],
  35098. [131, 402],
  35099. [132, 8222],
  35100. [133, 8230],
  35101. [134, 8224],
  35102. [135, 8225],
  35103. [136, 710],
  35104. [137, 8240],
  35105. [138, 352],
  35106. [139, 8249],
  35107. [140, 338],
  35108. [142, 381],
  35109. [145, 8216],
  35110. [146, 8217],
  35111. [147, 8220],
  35112. [148, 8221],
  35113. [149, 8226],
  35114. [150, 8211],
  35115. [151, 8212],
  35116. [152, 732],
  35117. [153, 8482],
  35118. [154, 353],
  35119. [155, 8250],
  35120. [156, 339],
  35121. [158, 382],
  35122. [159, 376]
  35123. ]);
  35124. var fromCodePoint = (
  35125. // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition, node/no-unsupported-features/es-builtins
  35126. (_a = String.fromCodePoint) !== null && _a !== void 0 ? _a : function(codePoint) {
  35127. let output = "";
  35128. if (codePoint > 65535) {
  35129. codePoint -= 65536;
  35130. output += String.fromCharCode(codePoint >>> 10 & 1023 | 55296);
  35131. codePoint = 56320 | codePoint & 1023;
  35132. }
  35133. output += String.fromCharCode(codePoint);
  35134. return output;
  35135. }
  35136. );
  35137. function replaceCodePoint(codePoint) {
  35138. var _a2;
  35139. if (codePoint >= 55296 && codePoint <= 57343 || codePoint > 1114111) {
  35140. return 65533;
  35141. }
  35142. return (_a2 = decodeMap.get(codePoint)) !== null && _a2 !== void 0 ? _a2 : codePoint;
  35143. }
  35144. // node_modules/entities/lib/esm/decode.js
  35145. var CharCodes;
  35146. (function(CharCodes2) {
  35147. CharCodes2[CharCodes2["NUM"] = 35] = "NUM";
  35148. CharCodes2[CharCodes2["SEMI"] = 59] = "SEMI";
  35149. CharCodes2[CharCodes2["EQUALS"] = 61] = "EQUALS";
  35150. CharCodes2[CharCodes2["ZERO"] = 48] = "ZERO";
  35151. CharCodes2[CharCodes2["NINE"] = 57] = "NINE";
  35152. CharCodes2[CharCodes2["LOWER_A"] = 97] = "LOWER_A";
  35153. CharCodes2[CharCodes2["LOWER_F"] = 102] = "LOWER_F";
  35154. CharCodes2[CharCodes2["LOWER_X"] = 120] = "LOWER_X";
  35155. CharCodes2[CharCodes2["LOWER_Z"] = 122] = "LOWER_Z";
  35156. CharCodes2[CharCodes2["UPPER_A"] = 65] = "UPPER_A";
  35157. CharCodes2[CharCodes2["UPPER_F"] = 70] = "UPPER_F";
  35158. CharCodes2[CharCodes2["UPPER_Z"] = 90] = "UPPER_Z";
  35159. })(CharCodes || (CharCodes = {}));
  35160. var TO_LOWER_BIT = 32;
  35161. var BinTrieFlags;
  35162. (function(BinTrieFlags2) {
  35163. BinTrieFlags2[BinTrieFlags2["VALUE_LENGTH"] = 49152] = "VALUE_LENGTH";
  35164. BinTrieFlags2[BinTrieFlags2["BRANCH_LENGTH"] = 16256] = "BRANCH_LENGTH";
  35165. BinTrieFlags2[BinTrieFlags2["JUMP_TABLE"] = 127] = "JUMP_TABLE";
  35166. })(BinTrieFlags || (BinTrieFlags = {}));
  35167. function isNumber(code) {
  35168. return code >= CharCodes.ZERO && code <= CharCodes.NINE;
  35169. }
  35170. function isHexadecimalCharacter(code) {
  35171. return code >= CharCodes.UPPER_A && code <= CharCodes.UPPER_F || code >= CharCodes.LOWER_A && code <= CharCodes.LOWER_F;
  35172. }
  35173. function isAsciiAlphaNumeric(code) {
  35174. return code >= CharCodes.UPPER_A && code <= CharCodes.UPPER_Z || code >= CharCodes.LOWER_A && code <= CharCodes.LOWER_Z || isNumber(code);
  35175. }
  35176. function isEntityInAttributeInvalidEnd(code) {
  35177. return code === CharCodes.EQUALS || isAsciiAlphaNumeric(code);
  35178. }
  35179. var EntityDecoderState;
  35180. (function(EntityDecoderState2) {
  35181. EntityDecoderState2[EntityDecoderState2["EntityStart"] = 0] = "EntityStart";
  35182. EntityDecoderState2[EntityDecoderState2["NumericStart"] = 1] = "NumericStart";
  35183. EntityDecoderState2[EntityDecoderState2["NumericDecimal"] = 2] = "NumericDecimal";
  35184. EntityDecoderState2[EntityDecoderState2["NumericHex"] = 3] = "NumericHex";
  35185. EntityDecoderState2[EntityDecoderState2["NamedEntity"] = 4] = "NamedEntity";
  35186. })(EntityDecoderState || (EntityDecoderState = {}));
  35187. var DecodingMode;
  35188. (function(DecodingMode2) {
  35189. DecodingMode2[DecodingMode2["Legacy"] = 0] = "Legacy";
  35190. DecodingMode2[DecodingMode2["Strict"] = 1] = "Strict";
  35191. DecodingMode2[DecodingMode2["Attribute"] = 2] = "Attribute";
  35192. })(DecodingMode || (DecodingMode = {}));
  35193. var EntityDecoder = class {
  35194. constructor(decodeTree, emitCodePoint, errors) {
  35195. this.decodeTree = decodeTree;
  35196. this.emitCodePoint = emitCodePoint;
  35197. this.errors = errors;
  35198. this.state = EntityDecoderState.EntityStart;
  35199. this.consumed = 1;
  35200. this.result = 0;
  35201. this.treeIndex = 0;
  35202. this.excess = 1;
  35203. this.decodeMode = DecodingMode.Strict;
  35204. }
  35205. /** Resets the instance to make it reusable. */
  35206. startEntity(decodeMode) {
  35207. this.decodeMode = decodeMode;
  35208. this.state = EntityDecoderState.EntityStart;
  35209. this.result = 0;
  35210. this.treeIndex = 0;
  35211. this.excess = 1;
  35212. this.consumed = 1;
  35213. }
  35214. /**
  35215. * Write an entity to the decoder. This can be called multiple times with partial entities.
  35216. * If the entity is incomplete, the decoder will return -1.
  35217. *
  35218. * Mirrors the implementation of `getDecoder`, but with the ability to stop decoding if the
  35219. * entity is incomplete, and resume when the next string is written.
  35220. *
  35221. * @param string The string containing the entity (or a continuation of the entity).
  35222. * @param offset The offset at which the entity begins. Should be 0 if this is not the first call.
  35223. * @returns The number of characters that were consumed, or -1 if the entity is incomplete.
  35224. */
  35225. write(str, offset) {
  35226. switch (this.state) {
  35227. case EntityDecoderState.EntityStart: {
  35228. if (str.charCodeAt(offset) === CharCodes.NUM) {
  35229. this.state = EntityDecoderState.NumericStart;
  35230. this.consumed += 1;
  35231. return this.stateNumericStart(str, offset + 1);
  35232. }
  35233. this.state = EntityDecoderState.NamedEntity;
  35234. return this.stateNamedEntity(str, offset);
  35235. }
  35236. case EntityDecoderState.NumericStart: {
  35237. return this.stateNumericStart(str, offset);
  35238. }
  35239. case EntityDecoderState.NumericDecimal: {
  35240. return this.stateNumericDecimal(str, offset);
  35241. }
  35242. case EntityDecoderState.NumericHex: {
  35243. return this.stateNumericHex(str, offset);
  35244. }
  35245. case EntityDecoderState.NamedEntity: {
  35246. return this.stateNamedEntity(str, offset);
  35247. }
  35248. }
  35249. }
  35250. /**
  35251. * Switches between the numeric decimal and hexadecimal states.
  35252. *
  35253. * Equivalent to the `Numeric character reference state` in the HTML spec.
  35254. *
  35255. * @param str The string containing the entity (or a continuation of the entity).
  35256. * @param offset The current offset.
  35257. * @returns The number of characters that were consumed, or -1 if the entity is incomplete.
  35258. */
  35259. stateNumericStart(str, offset) {
  35260. if (offset >= str.length) {
  35261. return -1;
  35262. }
  35263. if ((str.charCodeAt(offset) | TO_LOWER_BIT) === CharCodes.LOWER_X) {
  35264. this.state = EntityDecoderState.NumericHex;
  35265. this.consumed += 1;
  35266. return this.stateNumericHex(str, offset + 1);
  35267. }
  35268. this.state = EntityDecoderState.NumericDecimal;
  35269. return this.stateNumericDecimal(str, offset);
  35270. }
  35271. addToNumericResult(str, start, end, base) {
  35272. if (start !== end) {
  35273. const digitCount = end - start;
  35274. this.result = this.result * Math.pow(base, digitCount) + parseInt(str.substr(start, digitCount), base);
  35275. this.consumed += digitCount;
  35276. }
  35277. }
  35278. /**
  35279. * Parses a hexadecimal numeric entity.
  35280. *
  35281. * Equivalent to the `Hexademical character reference state` in the HTML spec.
  35282. *
  35283. * @param str The string containing the entity (or a continuation of the entity).
  35284. * @param offset The current offset.
  35285. * @returns The number of characters that were consumed, or -1 if the entity is incomplete.
  35286. */
  35287. stateNumericHex(str, offset) {
  35288. const startIdx = offset;
  35289. while (offset < str.length) {
  35290. const char = str.charCodeAt(offset);
  35291. if (isNumber(char) || isHexadecimalCharacter(char)) {
  35292. offset += 1;
  35293. } else {
  35294. this.addToNumericResult(str, startIdx, offset, 16);
  35295. return this.emitNumericEntity(char, 3);
  35296. }
  35297. }
  35298. this.addToNumericResult(str, startIdx, offset, 16);
  35299. return -1;
  35300. }
  35301. /**
  35302. * Parses a decimal numeric entity.
  35303. *
  35304. * Equivalent to the `Decimal character reference state` in the HTML spec.
  35305. *
  35306. * @param str The string containing the entity (or a continuation of the entity).
  35307. * @param offset The current offset.
  35308. * @returns The number of characters that were consumed, or -1 if the entity is incomplete.
  35309. */
  35310. stateNumericDecimal(str, offset) {
  35311. const startIdx = offset;
  35312. while (offset < str.length) {
  35313. const char = str.charCodeAt(offset);
  35314. if (isNumber(char)) {
  35315. offset += 1;
  35316. } else {
  35317. this.addToNumericResult(str, startIdx, offset, 10);
  35318. return this.emitNumericEntity(char, 2);
  35319. }
  35320. }
  35321. this.addToNumericResult(str, startIdx, offset, 10);
  35322. return -1;
  35323. }
  35324. /**
  35325. * Validate and emit a numeric entity.
  35326. *
  35327. * Implements the logic from the `Hexademical character reference start
  35328. * state` and `Numeric character reference end state` in the HTML spec.
  35329. *
  35330. * @param lastCp The last code point of the entity. Used to see if the
  35331. * entity was terminated with a semicolon.
  35332. * @param expectedLength The minimum number of characters that should be
  35333. * consumed. Used to validate that at least one digit
  35334. * was consumed.
  35335. * @returns The number of characters that were consumed.
  35336. */
  35337. emitNumericEntity(lastCp, expectedLength) {
  35338. var _a2;
  35339. if (this.consumed <= expectedLength) {
  35340. (_a2 = this.errors) === null || _a2 === void 0 ? void 0 : _a2.absenceOfDigitsInNumericCharacterReference(this.consumed);
  35341. return 0;
  35342. }
  35343. if (lastCp === CharCodes.SEMI) {
  35344. this.consumed += 1;
  35345. } else if (this.decodeMode === DecodingMode.Strict) {
  35346. return 0;
  35347. }
  35348. this.emitCodePoint(replaceCodePoint(this.result), this.consumed);
  35349. if (this.errors) {
  35350. if (lastCp !== CharCodes.SEMI) {
  35351. this.errors.missingSemicolonAfterCharacterReference();
  35352. }
  35353. this.errors.validateNumericCharacterReference(this.result);
  35354. }
  35355. return this.consumed;
  35356. }
  35357. /**
  35358. * Parses a named entity.
  35359. *
  35360. * Equivalent to the `Named character reference state` in the HTML spec.
  35361. *
  35362. * @param str The string containing the entity (or a continuation of the entity).
  35363. * @param offset The current offset.
  35364. * @returns The number of characters that were consumed, or -1 if the entity is incomplete.
  35365. */
  35366. stateNamedEntity(str, offset) {
  35367. const { decodeTree } = this;
  35368. let current = decodeTree[this.treeIndex];
  35369. let valueLength = (current & BinTrieFlags.VALUE_LENGTH) >> 14;
  35370. for (; offset < str.length; offset++, this.excess++) {
  35371. const char = str.charCodeAt(offset);
  35372. this.treeIndex = determineBranch(decodeTree, current, this.treeIndex + Math.max(1, valueLength), char);
  35373. if (this.treeIndex < 0) {
  35374. return this.result === 0 || // If we are parsing an attribute
  35375. this.decodeMode === DecodingMode.Attribute && // We shouldn't have consumed any characters after the entity,
  35376. (valueLength === 0 || // And there should be no invalid characters.
  35377. isEntityInAttributeInvalidEnd(char)) ? 0 : this.emitNotTerminatedNamedEntity();
  35378. }
  35379. current = decodeTree[this.treeIndex];
  35380. valueLength = (current & BinTrieFlags.VALUE_LENGTH) >> 14;
  35381. if (valueLength !== 0) {
  35382. if (char === CharCodes.SEMI) {
  35383. return this.emitNamedEntityData(this.treeIndex, valueLength, this.consumed + this.excess);
  35384. }
  35385. if (this.decodeMode !== DecodingMode.Strict) {
  35386. this.result = this.treeIndex;
  35387. this.consumed += this.excess;
  35388. this.excess = 0;
  35389. }
  35390. }
  35391. }
  35392. return -1;
  35393. }
  35394. /**
  35395. * Emit a named entity that was not terminated with a semicolon.
  35396. *
  35397. * @returns The number of characters consumed.
  35398. */
  35399. emitNotTerminatedNamedEntity() {
  35400. var _a2;
  35401. const { result, decodeTree } = this;
  35402. const valueLength = (decodeTree[result] & BinTrieFlags.VALUE_LENGTH) >> 14;
  35403. this.emitNamedEntityData(result, valueLength, this.consumed);
  35404. (_a2 = this.errors) === null || _a2 === void 0 ? void 0 : _a2.missingSemicolonAfterCharacterReference();
  35405. return this.consumed;
  35406. }
  35407. /**
  35408. * Emit a named entity.
  35409. *
  35410. * @param result The index of the entity in the decode tree.
  35411. * @param valueLength The number of bytes in the entity.
  35412. * @param consumed The number of characters consumed.
  35413. *
  35414. * @returns The number of characters consumed.
  35415. */
  35416. emitNamedEntityData(result, valueLength, consumed) {
  35417. const { decodeTree } = this;
  35418. this.emitCodePoint(valueLength === 1 ? decodeTree[result] & ~BinTrieFlags.VALUE_LENGTH : decodeTree[result + 1], consumed);
  35419. if (valueLength === 3) {
  35420. this.emitCodePoint(decodeTree[result + 2], consumed);
  35421. }
  35422. return consumed;
  35423. }
  35424. /**
  35425. * Signal to the parser that the end of the input was reached.
  35426. *
  35427. * Remaining data will be emitted and relevant errors will be produced.
  35428. *
  35429. * @returns The number of characters consumed.
  35430. */
  35431. end() {
  35432. var _a2;
  35433. switch (this.state) {
  35434. case EntityDecoderState.NamedEntity: {
  35435. return this.result !== 0 && (this.decodeMode !== DecodingMode.Attribute || this.result === this.treeIndex) ? this.emitNotTerminatedNamedEntity() : 0;
  35436. }
  35437. case EntityDecoderState.NumericDecimal: {
  35438. return this.emitNumericEntity(0, 2);
  35439. }
  35440. case EntityDecoderState.NumericHex: {
  35441. return this.emitNumericEntity(0, 3);
  35442. }
  35443. case EntityDecoderState.NumericStart: {
  35444. (_a2 = this.errors) === null || _a2 === void 0 ? void 0 : _a2.absenceOfDigitsInNumericCharacterReference(this.consumed);
  35445. return 0;
  35446. }
  35447. case EntityDecoderState.EntityStart: {
  35448. return 0;
  35449. }
  35450. }
  35451. }
  35452. };
  35453. function getDecoder(decodeTree) {
  35454. let ret = "";
  35455. const decoder = new EntityDecoder(decodeTree, (str) => ret += fromCodePoint(str));
  35456. return function decodeWithTrie(str, decodeMode) {
  35457. let lastIndex = 0;
  35458. let offset = 0;
  35459. while ((offset = str.indexOf("&", offset)) >= 0) {
  35460. ret += str.slice(lastIndex, offset);
  35461. decoder.startEntity(decodeMode);
  35462. const len = decoder.write(
  35463. str,
  35464. // Skip the "&"
  35465. offset + 1
  35466. );
  35467. if (len < 0) {
  35468. lastIndex = offset + decoder.end();
  35469. break;
  35470. }
  35471. lastIndex = offset + len;
  35472. offset = len === 0 ? lastIndex + 1 : lastIndex;
  35473. }
  35474. const result = ret + str.slice(lastIndex);
  35475. ret = "";
  35476. return result;
  35477. };
  35478. }
  35479. function determineBranch(decodeTree, current, nodeIdx, char) {
  35480. const branchCount = (current & BinTrieFlags.BRANCH_LENGTH) >> 7;
  35481. const jumpOffset = current & BinTrieFlags.JUMP_TABLE;
  35482. if (branchCount === 0) {
  35483. return jumpOffset !== 0 && char === jumpOffset ? nodeIdx : -1;
  35484. }
  35485. if (jumpOffset) {
  35486. const value = char - jumpOffset;
  35487. return value < 0 || value >= branchCount ? -1 : decodeTree[nodeIdx + value] - 1;
  35488. }
  35489. let lo = nodeIdx;
  35490. let hi = lo + branchCount - 1;
  35491. while (lo <= hi) {
  35492. const mid = lo + hi >>> 1;
  35493. const midVal = decodeTree[mid];
  35494. if (midVal < char) {
  35495. lo = mid + 1;
  35496. } else if (midVal > char) {
  35497. hi = mid - 1;
  35498. } else {
  35499. return decodeTree[mid + branchCount];
  35500. }
  35501. }
  35502. return -1;
  35503. }
  35504. var htmlDecoder = getDecoder(decode_data_html_default);
  35505. var xmlDecoder = getDecoder(decode_data_xml_default);
  35506. // node_modules/parse5/dist/common/html.js
  35507. var html_exports = {};
  35508. __export(html_exports, {
  35509. ATTRS: () => ATTRS,
  35510. DOCUMENT_MODE: () => DOCUMENT_MODE,
  35511. NS: () => NS,
  35512. SPECIAL_ELEMENTS: () => SPECIAL_ELEMENTS,
  35513. TAG_ID: () => TAG_ID,
  35514. TAG_NAMES: () => TAG_NAMES,
  35515. getTagID: () => getTagID,
  35516. hasUnescapedText: () => hasUnescapedText,
  35517. isNumberedHeader: () => isNumberedHeader
  35518. });
  35519. var NS;
  35520. (function(NS2) {
  35521. NS2["HTML"] = "http://www.w3.org/1999/xhtml";
  35522. NS2["MATHML"] = "http://www.w3.org/1998/Math/MathML";
  35523. NS2["SVG"] = "http://www.w3.org/2000/svg";
  35524. NS2["XLINK"] = "http://www.w3.org/1999/xlink";
  35525. NS2["XML"] = "http://www.w3.org/XML/1998/namespace";
  35526. NS2["XMLNS"] = "http://www.w3.org/2000/xmlns/";
  35527. })(NS = NS || (NS = {}));
  35528. var ATTRS;
  35529. (function(ATTRS2) {
  35530. ATTRS2["TYPE"] = "type";
  35531. ATTRS2["ACTION"] = "action";
  35532. ATTRS2["ENCODING"] = "encoding";
  35533. ATTRS2["PROMPT"] = "prompt";
  35534. ATTRS2["NAME"] = "name";
  35535. ATTRS2["COLOR"] = "color";
  35536. ATTRS2["FACE"] = "face";
  35537. ATTRS2["SIZE"] = "size";
  35538. })(ATTRS = ATTRS || (ATTRS = {}));
  35539. var DOCUMENT_MODE;
  35540. (function(DOCUMENT_MODE2) {
  35541. DOCUMENT_MODE2["NO_QUIRKS"] = "no-quirks";
  35542. DOCUMENT_MODE2["QUIRKS"] = "quirks";
  35543. DOCUMENT_MODE2["LIMITED_QUIRKS"] = "limited-quirks";
  35544. })(DOCUMENT_MODE = DOCUMENT_MODE || (DOCUMENT_MODE = {}));
  35545. var TAG_NAMES;
  35546. (function(TAG_NAMES2) {
  35547. TAG_NAMES2["A"] = "a";
  35548. TAG_NAMES2["ADDRESS"] = "address";
  35549. TAG_NAMES2["ANNOTATION_XML"] = "annotation-xml";
  35550. TAG_NAMES2["APPLET"] = "applet";
  35551. TAG_NAMES2["AREA"] = "area";
  35552. TAG_NAMES2["ARTICLE"] = "article";
  35553. TAG_NAMES2["ASIDE"] = "aside";
  35554. TAG_NAMES2["B"] = "b";
  35555. TAG_NAMES2["BASE"] = "base";
  35556. TAG_NAMES2["BASEFONT"] = "basefont";
  35557. TAG_NAMES2["BGSOUND"] = "bgsound";
  35558. TAG_NAMES2["BIG"] = "big";
  35559. TAG_NAMES2["BLOCKQUOTE"] = "blockquote";
  35560. TAG_NAMES2["BODY"] = "body";
  35561. TAG_NAMES2["BR"] = "br";
  35562. TAG_NAMES2["BUTTON"] = "button";
  35563. TAG_NAMES2["CAPTION"] = "caption";
  35564. TAG_NAMES2["CENTER"] = "center";
  35565. TAG_NAMES2["CODE"] = "code";
  35566. TAG_NAMES2["COL"] = "col";
  35567. TAG_NAMES2["COLGROUP"] = "colgroup";
  35568. TAG_NAMES2["DD"] = "dd";
  35569. TAG_NAMES2["DESC"] = "desc";
  35570. TAG_NAMES2["DETAILS"] = "details";
  35571. TAG_NAMES2["DIALOG"] = "dialog";
  35572. TAG_NAMES2["DIR"] = "dir";
  35573. TAG_NAMES2["DIV"] = "div";
  35574. TAG_NAMES2["DL"] = "dl";
  35575. TAG_NAMES2["DT"] = "dt";
  35576. TAG_NAMES2["EM"] = "em";
  35577. TAG_NAMES2["EMBED"] = "embed";
  35578. TAG_NAMES2["FIELDSET"] = "fieldset";
  35579. TAG_NAMES2["FIGCAPTION"] = "figcaption";
  35580. TAG_NAMES2["FIGURE"] = "figure";
  35581. TAG_NAMES2["FONT"] = "font";
  35582. TAG_NAMES2["FOOTER"] = "footer";
  35583. TAG_NAMES2["FOREIGN_OBJECT"] = "foreignObject";
  35584. TAG_NAMES2["FORM"] = "form";
  35585. TAG_NAMES2["FRAME"] = "frame";
  35586. TAG_NAMES2["FRAMESET"] = "frameset";
  35587. TAG_NAMES2["H1"] = "h1";
  35588. TAG_NAMES2["H2"] = "h2";
  35589. TAG_NAMES2["H3"] = "h3";
  35590. TAG_NAMES2["H4"] = "h4";
  35591. TAG_NAMES2["H5"] = "h5";
  35592. TAG_NAMES2["H6"] = "h6";
  35593. TAG_NAMES2["HEAD"] = "head";
  35594. TAG_NAMES2["HEADER"] = "header";
  35595. TAG_NAMES2["HGROUP"] = "hgroup";
  35596. TAG_NAMES2["HR"] = "hr";
  35597. TAG_NAMES2["HTML"] = "html";
  35598. TAG_NAMES2["I"] = "i";
  35599. TAG_NAMES2["IMG"] = "img";
  35600. TAG_NAMES2["IMAGE"] = "image";
  35601. TAG_NAMES2["INPUT"] = "input";
  35602. TAG_NAMES2["IFRAME"] = "iframe";
  35603. TAG_NAMES2["KEYGEN"] = "keygen";
  35604. TAG_NAMES2["LABEL"] = "label";
  35605. TAG_NAMES2["LI"] = "li";
  35606. TAG_NAMES2["LINK"] = "link";
  35607. TAG_NAMES2["LISTING"] = "listing";
  35608. TAG_NAMES2["MAIN"] = "main";
  35609. TAG_NAMES2["MALIGNMARK"] = "malignmark";
  35610. TAG_NAMES2["MARQUEE"] = "marquee";
  35611. TAG_NAMES2["MATH"] = "math";
  35612. TAG_NAMES2["MENU"] = "menu";
  35613. TAG_NAMES2["META"] = "meta";
  35614. TAG_NAMES2["MGLYPH"] = "mglyph";
  35615. TAG_NAMES2["MI"] = "mi";
  35616. TAG_NAMES2["MO"] = "mo";
  35617. TAG_NAMES2["MN"] = "mn";
  35618. TAG_NAMES2["MS"] = "ms";
  35619. TAG_NAMES2["MTEXT"] = "mtext";
  35620. TAG_NAMES2["NAV"] = "nav";
  35621. TAG_NAMES2["NOBR"] = "nobr";
  35622. TAG_NAMES2["NOFRAMES"] = "noframes";
  35623. TAG_NAMES2["NOEMBED"] = "noembed";
  35624. TAG_NAMES2["NOSCRIPT"] = "noscript";
  35625. TAG_NAMES2["OBJECT"] = "object";
  35626. TAG_NAMES2["OL"] = "ol";
  35627. TAG_NAMES2["OPTGROUP"] = "optgroup";
  35628. TAG_NAMES2["OPTION"] = "option";
  35629. TAG_NAMES2["P"] = "p";
  35630. TAG_NAMES2["PARAM"] = "param";
  35631. TAG_NAMES2["PLAINTEXT"] = "plaintext";
  35632. TAG_NAMES2["PRE"] = "pre";
  35633. TAG_NAMES2["RB"] = "rb";
  35634. TAG_NAMES2["RP"] = "rp";
  35635. TAG_NAMES2["RT"] = "rt";
  35636. TAG_NAMES2["RTC"] = "rtc";
  35637. TAG_NAMES2["RUBY"] = "ruby";
  35638. TAG_NAMES2["S"] = "s";
  35639. TAG_NAMES2["SCRIPT"] = "script";
  35640. TAG_NAMES2["SECTION"] = "section";
  35641. TAG_NAMES2["SELECT"] = "select";
  35642. TAG_NAMES2["SOURCE"] = "source";
  35643. TAG_NAMES2["SMALL"] = "small";
  35644. TAG_NAMES2["SPAN"] = "span";
  35645. TAG_NAMES2["STRIKE"] = "strike";
  35646. TAG_NAMES2["STRONG"] = "strong";
  35647. TAG_NAMES2["STYLE"] = "style";
  35648. TAG_NAMES2["SUB"] = "sub";
  35649. TAG_NAMES2["SUMMARY"] = "summary";
  35650. TAG_NAMES2["SUP"] = "sup";
  35651. TAG_NAMES2["TABLE"] = "table";
  35652. TAG_NAMES2["TBODY"] = "tbody";
  35653. TAG_NAMES2["TEMPLATE"] = "template";
  35654. TAG_NAMES2["TEXTAREA"] = "textarea";
  35655. TAG_NAMES2["TFOOT"] = "tfoot";
  35656. TAG_NAMES2["TD"] = "td";
  35657. TAG_NAMES2["TH"] = "th";
  35658. TAG_NAMES2["THEAD"] = "thead";
  35659. TAG_NAMES2["TITLE"] = "title";
  35660. TAG_NAMES2["TR"] = "tr";
  35661. TAG_NAMES2["TRACK"] = "track";
  35662. TAG_NAMES2["TT"] = "tt";
  35663. TAG_NAMES2["U"] = "u";
  35664. TAG_NAMES2["UL"] = "ul";
  35665. TAG_NAMES2["SVG"] = "svg";
  35666. TAG_NAMES2["VAR"] = "var";
  35667. TAG_NAMES2["WBR"] = "wbr";
  35668. TAG_NAMES2["XMP"] = "xmp";
  35669. })(TAG_NAMES = TAG_NAMES || (TAG_NAMES = {}));
  35670. var TAG_ID;
  35671. (function(TAG_ID2) {
  35672. TAG_ID2[TAG_ID2["UNKNOWN"] = 0] = "UNKNOWN";
  35673. TAG_ID2[TAG_ID2["A"] = 1] = "A";
  35674. TAG_ID2[TAG_ID2["ADDRESS"] = 2] = "ADDRESS";
  35675. TAG_ID2[TAG_ID2["ANNOTATION_XML"] = 3] = "ANNOTATION_XML";
  35676. TAG_ID2[TAG_ID2["APPLET"] = 4] = "APPLET";
  35677. TAG_ID2[TAG_ID2["AREA"] = 5] = "AREA";
  35678. TAG_ID2[TAG_ID2["ARTICLE"] = 6] = "ARTICLE";
  35679. TAG_ID2[TAG_ID2["ASIDE"] = 7] = "ASIDE";
  35680. TAG_ID2[TAG_ID2["B"] = 8] = "B";
  35681. TAG_ID2[TAG_ID2["BASE"] = 9] = "BASE";
  35682. TAG_ID2[TAG_ID2["BASEFONT"] = 10] = "BASEFONT";
  35683. TAG_ID2[TAG_ID2["BGSOUND"] = 11] = "BGSOUND";
  35684. TAG_ID2[TAG_ID2["BIG"] = 12] = "BIG";
  35685. TAG_ID2[TAG_ID2["BLOCKQUOTE"] = 13] = "BLOCKQUOTE";
  35686. TAG_ID2[TAG_ID2["BODY"] = 14] = "BODY";
  35687. TAG_ID2[TAG_ID2["BR"] = 15] = "BR";
  35688. TAG_ID2[TAG_ID2["BUTTON"] = 16] = "BUTTON";
  35689. TAG_ID2[TAG_ID2["CAPTION"] = 17] = "CAPTION";
  35690. TAG_ID2[TAG_ID2["CENTER"] = 18] = "CENTER";
  35691. TAG_ID2[TAG_ID2["CODE"] = 19] = "CODE";
  35692. TAG_ID2[TAG_ID2["COL"] = 20] = "COL";
  35693. TAG_ID2[TAG_ID2["COLGROUP"] = 21] = "COLGROUP";
  35694. TAG_ID2[TAG_ID2["DD"] = 22] = "DD";
  35695. TAG_ID2[TAG_ID2["DESC"] = 23] = "DESC";
  35696. TAG_ID2[TAG_ID2["DETAILS"] = 24] = "DETAILS";
  35697. TAG_ID2[TAG_ID2["DIALOG"] = 25] = "DIALOG";
  35698. TAG_ID2[TAG_ID2["DIR"] = 26] = "DIR";
  35699. TAG_ID2[TAG_ID2["DIV"] = 27] = "DIV";
  35700. TAG_ID2[TAG_ID2["DL"] = 28] = "DL";
  35701. TAG_ID2[TAG_ID2["DT"] = 29] = "DT";
  35702. TAG_ID2[TAG_ID2["EM"] = 30] = "EM";
  35703. TAG_ID2[TAG_ID2["EMBED"] = 31] = "EMBED";
  35704. TAG_ID2[TAG_ID2["FIELDSET"] = 32] = "FIELDSET";
  35705. TAG_ID2[TAG_ID2["FIGCAPTION"] = 33] = "FIGCAPTION";
  35706. TAG_ID2[TAG_ID2["FIGURE"] = 34] = "FIGURE";
  35707. TAG_ID2[TAG_ID2["FONT"] = 35] = "FONT";
  35708. TAG_ID2[TAG_ID2["FOOTER"] = 36] = "FOOTER";
  35709. TAG_ID2[TAG_ID2["FOREIGN_OBJECT"] = 37] = "FOREIGN_OBJECT";
  35710. TAG_ID2[TAG_ID2["FORM"] = 38] = "FORM";
  35711. TAG_ID2[TAG_ID2["FRAME"] = 39] = "FRAME";
  35712. TAG_ID2[TAG_ID2["FRAMESET"] = 40] = "FRAMESET";
  35713. TAG_ID2[TAG_ID2["H1"] = 41] = "H1";
  35714. TAG_ID2[TAG_ID2["H2"] = 42] = "H2";
  35715. TAG_ID2[TAG_ID2["H3"] = 43] = "H3";
  35716. TAG_ID2[TAG_ID2["H4"] = 44] = "H4";
  35717. TAG_ID2[TAG_ID2["H5"] = 45] = "H5";
  35718. TAG_ID2[TAG_ID2["H6"] = 46] = "H6";
  35719. TAG_ID2[TAG_ID2["HEAD"] = 47] = "HEAD";
  35720. TAG_ID2[TAG_ID2["HEADER"] = 48] = "HEADER";
  35721. TAG_ID2[TAG_ID2["HGROUP"] = 49] = "HGROUP";
  35722. TAG_ID2[TAG_ID2["HR"] = 50] = "HR";
  35723. TAG_ID2[TAG_ID2["HTML"] = 51] = "HTML";
  35724. TAG_ID2[TAG_ID2["I"] = 52] = "I";
  35725. TAG_ID2[TAG_ID2["IMG"] = 53] = "IMG";
  35726. TAG_ID2[TAG_ID2["IMAGE"] = 54] = "IMAGE";
  35727. TAG_ID2[TAG_ID2["INPUT"] = 55] = "INPUT";
  35728. TAG_ID2[TAG_ID2["IFRAME"] = 56] = "IFRAME";
  35729. TAG_ID2[TAG_ID2["KEYGEN"] = 57] = "KEYGEN";
  35730. TAG_ID2[TAG_ID2["LABEL"] = 58] = "LABEL";
  35731. TAG_ID2[TAG_ID2["LI"] = 59] = "LI";
  35732. TAG_ID2[TAG_ID2["LINK"] = 60] = "LINK";
  35733. TAG_ID2[TAG_ID2["LISTING"] = 61] = "LISTING";
  35734. TAG_ID2[TAG_ID2["MAIN"] = 62] = "MAIN";
  35735. TAG_ID2[TAG_ID2["MALIGNMARK"] = 63] = "MALIGNMARK";
  35736. TAG_ID2[TAG_ID2["MARQUEE"] = 64] = "MARQUEE";
  35737. TAG_ID2[TAG_ID2["MATH"] = 65] = "MATH";
  35738. TAG_ID2[TAG_ID2["MENU"] = 66] = "MENU";
  35739. TAG_ID2[TAG_ID2["META"] = 67] = "META";
  35740. TAG_ID2[TAG_ID2["MGLYPH"] = 68] = "MGLYPH";
  35741. TAG_ID2[TAG_ID2["MI"] = 69] = "MI";
  35742. TAG_ID2[TAG_ID2["MO"] = 70] = "MO";
  35743. TAG_ID2[TAG_ID2["MN"] = 71] = "MN";
  35744. TAG_ID2[TAG_ID2["MS"] = 72] = "MS";
  35745. TAG_ID2[TAG_ID2["MTEXT"] = 73] = "MTEXT";
  35746. TAG_ID2[TAG_ID2["NAV"] = 74] = "NAV";
  35747. TAG_ID2[TAG_ID2["NOBR"] = 75] = "NOBR";
  35748. TAG_ID2[TAG_ID2["NOFRAMES"] = 76] = "NOFRAMES";
  35749. TAG_ID2[TAG_ID2["NOEMBED"] = 77] = "NOEMBED";
  35750. TAG_ID2[TAG_ID2["NOSCRIPT"] = 78] = "NOSCRIPT";
  35751. TAG_ID2[TAG_ID2["OBJECT"] = 79] = "OBJECT";
  35752. TAG_ID2[TAG_ID2["OL"] = 80] = "OL";
  35753. TAG_ID2[TAG_ID2["OPTGROUP"] = 81] = "OPTGROUP";
  35754. TAG_ID2[TAG_ID2["OPTION"] = 82] = "OPTION";
  35755. TAG_ID2[TAG_ID2["P"] = 83] = "P";
  35756. TAG_ID2[TAG_ID2["PARAM"] = 84] = "PARAM";
  35757. TAG_ID2[TAG_ID2["PLAINTEXT"] = 85] = "PLAINTEXT";
  35758. TAG_ID2[TAG_ID2["PRE"] = 86] = "PRE";
  35759. TAG_ID2[TAG_ID2["RB"] = 87] = "RB";
  35760. TAG_ID2[TAG_ID2["RP"] = 88] = "RP";
  35761. TAG_ID2[TAG_ID2["RT"] = 89] = "RT";
  35762. TAG_ID2[TAG_ID2["RTC"] = 90] = "RTC";
  35763. TAG_ID2[TAG_ID2["RUBY"] = 91] = "RUBY";
  35764. TAG_ID2[TAG_ID2["S"] = 92] = "S";
  35765. TAG_ID2[TAG_ID2["SCRIPT"] = 93] = "SCRIPT";
  35766. TAG_ID2[TAG_ID2["SECTION"] = 94] = "SECTION";
  35767. TAG_ID2[TAG_ID2["SELECT"] = 95] = "SELECT";
  35768. TAG_ID2[TAG_ID2["SOURCE"] = 96] = "SOURCE";
  35769. TAG_ID2[TAG_ID2["SMALL"] = 97] = "SMALL";
  35770. TAG_ID2[TAG_ID2["SPAN"] = 98] = "SPAN";
  35771. TAG_ID2[TAG_ID2["STRIKE"] = 99] = "STRIKE";
  35772. TAG_ID2[TAG_ID2["STRONG"] = 100] = "STRONG";
  35773. TAG_ID2[TAG_ID2["STYLE"] = 101] = "STYLE";
  35774. TAG_ID2[TAG_ID2["SUB"] = 102] = "SUB";
  35775. TAG_ID2[TAG_ID2["SUMMARY"] = 103] = "SUMMARY";
  35776. TAG_ID2[TAG_ID2["SUP"] = 104] = "SUP";
  35777. TAG_ID2[TAG_ID2["TABLE"] = 105] = "TABLE";
  35778. TAG_ID2[TAG_ID2["TBODY"] = 106] = "TBODY";
  35779. TAG_ID2[TAG_ID2["TEMPLATE"] = 107] = "TEMPLATE";
  35780. TAG_ID2[TAG_ID2["TEXTAREA"] = 108] = "TEXTAREA";
  35781. TAG_ID2[TAG_ID2["TFOOT"] = 109] = "TFOOT";
  35782. TAG_ID2[TAG_ID2["TD"] = 110] = "TD";
  35783. TAG_ID2[TAG_ID2["TH"] = 111] = "TH";
  35784. TAG_ID2[TAG_ID2["THEAD"] = 112] = "THEAD";
  35785. TAG_ID2[TAG_ID2["TITLE"] = 113] = "TITLE";
  35786. TAG_ID2[TAG_ID2["TR"] = 114] = "TR";
  35787. TAG_ID2[TAG_ID2["TRACK"] = 115] = "TRACK";
  35788. TAG_ID2[TAG_ID2["TT"] = 116] = "TT";
  35789. TAG_ID2[TAG_ID2["U"] = 117] = "U";
  35790. TAG_ID2[TAG_ID2["UL"] = 118] = "UL";
  35791. TAG_ID2[TAG_ID2["SVG"] = 119] = "SVG";
  35792. TAG_ID2[TAG_ID2["VAR"] = 120] = "VAR";
  35793. TAG_ID2[TAG_ID2["WBR"] = 121] = "WBR";
  35794. TAG_ID2[TAG_ID2["XMP"] = 122] = "XMP";
  35795. })(TAG_ID = TAG_ID || (TAG_ID = {}));
  35796. var TAG_NAME_TO_ID = /* @__PURE__ */ new Map([
  35797. [TAG_NAMES.A, TAG_ID.A],
  35798. [TAG_NAMES.ADDRESS, TAG_ID.ADDRESS],
  35799. [TAG_NAMES.ANNOTATION_XML, TAG_ID.ANNOTATION_XML],
  35800. [TAG_NAMES.APPLET, TAG_ID.APPLET],
  35801. [TAG_NAMES.AREA, TAG_ID.AREA],
  35802. [TAG_NAMES.ARTICLE, TAG_ID.ARTICLE],
  35803. [TAG_NAMES.ASIDE, TAG_ID.ASIDE],
  35804. [TAG_NAMES.B, TAG_ID.B],
  35805. [TAG_NAMES.BASE, TAG_ID.BASE],
  35806. [TAG_NAMES.BASEFONT, TAG_ID.BASEFONT],
  35807. [TAG_NAMES.BGSOUND, TAG_ID.BGSOUND],
  35808. [TAG_NAMES.BIG, TAG_ID.BIG],
  35809. [TAG_NAMES.BLOCKQUOTE, TAG_ID.BLOCKQUOTE],
  35810. [TAG_NAMES.BODY, TAG_ID.BODY],
  35811. [TAG_NAMES.BR, TAG_ID.BR],
  35812. [TAG_NAMES.BUTTON, TAG_ID.BUTTON],
  35813. [TAG_NAMES.CAPTION, TAG_ID.CAPTION],
  35814. [TAG_NAMES.CENTER, TAG_ID.CENTER],
  35815. [TAG_NAMES.CODE, TAG_ID.CODE],
  35816. [TAG_NAMES.COL, TAG_ID.COL],
  35817. [TAG_NAMES.COLGROUP, TAG_ID.COLGROUP],
  35818. [TAG_NAMES.DD, TAG_ID.DD],
  35819. [TAG_NAMES.DESC, TAG_ID.DESC],
  35820. [TAG_NAMES.DETAILS, TAG_ID.DETAILS],
  35821. [TAG_NAMES.DIALOG, TAG_ID.DIALOG],
  35822. [TAG_NAMES.DIR, TAG_ID.DIR],
  35823. [TAG_NAMES.DIV, TAG_ID.DIV],
  35824. [TAG_NAMES.DL, TAG_ID.DL],
  35825. [TAG_NAMES.DT, TAG_ID.DT],
  35826. [TAG_NAMES.EM, TAG_ID.EM],
  35827. [TAG_NAMES.EMBED, TAG_ID.EMBED],
  35828. [TAG_NAMES.FIELDSET, TAG_ID.FIELDSET],
  35829. [TAG_NAMES.FIGCAPTION, TAG_ID.FIGCAPTION],
  35830. [TAG_NAMES.FIGURE, TAG_ID.FIGURE],
  35831. [TAG_NAMES.FONT, TAG_ID.FONT],
  35832. [TAG_NAMES.FOOTER, TAG_ID.FOOTER],
  35833. [TAG_NAMES.FOREIGN_OBJECT, TAG_ID.FOREIGN_OBJECT],
  35834. [TAG_NAMES.FORM, TAG_ID.FORM],
  35835. [TAG_NAMES.FRAME, TAG_ID.FRAME],
  35836. [TAG_NAMES.FRAMESET, TAG_ID.FRAMESET],
  35837. [TAG_NAMES.H1, TAG_ID.H1],
  35838. [TAG_NAMES.H2, TAG_ID.H2],
  35839. [TAG_NAMES.H3, TAG_ID.H3],
  35840. [TAG_NAMES.H4, TAG_ID.H4],
  35841. [TAG_NAMES.H5, TAG_ID.H5],
  35842. [TAG_NAMES.H6, TAG_ID.H6],
  35843. [TAG_NAMES.HEAD, TAG_ID.HEAD],
  35844. [TAG_NAMES.HEADER, TAG_ID.HEADER],
  35845. [TAG_NAMES.HGROUP, TAG_ID.HGROUP],
  35846. [TAG_NAMES.HR, TAG_ID.HR],
  35847. [TAG_NAMES.HTML, TAG_ID.HTML],
  35848. [TAG_NAMES.I, TAG_ID.I],
  35849. [TAG_NAMES.IMG, TAG_ID.IMG],
  35850. [TAG_NAMES.IMAGE, TAG_ID.IMAGE],
  35851. [TAG_NAMES.INPUT, TAG_ID.INPUT],
  35852. [TAG_NAMES.IFRAME, TAG_ID.IFRAME],
  35853. [TAG_NAMES.KEYGEN, TAG_ID.KEYGEN],
  35854. [TAG_NAMES.LABEL, TAG_ID.LABEL],
  35855. [TAG_NAMES.LI, TAG_ID.LI],
  35856. [TAG_NAMES.LINK, TAG_ID.LINK],
  35857. [TAG_NAMES.LISTING, TAG_ID.LISTING],
  35858. [TAG_NAMES.MAIN, TAG_ID.MAIN],
  35859. [TAG_NAMES.MALIGNMARK, TAG_ID.MALIGNMARK],
  35860. [TAG_NAMES.MARQUEE, TAG_ID.MARQUEE],
  35861. [TAG_NAMES.MATH, TAG_ID.MATH],
  35862. [TAG_NAMES.MENU, TAG_ID.MENU],
  35863. [TAG_NAMES.META, TAG_ID.META],
  35864. [TAG_NAMES.MGLYPH, TAG_ID.MGLYPH],
  35865. [TAG_NAMES.MI, TAG_ID.MI],
  35866. [TAG_NAMES.MO, TAG_ID.MO],
  35867. [TAG_NAMES.MN, TAG_ID.MN],
  35868. [TAG_NAMES.MS, TAG_ID.MS],
  35869. [TAG_NAMES.MTEXT, TAG_ID.MTEXT],
  35870. [TAG_NAMES.NAV, TAG_ID.NAV],
  35871. [TAG_NAMES.NOBR, TAG_ID.NOBR],
  35872. [TAG_NAMES.NOFRAMES, TAG_ID.NOFRAMES],
  35873. [TAG_NAMES.NOEMBED, TAG_ID.NOEMBED],
  35874. [TAG_NAMES.NOSCRIPT, TAG_ID.NOSCRIPT],
  35875. [TAG_NAMES.OBJECT, TAG_ID.OBJECT],
  35876. [TAG_NAMES.OL, TAG_ID.OL],
  35877. [TAG_NAMES.OPTGROUP, TAG_ID.OPTGROUP],
  35878. [TAG_NAMES.OPTION, TAG_ID.OPTION],
  35879. [TAG_NAMES.P, TAG_ID.P],
  35880. [TAG_NAMES.PARAM, TAG_ID.PARAM],
  35881. [TAG_NAMES.PLAINTEXT, TAG_ID.PLAINTEXT],
  35882. [TAG_NAMES.PRE, TAG_ID.PRE],
  35883. [TAG_NAMES.RB, TAG_ID.RB],
  35884. [TAG_NAMES.RP, TAG_ID.RP],
  35885. [TAG_NAMES.RT, TAG_ID.RT],
  35886. [TAG_NAMES.RTC, TAG_ID.RTC],
  35887. [TAG_NAMES.RUBY, TAG_ID.RUBY],
  35888. [TAG_NAMES.S, TAG_ID.S],
  35889. [TAG_NAMES.SCRIPT, TAG_ID.SCRIPT],
  35890. [TAG_NAMES.SECTION, TAG_ID.SECTION],
  35891. [TAG_NAMES.SELECT, TAG_ID.SELECT],
  35892. [TAG_NAMES.SOURCE, TAG_ID.SOURCE],
  35893. [TAG_NAMES.SMALL, TAG_ID.SMALL],
  35894. [TAG_NAMES.SPAN, TAG_ID.SPAN],
  35895. [TAG_NAMES.STRIKE, TAG_ID.STRIKE],
  35896. [TAG_NAMES.STRONG, TAG_ID.STRONG],
  35897. [TAG_NAMES.STYLE, TAG_ID.STYLE],
  35898. [TAG_NAMES.SUB, TAG_ID.SUB],
  35899. [TAG_NAMES.SUMMARY, TAG_ID.SUMMARY],
  35900. [TAG_NAMES.SUP, TAG_ID.SUP],
  35901. [TAG_NAMES.TABLE, TAG_ID.TABLE],
  35902. [TAG_NAMES.TBODY, TAG_ID.TBODY],
  35903. [TAG_NAMES.TEMPLATE, TAG_ID.TEMPLATE],
  35904. [TAG_NAMES.TEXTAREA, TAG_ID.TEXTAREA],
  35905. [TAG_NAMES.TFOOT, TAG_ID.TFOOT],
  35906. [TAG_NAMES.TD, TAG_ID.TD],
  35907. [TAG_NAMES.TH, TAG_ID.TH],
  35908. [TAG_NAMES.THEAD, TAG_ID.THEAD],
  35909. [TAG_NAMES.TITLE, TAG_ID.TITLE],
  35910. [TAG_NAMES.TR, TAG_ID.TR],
  35911. [TAG_NAMES.TRACK, TAG_ID.TRACK],
  35912. [TAG_NAMES.TT, TAG_ID.TT],
  35913. [TAG_NAMES.U, TAG_ID.U],
  35914. [TAG_NAMES.UL, TAG_ID.UL],
  35915. [TAG_NAMES.SVG, TAG_ID.SVG],
  35916. [TAG_NAMES.VAR, TAG_ID.VAR],
  35917. [TAG_NAMES.WBR, TAG_ID.WBR],
  35918. [TAG_NAMES.XMP, TAG_ID.XMP]
  35919. ]);
  35920. function getTagID(tagName) {
  35921. var _a2;
  35922. return (_a2 = TAG_NAME_TO_ID.get(tagName)) !== null && _a2 !== void 0 ? _a2 : TAG_ID.UNKNOWN;
  35923. }
  35924. var $ = TAG_ID;
  35925. var SPECIAL_ELEMENTS = {
  35926. [NS.HTML]: /* @__PURE__ */ new Set([
  35927. $.ADDRESS,
  35928. $.APPLET,
  35929. $.AREA,
  35930. $.ARTICLE,
  35931. $.ASIDE,
  35932. $.BASE,
  35933. $.BASEFONT,
  35934. $.BGSOUND,
  35935. $.BLOCKQUOTE,
  35936. $.BODY,
  35937. $.BR,
  35938. $.BUTTON,
  35939. $.CAPTION,
  35940. $.CENTER,
  35941. $.COL,
  35942. $.COLGROUP,
  35943. $.DD,
  35944. $.DETAILS,
  35945. $.DIR,
  35946. $.DIV,
  35947. $.DL,
  35948. $.DT,
  35949. $.EMBED,
  35950. $.FIELDSET,
  35951. $.FIGCAPTION,
  35952. $.FIGURE,
  35953. $.FOOTER,
  35954. $.FORM,
  35955. $.FRAME,
  35956. $.FRAMESET,
  35957. $.H1,
  35958. $.H2,
  35959. $.H3,
  35960. $.H4,
  35961. $.H5,
  35962. $.H6,
  35963. $.HEAD,
  35964. $.HEADER,
  35965. $.HGROUP,
  35966. $.HR,
  35967. $.HTML,
  35968. $.IFRAME,
  35969. $.IMG,
  35970. $.INPUT,
  35971. $.LI,
  35972. $.LINK,
  35973. $.LISTING,
  35974. $.MAIN,
  35975. $.MARQUEE,
  35976. $.MENU,
  35977. $.META,
  35978. $.NAV,
  35979. $.NOEMBED,
  35980. $.NOFRAMES,
  35981. $.NOSCRIPT,
  35982. $.OBJECT,
  35983. $.OL,
  35984. $.P,
  35985. $.PARAM,
  35986. $.PLAINTEXT,
  35987. $.PRE,
  35988. $.SCRIPT,
  35989. $.SECTION,
  35990. $.SELECT,
  35991. $.SOURCE,
  35992. $.STYLE,
  35993. $.SUMMARY,
  35994. $.TABLE,
  35995. $.TBODY,
  35996. $.TD,
  35997. $.TEMPLATE,
  35998. $.TEXTAREA,
  35999. $.TFOOT,
  36000. $.TH,
  36001. $.THEAD,
  36002. $.TITLE,
  36003. $.TR,
  36004. $.TRACK,
  36005. $.UL,
  36006. $.WBR,
  36007. $.XMP
  36008. ]),
  36009. [NS.MATHML]: /* @__PURE__ */ new Set([$.MI, $.MO, $.MN, $.MS, $.MTEXT, $.ANNOTATION_XML]),
  36010. [NS.SVG]: /* @__PURE__ */ new Set([$.TITLE, $.FOREIGN_OBJECT, $.DESC]),
  36011. [NS.XLINK]: /* @__PURE__ */ new Set(),
  36012. [NS.XML]: /* @__PURE__ */ new Set(),
  36013. [NS.XMLNS]: /* @__PURE__ */ new Set()
  36014. };
  36015. function isNumberedHeader(tn) {
  36016. return tn === $.H1 || tn === $.H2 || tn === $.H3 || tn === $.H4 || tn === $.H5 || tn === $.H6;
  36017. }
  36018. var UNESCAPED_TEXT = /* @__PURE__ */ new Set([
  36019. TAG_NAMES.STYLE,
  36020. TAG_NAMES.SCRIPT,
  36021. TAG_NAMES.XMP,
  36022. TAG_NAMES.IFRAME,
  36023. TAG_NAMES.NOEMBED,
  36024. TAG_NAMES.NOFRAMES,
  36025. TAG_NAMES.PLAINTEXT
  36026. ]);
  36027. function hasUnescapedText(tn, scriptingEnabled) {
  36028. return UNESCAPED_TEXT.has(tn) || scriptingEnabled && tn === TAG_NAMES.NOSCRIPT;
  36029. }
  36030. // node_modules/parse5/dist/tokenizer/index.js
  36031. var C1_CONTROLS_REFERENCE_REPLACEMENTS = /* @__PURE__ */ new Map([
  36032. [128, 8364],
  36033. [130, 8218],
  36034. [131, 402],
  36035. [132, 8222],
  36036. [133, 8230],
  36037. [134, 8224],
  36038. [135, 8225],
  36039. [136, 710],
  36040. [137, 8240],
  36041. [138, 352],
  36042. [139, 8249],
  36043. [140, 338],
  36044. [142, 381],
  36045. [145, 8216],
  36046. [146, 8217],
  36047. [147, 8220],
  36048. [148, 8221],
  36049. [149, 8226],
  36050. [150, 8211],
  36051. [151, 8212],
  36052. [152, 732],
  36053. [153, 8482],
  36054. [154, 353],
  36055. [155, 8250],
  36056. [156, 339],
  36057. [158, 382],
  36058. [159, 376]
  36059. ]);
  36060. var State;
  36061. (function(State2) {
  36062. State2[State2["DATA"] = 0] = "DATA";
  36063. State2[State2["RCDATA"] = 1] = "RCDATA";
  36064. State2[State2["RAWTEXT"] = 2] = "RAWTEXT";
  36065. State2[State2["SCRIPT_DATA"] = 3] = "SCRIPT_DATA";
  36066. State2[State2["PLAINTEXT"] = 4] = "PLAINTEXT";
  36067. State2[State2["TAG_OPEN"] = 5] = "TAG_OPEN";
  36068. State2[State2["END_TAG_OPEN"] = 6] = "END_TAG_OPEN";
  36069. State2[State2["TAG_NAME"] = 7] = "TAG_NAME";
  36070. State2[State2["RCDATA_LESS_THAN_SIGN"] = 8] = "RCDATA_LESS_THAN_SIGN";
  36071. State2[State2["RCDATA_END_TAG_OPEN"] = 9] = "RCDATA_END_TAG_OPEN";
  36072. State2[State2["RCDATA_END_TAG_NAME"] = 10] = "RCDATA_END_TAG_NAME";
  36073. State2[State2["RAWTEXT_LESS_THAN_SIGN"] = 11] = "RAWTEXT_LESS_THAN_SIGN";
  36074. State2[State2["RAWTEXT_END_TAG_OPEN"] = 12] = "RAWTEXT_END_TAG_OPEN";
  36075. State2[State2["RAWTEXT_END_TAG_NAME"] = 13] = "RAWTEXT_END_TAG_NAME";
  36076. State2[State2["SCRIPT_DATA_LESS_THAN_SIGN"] = 14] = "SCRIPT_DATA_LESS_THAN_SIGN";
  36077. State2[State2["SCRIPT_DATA_END_TAG_OPEN"] = 15] = "SCRIPT_DATA_END_TAG_OPEN";
  36078. State2[State2["SCRIPT_DATA_END_TAG_NAME"] = 16] = "SCRIPT_DATA_END_TAG_NAME";
  36079. State2[State2["SCRIPT_DATA_ESCAPE_START"] = 17] = "SCRIPT_DATA_ESCAPE_START";
  36080. State2[State2["SCRIPT_DATA_ESCAPE_START_DASH"] = 18] = "SCRIPT_DATA_ESCAPE_START_DASH";
  36081. State2[State2["SCRIPT_DATA_ESCAPED"] = 19] = "SCRIPT_DATA_ESCAPED";
  36082. State2[State2["SCRIPT_DATA_ESCAPED_DASH"] = 20] = "SCRIPT_DATA_ESCAPED_DASH";
  36083. State2[State2["SCRIPT_DATA_ESCAPED_DASH_DASH"] = 21] = "SCRIPT_DATA_ESCAPED_DASH_DASH";
  36084. State2[State2["SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN"] = 22] = "SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN";
  36085. State2[State2["SCRIPT_DATA_ESCAPED_END_TAG_OPEN"] = 23] = "SCRIPT_DATA_ESCAPED_END_TAG_OPEN";
  36086. State2[State2["SCRIPT_DATA_ESCAPED_END_TAG_NAME"] = 24] = "SCRIPT_DATA_ESCAPED_END_TAG_NAME";
  36087. State2[State2["SCRIPT_DATA_DOUBLE_ESCAPE_START"] = 25] = "SCRIPT_DATA_DOUBLE_ESCAPE_START";
  36088. State2[State2["SCRIPT_DATA_DOUBLE_ESCAPED"] = 26] = "SCRIPT_DATA_DOUBLE_ESCAPED";
  36089. State2[State2["SCRIPT_DATA_DOUBLE_ESCAPED_DASH"] = 27] = "SCRIPT_DATA_DOUBLE_ESCAPED_DASH";
  36090. State2[State2["SCRIPT_DATA_DOUBLE_ESCAPED_DASH_DASH"] = 28] = "SCRIPT_DATA_DOUBLE_ESCAPED_DASH_DASH";
  36091. State2[State2["SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN"] = 29] = "SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN";
  36092. State2[State2["SCRIPT_DATA_DOUBLE_ESCAPE_END"] = 30] = "SCRIPT_DATA_DOUBLE_ESCAPE_END";
  36093. State2[State2["BEFORE_ATTRIBUTE_NAME"] = 31] = "BEFORE_ATTRIBUTE_NAME";
  36094. State2[State2["ATTRIBUTE_NAME"] = 32] = "ATTRIBUTE_NAME";
  36095. State2[State2["AFTER_ATTRIBUTE_NAME"] = 33] = "AFTER_ATTRIBUTE_NAME";
  36096. State2[State2["BEFORE_ATTRIBUTE_VALUE"] = 34] = "BEFORE_ATTRIBUTE_VALUE";
  36097. State2[State2["ATTRIBUTE_VALUE_DOUBLE_QUOTED"] = 35] = "ATTRIBUTE_VALUE_DOUBLE_QUOTED";
  36098. State2[State2["ATTRIBUTE_VALUE_SINGLE_QUOTED"] = 36] = "ATTRIBUTE_VALUE_SINGLE_QUOTED";
  36099. State2[State2["ATTRIBUTE_VALUE_UNQUOTED"] = 37] = "ATTRIBUTE_VALUE_UNQUOTED";
  36100. State2[State2["AFTER_ATTRIBUTE_VALUE_QUOTED"] = 38] = "AFTER_ATTRIBUTE_VALUE_QUOTED";
  36101. State2[State2["SELF_CLOSING_START_TAG"] = 39] = "SELF_CLOSING_START_TAG";
  36102. State2[State2["BOGUS_COMMENT"] = 40] = "BOGUS_COMMENT";
  36103. State2[State2["MARKUP_DECLARATION_OPEN"] = 41] = "MARKUP_DECLARATION_OPEN";
  36104. State2[State2["COMMENT_START"] = 42] = "COMMENT_START";
  36105. State2[State2["COMMENT_START_DASH"] = 43] = "COMMENT_START_DASH";
  36106. State2[State2["COMMENT"] = 44] = "COMMENT";
  36107. State2[State2["COMMENT_LESS_THAN_SIGN"] = 45] = "COMMENT_LESS_THAN_SIGN";
  36108. State2[State2["COMMENT_LESS_THAN_SIGN_BANG"] = 46] = "COMMENT_LESS_THAN_SIGN_BANG";
  36109. State2[State2["COMMENT_LESS_THAN_SIGN_BANG_DASH"] = 47] = "COMMENT_LESS_THAN_SIGN_BANG_DASH";
  36110. State2[State2["COMMENT_LESS_THAN_SIGN_BANG_DASH_DASH"] = 48] = "COMMENT_LESS_THAN_SIGN_BANG_DASH_DASH";
  36111. State2[State2["COMMENT_END_DASH"] = 49] = "COMMENT_END_DASH";
  36112. State2[State2["COMMENT_END"] = 50] = "COMMENT_END";
  36113. State2[State2["COMMENT_END_BANG"] = 51] = "COMMENT_END_BANG";
  36114. State2[State2["DOCTYPE"] = 52] = "DOCTYPE";
  36115. State2[State2["BEFORE_DOCTYPE_NAME"] = 53] = "BEFORE_DOCTYPE_NAME";
  36116. State2[State2["DOCTYPE_NAME"] = 54] = "DOCTYPE_NAME";
  36117. State2[State2["AFTER_DOCTYPE_NAME"] = 55] = "AFTER_DOCTYPE_NAME";
  36118. State2[State2["AFTER_DOCTYPE_PUBLIC_KEYWORD"] = 56] = "AFTER_DOCTYPE_PUBLIC_KEYWORD";
  36119. State2[State2["BEFORE_DOCTYPE_PUBLIC_IDENTIFIER"] = 57] = "BEFORE_DOCTYPE_PUBLIC_IDENTIFIER";
  36120. State2[State2["DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED"] = 58] = "DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED";
  36121. State2[State2["DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED"] = 59] = "DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED";
  36122. State2[State2["AFTER_DOCTYPE_PUBLIC_IDENTIFIER"] = 60] = "AFTER_DOCTYPE_PUBLIC_IDENTIFIER";
  36123. State2[State2["BETWEEN_DOCTYPE_PUBLIC_AND_SYSTEM_IDENTIFIERS"] = 61] = "BETWEEN_DOCTYPE_PUBLIC_AND_SYSTEM_IDENTIFIERS";
  36124. State2[State2["AFTER_DOCTYPE_SYSTEM_KEYWORD"] = 62] = "AFTER_DOCTYPE_SYSTEM_KEYWORD";
  36125. State2[State2["BEFORE_DOCTYPE_SYSTEM_IDENTIFIER"] = 63] = "BEFORE_DOCTYPE_SYSTEM_IDENTIFIER";
  36126. State2[State2["DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED"] = 64] = "DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED";
  36127. State2[State2["DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED"] = 65] = "DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED";
  36128. State2[State2["AFTER_DOCTYPE_SYSTEM_IDENTIFIER"] = 66] = "AFTER_DOCTYPE_SYSTEM_IDENTIFIER";
  36129. State2[State2["BOGUS_DOCTYPE"] = 67] = "BOGUS_DOCTYPE";
  36130. State2[State2["CDATA_SECTION"] = 68] = "CDATA_SECTION";
  36131. State2[State2["CDATA_SECTION_BRACKET"] = 69] = "CDATA_SECTION_BRACKET";
  36132. State2[State2["CDATA_SECTION_END"] = 70] = "CDATA_SECTION_END";
  36133. State2[State2["CHARACTER_REFERENCE"] = 71] = "CHARACTER_REFERENCE";
  36134. State2[State2["NAMED_CHARACTER_REFERENCE"] = 72] = "NAMED_CHARACTER_REFERENCE";
  36135. State2[State2["AMBIGUOUS_AMPERSAND"] = 73] = "AMBIGUOUS_AMPERSAND";
  36136. State2[State2["NUMERIC_CHARACTER_REFERENCE"] = 74] = "NUMERIC_CHARACTER_REFERENCE";
  36137. State2[State2["HEXADEMICAL_CHARACTER_REFERENCE_START"] = 75] = "HEXADEMICAL_CHARACTER_REFERENCE_START";
  36138. State2[State2["HEXADEMICAL_CHARACTER_REFERENCE"] = 76] = "HEXADEMICAL_CHARACTER_REFERENCE";
  36139. State2[State2["DECIMAL_CHARACTER_REFERENCE"] = 77] = "DECIMAL_CHARACTER_REFERENCE";
  36140. State2[State2["NUMERIC_CHARACTER_REFERENCE_END"] = 78] = "NUMERIC_CHARACTER_REFERENCE_END";
  36141. })(State || (State = {}));
  36142. var TokenizerMode = {
  36143. DATA: State.DATA,
  36144. RCDATA: State.RCDATA,
  36145. RAWTEXT: State.RAWTEXT,
  36146. SCRIPT_DATA: State.SCRIPT_DATA,
  36147. PLAINTEXT: State.PLAINTEXT,
  36148. CDATA_SECTION: State.CDATA_SECTION
  36149. };
  36150. function isAsciiDigit(cp) {
  36151. return cp >= CODE_POINTS.DIGIT_0 && cp <= CODE_POINTS.DIGIT_9;
  36152. }
  36153. function isAsciiUpper(cp) {
  36154. return cp >= CODE_POINTS.LATIN_CAPITAL_A && cp <= CODE_POINTS.LATIN_CAPITAL_Z;
  36155. }
  36156. function isAsciiLower(cp) {
  36157. return cp >= CODE_POINTS.LATIN_SMALL_A && cp <= CODE_POINTS.LATIN_SMALL_Z;
  36158. }
  36159. function isAsciiLetter(cp) {
  36160. return isAsciiLower(cp) || isAsciiUpper(cp);
  36161. }
  36162. function isAsciiAlphaNumeric2(cp) {
  36163. return isAsciiLetter(cp) || isAsciiDigit(cp);
  36164. }
  36165. function isAsciiUpperHexDigit(cp) {
  36166. return cp >= CODE_POINTS.LATIN_CAPITAL_A && cp <= CODE_POINTS.LATIN_CAPITAL_F;
  36167. }
  36168. function isAsciiLowerHexDigit(cp) {
  36169. return cp >= CODE_POINTS.LATIN_SMALL_A && cp <= CODE_POINTS.LATIN_SMALL_F;
  36170. }
  36171. function isAsciiHexDigit(cp) {
  36172. return isAsciiDigit(cp) || isAsciiUpperHexDigit(cp) || isAsciiLowerHexDigit(cp);
  36173. }
  36174. function toAsciiLower(cp) {
  36175. return cp + 32;
  36176. }
  36177. function isWhitespace(cp) {
  36178. return cp === CODE_POINTS.SPACE || cp === CODE_POINTS.LINE_FEED || cp === CODE_POINTS.TABULATION || cp === CODE_POINTS.FORM_FEED;
  36179. }
  36180. function isEntityInAttributeInvalidEnd2(nextCp) {
  36181. return nextCp === CODE_POINTS.EQUALS_SIGN || isAsciiAlphaNumeric2(nextCp);
  36182. }
  36183. function isScriptDataDoubleEscapeSequenceEnd(cp) {
  36184. return isWhitespace(cp) || cp === CODE_POINTS.SOLIDUS || cp === CODE_POINTS.GREATER_THAN_SIGN;
  36185. }
  36186. var Tokenizer = class {
  36187. constructor(options, handler) {
  36188. this.options = options;
  36189. this.handler = handler;
  36190. this.paused = false;
  36191. this.inLoop = false;
  36192. this.inForeignNode = false;
  36193. this.lastStartTagName = "";
  36194. this.active = false;
  36195. this.state = State.DATA;
  36196. this.returnState = State.DATA;
  36197. this.charRefCode = -1;
  36198. this.consumedAfterSnapshot = -1;
  36199. this.currentCharacterToken = null;
  36200. this.currentToken = null;
  36201. this.currentAttr = { name: "", value: "" };
  36202. this.preprocessor = new Preprocessor(handler);
  36203. this.currentLocation = this.getCurrentLocation(-1);
  36204. }
  36205. //Errors
  36206. _err(code) {
  36207. var _a2, _b;
  36208. (_b = (_a2 = this.handler).onParseError) === null || _b === void 0 ? void 0 : _b.call(_a2, this.preprocessor.getError(code));
  36209. }
  36210. // NOTE: `offset` may never run across line boundaries.
  36211. getCurrentLocation(offset) {
  36212. if (!this.options.sourceCodeLocationInfo) {
  36213. return null;
  36214. }
  36215. return {
  36216. startLine: this.preprocessor.line,
  36217. startCol: this.preprocessor.col - offset,
  36218. startOffset: this.preprocessor.offset - offset,
  36219. endLine: -1,
  36220. endCol: -1,
  36221. endOffset: -1
  36222. };
  36223. }
  36224. _runParsingLoop() {
  36225. if (this.inLoop)
  36226. return;
  36227. this.inLoop = true;
  36228. while (this.active && !this.paused) {
  36229. this.consumedAfterSnapshot = 0;
  36230. const cp = this._consume();
  36231. if (!this._ensureHibernation()) {
  36232. this._callState(cp);
  36233. }
  36234. }
  36235. this.inLoop = false;
  36236. }
  36237. //API
  36238. pause() {
  36239. this.paused = true;
  36240. }
  36241. resume(writeCallback) {
  36242. if (!this.paused) {
  36243. throw new Error("Parser was already resumed");
  36244. }
  36245. this.paused = false;
  36246. if (this.inLoop)
  36247. return;
  36248. this._runParsingLoop();
  36249. if (!this.paused) {
  36250. writeCallback === null || writeCallback === void 0 ? void 0 : writeCallback();
  36251. }
  36252. }
  36253. write(chunk, isLastChunk, writeCallback) {
  36254. this.active = true;
  36255. this.preprocessor.write(chunk, isLastChunk);
  36256. this._runParsingLoop();
  36257. if (!this.paused) {
  36258. writeCallback === null || writeCallback === void 0 ? void 0 : writeCallback();
  36259. }
  36260. }
  36261. insertHtmlAtCurrentPos(chunk) {
  36262. this.active = true;
  36263. this.preprocessor.insertHtmlAtCurrentPos(chunk);
  36264. this._runParsingLoop();
  36265. }
  36266. //Hibernation
  36267. _ensureHibernation() {
  36268. if (this.preprocessor.endOfChunkHit) {
  36269. this._unconsume(this.consumedAfterSnapshot);
  36270. this.active = false;
  36271. return true;
  36272. }
  36273. return false;
  36274. }
  36275. //Consumption
  36276. _consume() {
  36277. this.consumedAfterSnapshot++;
  36278. return this.preprocessor.advance();
  36279. }
  36280. _unconsume(count) {
  36281. this.consumedAfterSnapshot -= count;
  36282. this.preprocessor.retreat(count);
  36283. }
  36284. _reconsumeInState(state, cp) {
  36285. this.state = state;
  36286. this._callState(cp);
  36287. }
  36288. _advanceBy(count) {
  36289. this.consumedAfterSnapshot += count;
  36290. for (let i = 0; i < count; i++) {
  36291. this.preprocessor.advance();
  36292. }
  36293. }
  36294. _consumeSequenceIfMatch(pattern, caseSensitive) {
  36295. if (this.preprocessor.startsWith(pattern, caseSensitive)) {
  36296. this._advanceBy(pattern.length - 1);
  36297. return true;
  36298. }
  36299. return false;
  36300. }
  36301. //Token creation
  36302. _createStartTagToken() {
  36303. this.currentToken = {
  36304. type: TokenType.START_TAG,
  36305. tagName: "",
  36306. tagID: TAG_ID.UNKNOWN,
  36307. selfClosing: false,
  36308. ackSelfClosing: false,
  36309. attrs: [],
  36310. location: this.getCurrentLocation(1)
  36311. };
  36312. }
  36313. _createEndTagToken() {
  36314. this.currentToken = {
  36315. type: TokenType.END_TAG,
  36316. tagName: "",
  36317. tagID: TAG_ID.UNKNOWN,
  36318. selfClosing: false,
  36319. ackSelfClosing: false,
  36320. attrs: [],
  36321. location: this.getCurrentLocation(2)
  36322. };
  36323. }
  36324. _createCommentToken(offset) {
  36325. this.currentToken = {
  36326. type: TokenType.COMMENT,
  36327. data: "",
  36328. location: this.getCurrentLocation(offset)
  36329. };
  36330. }
  36331. _createDoctypeToken(initialName) {
  36332. this.currentToken = {
  36333. type: TokenType.DOCTYPE,
  36334. name: initialName,
  36335. forceQuirks: false,
  36336. publicId: null,
  36337. systemId: null,
  36338. location: this.currentLocation
  36339. };
  36340. }
  36341. _createCharacterToken(type, chars) {
  36342. this.currentCharacterToken = {
  36343. type,
  36344. chars,
  36345. location: this.currentLocation
  36346. };
  36347. }
  36348. //Tag attributes
  36349. _createAttr(attrNameFirstCh) {
  36350. this.currentAttr = {
  36351. name: attrNameFirstCh,
  36352. value: ""
  36353. };
  36354. this.currentLocation = this.getCurrentLocation(0);
  36355. }
  36356. _leaveAttrName() {
  36357. var _a2;
  36358. var _b;
  36359. const token = this.currentToken;
  36360. if (getTokenAttr(token, this.currentAttr.name) === null) {
  36361. token.attrs.push(this.currentAttr);
  36362. if (token.location && this.currentLocation) {
  36363. const attrLocations = (_a2 = (_b = token.location).attrs) !== null && _a2 !== void 0 ? _a2 : _b.attrs = /* @__PURE__ */ Object.create(null);
  36364. attrLocations[this.currentAttr.name] = this.currentLocation;
  36365. this._leaveAttrValue();
  36366. }
  36367. } else {
  36368. this._err(ERR.duplicateAttribute);
  36369. }
  36370. }
  36371. _leaveAttrValue() {
  36372. if (this.currentLocation) {
  36373. this.currentLocation.endLine = this.preprocessor.line;
  36374. this.currentLocation.endCol = this.preprocessor.col;
  36375. this.currentLocation.endOffset = this.preprocessor.offset;
  36376. }
  36377. }
  36378. //Token emission
  36379. prepareToken(ct) {
  36380. this._emitCurrentCharacterToken(ct.location);
  36381. this.currentToken = null;
  36382. if (ct.location) {
  36383. ct.location.endLine = this.preprocessor.line;
  36384. ct.location.endCol = this.preprocessor.col + 1;
  36385. ct.location.endOffset = this.preprocessor.offset + 1;
  36386. }
  36387. this.currentLocation = this.getCurrentLocation(-1);
  36388. }
  36389. emitCurrentTagToken() {
  36390. const ct = this.currentToken;
  36391. this.prepareToken(ct);
  36392. ct.tagID = getTagID(ct.tagName);
  36393. if (ct.type === TokenType.START_TAG) {
  36394. this.lastStartTagName = ct.tagName;
  36395. this.handler.onStartTag(ct);
  36396. } else {
  36397. if (ct.attrs.length > 0) {
  36398. this._err(ERR.endTagWithAttributes);
  36399. }
  36400. if (ct.selfClosing) {
  36401. this._err(ERR.endTagWithTrailingSolidus);
  36402. }
  36403. this.handler.onEndTag(ct);
  36404. }
  36405. this.preprocessor.dropParsedChunk();
  36406. }
  36407. emitCurrentComment(ct) {
  36408. this.prepareToken(ct);
  36409. this.handler.onComment(ct);
  36410. this.preprocessor.dropParsedChunk();
  36411. }
  36412. emitCurrentDoctype(ct) {
  36413. this.prepareToken(ct);
  36414. this.handler.onDoctype(ct);
  36415. this.preprocessor.dropParsedChunk();
  36416. }
  36417. _emitCurrentCharacterToken(nextLocation) {
  36418. if (this.currentCharacterToken) {
  36419. if (nextLocation && this.currentCharacterToken.location) {
  36420. this.currentCharacterToken.location.endLine = nextLocation.startLine;
  36421. this.currentCharacterToken.location.endCol = nextLocation.startCol;
  36422. this.currentCharacterToken.location.endOffset = nextLocation.startOffset;
  36423. }
  36424. switch (this.currentCharacterToken.type) {
  36425. case TokenType.CHARACTER: {
  36426. this.handler.onCharacter(this.currentCharacterToken);
  36427. break;
  36428. }
  36429. case TokenType.NULL_CHARACTER: {
  36430. this.handler.onNullCharacter(this.currentCharacterToken);
  36431. break;
  36432. }
  36433. case TokenType.WHITESPACE_CHARACTER: {
  36434. this.handler.onWhitespaceCharacter(this.currentCharacterToken);
  36435. break;
  36436. }
  36437. }
  36438. this.currentCharacterToken = null;
  36439. }
  36440. }
  36441. _emitEOFToken() {
  36442. const location2 = this.getCurrentLocation(0);
  36443. if (location2) {
  36444. location2.endLine = location2.startLine;
  36445. location2.endCol = location2.startCol;
  36446. location2.endOffset = location2.startOffset;
  36447. }
  36448. this._emitCurrentCharacterToken(location2);
  36449. this.handler.onEof({ type: TokenType.EOF, location: location2 });
  36450. this.active = false;
  36451. }
  36452. //Characters emission
  36453. //OPTIMIZATION: specification uses only one type of character tokens (one token per character).
  36454. //This causes a huge memory overhead and a lot of unnecessary parser loops. parse5 uses 3 groups of characters.
  36455. //If we have a sequence of characters that belong to the same group, the parser can process it
  36456. //as a single solid character token.
  36457. //So, there are 3 types of character tokens in parse5:
  36458. //1)TokenType.NULL_CHARACTER - \u0000-character sequences (e.g. '\u0000\u0000\u0000')
  36459. //2)TokenType.WHITESPACE_CHARACTER - any whitespace/new-line character sequences (e.g. '\n \r\t \f')
  36460. //3)TokenType.CHARACTER - any character sequence which don't belong to groups 1 and 2 (e.g. 'abcdef1234@@#$%^')
  36461. _appendCharToCurrentCharacterToken(type, ch) {
  36462. if (this.currentCharacterToken) {
  36463. if (this.currentCharacterToken.type !== type) {
  36464. this.currentLocation = this.getCurrentLocation(0);
  36465. this._emitCurrentCharacterToken(this.currentLocation);
  36466. this.preprocessor.dropParsedChunk();
  36467. } else {
  36468. this.currentCharacterToken.chars += ch;
  36469. return;
  36470. }
  36471. }
  36472. this._createCharacterToken(type, ch);
  36473. }
  36474. _emitCodePoint(cp) {
  36475. const type = isWhitespace(cp) ? TokenType.WHITESPACE_CHARACTER : cp === CODE_POINTS.NULL ? TokenType.NULL_CHARACTER : TokenType.CHARACTER;
  36476. this._appendCharToCurrentCharacterToken(type, String.fromCodePoint(cp));
  36477. }
  36478. //NOTE: used when we emit characters explicitly.
  36479. //This is always for non-whitespace and non-null characters, which allows us to avoid additional checks.
  36480. _emitChars(ch) {
  36481. this._appendCharToCurrentCharacterToken(TokenType.CHARACTER, ch);
  36482. }
  36483. // Character reference helpers
  36484. _matchNamedCharacterReference(cp) {
  36485. let result = null;
  36486. let excess = 0;
  36487. let withoutSemicolon = false;
  36488. for (let i = 0, current = decode_data_html_default[0]; i >= 0; cp = this._consume()) {
  36489. i = determineBranch(decode_data_html_default, current, i + 1, cp);
  36490. if (i < 0)
  36491. break;
  36492. excess += 1;
  36493. current = decode_data_html_default[i];
  36494. const masked = current & BinTrieFlags.VALUE_LENGTH;
  36495. if (masked) {
  36496. const valueLength = (masked >> 14) - 1;
  36497. if (cp !== CODE_POINTS.SEMICOLON && this._isCharacterReferenceInAttribute() && isEntityInAttributeInvalidEnd2(this.preprocessor.peek(1))) {
  36498. result = [CODE_POINTS.AMPERSAND];
  36499. i += valueLength;
  36500. } else {
  36501. result = valueLength === 0 ? [decode_data_html_default[i] & ~BinTrieFlags.VALUE_LENGTH] : valueLength === 1 ? [decode_data_html_default[++i]] : [decode_data_html_default[++i], decode_data_html_default[++i]];
  36502. excess = 0;
  36503. withoutSemicolon = cp !== CODE_POINTS.SEMICOLON;
  36504. }
  36505. if (valueLength === 0) {
  36506. this._consume();
  36507. break;
  36508. }
  36509. }
  36510. }
  36511. this._unconsume(excess);
  36512. if (withoutSemicolon && !this.preprocessor.endOfChunkHit) {
  36513. this._err(ERR.missingSemicolonAfterCharacterReference);
  36514. }
  36515. this._unconsume(1);
  36516. return result;
  36517. }
  36518. _isCharacterReferenceInAttribute() {
  36519. return this.returnState === State.ATTRIBUTE_VALUE_DOUBLE_QUOTED || this.returnState === State.ATTRIBUTE_VALUE_SINGLE_QUOTED || this.returnState === State.ATTRIBUTE_VALUE_UNQUOTED;
  36520. }
  36521. _flushCodePointConsumedAsCharacterReference(cp) {
  36522. if (this._isCharacterReferenceInAttribute()) {
  36523. this.currentAttr.value += String.fromCodePoint(cp);
  36524. } else {
  36525. this._emitCodePoint(cp);
  36526. }
  36527. }
  36528. // Calling states this way turns out to be much faster than any other approach.
  36529. _callState(cp) {
  36530. switch (this.state) {
  36531. case State.DATA: {
  36532. this._stateData(cp);
  36533. break;
  36534. }
  36535. case State.RCDATA: {
  36536. this._stateRcdata(cp);
  36537. break;
  36538. }
  36539. case State.RAWTEXT: {
  36540. this._stateRawtext(cp);
  36541. break;
  36542. }
  36543. case State.SCRIPT_DATA: {
  36544. this._stateScriptData(cp);
  36545. break;
  36546. }
  36547. case State.PLAINTEXT: {
  36548. this._statePlaintext(cp);
  36549. break;
  36550. }
  36551. case State.TAG_OPEN: {
  36552. this._stateTagOpen(cp);
  36553. break;
  36554. }
  36555. case State.END_TAG_OPEN: {
  36556. this._stateEndTagOpen(cp);
  36557. break;
  36558. }
  36559. case State.TAG_NAME: {
  36560. this._stateTagName(cp);
  36561. break;
  36562. }
  36563. case State.RCDATA_LESS_THAN_SIGN: {
  36564. this._stateRcdataLessThanSign(cp);
  36565. break;
  36566. }
  36567. case State.RCDATA_END_TAG_OPEN: {
  36568. this._stateRcdataEndTagOpen(cp);
  36569. break;
  36570. }
  36571. case State.RCDATA_END_TAG_NAME: {
  36572. this._stateRcdataEndTagName(cp);
  36573. break;
  36574. }
  36575. case State.RAWTEXT_LESS_THAN_SIGN: {
  36576. this._stateRawtextLessThanSign(cp);
  36577. break;
  36578. }
  36579. case State.RAWTEXT_END_TAG_OPEN: {
  36580. this._stateRawtextEndTagOpen(cp);
  36581. break;
  36582. }
  36583. case State.RAWTEXT_END_TAG_NAME: {
  36584. this._stateRawtextEndTagName(cp);
  36585. break;
  36586. }
  36587. case State.SCRIPT_DATA_LESS_THAN_SIGN: {
  36588. this._stateScriptDataLessThanSign(cp);
  36589. break;
  36590. }
  36591. case State.SCRIPT_DATA_END_TAG_OPEN: {
  36592. this._stateScriptDataEndTagOpen(cp);
  36593. break;
  36594. }
  36595. case State.SCRIPT_DATA_END_TAG_NAME: {
  36596. this._stateScriptDataEndTagName(cp);
  36597. break;
  36598. }
  36599. case State.SCRIPT_DATA_ESCAPE_START: {
  36600. this._stateScriptDataEscapeStart(cp);
  36601. break;
  36602. }
  36603. case State.SCRIPT_DATA_ESCAPE_START_DASH: {
  36604. this._stateScriptDataEscapeStartDash(cp);
  36605. break;
  36606. }
  36607. case State.SCRIPT_DATA_ESCAPED: {
  36608. this._stateScriptDataEscaped(cp);
  36609. break;
  36610. }
  36611. case State.SCRIPT_DATA_ESCAPED_DASH: {
  36612. this._stateScriptDataEscapedDash(cp);
  36613. break;
  36614. }
  36615. case State.SCRIPT_DATA_ESCAPED_DASH_DASH: {
  36616. this._stateScriptDataEscapedDashDash(cp);
  36617. break;
  36618. }
  36619. case State.SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN: {
  36620. this._stateScriptDataEscapedLessThanSign(cp);
  36621. break;
  36622. }
  36623. case State.SCRIPT_DATA_ESCAPED_END_TAG_OPEN: {
  36624. this._stateScriptDataEscapedEndTagOpen(cp);
  36625. break;
  36626. }
  36627. case State.SCRIPT_DATA_ESCAPED_END_TAG_NAME: {
  36628. this._stateScriptDataEscapedEndTagName(cp);
  36629. break;
  36630. }
  36631. case State.SCRIPT_DATA_DOUBLE_ESCAPE_START: {
  36632. this._stateScriptDataDoubleEscapeStart(cp);
  36633. break;
  36634. }
  36635. case State.SCRIPT_DATA_DOUBLE_ESCAPED: {
  36636. this._stateScriptDataDoubleEscaped(cp);
  36637. break;
  36638. }
  36639. case State.SCRIPT_DATA_DOUBLE_ESCAPED_DASH: {
  36640. this._stateScriptDataDoubleEscapedDash(cp);
  36641. break;
  36642. }
  36643. case State.SCRIPT_DATA_DOUBLE_ESCAPED_DASH_DASH: {
  36644. this._stateScriptDataDoubleEscapedDashDash(cp);
  36645. break;
  36646. }
  36647. case State.SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN: {
  36648. this._stateScriptDataDoubleEscapedLessThanSign(cp);
  36649. break;
  36650. }
  36651. case State.SCRIPT_DATA_DOUBLE_ESCAPE_END: {
  36652. this._stateScriptDataDoubleEscapeEnd(cp);
  36653. break;
  36654. }
  36655. case State.BEFORE_ATTRIBUTE_NAME: {
  36656. this._stateBeforeAttributeName(cp);
  36657. break;
  36658. }
  36659. case State.ATTRIBUTE_NAME: {
  36660. this._stateAttributeName(cp);
  36661. break;
  36662. }
  36663. case State.AFTER_ATTRIBUTE_NAME: {
  36664. this._stateAfterAttributeName(cp);
  36665. break;
  36666. }
  36667. case State.BEFORE_ATTRIBUTE_VALUE: {
  36668. this._stateBeforeAttributeValue(cp);
  36669. break;
  36670. }
  36671. case State.ATTRIBUTE_VALUE_DOUBLE_QUOTED: {
  36672. this._stateAttributeValueDoubleQuoted(cp);
  36673. break;
  36674. }
  36675. case State.ATTRIBUTE_VALUE_SINGLE_QUOTED: {
  36676. this._stateAttributeValueSingleQuoted(cp);
  36677. break;
  36678. }
  36679. case State.ATTRIBUTE_VALUE_UNQUOTED: {
  36680. this._stateAttributeValueUnquoted(cp);
  36681. break;
  36682. }
  36683. case State.AFTER_ATTRIBUTE_VALUE_QUOTED: {
  36684. this._stateAfterAttributeValueQuoted(cp);
  36685. break;
  36686. }
  36687. case State.SELF_CLOSING_START_TAG: {
  36688. this._stateSelfClosingStartTag(cp);
  36689. break;
  36690. }
  36691. case State.BOGUS_COMMENT: {
  36692. this._stateBogusComment(cp);
  36693. break;
  36694. }
  36695. case State.MARKUP_DECLARATION_OPEN: {
  36696. this._stateMarkupDeclarationOpen(cp);
  36697. break;
  36698. }
  36699. case State.COMMENT_START: {
  36700. this._stateCommentStart(cp);
  36701. break;
  36702. }
  36703. case State.COMMENT_START_DASH: {
  36704. this._stateCommentStartDash(cp);
  36705. break;
  36706. }
  36707. case State.COMMENT: {
  36708. this._stateComment(cp);
  36709. break;
  36710. }
  36711. case State.COMMENT_LESS_THAN_SIGN: {
  36712. this._stateCommentLessThanSign(cp);
  36713. break;
  36714. }
  36715. case State.COMMENT_LESS_THAN_SIGN_BANG: {
  36716. this._stateCommentLessThanSignBang(cp);
  36717. break;
  36718. }
  36719. case State.COMMENT_LESS_THAN_SIGN_BANG_DASH: {
  36720. this._stateCommentLessThanSignBangDash(cp);
  36721. break;
  36722. }
  36723. case State.COMMENT_LESS_THAN_SIGN_BANG_DASH_DASH: {
  36724. this._stateCommentLessThanSignBangDashDash(cp);
  36725. break;
  36726. }
  36727. case State.COMMENT_END_DASH: {
  36728. this._stateCommentEndDash(cp);
  36729. break;
  36730. }
  36731. case State.COMMENT_END: {
  36732. this._stateCommentEnd(cp);
  36733. break;
  36734. }
  36735. case State.COMMENT_END_BANG: {
  36736. this._stateCommentEndBang(cp);
  36737. break;
  36738. }
  36739. case State.DOCTYPE: {
  36740. this._stateDoctype(cp);
  36741. break;
  36742. }
  36743. case State.BEFORE_DOCTYPE_NAME: {
  36744. this._stateBeforeDoctypeName(cp);
  36745. break;
  36746. }
  36747. case State.DOCTYPE_NAME: {
  36748. this._stateDoctypeName(cp);
  36749. break;
  36750. }
  36751. case State.AFTER_DOCTYPE_NAME: {
  36752. this._stateAfterDoctypeName(cp);
  36753. break;
  36754. }
  36755. case State.AFTER_DOCTYPE_PUBLIC_KEYWORD: {
  36756. this._stateAfterDoctypePublicKeyword(cp);
  36757. break;
  36758. }
  36759. case State.BEFORE_DOCTYPE_PUBLIC_IDENTIFIER: {
  36760. this._stateBeforeDoctypePublicIdentifier(cp);
  36761. break;
  36762. }
  36763. case State.DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED: {
  36764. this._stateDoctypePublicIdentifierDoubleQuoted(cp);
  36765. break;
  36766. }
  36767. case State.DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED: {
  36768. this._stateDoctypePublicIdentifierSingleQuoted(cp);
  36769. break;
  36770. }
  36771. case State.AFTER_DOCTYPE_PUBLIC_IDENTIFIER: {
  36772. this._stateAfterDoctypePublicIdentifier(cp);
  36773. break;
  36774. }
  36775. case State.BETWEEN_DOCTYPE_PUBLIC_AND_SYSTEM_IDENTIFIERS: {
  36776. this._stateBetweenDoctypePublicAndSystemIdentifiers(cp);
  36777. break;
  36778. }
  36779. case State.AFTER_DOCTYPE_SYSTEM_KEYWORD: {
  36780. this._stateAfterDoctypeSystemKeyword(cp);
  36781. break;
  36782. }
  36783. case State.BEFORE_DOCTYPE_SYSTEM_IDENTIFIER: {
  36784. this._stateBeforeDoctypeSystemIdentifier(cp);
  36785. break;
  36786. }
  36787. case State.DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED: {
  36788. this._stateDoctypeSystemIdentifierDoubleQuoted(cp);
  36789. break;
  36790. }
  36791. case State.DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED: {
  36792. this._stateDoctypeSystemIdentifierSingleQuoted(cp);
  36793. break;
  36794. }
  36795. case State.AFTER_DOCTYPE_SYSTEM_IDENTIFIER: {
  36796. this._stateAfterDoctypeSystemIdentifier(cp);
  36797. break;
  36798. }
  36799. case State.BOGUS_DOCTYPE: {
  36800. this._stateBogusDoctype(cp);
  36801. break;
  36802. }
  36803. case State.CDATA_SECTION: {
  36804. this._stateCdataSection(cp);
  36805. break;
  36806. }
  36807. case State.CDATA_SECTION_BRACKET: {
  36808. this._stateCdataSectionBracket(cp);
  36809. break;
  36810. }
  36811. case State.CDATA_SECTION_END: {
  36812. this._stateCdataSectionEnd(cp);
  36813. break;
  36814. }
  36815. case State.CHARACTER_REFERENCE: {
  36816. this._stateCharacterReference(cp);
  36817. break;
  36818. }
  36819. case State.NAMED_CHARACTER_REFERENCE: {
  36820. this._stateNamedCharacterReference(cp);
  36821. break;
  36822. }
  36823. case State.AMBIGUOUS_AMPERSAND: {
  36824. this._stateAmbiguousAmpersand(cp);
  36825. break;
  36826. }
  36827. case State.NUMERIC_CHARACTER_REFERENCE: {
  36828. this._stateNumericCharacterReference(cp);
  36829. break;
  36830. }
  36831. case State.HEXADEMICAL_CHARACTER_REFERENCE_START: {
  36832. this._stateHexademicalCharacterReferenceStart(cp);
  36833. break;
  36834. }
  36835. case State.HEXADEMICAL_CHARACTER_REFERENCE: {
  36836. this._stateHexademicalCharacterReference(cp);
  36837. break;
  36838. }
  36839. case State.DECIMAL_CHARACTER_REFERENCE: {
  36840. this._stateDecimalCharacterReference(cp);
  36841. break;
  36842. }
  36843. case State.NUMERIC_CHARACTER_REFERENCE_END: {
  36844. this._stateNumericCharacterReferenceEnd(cp);
  36845. break;
  36846. }
  36847. default: {
  36848. throw new Error("Unknown state");
  36849. }
  36850. }
  36851. }
  36852. // State machine
  36853. // Data state
  36854. //------------------------------------------------------------------
  36855. _stateData(cp) {
  36856. switch (cp) {
  36857. case CODE_POINTS.LESS_THAN_SIGN: {
  36858. this.state = State.TAG_OPEN;
  36859. break;
  36860. }
  36861. case CODE_POINTS.AMPERSAND: {
  36862. this.returnState = State.DATA;
  36863. this.state = State.CHARACTER_REFERENCE;
  36864. break;
  36865. }
  36866. case CODE_POINTS.NULL: {
  36867. this._err(ERR.unexpectedNullCharacter);
  36868. this._emitCodePoint(cp);
  36869. break;
  36870. }
  36871. case CODE_POINTS.EOF: {
  36872. this._emitEOFToken();
  36873. break;
  36874. }
  36875. default: {
  36876. this._emitCodePoint(cp);
  36877. }
  36878. }
  36879. }
  36880. // RCDATA state
  36881. //------------------------------------------------------------------
  36882. _stateRcdata(cp) {
  36883. switch (cp) {
  36884. case CODE_POINTS.AMPERSAND: {
  36885. this.returnState = State.RCDATA;
  36886. this.state = State.CHARACTER_REFERENCE;
  36887. break;
  36888. }
  36889. case CODE_POINTS.LESS_THAN_SIGN: {
  36890. this.state = State.RCDATA_LESS_THAN_SIGN;
  36891. break;
  36892. }
  36893. case CODE_POINTS.NULL: {
  36894. this._err(ERR.unexpectedNullCharacter);
  36895. this._emitChars(REPLACEMENT_CHARACTER);
  36896. break;
  36897. }
  36898. case CODE_POINTS.EOF: {
  36899. this._emitEOFToken();
  36900. break;
  36901. }
  36902. default: {
  36903. this._emitCodePoint(cp);
  36904. }
  36905. }
  36906. }
  36907. // RAWTEXT state
  36908. //------------------------------------------------------------------
  36909. _stateRawtext(cp) {
  36910. switch (cp) {
  36911. case CODE_POINTS.LESS_THAN_SIGN: {
  36912. this.state = State.RAWTEXT_LESS_THAN_SIGN;
  36913. break;
  36914. }
  36915. case CODE_POINTS.NULL: {
  36916. this._err(ERR.unexpectedNullCharacter);
  36917. this._emitChars(REPLACEMENT_CHARACTER);
  36918. break;
  36919. }
  36920. case CODE_POINTS.EOF: {
  36921. this._emitEOFToken();
  36922. break;
  36923. }
  36924. default: {
  36925. this._emitCodePoint(cp);
  36926. }
  36927. }
  36928. }
  36929. // Script data state
  36930. //------------------------------------------------------------------
  36931. _stateScriptData(cp) {
  36932. switch (cp) {
  36933. case CODE_POINTS.LESS_THAN_SIGN: {
  36934. this.state = State.SCRIPT_DATA_LESS_THAN_SIGN;
  36935. break;
  36936. }
  36937. case CODE_POINTS.NULL: {
  36938. this._err(ERR.unexpectedNullCharacter);
  36939. this._emitChars(REPLACEMENT_CHARACTER);
  36940. break;
  36941. }
  36942. case CODE_POINTS.EOF: {
  36943. this._emitEOFToken();
  36944. break;
  36945. }
  36946. default: {
  36947. this._emitCodePoint(cp);
  36948. }
  36949. }
  36950. }
  36951. // PLAINTEXT state
  36952. //------------------------------------------------------------------
  36953. _statePlaintext(cp) {
  36954. switch (cp) {
  36955. case CODE_POINTS.NULL: {
  36956. this._err(ERR.unexpectedNullCharacter);
  36957. this._emitChars(REPLACEMENT_CHARACTER);
  36958. break;
  36959. }
  36960. case CODE_POINTS.EOF: {
  36961. this._emitEOFToken();
  36962. break;
  36963. }
  36964. default: {
  36965. this._emitCodePoint(cp);
  36966. }
  36967. }
  36968. }
  36969. // Tag open state
  36970. //------------------------------------------------------------------
  36971. _stateTagOpen(cp) {
  36972. if (isAsciiLetter(cp)) {
  36973. this._createStartTagToken();
  36974. this.state = State.TAG_NAME;
  36975. this._stateTagName(cp);
  36976. } else
  36977. switch (cp) {
  36978. case CODE_POINTS.EXCLAMATION_MARK: {
  36979. this.state = State.MARKUP_DECLARATION_OPEN;
  36980. break;
  36981. }
  36982. case CODE_POINTS.SOLIDUS: {
  36983. this.state = State.END_TAG_OPEN;
  36984. break;
  36985. }
  36986. case CODE_POINTS.QUESTION_MARK: {
  36987. this._err(ERR.unexpectedQuestionMarkInsteadOfTagName);
  36988. this._createCommentToken(1);
  36989. this.state = State.BOGUS_COMMENT;
  36990. this._stateBogusComment(cp);
  36991. break;
  36992. }
  36993. case CODE_POINTS.EOF: {
  36994. this._err(ERR.eofBeforeTagName);
  36995. this._emitChars("<");
  36996. this._emitEOFToken();
  36997. break;
  36998. }
  36999. default: {
  37000. this._err(ERR.invalidFirstCharacterOfTagName);
  37001. this._emitChars("<");
  37002. this.state = State.DATA;
  37003. this._stateData(cp);
  37004. }
  37005. }
  37006. }
  37007. // End tag open state
  37008. //------------------------------------------------------------------
  37009. _stateEndTagOpen(cp) {
  37010. if (isAsciiLetter(cp)) {
  37011. this._createEndTagToken();
  37012. this.state = State.TAG_NAME;
  37013. this._stateTagName(cp);
  37014. } else
  37015. switch (cp) {
  37016. case CODE_POINTS.GREATER_THAN_SIGN: {
  37017. this._err(ERR.missingEndTagName);
  37018. this.state = State.DATA;
  37019. break;
  37020. }
  37021. case CODE_POINTS.EOF: {
  37022. this._err(ERR.eofBeforeTagName);
  37023. this._emitChars("</");
  37024. this._emitEOFToken();
  37025. break;
  37026. }
  37027. default: {
  37028. this._err(ERR.invalidFirstCharacterOfTagName);
  37029. this._createCommentToken(2);
  37030. this.state = State.BOGUS_COMMENT;
  37031. this._stateBogusComment(cp);
  37032. }
  37033. }
  37034. }
  37035. // Tag name state
  37036. //------------------------------------------------------------------
  37037. _stateTagName(cp) {
  37038. const token = this.currentToken;
  37039. switch (cp) {
  37040. case CODE_POINTS.SPACE:
  37041. case CODE_POINTS.LINE_FEED:
  37042. case CODE_POINTS.TABULATION:
  37043. case CODE_POINTS.FORM_FEED: {
  37044. this.state = State.BEFORE_ATTRIBUTE_NAME;
  37045. break;
  37046. }
  37047. case CODE_POINTS.SOLIDUS: {
  37048. this.state = State.SELF_CLOSING_START_TAG;
  37049. break;
  37050. }
  37051. case CODE_POINTS.GREATER_THAN_SIGN: {
  37052. this.state = State.DATA;
  37053. this.emitCurrentTagToken();
  37054. break;
  37055. }
  37056. case CODE_POINTS.NULL: {
  37057. this._err(ERR.unexpectedNullCharacter);
  37058. token.tagName += REPLACEMENT_CHARACTER;
  37059. break;
  37060. }
  37061. case CODE_POINTS.EOF: {
  37062. this._err(ERR.eofInTag);
  37063. this._emitEOFToken();
  37064. break;
  37065. }
  37066. default: {
  37067. token.tagName += String.fromCodePoint(isAsciiUpper(cp) ? toAsciiLower(cp) : cp);
  37068. }
  37069. }
  37070. }
  37071. // RCDATA less-than sign state
  37072. //------------------------------------------------------------------
  37073. _stateRcdataLessThanSign(cp) {
  37074. if (cp === CODE_POINTS.SOLIDUS) {
  37075. this.state = State.RCDATA_END_TAG_OPEN;
  37076. } else {
  37077. this._emitChars("<");
  37078. this.state = State.RCDATA;
  37079. this._stateRcdata(cp);
  37080. }
  37081. }
  37082. // RCDATA end tag open state
  37083. //------------------------------------------------------------------
  37084. _stateRcdataEndTagOpen(cp) {
  37085. if (isAsciiLetter(cp)) {
  37086. this.state = State.RCDATA_END_TAG_NAME;
  37087. this._stateRcdataEndTagName(cp);
  37088. } else {
  37089. this._emitChars("</");
  37090. this.state = State.RCDATA;
  37091. this._stateRcdata(cp);
  37092. }
  37093. }
  37094. handleSpecialEndTag(_cp) {
  37095. if (!this.preprocessor.startsWith(this.lastStartTagName, false)) {
  37096. return !this._ensureHibernation();
  37097. }
  37098. this._createEndTagToken();
  37099. const token = this.currentToken;
  37100. token.tagName = this.lastStartTagName;
  37101. const cp = this.preprocessor.peek(this.lastStartTagName.length);
  37102. switch (cp) {
  37103. case CODE_POINTS.SPACE:
  37104. case CODE_POINTS.LINE_FEED:
  37105. case CODE_POINTS.TABULATION:
  37106. case CODE_POINTS.FORM_FEED: {
  37107. this._advanceBy(this.lastStartTagName.length);
  37108. this.state = State.BEFORE_ATTRIBUTE_NAME;
  37109. return false;
  37110. }
  37111. case CODE_POINTS.SOLIDUS: {
  37112. this._advanceBy(this.lastStartTagName.length);
  37113. this.state = State.SELF_CLOSING_START_TAG;
  37114. return false;
  37115. }
  37116. case CODE_POINTS.GREATER_THAN_SIGN: {
  37117. this._advanceBy(this.lastStartTagName.length);
  37118. this.emitCurrentTagToken();
  37119. this.state = State.DATA;
  37120. return false;
  37121. }
  37122. default: {
  37123. return !this._ensureHibernation();
  37124. }
  37125. }
  37126. }
  37127. // RCDATA end tag name state
  37128. //------------------------------------------------------------------
  37129. _stateRcdataEndTagName(cp) {
  37130. if (this.handleSpecialEndTag(cp)) {
  37131. this._emitChars("</");
  37132. this.state = State.RCDATA;
  37133. this._stateRcdata(cp);
  37134. }
  37135. }
  37136. // RAWTEXT less-than sign state
  37137. //------------------------------------------------------------------
  37138. _stateRawtextLessThanSign(cp) {
  37139. if (cp === CODE_POINTS.SOLIDUS) {
  37140. this.state = State.RAWTEXT_END_TAG_OPEN;
  37141. } else {
  37142. this._emitChars("<");
  37143. this.state = State.RAWTEXT;
  37144. this._stateRawtext(cp);
  37145. }
  37146. }
  37147. // RAWTEXT end tag open state
  37148. //------------------------------------------------------------------
  37149. _stateRawtextEndTagOpen(cp) {
  37150. if (isAsciiLetter(cp)) {
  37151. this.state = State.RAWTEXT_END_TAG_NAME;
  37152. this._stateRawtextEndTagName(cp);
  37153. } else {
  37154. this._emitChars("</");
  37155. this.state = State.RAWTEXT;
  37156. this._stateRawtext(cp);
  37157. }
  37158. }
  37159. // RAWTEXT end tag name state
  37160. //------------------------------------------------------------------
  37161. _stateRawtextEndTagName(cp) {
  37162. if (this.handleSpecialEndTag(cp)) {
  37163. this._emitChars("</");
  37164. this.state = State.RAWTEXT;
  37165. this._stateRawtext(cp);
  37166. }
  37167. }
  37168. // Script data less-than sign state
  37169. //------------------------------------------------------------------
  37170. _stateScriptDataLessThanSign(cp) {
  37171. switch (cp) {
  37172. case CODE_POINTS.SOLIDUS: {
  37173. this.state = State.SCRIPT_DATA_END_TAG_OPEN;
  37174. break;
  37175. }
  37176. case CODE_POINTS.EXCLAMATION_MARK: {
  37177. this.state = State.SCRIPT_DATA_ESCAPE_START;
  37178. this._emitChars("<!");
  37179. break;
  37180. }
  37181. default: {
  37182. this._emitChars("<");
  37183. this.state = State.SCRIPT_DATA;
  37184. this._stateScriptData(cp);
  37185. }
  37186. }
  37187. }
  37188. // Script data end tag open state
  37189. //------------------------------------------------------------------
  37190. _stateScriptDataEndTagOpen(cp) {
  37191. if (isAsciiLetter(cp)) {
  37192. this.state = State.SCRIPT_DATA_END_TAG_NAME;
  37193. this._stateScriptDataEndTagName(cp);
  37194. } else {
  37195. this._emitChars("</");
  37196. this.state = State.SCRIPT_DATA;
  37197. this._stateScriptData(cp);
  37198. }
  37199. }
  37200. // Script data end tag name state
  37201. //------------------------------------------------------------------
  37202. _stateScriptDataEndTagName(cp) {
  37203. if (this.handleSpecialEndTag(cp)) {
  37204. this._emitChars("</");
  37205. this.state = State.SCRIPT_DATA;
  37206. this._stateScriptData(cp);
  37207. }
  37208. }
  37209. // Script data escape start state
  37210. //------------------------------------------------------------------
  37211. _stateScriptDataEscapeStart(cp) {
  37212. if (cp === CODE_POINTS.HYPHEN_MINUS) {
  37213. this.state = State.SCRIPT_DATA_ESCAPE_START_DASH;
  37214. this._emitChars("-");
  37215. } else {
  37216. this.state = State.SCRIPT_DATA;
  37217. this._stateScriptData(cp);
  37218. }
  37219. }
  37220. // Script data escape start dash state
  37221. //------------------------------------------------------------------
  37222. _stateScriptDataEscapeStartDash(cp) {
  37223. if (cp === CODE_POINTS.HYPHEN_MINUS) {
  37224. this.state = State.SCRIPT_DATA_ESCAPED_DASH_DASH;
  37225. this._emitChars("-");
  37226. } else {
  37227. this.state = State.SCRIPT_DATA;
  37228. this._stateScriptData(cp);
  37229. }
  37230. }
  37231. // Script data escaped state
  37232. //------------------------------------------------------------------
  37233. _stateScriptDataEscaped(cp) {
  37234. switch (cp) {
  37235. case CODE_POINTS.HYPHEN_MINUS: {
  37236. this.state = State.SCRIPT_DATA_ESCAPED_DASH;
  37237. this._emitChars("-");
  37238. break;
  37239. }
  37240. case CODE_POINTS.LESS_THAN_SIGN: {
  37241. this.state = State.SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN;
  37242. break;
  37243. }
  37244. case CODE_POINTS.NULL: {
  37245. this._err(ERR.unexpectedNullCharacter);
  37246. this._emitChars(REPLACEMENT_CHARACTER);
  37247. break;
  37248. }
  37249. case CODE_POINTS.EOF: {
  37250. this._err(ERR.eofInScriptHtmlCommentLikeText);
  37251. this._emitEOFToken();
  37252. break;
  37253. }
  37254. default: {
  37255. this._emitCodePoint(cp);
  37256. }
  37257. }
  37258. }
  37259. // Script data escaped dash state
  37260. //------------------------------------------------------------------
  37261. _stateScriptDataEscapedDash(cp) {
  37262. switch (cp) {
  37263. case CODE_POINTS.HYPHEN_MINUS: {
  37264. this.state = State.SCRIPT_DATA_ESCAPED_DASH_DASH;
  37265. this._emitChars("-");
  37266. break;
  37267. }
  37268. case CODE_POINTS.LESS_THAN_SIGN: {
  37269. this.state = State.SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN;
  37270. break;
  37271. }
  37272. case CODE_POINTS.NULL: {
  37273. this._err(ERR.unexpectedNullCharacter);
  37274. this.state = State.SCRIPT_DATA_ESCAPED;
  37275. this._emitChars(REPLACEMENT_CHARACTER);
  37276. break;
  37277. }
  37278. case CODE_POINTS.EOF: {
  37279. this._err(ERR.eofInScriptHtmlCommentLikeText);
  37280. this._emitEOFToken();
  37281. break;
  37282. }
  37283. default: {
  37284. this.state = State.SCRIPT_DATA_ESCAPED;
  37285. this._emitCodePoint(cp);
  37286. }
  37287. }
  37288. }
  37289. // Script data escaped dash dash state
  37290. //------------------------------------------------------------------
  37291. _stateScriptDataEscapedDashDash(cp) {
  37292. switch (cp) {
  37293. case CODE_POINTS.HYPHEN_MINUS: {
  37294. this._emitChars("-");
  37295. break;
  37296. }
  37297. case CODE_POINTS.LESS_THAN_SIGN: {
  37298. this.state = State.SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN;
  37299. break;
  37300. }
  37301. case CODE_POINTS.GREATER_THAN_SIGN: {
  37302. this.state = State.SCRIPT_DATA;
  37303. this._emitChars(">");
  37304. break;
  37305. }
  37306. case CODE_POINTS.NULL: {
  37307. this._err(ERR.unexpectedNullCharacter);
  37308. this.state = State.SCRIPT_DATA_ESCAPED;
  37309. this._emitChars(REPLACEMENT_CHARACTER);
  37310. break;
  37311. }
  37312. case CODE_POINTS.EOF: {
  37313. this._err(ERR.eofInScriptHtmlCommentLikeText);
  37314. this._emitEOFToken();
  37315. break;
  37316. }
  37317. default: {
  37318. this.state = State.SCRIPT_DATA_ESCAPED;
  37319. this._emitCodePoint(cp);
  37320. }
  37321. }
  37322. }
  37323. // Script data escaped less-than sign state
  37324. //------------------------------------------------------------------
  37325. _stateScriptDataEscapedLessThanSign(cp) {
  37326. if (cp === CODE_POINTS.SOLIDUS) {
  37327. this.state = State.SCRIPT_DATA_ESCAPED_END_TAG_OPEN;
  37328. } else if (isAsciiLetter(cp)) {
  37329. this._emitChars("<");
  37330. this.state = State.SCRIPT_DATA_DOUBLE_ESCAPE_START;
  37331. this._stateScriptDataDoubleEscapeStart(cp);
  37332. } else {
  37333. this._emitChars("<");
  37334. this.state = State.SCRIPT_DATA_ESCAPED;
  37335. this._stateScriptDataEscaped(cp);
  37336. }
  37337. }
  37338. // Script data escaped end tag open state
  37339. //------------------------------------------------------------------
  37340. _stateScriptDataEscapedEndTagOpen(cp) {
  37341. if (isAsciiLetter(cp)) {
  37342. this.state = State.SCRIPT_DATA_ESCAPED_END_TAG_NAME;
  37343. this._stateScriptDataEscapedEndTagName(cp);
  37344. } else {
  37345. this._emitChars("</");
  37346. this.state = State.SCRIPT_DATA_ESCAPED;
  37347. this._stateScriptDataEscaped(cp);
  37348. }
  37349. }
  37350. // Script data escaped end tag name state
  37351. //------------------------------------------------------------------
  37352. _stateScriptDataEscapedEndTagName(cp) {
  37353. if (this.handleSpecialEndTag(cp)) {
  37354. this._emitChars("</");
  37355. this.state = State.SCRIPT_DATA_ESCAPED;
  37356. this._stateScriptDataEscaped(cp);
  37357. }
  37358. }
  37359. // Script data double escape start state
  37360. //------------------------------------------------------------------
  37361. _stateScriptDataDoubleEscapeStart(cp) {
  37362. if (this.preprocessor.startsWith(SEQUENCES.SCRIPT, false) && isScriptDataDoubleEscapeSequenceEnd(this.preprocessor.peek(SEQUENCES.SCRIPT.length))) {
  37363. this._emitCodePoint(cp);
  37364. for (let i = 0; i < SEQUENCES.SCRIPT.length; i++) {
  37365. this._emitCodePoint(this._consume());
  37366. }
  37367. this.state = State.SCRIPT_DATA_DOUBLE_ESCAPED;
  37368. } else if (!this._ensureHibernation()) {
  37369. this.state = State.SCRIPT_DATA_ESCAPED;
  37370. this._stateScriptDataEscaped(cp);
  37371. }
  37372. }
  37373. // Script data double escaped state
  37374. //------------------------------------------------------------------
  37375. _stateScriptDataDoubleEscaped(cp) {
  37376. switch (cp) {
  37377. case CODE_POINTS.HYPHEN_MINUS: {
  37378. this.state = State.SCRIPT_DATA_DOUBLE_ESCAPED_DASH;
  37379. this._emitChars("-");
  37380. break;
  37381. }
  37382. case CODE_POINTS.LESS_THAN_SIGN: {
  37383. this.state = State.SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN;
  37384. this._emitChars("<");
  37385. break;
  37386. }
  37387. case CODE_POINTS.NULL: {
  37388. this._err(ERR.unexpectedNullCharacter);
  37389. this._emitChars(REPLACEMENT_CHARACTER);
  37390. break;
  37391. }
  37392. case CODE_POINTS.EOF: {
  37393. this._err(ERR.eofInScriptHtmlCommentLikeText);
  37394. this._emitEOFToken();
  37395. break;
  37396. }
  37397. default: {
  37398. this._emitCodePoint(cp);
  37399. }
  37400. }
  37401. }
  37402. // Script data double escaped dash state
  37403. //------------------------------------------------------------------
  37404. _stateScriptDataDoubleEscapedDash(cp) {
  37405. switch (cp) {
  37406. case CODE_POINTS.HYPHEN_MINUS: {
  37407. this.state = State.SCRIPT_DATA_DOUBLE_ESCAPED_DASH_DASH;
  37408. this._emitChars("-");
  37409. break;
  37410. }
  37411. case CODE_POINTS.LESS_THAN_SIGN: {
  37412. this.state = State.SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN;
  37413. this._emitChars("<");
  37414. break;
  37415. }
  37416. case CODE_POINTS.NULL: {
  37417. this._err(ERR.unexpectedNullCharacter);
  37418. this.state = State.SCRIPT_DATA_DOUBLE_ESCAPED;
  37419. this._emitChars(REPLACEMENT_CHARACTER);
  37420. break;
  37421. }
  37422. case CODE_POINTS.EOF: {
  37423. this._err(ERR.eofInScriptHtmlCommentLikeText);
  37424. this._emitEOFToken();
  37425. break;
  37426. }
  37427. default: {
  37428. this.state = State.SCRIPT_DATA_DOUBLE_ESCAPED;
  37429. this._emitCodePoint(cp);
  37430. }
  37431. }
  37432. }
  37433. // Script data double escaped dash dash state
  37434. //------------------------------------------------------------------
  37435. _stateScriptDataDoubleEscapedDashDash(cp) {
  37436. switch (cp) {
  37437. case CODE_POINTS.HYPHEN_MINUS: {
  37438. this._emitChars("-");
  37439. break;
  37440. }
  37441. case CODE_POINTS.LESS_THAN_SIGN: {
  37442. this.state = State.SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN;
  37443. this._emitChars("<");
  37444. break;
  37445. }
  37446. case CODE_POINTS.GREATER_THAN_SIGN: {
  37447. this.state = State.SCRIPT_DATA;
  37448. this._emitChars(">");
  37449. break;
  37450. }
  37451. case CODE_POINTS.NULL: {
  37452. this._err(ERR.unexpectedNullCharacter);
  37453. this.state = State.SCRIPT_DATA_DOUBLE_ESCAPED;
  37454. this._emitChars(REPLACEMENT_CHARACTER);
  37455. break;
  37456. }
  37457. case CODE_POINTS.EOF: {
  37458. this._err(ERR.eofInScriptHtmlCommentLikeText);
  37459. this._emitEOFToken();
  37460. break;
  37461. }
  37462. default: {
  37463. this.state = State.SCRIPT_DATA_DOUBLE_ESCAPED;
  37464. this._emitCodePoint(cp);
  37465. }
  37466. }
  37467. }
  37468. // Script data double escaped less-than sign state
  37469. //------------------------------------------------------------------
  37470. _stateScriptDataDoubleEscapedLessThanSign(cp) {
  37471. if (cp === CODE_POINTS.SOLIDUS) {
  37472. this.state = State.SCRIPT_DATA_DOUBLE_ESCAPE_END;
  37473. this._emitChars("/");
  37474. } else {
  37475. this.state = State.SCRIPT_DATA_DOUBLE_ESCAPED;
  37476. this._stateScriptDataDoubleEscaped(cp);
  37477. }
  37478. }
  37479. // Script data double escape end state
  37480. //------------------------------------------------------------------
  37481. _stateScriptDataDoubleEscapeEnd(cp) {
  37482. if (this.preprocessor.startsWith(SEQUENCES.SCRIPT, false) && isScriptDataDoubleEscapeSequenceEnd(this.preprocessor.peek(SEQUENCES.SCRIPT.length))) {
  37483. this._emitCodePoint(cp);
  37484. for (let i = 0; i < SEQUENCES.SCRIPT.length; i++) {
  37485. this._emitCodePoint(this._consume());
  37486. }
  37487. this.state = State.SCRIPT_DATA_ESCAPED;
  37488. } else if (!this._ensureHibernation()) {
  37489. this.state = State.SCRIPT_DATA_DOUBLE_ESCAPED;
  37490. this._stateScriptDataDoubleEscaped(cp);
  37491. }
  37492. }
  37493. // Before attribute name state
  37494. //------------------------------------------------------------------
  37495. _stateBeforeAttributeName(cp) {
  37496. switch (cp) {
  37497. case CODE_POINTS.SPACE:
  37498. case CODE_POINTS.LINE_FEED:
  37499. case CODE_POINTS.TABULATION:
  37500. case CODE_POINTS.FORM_FEED: {
  37501. break;
  37502. }
  37503. case CODE_POINTS.SOLIDUS:
  37504. case CODE_POINTS.GREATER_THAN_SIGN:
  37505. case CODE_POINTS.EOF: {
  37506. this.state = State.AFTER_ATTRIBUTE_NAME;
  37507. this._stateAfterAttributeName(cp);
  37508. break;
  37509. }
  37510. case CODE_POINTS.EQUALS_SIGN: {
  37511. this._err(ERR.unexpectedEqualsSignBeforeAttributeName);
  37512. this._createAttr("=");
  37513. this.state = State.ATTRIBUTE_NAME;
  37514. break;
  37515. }
  37516. default: {
  37517. this._createAttr("");
  37518. this.state = State.ATTRIBUTE_NAME;
  37519. this._stateAttributeName(cp);
  37520. }
  37521. }
  37522. }
  37523. // Attribute name state
  37524. //------------------------------------------------------------------
  37525. _stateAttributeName(cp) {
  37526. switch (cp) {
  37527. case CODE_POINTS.SPACE:
  37528. case CODE_POINTS.LINE_FEED:
  37529. case CODE_POINTS.TABULATION:
  37530. case CODE_POINTS.FORM_FEED:
  37531. case CODE_POINTS.SOLIDUS:
  37532. case CODE_POINTS.GREATER_THAN_SIGN:
  37533. case CODE_POINTS.EOF: {
  37534. this._leaveAttrName();
  37535. this.state = State.AFTER_ATTRIBUTE_NAME;
  37536. this._stateAfterAttributeName(cp);
  37537. break;
  37538. }
  37539. case CODE_POINTS.EQUALS_SIGN: {
  37540. this._leaveAttrName();
  37541. this.state = State.BEFORE_ATTRIBUTE_VALUE;
  37542. break;
  37543. }
  37544. case CODE_POINTS.QUOTATION_MARK:
  37545. case CODE_POINTS.APOSTROPHE:
  37546. case CODE_POINTS.LESS_THAN_SIGN: {
  37547. this._err(ERR.unexpectedCharacterInAttributeName);
  37548. this.currentAttr.name += String.fromCodePoint(cp);
  37549. break;
  37550. }
  37551. case CODE_POINTS.NULL: {
  37552. this._err(ERR.unexpectedNullCharacter);
  37553. this.currentAttr.name += REPLACEMENT_CHARACTER;
  37554. break;
  37555. }
  37556. default: {
  37557. this.currentAttr.name += String.fromCodePoint(isAsciiUpper(cp) ? toAsciiLower(cp) : cp);
  37558. }
  37559. }
  37560. }
  37561. // After attribute name state
  37562. //------------------------------------------------------------------
  37563. _stateAfterAttributeName(cp) {
  37564. switch (cp) {
  37565. case CODE_POINTS.SPACE:
  37566. case CODE_POINTS.LINE_FEED:
  37567. case CODE_POINTS.TABULATION:
  37568. case CODE_POINTS.FORM_FEED: {
  37569. break;
  37570. }
  37571. case CODE_POINTS.SOLIDUS: {
  37572. this.state = State.SELF_CLOSING_START_TAG;
  37573. break;
  37574. }
  37575. case CODE_POINTS.EQUALS_SIGN: {
  37576. this.state = State.BEFORE_ATTRIBUTE_VALUE;
  37577. break;
  37578. }
  37579. case CODE_POINTS.GREATER_THAN_SIGN: {
  37580. this.state = State.DATA;
  37581. this.emitCurrentTagToken();
  37582. break;
  37583. }
  37584. case CODE_POINTS.EOF: {
  37585. this._err(ERR.eofInTag);
  37586. this._emitEOFToken();
  37587. break;
  37588. }
  37589. default: {
  37590. this._createAttr("");
  37591. this.state = State.ATTRIBUTE_NAME;
  37592. this._stateAttributeName(cp);
  37593. }
  37594. }
  37595. }
  37596. // Before attribute value state
  37597. //------------------------------------------------------------------
  37598. _stateBeforeAttributeValue(cp) {
  37599. switch (cp) {
  37600. case CODE_POINTS.SPACE:
  37601. case CODE_POINTS.LINE_FEED:
  37602. case CODE_POINTS.TABULATION:
  37603. case CODE_POINTS.FORM_FEED: {
  37604. break;
  37605. }
  37606. case CODE_POINTS.QUOTATION_MARK: {
  37607. this.state = State.ATTRIBUTE_VALUE_DOUBLE_QUOTED;
  37608. break;
  37609. }
  37610. case CODE_POINTS.APOSTROPHE: {
  37611. this.state = State.ATTRIBUTE_VALUE_SINGLE_QUOTED;
  37612. break;
  37613. }
  37614. case CODE_POINTS.GREATER_THAN_SIGN: {
  37615. this._err(ERR.missingAttributeValue);
  37616. this.state = State.DATA;
  37617. this.emitCurrentTagToken();
  37618. break;
  37619. }
  37620. default: {
  37621. this.state = State.ATTRIBUTE_VALUE_UNQUOTED;
  37622. this._stateAttributeValueUnquoted(cp);
  37623. }
  37624. }
  37625. }
  37626. // Attribute value (double-quoted) state
  37627. //------------------------------------------------------------------
  37628. _stateAttributeValueDoubleQuoted(cp) {
  37629. switch (cp) {
  37630. case CODE_POINTS.QUOTATION_MARK: {
  37631. this.state = State.AFTER_ATTRIBUTE_VALUE_QUOTED;
  37632. break;
  37633. }
  37634. case CODE_POINTS.AMPERSAND: {
  37635. this.returnState = State.ATTRIBUTE_VALUE_DOUBLE_QUOTED;
  37636. this.state = State.CHARACTER_REFERENCE;
  37637. break;
  37638. }
  37639. case CODE_POINTS.NULL: {
  37640. this._err(ERR.unexpectedNullCharacter);
  37641. this.currentAttr.value += REPLACEMENT_CHARACTER;
  37642. break;
  37643. }
  37644. case CODE_POINTS.EOF: {
  37645. this._err(ERR.eofInTag);
  37646. this._emitEOFToken();
  37647. break;
  37648. }
  37649. default: {
  37650. this.currentAttr.value += String.fromCodePoint(cp);
  37651. }
  37652. }
  37653. }
  37654. // Attribute value (single-quoted) state
  37655. //------------------------------------------------------------------
  37656. _stateAttributeValueSingleQuoted(cp) {
  37657. switch (cp) {
  37658. case CODE_POINTS.APOSTROPHE: {
  37659. this.state = State.AFTER_ATTRIBUTE_VALUE_QUOTED;
  37660. break;
  37661. }
  37662. case CODE_POINTS.AMPERSAND: {
  37663. this.returnState = State.ATTRIBUTE_VALUE_SINGLE_QUOTED;
  37664. this.state = State.CHARACTER_REFERENCE;
  37665. break;
  37666. }
  37667. case CODE_POINTS.NULL: {
  37668. this._err(ERR.unexpectedNullCharacter);
  37669. this.currentAttr.value += REPLACEMENT_CHARACTER;
  37670. break;
  37671. }
  37672. case CODE_POINTS.EOF: {
  37673. this._err(ERR.eofInTag);
  37674. this._emitEOFToken();
  37675. break;
  37676. }
  37677. default: {
  37678. this.currentAttr.value += String.fromCodePoint(cp);
  37679. }
  37680. }
  37681. }
  37682. // Attribute value (unquoted) state
  37683. //------------------------------------------------------------------
  37684. _stateAttributeValueUnquoted(cp) {
  37685. switch (cp) {
  37686. case CODE_POINTS.SPACE:
  37687. case CODE_POINTS.LINE_FEED:
  37688. case CODE_POINTS.TABULATION:
  37689. case CODE_POINTS.FORM_FEED: {
  37690. this._leaveAttrValue();
  37691. this.state = State.BEFORE_ATTRIBUTE_NAME;
  37692. break;
  37693. }
  37694. case CODE_POINTS.AMPERSAND: {
  37695. this.returnState = State.ATTRIBUTE_VALUE_UNQUOTED;
  37696. this.state = State.CHARACTER_REFERENCE;
  37697. break;
  37698. }
  37699. case CODE_POINTS.GREATER_THAN_SIGN: {
  37700. this._leaveAttrValue();
  37701. this.state = State.DATA;
  37702. this.emitCurrentTagToken();
  37703. break;
  37704. }
  37705. case CODE_POINTS.NULL: {
  37706. this._err(ERR.unexpectedNullCharacter);
  37707. this.currentAttr.value += REPLACEMENT_CHARACTER;
  37708. break;
  37709. }
  37710. case CODE_POINTS.QUOTATION_MARK:
  37711. case CODE_POINTS.APOSTROPHE:
  37712. case CODE_POINTS.LESS_THAN_SIGN:
  37713. case CODE_POINTS.EQUALS_SIGN:
  37714. case CODE_POINTS.GRAVE_ACCENT: {
  37715. this._err(ERR.unexpectedCharacterInUnquotedAttributeValue);
  37716. this.currentAttr.value += String.fromCodePoint(cp);
  37717. break;
  37718. }
  37719. case CODE_POINTS.EOF: {
  37720. this._err(ERR.eofInTag);
  37721. this._emitEOFToken();
  37722. break;
  37723. }
  37724. default: {
  37725. this.currentAttr.value += String.fromCodePoint(cp);
  37726. }
  37727. }
  37728. }
  37729. // After attribute value (quoted) state
  37730. //------------------------------------------------------------------
  37731. _stateAfterAttributeValueQuoted(cp) {
  37732. switch (cp) {
  37733. case CODE_POINTS.SPACE:
  37734. case CODE_POINTS.LINE_FEED:
  37735. case CODE_POINTS.TABULATION:
  37736. case CODE_POINTS.FORM_FEED: {
  37737. this._leaveAttrValue();
  37738. this.state = State.BEFORE_ATTRIBUTE_NAME;
  37739. break;
  37740. }
  37741. case CODE_POINTS.SOLIDUS: {
  37742. this._leaveAttrValue();
  37743. this.state = State.SELF_CLOSING_START_TAG;
  37744. break;
  37745. }
  37746. case CODE_POINTS.GREATER_THAN_SIGN: {
  37747. this._leaveAttrValue();
  37748. this.state = State.DATA;
  37749. this.emitCurrentTagToken();
  37750. break;
  37751. }
  37752. case CODE_POINTS.EOF: {
  37753. this._err(ERR.eofInTag);
  37754. this._emitEOFToken();
  37755. break;
  37756. }
  37757. default: {
  37758. this._err(ERR.missingWhitespaceBetweenAttributes);
  37759. this.state = State.BEFORE_ATTRIBUTE_NAME;
  37760. this._stateBeforeAttributeName(cp);
  37761. }
  37762. }
  37763. }
  37764. // Self-closing start tag state
  37765. //------------------------------------------------------------------
  37766. _stateSelfClosingStartTag(cp) {
  37767. switch (cp) {
  37768. case CODE_POINTS.GREATER_THAN_SIGN: {
  37769. const token = this.currentToken;
  37770. token.selfClosing = true;
  37771. this.state = State.DATA;
  37772. this.emitCurrentTagToken();
  37773. break;
  37774. }
  37775. case CODE_POINTS.EOF: {
  37776. this._err(ERR.eofInTag);
  37777. this._emitEOFToken();
  37778. break;
  37779. }
  37780. default: {
  37781. this._err(ERR.unexpectedSolidusInTag);
  37782. this.state = State.BEFORE_ATTRIBUTE_NAME;
  37783. this._stateBeforeAttributeName(cp);
  37784. }
  37785. }
  37786. }
  37787. // Bogus comment state
  37788. //------------------------------------------------------------------
  37789. _stateBogusComment(cp) {
  37790. const token = this.currentToken;
  37791. switch (cp) {
  37792. case CODE_POINTS.GREATER_THAN_SIGN: {
  37793. this.state = State.DATA;
  37794. this.emitCurrentComment(token);
  37795. break;
  37796. }
  37797. case CODE_POINTS.EOF: {
  37798. this.emitCurrentComment(token);
  37799. this._emitEOFToken();
  37800. break;
  37801. }
  37802. case CODE_POINTS.NULL: {
  37803. this._err(ERR.unexpectedNullCharacter);
  37804. token.data += REPLACEMENT_CHARACTER;
  37805. break;
  37806. }
  37807. default: {
  37808. token.data += String.fromCodePoint(cp);
  37809. }
  37810. }
  37811. }
  37812. // Markup declaration open state
  37813. //------------------------------------------------------------------
  37814. _stateMarkupDeclarationOpen(cp) {
  37815. if (this._consumeSequenceIfMatch(SEQUENCES.DASH_DASH, true)) {
  37816. this._createCommentToken(SEQUENCES.DASH_DASH.length + 1);
  37817. this.state = State.COMMENT_START;
  37818. } else if (this._consumeSequenceIfMatch(SEQUENCES.DOCTYPE, false)) {
  37819. this.currentLocation = this.getCurrentLocation(SEQUENCES.DOCTYPE.length + 1);
  37820. this.state = State.DOCTYPE;
  37821. } else if (this._consumeSequenceIfMatch(SEQUENCES.CDATA_START, true)) {
  37822. if (this.inForeignNode) {
  37823. this.state = State.CDATA_SECTION;
  37824. } else {
  37825. this._err(ERR.cdataInHtmlContent);
  37826. this._createCommentToken(SEQUENCES.CDATA_START.length + 1);
  37827. this.currentToken.data = "[CDATA[";
  37828. this.state = State.BOGUS_COMMENT;
  37829. }
  37830. } else if (!this._ensureHibernation()) {
  37831. this._err(ERR.incorrectlyOpenedComment);
  37832. this._createCommentToken(2);
  37833. this.state = State.BOGUS_COMMENT;
  37834. this._stateBogusComment(cp);
  37835. }
  37836. }
  37837. // Comment start state
  37838. //------------------------------------------------------------------
  37839. _stateCommentStart(cp) {
  37840. switch (cp) {
  37841. case CODE_POINTS.HYPHEN_MINUS: {
  37842. this.state = State.COMMENT_START_DASH;
  37843. break;
  37844. }
  37845. case CODE_POINTS.GREATER_THAN_SIGN: {
  37846. this._err(ERR.abruptClosingOfEmptyComment);
  37847. this.state = State.DATA;
  37848. const token = this.currentToken;
  37849. this.emitCurrentComment(token);
  37850. break;
  37851. }
  37852. default: {
  37853. this.state = State.COMMENT;
  37854. this._stateComment(cp);
  37855. }
  37856. }
  37857. }
  37858. // Comment start dash state
  37859. //------------------------------------------------------------------
  37860. _stateCommentStartDash(cp) {
  37861. const token = this.currentToken;
  37862. switch (cp) {
  37863. case CODE_POINTS.HYPHEN_MINUS: {
  37864. this.state = State.COMMENT_END;
  37865. break;
  37866. }
  37867. case CODE_POINTS.GREATER_THAN_SIGN: {
  37868. this._err(ERR.abruptClosingOfEmptyComment);
  37869. this.state = State.DATA;
  37870. this.emitCurrentComment(token);
  37871. break;
  37872. }
  37873. case CODE_POINTS.EOF: {
  37874. this._err(ERR.eofInComment);
  37875. this.emitCurrentComment(token);
  37876. this._emitEOFToken();
  37877. break;
  37878. }
  37879. default: {
  37880. token.data += "-";
  37881. this.state = State.COMMENT;
  37882. this._stateComment(cp);
  37883. }
  37884. }
  37885. }
  37886. // Comment state
  37887. //------------------------------------------------------------------
  37888. _stateComment(cp) {
  37889. const token = this.currentToken;
  37890. switch (cp) {
  37891. case CODE_POINTS.HYPHEN_MINUS: {
  37892. this.state = State.COMMENT_END_DASH;
  37893. break;
  37894. }
  37895. case CODE_POINTS.LESS_THAN_SIGN: {
  37896. token.data += "<";
  37897. this.state = State.COMMENT_LESS_THAN_SIGN;
  37898. break;
  37899. }
  37900. case CODE_POINTS.NULL: {
  37901. this._err(ERR.unexpectedNullCharacter);
  37902. token.data += REPLACEMENT_CHARACTER;
  37903. break;
  37904. }
  37905. case CODE_POINTS.EOF: {
  37906. this._err(ERR.eofInComment);
  37907. this.emitCurrentComment(token);
  37908. this._emitEOFToken();
  37909. break;
  37910. }
  37911. default: {
  37912. token.data += String.fromCodePoint(cp);
  37913. }
  37914. }
  37915. }
  37916. // Comment less-than sign state
  37917. //------------------------------------------------------------------
  37918. _stateCommentLessThanSign(cp) {
  37919. const token = this.currentToken;
  37920. switch (cp) {
  37921. case CODE_POINTS.EXCLAMATION_MARK: {
  37922. token.data += "!";
  37923. this.state = State.COMMENT_LESS_THAN_SIGN_BANG;
  37924. break;
  37925. }
  37926. case CODE_POINTS.LESS_THAN_SIGN: {
  37927. token.data += "<";
  37928. break;
  37929. }
  37930. default: {
  37931. this.state = State.COMMENT;
  37932. this._stateComment(cp);
  37933. }
  37934. }
  37935. }
  37936. // Comment less-than sign bang state
  37937. //------------------------------------------------------------------
  37938. _stateCommentLessThanSignBang(cp) {
  37939. if (cp === CODE_POINTS.HYPHEN_MINUS) {
  37940. this.state = State.COMMENT_LESS_THAN_SIGN_BANG_DASH;
  37941. } else {
  37942. this.state = State.COMMENT;
  37943. this._stateComment(cp);
  37944. }
  37945. }
  37946. // Comment less-than sign bang dash state
  37947. //------------------------------------------------------------------
  37948. _stateCommentLessThanSignBangDash(cp) {
  37949. if (cp === CODE_POINTS.HYPHEN_MINUS) {
  37950. this.state = State.COMMENT_LESS_THAN_SIGN_BANG_DASH_DASH;
  37951. } else {
  37952. this.state = State.COMMENT_END_DASH;
  37953. this._stateCommentEndDash(cp);
  37954. }
  37955. }
  37956. // Comment less-than sign bang dash dash state
  37957. //------------------------------------------------------------------
  37958. _stateCommentLessThanSignBangDashDash(cp) {
  37959. if (cp !== CODE_POINTS.GREATER_THAN_SIGN && cp !== CODE_POINTS.EOF) {
  37960. this._err(ERR.nestedComment);
  37961. }
  37962. this.state = State.COMMENT_END;
  37963. this._stateCommentEnd(cp);
  37964. }
  37965. // Comment end dash state
  37966. //------------------------------------------------------------------
  37967. _stateCommentEndDash(cp) {
  37968. const token = this.currentToken;
  37969. switch (cp) {
  37970. case CODE_POINTS.HYPHEN_MINUS: {
  37971. this.state = State.COMMENT_END;
  37972. break;
  37973. }
  37974. case CODE_POINTS.EOF: {
  37975. this._err(ERR.eofInComment);
  37976. this.emitCurrentComment(token);
  37977. this._emitEOFToken();
  37978. break;
  37979. }
  37980. default: {
  37981. token.data += "-";
  37982. this.state = State.COMMENT;
  37983. this._stateComment(cp);
  37984. }
  37985. }
  37986. }
  37987. // Comment end state
  37988. //------------------------------------------------------------------
  37989. _stateCommentEnd(cp) {
  37990. const token = this.currentToken;
  37991. switch (cp) {
  37992. case CODE_POINTS.GREATER_THAN_SIGN: {
  37993. this.state = State.DATA;
  37994. this.emitCurrentComment(token);
  37995. break;
  37996. }
  37997. case CODE_POINTS.EXCLAMATION_MARK: {
  37998. this.state = State.COMMENT_END_BANG;
  37999. break;
  38000. }
  38001. case CODE_POINTS.HYPHEN_MINUS: {
  38002. token.data += "-";
  38003. break;
  38004. }
  38005. case CODE_POINTS.EOF: {
  38006. this._err(ERR.eofInComment);
  38007. this.emitCurrentComment(token);
  38008. this._emitEOFToken();
  38009. break;
  38010. }
  38011. default: {
  38012. token.data += "--";
  38013. this.state = State.COMMENT;
  38014. this._stateComment(cp);
  38015. }
  38016. }
  38017. }
  38018. // Comment end bang state
  38019. //------------------------------------------------------------------
  38020. _stateCommentEndBang(cp) {
  38021. const token = this.currentToken;
  38022. switch (cp) {
  38023. case CODE_POINTS.HYPHEN_MINUS: {
  38024. token.data += "--!";
  38025. this.state = State.COMMENT_END_DASH;
  38026. break;
  38027. }
  38028. case CODE_POINTS.GREATER_THAN_SIGN: {
  38029. this._err(ERR.incorrectlyClosedComment);
  38030. this.state = State.DATA;
  38031. this.emitCurrentComment(token);
  38032. break;
  38033. }
  38034. case CODE_POINTS.EOF: {
  38035. this._err(ERR.eofInComment);
  38036. this.emitCurrentComment(token);
  38037. this._emitEOFToken();
  38038. break;
  38039. }
  38040. default: {
  38041. token.data += "--!";
  38042. this.state = State.COMMENT;
  38043. this._stateComment(cp);
  38044. }
  38045. }
  38046. }
  38047. // DOCTYPE state
  38048. //------------------------------------------------------------------
  38049. _stateDoctype(cp) {
  38050. switch (cp) {
  38051. case CODE_POINTS.SPACE:
  38052. case CODE_POINTS.LINE_FEED:
  38053. case CODE_POINTS.TABULATION:
  38054. case CODE_POINTS.FORM_FEED: {
  38055. this.state = State.BEFORE_DOCTYPE_NAME;
  38056. break;
  38057. }
  38058. case CODE_POINTS.GREATER_THAN_SIGN: {
  38059. this.state = State.BEFORE_DOCTYPE_NAME;
  38060. this._stateBeforeDoctypeName(cp);
  38061. break;
  38062. }
  38063. case CODE_POINTS.EOF: {
  38064. this._err(ERR.eofInDoctype);
  38065. this._createDoctypeToken(null);
  38066. const token = this.currentToken;
  38067. token.forceQuirks = true;
  38068. this.emitCurrentDoctype(token);
  38069. this._emitEOFToken();
  38070. break;
  38071. }
  38072. default: {
  38073. this._err(ERR.missingWhitespaceBeforeDoctypeName);
  38074. this.state = State.BEFORE_DOCTYPE_NAME;
  38075. this._stateBeforeDoctypeName(cp);
  38076. }
  38077. }
  38078. }
  38079. // Before DOCTYPE name state
  38080. //------------------------------------------------------------------
  38081. _stateBeforeDoctypeName(cp) {
  38082. if (isAsciiUpper(cp)) {
  38083. this._createDoctypeToken(String.fromCharCode(toAsciiLower(cp)));
  38084. this.state = State.DOCTYPE_NAME;
  38085. } else
  38086. switch (cp) {
  38087. case CODE_POINTS.SPACE:
  38088. case CODE_POINTS.LINE_FEED:
  38089. case CODE_POINTS.TABULATION:
  38090. case CODE_POINTS.FORM_FEED: {
  38091. break;
  38092. }
  38093. case CODE_POINTS.NULL: {
  38094. this._err(ERR.unexpectedNullCharacter);
  38095. this._createDoctypeToken(REPLACEMENT_CHARACTER);
  38096. this.state = State.DOCTYPE_NAME;
  38097. break;
  38098. }
  38099. case CODE_POINTS.GREATER_THAN_SIGN: {
  38100. this._err(ERR.missingDoctypeName);
  38101. this._createDoctypeToken(null);
  38102. const token = this.currentToken;
  38103. token.forceQuirks = true;
  38104. this.emitCurrentDoctype(token);
  38105. this.state = State.DATA;
  38106. break;
  38107. }
  38108. case CODE_POINTS.EOF: {
  38109. this._err(ERR.eofInDoctype);
  38110. this._createDoctypeToken(null);
  38111. const token = this.currentToken;
  38112. token.forceQuirks = true;
  38113. this.emitCurrentDoctype(token);
  38114. this._emitEOFToken();
  38115. break;
  38116. }
  38117. default: {
  38118. this._createDoctypeToken(String.fromCodePoint(cp));
  38119. this.state = State.DOCTYPE_NAME;
  38120. }
  38121. }
  38122. }
  38123. // DOCTYPE name state
  38124. //------------------------------------------------------------------
  38125. _stateDoctypeName(cp) {
  38126. const token = this.currentToken;
  38127. switch (cp) {
  38128. case CODE_POINTS.SPACE:
  38129. case CODE_POINTS.LINE_FEED:
  38130. case CODE_POINTS.TABULATION:
  38131. case CODE_POINTS.FORM_FEED: {
  38132. this.state = State.AFTER_DOCTYPE_NAME;
  38133. break;
  38134. }
  38135. case CODE_POINTS.GREATER_THAN_SIGN: {
  38136. this.state = State.DATA;
  38137. this.emitCurrentDoctype(token);
  38138. break;
  38139. }
  38140. case CODE_POINTS.NULL: {
  38141. this._err(ERR.unexpectedNullCharacter);
  38142. token.name += REPLACEMENT_CHARACTER;
  38143. break;
  38144. }
  38145. case CODE_POINTS.EOF: {
  38146. this._err(ERR.eofInDoctype);
  38147. token.forceQuirks = true;
  38148. this.emitCurrentDoctype(token);
  38149. this._emitEOFToken();
  38150. break;
  38151. }
  38152. default: {
  38153. token.name += String.fromCodePoint(isAsciiUpper(cp) ? toAsciiLower(cp) : cp);
  38154. }
  38155. }
  38156. }
  38157. // After DOCTYPE name state
  38158. //------------------------------------------------------------------
  38159. _stateAfterDoctypeName(cp) {
  38160. const token = this.currentToken;
  38161. switch (cp) {
  38162. case CODE_POINTS.SPACE:
  38163. case CODE_POINTS.LINE_FEED:
  38164. case CODE_POINTS.TABULATION:
  38165. case CODE_POINTS.FORM_FEED: {
  38166. break;
  38167. }
  38168. case CODE_POINTS.GREATER_THAN_SIGN: {
  38169. this.state = State.DATA;
  38170. this.emitCurrentDoctype(token);
  38171. break;
  38172. }
  38173. case CODE_POINTS.EOF: {
  38174. this._err(ERR.eofInDoctype);
  38175. token.forceQuirks = true;
  38176. this.emitCurrentDoctype(token);
  38177. this._emitEOFToken();
  38178. break;
  38179. }
  38180. default: {
  38181. if (this._consumeSequenceIfMatch(SEQUENCES.PUBLIC, false)) {
  38182. this.state = State.AFTER_DOCTYPE_PUBLIC_KEYWORD;
  38183. } else if (this._consumeSequenceIfMatch(SEQUENCES.SYSTEM, false)) {
  38184. this.state = State.AFTER_DOCTYPE_SYSTEM_KEYWORD;
  38185. } else if (!this._ensureHibernation()) {
  38186. this._err(ERR.invalidCharacterSequenceAfterDoctypeName);
  38187. token.forceQuirks = true;
  38188. this.state = State.BOGUS_DOCTYPE;
  38189. this._stateBogusDoctype(cp);
  38190. }
  38191. }
  38192. }
  38193. }
  38194. // After DOCTYPE public keyword state
  38195. //------------------------------------------------------------------
  38196. _stateAfterDoctypePublicKeyword(cp) {
  38197. const token = this.currentToken;
  38198. switch (cp) {
  38199. case CODE_POINTS.SPACE:
  38200. case CODE_POINTS.LINE_FEED:
  38201. case CODE_POINTS.TABULATION:
  38202. case CODE_POINTS.FORM_FEED: {
  38203. this.state = State.BEFORE_DOCTYPE_PUBLIC_IDENTIFIER;
  38204. break;
  38205. }
  38206. case CODE_POINTS.QUOTATION_MARK: {
  38207. this._err(ERR.missingWhitespaceAfterDoctypePublicKeyword);
  38208. token.publicId = "";
  38209. this.state = State.DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED;
  38210. break;
  38211. }
  38212. case CODE_POINTS.APOSTROPHE: {
  38213. this._err(ERR.missingWhitespaceAfterDoctypePublicKeyword);
  38214. token.publicId = "";
  38215. this.state = State.DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED;
  38216. break;
  38217. }
  38218. case CODE_POINTS.GREATER_THAN_SIGN: {
  38219. this._err(ERR.missingDoctypePublicIdentifier);
  38220. token.forceQuirks = true;
  38221. this.state = State.DATA;
  38222. this.emitCurrentDoctype(token);
  38223. break;
  38224. }
  38225. case CODE_POINTS.EOF: {
  38226. this._err(ERR.eofInDoctype);
  38227. token.forceQuirks = true;
  38228. this.emitCurrentDoctype(token);
  38229. this._emitEOFToken();
  38230. break;
  38231. }
  38232. default: {
  38233. this._err(ERR.missingQuoteBeforeDoctypePublicIdentifier);
  38234. token.forceQuirks = true;
  38235. this.state = State.BOGUS_DOCTYPE;
  38236. this._stateBogusDoctype(cp);
  38237. }
  38238. }
  38239. }
  38240. // Before DOCTYPE public identifier state
  38241. //------------------------------------------------------------------
  38242. _stateBeforeDoctypePublicIdentifier(cp) {
  38243. const token = this.currentToken;
  38244. switch (cp) {
  38245. case CODE_POINTS.SPACE:
  38246. case CODE_POINTS.LINE_FEED:
  38247. case CODE_POINTS.TABULATION:
  38248. case CODE_POINTS.FORM_FEED: {
  38249. break;
  38250. }
  38251. case CODE_POINTS.QUOTATION_MARK: {
  38252. token.publicId = "";
  38253. this.state = State.DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED;
  38254. break;
  38255. }
  38256. case CODE_POINTS.APOSTROPHE: {
  38257. token.publicId = "";
  38258. this.state = State.DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED;
  38259. break;
  38260. }
  38261. case CODE_POINTS.GREATER_THAN_SIGN: {
  38262. this._err(ERR.missingDoctypePublicIdentifier);
  38263. token.forceQuirks = true;
  38264. this.state = State.DATA;
  38265. this.emitCurrentDoctype(token);
  38266. break;
  38267. }
  38268. case CODE_POINTS.EOF: {
  38269. this._err(ERR.eofInDoctype);
  38270. token.forceQuirks = true;
  38271. this.emitCurrentDoctype(token);
  38272. this._emitEOFToken();
  38273. break;
  38274. }
  38275. default: {
  38276. this._err(ERR.missingQuoteBeforeDoctypePublicIdentifier);
  38277. token.forceQuirks = true;
  38278. this.state = State.BOGUS_DOCTYPE;
  38279. this._stateBogusDoctype(cp);
  38280. }
  38281. }
  38282. }
  38283. // DOCTYPE public identifier (double-quoted) state
  38284. //------------------------------------------------------------------
  38285. _stateDoctypePublicIdentifierDoubleQuoted(cp) {
  38286. const token = this.currentToken;
  38287. switch (cp) {
  38288. case CODE_POINTS.QUOTATION_MARK: {
  38289. this.state = State.AFTER_DOCTYPE_PUBLIC_IDENTIFIER;
  38290. break;
  38291. }
  38292. case CODE_POINTS.NULL: {
  38293. this._err(ERR.unexpectedNullCharacter);
  38294. token.publicId += REPLACEMENT_CHARACTER;
  38295. break;
  38296. }
  38297. case CODE_POINTS.GREATER_THAN_SIGN: {
  38298. this._err(ERR.abruptDoctypePublicIdentifier);
  38299. token.forceQuirks = true;
  38300. this.emitCurrentDoctype(token);
  38301. this.state = State.DATA;
  38302. break;
  38303. }
  38304. case CODE_POINTS.EOF: {
  38305. this._err(ERR.eofInDoctype);
  38306. token.forceQuirks = true;
  38307. this.emitCurrentDoctype(token);
  38308. this._emitEOFToken();
  38309. break;
  38310. }
  38311. default: {
  38312. token.publicId += String.fromCodePoint(cp);
  38313. }
  38314. }
  38315. }
  38316. // DOCTYPE public identifier (single-quoted) state
  38317. //------------------------------------------------------------------
  38318. _stateDoctypePublicIdentifierSingleQuoted(cp) {
  38319. const token = this.currentToken;
  38320. switch (cp) {
  38321. case CODE_POINTS.APOSTROPHE: {
  38322. this.state = State.AFTER_DOCTYPE_PUBLIC_IDENTIFIER;
  38323. break;
  38324. }
  38325. case CODE_POINTS.NULL: {
  38326. this._err(ERR.unexpectedNullCharacter);
  38327. token.publicId += REPLACEMENT_CHARACTER;
  38328. break;
  38329. }
  38330. case CODE_POINTS.GREATER_THAN_SIGN: {
  38331. this._err(ERR.abruptDoctypePublicIdentifier);
  38332. token.forceQuirks = true;
  38333. this.emitCurrentDoctype(token);
  38334. this.state = State.DATA;
  38335. break;
  38336. }
  38337. case CODE_POINTS.EOF: {
  38338. this._err(ERR.eofInDoctype);
  38339. token.forceQuirks = true;
  38340. this.emitCurrentDoctype(token);
  38341. this._emitEOFToken();
  38342. break;
  38343. }
  38344. default: {
  38345. token.publicId += String.fromCodePoint(cp);
  38346. }
  38347. }
  38348. }
  38349. // After DOCTYPE public identifier state
  38350. //------------------------------------------------------------------
  38351. _stateAfterDoctypePublicIdentifier(cp) {
  38352. const token = this.currentToken;
  38353. switch (cp) {
  38354. case CODE_POINTS.SPACE:
  38355. case CODE_POINTS.LINE_FEED:
  38356. case CODE_POINTS.TABULATION:
  38357. case CODE_POINTS.FORM_FEED: {
  38358. this.state = State.BETWEEN_DOCTYPE_PUBLIC_AND_SYSTEM_IDENTIFIERS;
  38359. break;
  38360. }
  38361. case CODE_POINTS.GREATER_THAN_SIGN: {
  38362. this.state = State.DATA;
  38363. this.emitCurrentDoctype(token);
  38364. break;
  38365. }
  38366. case CODE_POINTS.QUOTATION_MARK: {
  38367. this._err(ERR.missingWhitespaceBetweenDoctypePublicAndSystemIdentifiers);
  38368. token.systemId = "";
  38369. this.state = State.DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED;
  38370. break;
  38371. }
  38372. case CODE_POINTS.APOSTROPHE: {
  38373. this._err(ERR.missingWhitespaceBetweenDoctypePublicAndSystemIdentifiers);
  38374. token.systemId = "";
  38375. this.state = State.DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED;
  38376. break;
  38377. }
  38378. case CODE_POINTS.EOF: {
  38379. this._err(ERR.eofInDoctype);
  38380. token.forceQuirks = true;
  38381. this.emitCurrentDoctype(token);
  38382. this._emitEOFToken();
  38383. break;
  38384. }
  38385. default: {
  38386. this._err(ERR.missingQuoteBeforeDoctypeSystemIdentifier);
  38387. token.forceQuirks = true;
  38388. this.state = State.BOGUS_DOCTYPE;
  38389. this._stateBogusDoctype(cp);
  38390. }
  38391. }
  38392. }
  38393. // Between DOCTYPE public and system identifiers state
  38394. //------------------------------------------------------------------
  38395. _stateBetweenDoctypePublicAndSystemIdentifiers(cp) {
  38396. const token = this.currentToken;
  38397. switch (cp) {
  38398. case CODE_POINTS.SPACE:
  38399. case CODE_POINTS.LINE_FEED:
  38400. case CODE_POINTS.TABULATION:
  38401. case CODE_POINTS.FORM_FEED: {
  38402. break;
  38403. }
  38404. case CODE_POINTS.GREATER_THAN_SIGN: {
  38405. this.emitCurrentDoctype(token);
  38406. this.state = State.DATA;
  38407. break;
  38408. }
  38409. case CODE_POINTS.QUOTATION_MARK: {
  38410. token.systemId = "";
  38411. this.state = State.DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED;
  38412. break;
  38413. }
  38414. case CODE_POINTS.APOSTROPHE: {
  38415. token.systemId = "";
  38416. this.state = State.DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED;
  38417. break;
  38418. }
  38419. case CODE_POINTS.EOF: {
  38420. this._err(ERR.eofInDoctype);
  38421. token.forceQuirks = true;
  38422. this.emitCurrentDoctype(token);
  38423. this._emitEOFToken();
  38424. break;
  38425. }
  38426. default: {
  38427. this._err(ERR.missingQuoteBeforeDoctypeSystemIdentifier);
  38428. token.forceQuirks = true;
  38429. this.state = State.BOGUS_DOCTYPE;
  38430. this._stateBogusDoctype(cp);
  38431. }
  38432. }
  38433. }
  38434. // After DOCTYPE system keyword state
  38435. //------------------------------------------------------------------
  38436. _stateAfterDoctypeSystemKeyword(cp) {
  38437. const token = this.currentToken;
  38438. switch (cp) {
  38439. case CODE_POINTS.SPACE:
  38440. case CODE_POINTS.LINE_FEED:
  38441. case CODE_POINTS.TABULATION:
  38442. case CODE_POINTS.FORM_FEED: {
  38443. this.state = State.BEFORE_DOCTYPE_SYSTEM_IDENTIFIER;
  38444. break;
  38445. }
  38446. case CODE_POINTS.QUOTATION_MARK: {
  38447. this._err(ERR.missingWhitespaceAfterDoctypeSystemKeyword);
  38448. token.systemId = "";
  38449. this.state = State.DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED;
  38450. break;
  38451. }
  38452. case CODE_POINTS.APOSTROPHE: {
  38453. this._err(ERR.missingWhitespaceAfterDoctypeSystemKeyword);
  38454. token.systemId = "";
  38455. this.state = State.DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED;
  38456. break;
  38457. }
  38458. case CODE_POINTS.GREATER_THAN_SIGN: {
  38459. this._err(ERR.missingDoctypeSystemIdentifier);
  38460. token.forceQuirks = true;
  38461. this.state = State.DATA;
  38462. this.emitCurrentDoctype(token);
  38463. break;
  38464. }
  38465. case CODE_POINTS.EOF: {
  38466. this._err(ERR.eofInDoctype);
  38467. token.forceQuirks = true;
  38468. this.emitCurrentDoctype(token);
  38469. this._emitEOFToken();
  38470. break;
  38471. }
  38472. default: {
  38473. this._err(ERR.missingQuoteBeforeDoctypeSystemIdentifier);
  38474. token.forceQuirks = true;
  38475. this.state = State.BOGUS_DOCTYPE;
  38476. this._stateBogusDoctype(cp);
  38477. }
  38478. }
  38479. }
  38480. // Before DOCTYPE system identifier state
  38481. //------------------------------------------------------------------
  38482. _stateBeforeDoctypeSystemIdentifier(cp) {
  38483. const token = this.currentToken;
  38484. switch (cp) {
  38485. case CODE_POINTS.SPACE:
  38486. case CODE_POINTS.LINE_FEED:
  38487. case CODE_POINTS.TABULATION:
  38488. case CODE_POINTS.FORM_FEED: {
  38489. break;
  38490. }
  38491. case CODE_POINTS.QUOTATION_MARK: {
  38492. token.systemId = "";
  38493. this.state = State.DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED;
  38494. break;
  38495. }
  38496. case CODE_POINTS.APOSTROPHE: {
  38497. token.systemId = "";
  38498. this.state = State.DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED;
  38499. break;
  38500. }
  38501. case CODE_POINTS.GREATER_THAN_SIGN: {
  38502. this._err(ERR.missingDoctypeSystemIdentifier);
  38503. token.forceQuirks = true;
  38504. this.state = State.DATA;
  38505. this.emitCurrentDoctype(token);
  38506. break;
  38507. }
  38508. case CODE_POINTS.EOF: {
  38509. this._err(ERR.eofInDoctype);
  38510. token.forceQuirks = true;
  38511. this.emitCurrentDoctype(token);
  38512. this._emitEOFToken();
  38513. break;
  38514. }
  38515. default: {
  38516. this._err(ERR.missingQuoteBeforeDoctypeSystemIdentifier);
  38517. token.forceQuirks = true;
  38518. this.state = State.BOGUS_DOCTYPE;
  38519. this._stateBogusDoctype(cp);
  38520. }
  38521. }
  38522. }
  38523. // DOCTYPE system identifier (double-quoted) state
  38524. //------------------------------------------------------------------
  38525. _stateDoctypeSystemIdentifierDoubleQuoted(cp) {
  38526. const token = this.currentToken;
  38527. switch (cp) {
  38528. case CODE_POINTS.QUOTATION_MARK: {
  38529. this.state = State.AFTER_DOCTYPE_SYSTEM_IDENTIFIER;
  38530. break;
  38531. }
  38532. case CODE_POINTS.NULL: {
  38533. this._err(ERR.unexpectedNullCharacter);
  38534. token.systemId += REPLACEMENT_CHARACTER;
  38535. break;
  38536. }
  38537. case CODE_POINTS.GREATER_THAN_SIGN: {
  38538. this._err(ERR.abruptDoctypeSystemIdentifier);
  38539. token.forceQuirks = true;
  38540. this.emitCurrentDoctype(token);
  38541. this.state = State.DATA;
  38542. break;
  38543. }
  38544. case CODE_POINTS.EOF: {
  38545. this._err(ERR.eofInDoctype);
  38546. token.forceQuirks = true;
  38547. this.emitCurrentDoctype(token);
  38548. this._emitEOFToken();
  38549. break;
  38550. }
  38551. default: {
  38552. token.systemId += String.fromCodePoint(cp);
  38553. }
  38554. }
  38555. }
  38556. // DOCTYPE system identifier (single-quoted) state
  38557. //------------------------------------------------------------------
  38558. _stateDoctypeSystemIdentifierSingleQuoted(cp) {
  38559. const token = this.currentToken;
  38560. switch (cp) {
  38561. case CODE_POINTS.APOSTROPHE: {
  38562. this.state = State.AFTER_DOCTYPE_SYSTEM_IDENTIFIER;
  38563. break;
  38564. }
  38565. case CODE_POINTS.NULL: {
  38566. this._err(ERR.unexpectedNullCharacter);
  38567. token.systemId += REPLACEMENT_CHARACTER;
  38568. break;
  38569. }
  38570. case CODE_POINTS.GREATER_THAN_SIGN: {
  38571. this._err(ERR.abruptDoctypeSystemIdentifier);
  38572. token.forceQuirks = true;
  38573. this.emitCurrentDoctype(token);
  38574. this.state = State.DATA;
  38575. break;
  38576. }
  38577. case CODE_POINTS.EOF: {
  38578. this._err(ERR.eofInDoctype);
  38579. token.forceQuirks = true;
  38580. this.emitCurrentDoctype(token);
  38581. this._emitEOFToken();
  38582. break;
  38583. }
  38584. default: {
  38585. token.systemId += String.fromCodePoint(cp);
  38586. }
  38587. }
  38588. }
  38589. // After DOCTYPE system identifier state
  38590. //------------------------------------------------------------------
  38591. _stateAfterDoctypeSystemIdentifier(cp) {
  38592. const token = this.currentToken;
  38593. switch (cp) {
  38594. case CODE_POINTS.SPACE:
  38595. case CODE_POINTS.LINE_FEED:
  38596. case CODE_POINTS.TABULATION:
  38597. case CODE_POINTS.FORM_FEED: {
  38598. break;
  38599. }
  38600. case CODE_POINTS.GREATER_THAN_SIGN: {
  38601. this.emitCurrentDoctype(token);
  38602. this.state = State.DATA;
  38603. break;
  38604. }
  38605. case CODE_POINTS.EOF: {
  38606. this._err(ERR.eofInDoctype);
  38607. token.forceQuirks = true;
  38608. this.emitCurrentDoctype(token);
  38609. this._emitEOFToken();
  38610. break;
  38611. }
  38612. default: {
  38613. this._err(ERR.unexpectedCharacterAfterDoctypeSystemIdentifier);
  38614. this.state = State.BOGUS_DOCTYPE;
  38615. this._stateBogusDoctype(cp);
  38616. }
  38617. }
  38618. }
  38619. // Bogus DOCTYPE state
  38620. //------------------------------------------------------------------
  38621. _stateBogusDoctype(cp) {
  38622. const token = this.currentToken;
  38623. switch (cp) {
  38624. case CODE_POINTS.GREATER_THAN_SIGN: {
  38625. this.emitCurrentDoctype(token);
  38626. this.state = State.DATA;
  38627. break;
  38628. }
  38629. case CODE_POINTS.NULL: {
  38630. this._err(ERR.unexpectedNullCharacter);
  38631. break;
  38632. }
  38633. case CODE_POINTS.EOF: {
  38634. this.emitCurrentDoctype(token);
  38635. this._emitEOFToken();
  38636. break;
  38637. }
  38638. default:
  38639. }
  38640. }
  38641. // CDATA section state
  38642. //------------------------------------------------------------------
  38643. _stateCdataSection(cp) {
  38644. switch (cp) {
  38645. case CODE_POINTS.RIGHT_SQUARE_BRACKET: {
  38646. this.state = State.CDATA_SECTION_BRACKET;
  38647. break;
  38648. }
  38649. case CODE_POINTS.EOF: {
  38650. this._err(ERR.eofInCdata);
  38651. this._emitEOFToken();
  38652. break;
  38653. }
  38654. default: {
  38655. this._emitCodePoint(cp);
  38656. }
  38657. }
  38658. }
  38659. // CDATA section bracket state
  38660. //------------------------------------------------------------------
  38661. _stateCdataSectionBracket(cp) {
  38662. if (cp === CODE_POINTS.RIGHT_SQUARE_BRACKET) {
  38663. this.state = State.CDATA_SECTION_END;
  38664. } else {
  38665. this._emitChars("]");
  38666. this.state = State.CDATA_SECTION;
  38667. this._stateCdataSection(cp);
  38668. }
  38669. }
  38670. // CDATA section end state
  38671. //------------------------------------------------------------------
  38672. _stateCdataSectionEnd(cp) {
  38673. switch (cp) {
  38674. case CODE_POINTS.GREATER_THAN_SIGN: {
  38675. this.state = State.DATA;
  38676. break;
  38677. }
  38678. case CODE_POINTS.RIGHT_SQUARE_BRACKET: {
  38679. this._emitChars("]");
  38680. break;
  38681. }
  38682. default: {
  38683. this._emitChars("]]");
  38684. this.state = State.CDATA_SECTION;
  38685. this._stateCdataSection(cp);
  38686. }
  38687. }
  38688. }
  38689. // Character reference state
  38690. //------------------------------------------------------------------
  38691. _stateCharacterReference(cp) {
  38692. if (cp === CODE_POINTS.NUMBER_SIGN) {
  38693. this.state = State.NUMERIC_CHARACTER_REFERENCE;
  38694. } else if (isAsciiAlphaNumeric2(cp)) {
  38695. this.state = State.NAMED_CHARACTER_REFERENCE;
  38696. this._stateNamedCharacterReference(cp);
  38697. } else {
  38698. this._flushCodePointConsumedAsCharacterReference(CODE_POINTS.AMPERSAND);
  38699. this._reconsumeInState(this.returnState, cp);
  38700. }
  38701. }
  38702. // Named character reference state
  38703. //------------------------------------------------------------------
  38704. _stateNamedCharacterReference(cp) {
  38705. const matchResult = this._matchNamedCharacterReference(cp);
  38706. if (this._ensureHibernation()) {
  38707. } else if (matchResult) {
  38708. for (let i = 0; i < matchResult.length; i++) {
  38709. this._flushCodePointConsumedAsCharacterReference(matchResult[i]);
  38710. }
  38711. this.state = this.returnState;
  38712. } else {
  38713. this._flushCodePointConsumedAsCharacterReference(CODE_POINTS.AMPERSAND);
  38714. this.state = State.AMBIGUOUS_AMPERSAND;
  38715. }
  38716. }
  38717. // Ambiguos ampersand state
  38718. //------------------------------------------------------------------
  38719. _stateAmbiguousAmpersand(cp) {
  38720. if (isAsciiAlphaNumeric2(cp)) {
  38721. this._flushCodePointConsumedAsCharacterReference(cp);
  38722. } else {
  38723. if (cp === CODE_POINTS.SEMICOLON) {
  38724. this._err(ERR.unknownNamedCharacterReference);
  38725. }
  38726. this._reconsumeInState(this.returnState, cp);
  38727. }
  38728. }
  38729. // Numeric character reference state
  38730. //------------------------------------------------------------------
  38731. _stateNumericCharacterReference(cp) {
  38732. this.charRefCode = 0;
  38733. if (cp === CODE_POINTS.LATIN_SMALL_X || cp === CODE_POINTS.LATIN_CAPITAL_X) {
  38734. this.state = State.HEXADEMICAL_CHARACTER_REFERENCE_START;
  38735. } else if (isAsciiDigit(cp)) {
  38736. this.state = State.DECIMAL_CHARACTER_REFERENCE;
  38737. this._stateDecimalCharacterReference(cp);
  38738. } else {
  38739. this._err(ERR.absenceOfDigitsInNumericCharacterReference);
  38740. this._flushCodePointConsumedAsCharacterReference(CODE_POINTS.AMPERSAND);
  38741. this._flushCodePointConsumedAsCharacterReference(CODE_POINTS.NUMBER_SIGN);
  38742. this._reconsumeInState(this.returnState, cp);
  38743. }
  38744. }
  38745. // Hexademical character reference start state
  38746. //------------------------------------------------------------------
  38747. _stateHexademicalCharacterReferenceStart(cp) {
  38748. if (isAsciiHexDigit(cp)) {
  38749. this.state = State.HEXADEMICAL_CHARACTER_REFERENCE;
  38750. this._stateHexademicalCharacterReference(cp);
  38751. } else {
  38752. this._err(ERR.absenceOfDigitsInNumericCharacterReference);
  38753. this._flushCodePointConsumedAsCharacterReference(CODE_POINTS.AMPERSAND);
  38754. this._flushCodePointConsumedAsCharacterReference(CODE_POINTS.NUMBER_SIGN);
  38755. this._unconsume(2);
  38756. this.state = this.returnState;
  38757. }
  38758. }
  38759. // Hexademical character reference state
  38760. //------------------------------------------------------------------
  38761. _stateHexademicalCharacterReference(cp) {
  38762. if (isAsciiUpperHexDigit(cp)) {
  38763. this.charRefCode = this.charRefCode * 16 + cp - 55;
  38764. } else if (isAsciiLowerHexDigit(cp)) {
  38765. this.charRefCode = this.charRefCode * 16 + cp - 87;
  38766. } else if (isAsciiDigit(cp)) {
  38767. this.charRefCode = this.charRefCode * 16 + cp - 48;
  38768. } else if (cp === CODE_POINTS.SEMICOLON) {
  38769. this.state = State.NUMERIC_CHARACTER_REFERENCE_END;
  38770. } else {
  38771. this._err(ERR.missingSemicolonAfterCharacterReference);
  38772. this.state = State.NUMERIC_CHARACTER_REFERENCE_END;
  38773. this._stateNumericCharacterReferenceEnd(cp);
  38774. }
  38775. }
  38776. // Decimal character reference state
  38777. //------------------------------------------------------------------
  38778. _stateDecimalCharacterReference(cp) {
  38779. if (isAsciiDigit(cp)) {
  38780. this.charRefCode = this.charRefCode * 10 + cp - 48;
  38781. } else if (cp === CODE_POINTS.SEMICOLON) {
  38782. this.state = State.NUMERIC_CHARACTER_REFERENCE_END;
  38783. } else {
  38784. this._err(ERR.missingSemicolonAfterCharacterReference);
  38785. this.state = State.NUMERIC_CHARACTER_REFERENCE_END;
  38786. this._stateNumericCharacterReferenceEnd(cp);
  38787. }
  38788. }
  38789. // Numeric character reference end state
  38790. //------------------------------------------------------------------
  38791. _stateNumericCharacterReferenceEnd(cp) {
  38792. if (this.charRefCode === CODE_POINTS.NULL) {
  38793. this._err(ERR.nullCharacterReference);
  38794. this.charRefCode = CODE_POINTS.REPLACEMENT_CHARACTER;
  38795. } else if (this.charRefCode > 1114111) {
  38796. this._err(ERR.characterReferenceOutsideUnicodeRange);
  38797. this.charRefCode = CODE_POINTS.REPLACEMENT_CHARACTER;
  38798. } else if (isSurrogate(this.charRefCode)) {
  38799. this._err(ERR.surrogateCharacterReference);
  38800. this.charRefCode = CODE_POINTS.REPLACEMENT_CHARACTER;
  38801. } else if (isUndefinedCodePoint(this.charRefCode)) {
  38802. this._err(ERR.noncharacterCharacterReference);
  38803. } else if (isControlCodePoint(this.charRefCode) || this.charRefCode === CODE_POINTS.CARRIAGE_RETURN) {
  38804. this._err(ERR.controlCharacterReference);
  38805. const replacement = C1_CONTROLS_REFERENCE_REPLACEMENTS.get(this.charRefCode);
  38806. if (replacement !== void 0) {
  38807. this.charRefCode = replacement;
  38808. }
  38809. }
  38810. this._flushCodePointConsumedAsCharacterReference(this.charRefCode);
  38811. this._reconsumeInState(this.returnState, cp);
  38812. }
  38813. };
  38814. // node_modules/parse5/dist/parser/open-element-stack.js
  38815. var IMPLICIT_END_TAG_REQUIRED = /* @__PURE__ */ new Set([TAG_ID.DD, TAG_ID.DT, TAG_ID.LI, TAG_ID.OPTGROUP, TAG_ID.OPTION, TAG_ID.P, TAG_ID.RB, TAG_ID.RP, TAG_ID.RT, TAG_ID.RTC]);
  38816. var IMPLICIT_END_TAG_REQUIRED_THOROUGHLY = /* @__PURE__ */ new Set([
  38817. ...IMPLICIT_END_TAG_REQUIRED,
  38818. TAG_ID.CAPTION,
  38819. TAG_ID.COLGROUP,
  38820. TAG_ID.TBODY,
  38821. TAG_ID.TD,
  38822. TAG_ID.TFOOT,
  38823. TAG_ID.TH,
  38824. TAG_ID.THEAD,
  38825. TAG_ID.TR
  38826. ]);
  38827. var SCOPING_ELEMENT_NS = /* @__PURE__ */ new Map([
  38828. [TAG_ID.APPLET, NS.HTML],
  38829. [TAG_ID.CAPTION, NS.HTML],
  38830. [TAG_ID.HTML, NS.HTML],
  38831. [TAG_ID.MARQUEE, NS.HTML],
  38832. [TAG_ID.OBJECT, NS.HTML],
  38833. [TAG_ID.TABLE, NS.HTML],
  38834. [TAG_ID.TD, NS.HTML],
  38835. [TAG_ID.TEMPLATE, NS.HTML],
  38836. [TAG_ID.TH, NS.HTML],
  38837. [TAG_ID.ANNOTATION_XML, NS.MATHML],
  38838. [TAG_ID.MI, NS.MATHML],
  38839. [TAG_ID.MN, NS.MATHML],
  38840. [TAG_ID.MO, NS.MATHML],
  38841. [TAG_ID.MS, NS.MATHML],
  38842. [TAG_ID.MTEXT, NS.MATHML],
  38843. [TAG_ID.DESC, NS.SVG],
  38844. [TAG_ID.FOREIGN_OBJECT, NS.SVG],
  38845. [TAG_ID.TITLE, NS.SVG]
  38846. ]);
  38847. var NAMED_HEADERS = [TAG_ID.H1, TAG_ID.H2, TAG_ID.H3, TAG_ID.H4, TAG_ID.H5, TAG_ID.H6];
  38848. var TABLE_ROW_CONTEXT = [TAG_ID.TR, TAG_ID.TEMPLATE, TAG_ID.HTML];
  38849. var TABLE_BODY_CONTEXT = [TAG_ID.TBODY, TAG_ID.TFOOT, TAG_ID.THEAD, TAG_ID.TEMPLATE, TAG_ID.HTML];
  38850. var TABLE_CONTEXT = [TAG_ID.TABLE, TAG_ID.TEMPLATE, TAG_ID.HTML];
  38851. var TABLE_CELLS = [TAG_ID.TD, TAG_ID.TH];
  38852. var OpenElementStack = class {
  38853. get currentTmplContentOrNode() {
  38854. return this._isInTemplate() ? this.treeAdapter.getTemplateContent(this.current) : this.current;
  38855. }
  38856. constructor(document, treeAdapter, handler) {
  38857. this.treeAdapter = treeAdapter;
  38858. this.handler = handler;
  38859. this.items = [];
  38860. this.tagIDs = [];
  38861. this.stackTop = -1;
  38862. this.tmplCount = 0;
  38863. this.currentTagId = TAG_ID.UNKNOWN;
  38864. this.current = document;
  38865. }
  38866. //Index of element
  38867. _indexOf(element) {
  38868. return this.items.lastIndexOf(element, this.stackTop);
  38869. }
  38870. //Update current element
  38871. _isInTemplate() {
  38872. return this.currentTagId === TAG_ID.TEMPLATE && this.treeAdapter.getNamespaceURI(this.current) === NS.HTML;
  38873. }
  38874. _updateCurrentElement() {
  38875. this.current = this.items[this.stackTop];
  38876. this.currentTagId = this.tagIDs[this.stackTop];
  38877. }
  38878. //Mutations
  38879. push(element, tagID) {
  38880. this.stackTop++;
  38881. this.items[this.stackTop] = element;
  38882. this.current = element;
  38883. this.tagIDs[this.stackTop] = tagID;
  38884. this.currentTagId = tagID;
  38885. if (this._isInTemplate()) {
  38886. this.tmplCount++;
  38887. }
  38888. this.handler.onItemPush(element, tagID, true);
  38889. }
  38890. pop() {
  38891. const popped = this.current;
  38892. if (this.tmplCount > 0 && this._isInTemplate()) {
  38893. this.tmplCount--;
  38894. }
  38895. this.stackTop--;
  38896. this._updateCurrentElement();
  38897. this.handler.onItemPop(popped, true);
  38898. }
  38899. replace(oldElement, newElement) {
  38900. const idx = this._indexOf(oldElement);
  38901. this.items[idx] = newElement;
  38902. if (idx === this.stackTop) {
  38903. this.current = newElement;
  38904. }
  38905. }
  38906. insertAfter(referenceElement, newElement, newElementID) {
  38907. const insertionIdx = this._indexOf(referenceElement) + 1;
  38908. this.items.splice(insertionIdx, 0, newElement);
  38909. this.tagIDs.splice(insertionIdx, 0, newElementID);
  38910. this.stackTop++;
  38911. if (insertionIdx === this.stackTop) {
  38912. this._updateCurrentElement();
  38913. }
  38914. this.handler.onItemPush(this.current, this.currentTagId, insertionIdx === this.stackTop);
  38915. }
  38916. popUntilTagNamePopped(tagName) {
  38917. let targetIdx = this.stackTop + 1;
  38918. do {
  38919. targetIdx = this.tagIDs.lastIndexOf(tagName, targetIdx - 1);
  38920. } while (targetIdx > 0 && this.treeAdapter.getNamespaceURI(this.items[targetIdx]) !== NS.HTML);
  38921. this.shortenToLength(targetIdx < 0 ? 0 : targetIdx);
  38922. }
  38923. shortenToLength(idx) {
  38924. while (this.stackTop >= idx) {
  38925. const popped = this.current;
  38926. if (this.tmplCount > 0 && this._isInTemplate()) {
  38927. this.tmplCount -= 1;
  38928. }
  38929. this.stackTop--;
  38930. this._updateCurrentElement();
  38931. this.handler.onItemPop(popped, this.stackTop < idx);
  38932. }
  38933. }
  38934. popUntilElementPopped(element) {
  38935. const idx = this._indexOf(element);
  38936. this.shortenToLength(idx < 0 ? 0 : idx);
  38937. }
  38938. popUntilPopped(tagNames, targetNS) {
  38939. const idx = this._indexOfTagNames(tagNames, targetNS);
  38940. this.shortenToLength(idx < 0 ? 0 : idx);
  38941. }
  38942. popUntilNumberedHeaderPopped() {
  38943. this.popUntilPopped(NAMED_HEADERS, NS.HTML);
  38944. }
  38945. popUntilTableCellPopped() {
  38946. this.popUntilPopped(TABLE_CELLS, NS.HTML);
  38947. }
  38948. popAllUpToHtmlElement() {
  38949. this.tmplCount = 0;
  38950. this.shortenToLength(1);
  38951. }
  38952. _indexOfTagNames(tagNames, namespace) {
  38953. for (let i = this.stackTop; i >= 0; i--) {
  38954. if (tagNames.includes(this.tagIDs[i]) && this.treeAdapter.getNamespaceURI(this.items[i]) === namespace) {
  38955. return i;
  38956. }
  38957. }
  38958. return -1;
  38959. }
  38960. clearBackTo(tagNames, targetNS) {
  38961. const idx = this._indexOfTagNames(tagNames, targetNS);
  38962. this.shortenToLength(idx + 1);
  38963. }
  38964. clearBackToTableContext() {
  38965. this.clearBackTo(TABLE_CONTEXT, NS.HTML);
  38966. }
  38967. clearBackToTableBodyContext() {
  38968. this.clearBackTo(TABLE_BODY_CONTEXT, NS.HTML);
  38969. }
  38970. clearBackToTableRowContext() {
  38971. this.clearBackTo(TABLE_ROW_CONTEXT, NS.HTML);
  38972. }
  38973. remove(element) {
  38974. const idx = this._indexOf(element);
  38975. if (idx >= 0) {
  38976. if (idx === this.stackTop) {
  38977. this.pop();
  38978. } else {
  38979. this.items.splice(idx, 1);
  38980. this.tagIDs.splice(idx, 1);
  38981. this.stackTop--;
  38982. this._updateCurrentElement();
  38983. this.handler.onItemPop(element, false);
  38984. }
  38985. }
  38986. }
  38987. //Search
  38988. tryPeekProperlyNestedBodyElement() {
  38989. return this.stackTop >= 1 && this.tagIDs[1] === TAG_ID.BODY ? this.items[1] : null;
  38990. }
  38991. contains(element) {
  38992. return this._indexOf(element) > -1;
  38993. }
  38994. getCommonAncestor(element) {
  38995. const elementIdx = this._indexOf(element) - 1;
  38996. return elementIdx >= 0 ? this.items[elementIdx] : null;
  38997. }
  38998. isRootHtmlElementCurrent() {
  38999. return this.stackTop === 0 && this.tagIDs[0] === TAG_ID.HTML;
  39000. }
  39001. //Element in scope
  39002. hasInScope(tagName) {
  39003. for (let i = this.stackTop; i >= 0; i--) {
  39004. const tn = this.tagIDs[i];
  39005. const ns = this.treeAdapter.getNamespaceURI(this.items[i]);
  39006. if (tn === tagName && ns === NS.HTML) {
  39007. return true;
  39008. }
  39009. if (SCOPING_ELEMENT_NS.get(tn) === ns) {
  39010. return false;
  39011. }
  39012. }
  39013. return true;
  39014. }
  39015. hasNumberedHeaderInScope() {
  39016. for (let i = this.stackTop; i >= 0; i--) {
  39017. const tn = this.tagIDs[i];
  39018. const ns = this.treeAdapter.getNamespaceURI(this.items[i]);
  39019. if (isNumberedHeader(tn) && ns === NS.HTML) {
  39020. return true;
  39021. }
  39022. if (SCOPING_ELEMENT_NS.get(tn) === ns) {
  39023. return false;
  39024. }
  39025. }
  39026. return true;
  39027. }
  39028. hasInListItemScope(tagName) {
  39029. for (let i = this.stackTop; i >= 0; i--) {
  39030. const tn = this.tagIDs[i];
  39031. const ns = this.treeAdapter.getNamespaceURI(this.items[i]);
  39032. if (tn === tagName && ns === NS.HTML) {
  39033. return true;
  39034. }
  39035. if ((tn === TAG_ID.UL || tn === TAG_ID.OL) && ns === NS.HTML || SCOPING_ELEMENT_NS.get(tn) === ns) {
  39036. return false;
  39037. }
  39038. }
  39039. return true;
  39040. }
  39041. hasInButtonScope(tagName) {
  39042. for (let i = this.stackTop; i >= 0; i--) {
  39043. const tn = this.tagIDs[i];
  39044. const ns = this.treeAdapter.getNamespaceURI(this.items[i]);
  39045. if (tn === tagName && ns === NS.HTML) {
  39046. return true;
  39047. }
  39048. if (tn === TAG_ID.BUTTON && ns === NS.HTML || SCOPING_ELEMENT_NS.get(tn) === ns) {
  39049. return false;
  39050. }
  39051. }
  39052. return true;
  39053. }
  39054. hasInTableScope(tagName) {
  39055. for (let i = this.stackTop; i >= 0; i--) {
  39056. const tn = this.tagIDs[i];
  39057. const ns = this.treeAdapter.getNamespaceURI(this.items[i]);
  39058. if (ns !== NS.HTML) {
  39059. continue;
  39060. }
  39061. if (tn === tagName) {
  39062. return true;
  39063. }
  39064. if (tn === TAG_ID.TABLE || tn === TAG_ID.TEMPLATE || tn === TAG_ID.HTML) {
  39065. return false;
  39066. }
  39067. }
  39068. return true;
  39069. }
  39070. hasTableBodyContextInTableScope() {
  39071. for (let i = this.stackTop; i >= 0; i--) {
  39072. const tn = this.tagIDs[i];
  39073. const ns = this.treeAdapter.getNamespaceURI(this.items[i]);
  39074. if (ns !== NS.HTML) {
  39075. continue;
  39076. }
  39077. if (tn === TAG_ID.TBODY || tn === TAG_ID.THEAD || tn === TAG_ID.TFOOT) {
  39078. return true;
  39079. }
  39080. if (tn === TAG_ID.TABLE || tn === TAG_ID.HTML) {
  39081. return false;
  39082. }
  39083. }
  39084. return true;
  39085. }
  39086. hasInSelectScope(tagName) {
  39087. for (let i = this.stackTop; i >= 0; i--) {
  39088. const tn = this.tagIDs[i];
  39089. const ns = this.treeAdapter.getNamespaceURI(this.items[i]);
  39090. if (ns !== NS.HTML) {
  39091. continue;
  39092. }
  39093. if (tn === tagName) {
  39094. return true;
  39095. }
  39096. if (tn !== TAG_ID.OPTION && tn !== TAG_ID.OPTGROUP) {
  39097. return false;
  39098. }
  39099. }
  39100. return true;
  39101. }
  39102. //Implied end tags
  39103. generateImpliedEndTags() {
  39104. while (IMPLICIT_END_TAG_REQUIRED.has(this.currentTagId)) {
  39105. this.pop();
  39106. }
  39107. }
  39108. generateImpliedEndTagsThoroughly() {
  39109. while (IMPLICIT_END_TAG_REQUIRED_THOROUGHLY.has(this.currentTagId)) {
  39110. this.pop();
  39111. }
  39112. }
  39113. generateImpliedEndTagsWithExclusion(exclusionId) {
  39114. while (this.currentTagId !== exclusionId && IMPLICIT_END_TAG_REQUIRED_THOROUGHLY.has(this.currentTagId)) {
  39115. this.pop();
  39116. }
  39117. }
  39118. };
  39119. // node_modules/parse5/dist/parser/formatting-element-list.js
  39120. var NOAH_ARK_CAPACITY = 3;
  39121. var EntryType;
  39122. (function(EntryType2) {
  39123. EntryType2[EntryType2["Marker"] = 0] = "Marker";
  39124. EntryType2[EntryType2["Element"] = 1] = "Element";
  39125. })(EntryType = EntryType || (EntryType = {}));
  39126. var MARKER = { type: EntryType.Marker };
  39127. var FormattingElementList = class {
  39128. constructor(treeAdapter) {
  39129. this.treeAdapter = treeAdapter;
  39130. this.entries = [];
  39131. this.bookmark = null;
  39132. }
  39133. //Noah Ark's condition
  39134. //OPTIMIZATION: at first we try to find possible candidates for exclusion using
  39135. //lightweight heuristics without thorough attributes check.
  39136. _getNoahArkConditionCandidates(newElement, neAttrs) {
  39137. const candidates = [];
  39138. const neAttrsLength = neAttrs.length;
  39139. const neTagName = this.treeAdapter.getTagName(newElement);
  39140. const neNamespaceURI = this.treeAdapter.getNamespaceURI(newElement);
  39141. for (let i = 0; i < this.entries.length; i++) {
  39142. const entry = this.entries[i];
  39143. if (entry.type === EntryType.Marker) {
  39144. break;
  39145. }
  39146. const { element } = entry;
  39147. if (this.treeAdapter.getTagName(element) === neTagName && this.treeAdapter.getNamespaceURI(element) === neNamespaceURI) {
  39148. const elementAttrs = this.treeAdapter.getAttrList(element);
  39149. if (elementAttrs.length === neAttrsLength) {
  39150. candidates.push({ idx: i, attrs: elementAttrs });
  39151. }
  39152. }
  39153. }
  39154. return candidates;
  39155. }
  39156. _ensureNoahArkCondition(newElement) {
  39157. if (this.entries.length < NOAH_ARK_CAPACITY)
  39158. return;
  39159. const neAttrs = this.treeAdapter.getAttrList(newElement);
  39160. const candidates = this._getNoahArkConditionCandidates(newElement, neAttrs);
  39161. if (candidates.length < NOAH_ARK_CAPACITY)
  39162. return;
  39163. const neAttrsMap = new Map(neAttrs.map((neAttr) => [neAttr.name, neAttr.value]));
  39164. let validCandidates = 0;
  39165. for (let i = 0; i < candidates.length; i++) {
  39166. const candidate = candidates[i];
  39167. if (candidate.attrs.every((cAttr) => neAttrsMap.get(cAttr.name) === cAttr.value)) {
  39168. validCandidates += 1;
  39169. if (validCandidates >= NOAH_ARK_CAPACITY) {
  39170. this.entries.splice(candidate.idx, 1);
  39171. }
  39172. }
  39173. }
  39174. }
  39175. //Mutations
  39176. insertMarker() {
  39177. this.entries.unshift(MARKER);
  39178. }
  39179. pushElement(element, token) {
  39180. this._ensureNoahArkCondition(element);
  39181. this.entries.unshift({
  39182. type: EntryType.Element,
  39183. element,
  39184. token
  39185. });
  39186. }
  39187. insertElementAfterBookmark(element, token) {
  39188. const bookmarkIdx = this.entries.indexOf(this.bookmark);
  39189. this.entries.splice(bookmarkIdx, 0, {
  39190. type: EntryType.Element,
  39191. element,
  39192. token
  39193. });
  39194. }
  39195. removeEntry(entry) {
  39196. const entryIndex = this.entries.indexOf(entry);
  39197. if (entryIndex >= 0) {
  39198. this.entries.splice(entryIndex, 1);
  39199. }
  39200. }
  39201. /**
  39202. * Clears the list of formatting elements up to the last marker.
  39203. *
  39204. * @see https://html.spec.whatwg.org/multipage/parsing.html#clear-the-list-of-active-formatting-elements-up-to-the-last-marker
  39205. */
  39206. clearToLastMarker() {
  39207. const markerIdx = this.entries.indexOf(MARKER);
  39208. if (markerIdx >= 0) {
  39209. this.entries.splice(0, markerIdx + 1);
  39210. } else {
  39211. this.entries.length = 0;
  39212. }
  39213. }
  39214. //Search
  39215. getElementEntryInScopeWithTagName(tagName) {
  39216. const entry = this.entries.find((entry2) => entry2.type === EntryType.Marker || this.treeAdapter.getTagName(entry2.element) === tagName);
  39217. return entry && entry.type === EntryType.Element ? entry : null;
  39218. }
  39219. getElementEntry(element) {
  39220. return this.entries.find((entry) => entry.type === EntryType.Element && entry.element === element);
  39221. }
  39222. };
  39223. // node_modules/parse5/dist/tree-adapters/default.js
  39224. function createTextNode(value) {
  39225. return {
  39226. nodeName: "#text",
  39227. value,
  39228. parentNode: null
  39229. };
  39230. }
  39231. var defaultTreeAdapter = {
  39232. //Node construction
  39233. createDocument() {
  39234. return {
  39235. nodeName: "#document",
  39236. mode: DOCUMENT_MODE.NO_QUIRKS,
  39237. childNodes: []
  39238. };
  39239. },
  39240. createDocumentFragment() {
  39241. return {
  39242. nodeName: "#document-fragment",
  39243. childNodes: []
  39244. };
  39245. },
  39246. createElement(tagName, namespaceURI, attrs) {
  39247. return {
  39248. nodeName: tagName,
  39249. tagName,
  39250. attrs,
  39251. namespaceURI,
  39252. childNodes: [],
  39253. parentNode: null
  39254. };
  39255. },
  39256. createCommentNode(data) {
  39257. return {
  39258. nodeName: "#comment",
  39259. data,
  39260. parentNode: null
  39261. };
  39262. },
  39263. //Tree mutation
  39264. appendChild(parentNode, newNode) {
  39265. parentNode.childNodes.push(newNode);
  39266. newNode.parentNode = parentNode;
  39267. },
  39268. insertBefore(parentNode, newNode, referenceNode) {
  39269. const insertionIdx = parentNode.childNodes.indexOf(referenceNode);
  39270. parentNode.childNodes.splice(insertionIdx, 0, newNode);
  39271. newNode.parentNode = parentNode;
  39272. },
  39273. setTemplateContent(templateElement, contentElement) {
  39274. templateElement.content = contentElement;
  39275. },
  39276. getTemplateContent(templateElement) {
  39277. return templateElement.content;
  39278. },
  39279. setDocumentType(document, name, publicId, systemId) {
  39280. const doctypeNode = document.childNodes.find((node) => node.nodeName === "#documentType");
  39281. if (doctypeNode) {
  39282. doctypeNode.name = name;
  39283. doctypeNode.publicId = publicId;
  39284. doctypeNode.systemId = systemId;
  39285. } else {
  39286. const node = {
  39287. nodeName: "#documentType",
  39288. name,
  39289. publicId,
  39290. systemId,
  39291. parentNode: null
  39292. };
  39293. defaultTreeAdapter.appendChild(document, node);
  39294. }
  39295. },
  39296. setDocumentMode(document, mode) {
  39297. document.mode = mode;
  39298. },
  39299. getDocumentMode(document) {
  39300. return document.mode;
  39301. },
  39302. detachNode(node) {
  39303. if (node.parentNode) {
  39304. const idx = node.parentNode.childNodes.indexOf(node);
  39305. node.parentNode.childNodes.splice(idx, 1);
  39306. node.parentNode = null;
  39307. }
  39308. },
  39309. insertText(parentNode, text) {
  39310. if (parentNode.childNodes.length > 0) {
  39311. const prevNode = parentNode.childNodes[parentNode.childNodes.length - 1];
  39312. if (defaultTreeAdapter.isTextNode(prevNode)) {
  39313. prevNode.value += text;
  39314. return;
  39315. }
  39316. }
  39317. defaultTreeAdapter.appendChild(parentNode, createTextNode(text));
  39318. },
  39319. insertTextBefore(parentNode, text, referenceNode) {
  39320. const prevNode = parentNode.childNodes[parentNode.childNodes.indexOf(referenceNode) - 1];
  39321. if (prevNode && defaultTreeAdapter.isTextNode(prevNode)) {
  39322. prevNode.value += text;
  39323. } else {
  39324. defaultTreeAdapter.insertBefore(parentNode, createTextNode(text), referenceNode);
  39325. }
  39326. },
  39327. adoptAttributes(recipient, attrs) {
  39328. const recipientAttrsMap = new Set(recipient.attrs.map((attr) => attr.name));
  39329. for (let j = 0; j < attrs.length; j++) {
  39330. if (!recipientAttrsMap.has(attrs[j].name)) {
  39331. recipient.attrs.push(attrs[j]);
  39332. }
  39333. }
  39334. },
  39335. //Tree traversing
  39336. getFirstChild(node) {
  39337. return node.childNodes[0];
  39338. },
  39339. getChildNodes(node) {
  39340. return node.childNodes;
  39341. },
  39342. getParentNode(node) {
  39343. return node.parentNode;
  39344. },
  39345. getAttrList(element) {
  39346. return element.attrs;
  39347. },
  39348. //Node data
  39349. getTagName(element) {
  39350. return element.tagName;
  39351. },
  39352. getNamespaceURI(element) {
  39353. return element.namespaceURI;
  39354. },
  39355. getTextNodeContent(textNode) {
  39356. return textNode.value;
  39357. },
  39358. getCommentNodeContent(commentNode) {
  39359. return commentNode.data;
  39360. },
  39361. getDocumentTypeNodeName(doctypeNode) {
  39362. return doctypeNode.name;
  39363. },
  39364. getDocumentTypeNodePublicId(doctypeNode) {
  39365. return doctypeNode.publicId;
  39366. },
  39367. getDocumentTypeNodeSystemId(doctypeNode) {
  39368. return doctypeNode.systemId;
  39369. },
  39370. //Node types
  39371. isTextNode(node) {
  39372. return node.nodeName === "#text";
  39373. },
  39374. isCommentNode(node) {
  39375. return node.nodeName === "#comment";
  39376. },
  39377. isDocumentTypeNode(node) {
  39378. return node.nodeName === "#documentType";
  39379. },
  39380. isElementNode(node) {
  39381. return Object.prototype.hasOwnProperty.call(node, "tagName");
  39382. },
  39383. // Source code location
  39384. setNodeSourceCodeLocation(node, location2) {
  39385. node.sourceCodeLocation = location2;
  39386. },
  39387. getNodeSourceCodeLocation(node) {
  39388. return node.sourceCodeLocation;
  39389. },
  39390. updateNodeSourceCodeLocation(node, endLocation) {
  39391. node.sourceCodeLocation = { ...node.sourceCodeLocation, ...endLocation };
  39392. }
  39393. };
  39394. // node_modules/parse5/dist/common/doctype.js
  39395. var VALID_DOCTYPE_NAME = "html";
  39396. var VALID_SYSTEM_ID = "about:legacy-compat";
  39397. var QUIRKS_MODE_SYSTEM_ID = "http://www.ibm.com/data/dtd/v11/ibmxhtml1-transitional.dtd";
  39398. var QUIRKS_MODE_PUBLIC_ID_PREFIXES = [
  39399. "+//silmaril//dtd html pro v0r11 19970101//",
  39400. "-//as//dtd html 3.0 aswedit + extensions//",
  39401. "-//advasoft ltd//dtd html 3.0 aswedit + extensions//",
  39402. "-//ietf//dtd html 2.0 level 1//",
  39403. "-//ietf//dtd html 2.0 level 2//",
  39404. "-//ietf//dtd html 2.0 strict level 1//",
  39405. "-//ietf//dtd html 2.0 strict level 2//",
  39406. "-//ietf//dtd html 2.0 strict//",
  39407. "-//ietf//dtd html 2.0//",
  39408. "-//ietf//dtd html 2.1e//",
  39409. "-//ietf//dtd html 3.0//",
  39410. "-//ietf//dtd html 3.2 final//",
  39411. "-//ietf//dtd html 3.2//",
  39412. "-//ietf//dtd html 3//",
  39413. "-//ietf//dtd html level 0//",
  39414. "-//ietf//dtd html level 1//",
  39415. "-//ietf//dtd html level 2//",
  39416. "-//ietf//dtd html level 3//",
  39417. "-//ietf//dtd html strict level 0//",
  39418. "-//ietf//dtd html strict level 1//",
  39419. "-//ietf//dtd html strict level 2//",
  39420. "-//ietf//dtd html strict level 3//",
  39421. "-//ietf//dtd html strict//",
  39422. "-//ietf//dtd html//",
  39423. "-//metrius//dtd metrius presentational//",
  39424. "-//microsoft//dtd internet explorer 2.0 html strict//",
  39425. "-//microsoft//dtd internet explorer 2.0 html//",
  39426. "-//microsoft//dtd internet explorer 2.0 tables//",
  39427. "-//microsoft//dtd internet explorer 3.0 html strict//",
  39428. "-//microsoft//dtd internet explorer 3.0 html//",
  39429. "-//microsoft//dtd internet explorer 3.0 tables//",
  39430. "-//netscape comm. corp.//dtd html//",
  39431. "-//netscape comm. corp.//dtd strict html//",
  39432. "-//o'reilly and associates//dtd html 2.0//",
  39433. "-//o'reilly and associates//dtd html extended 1.0//",
  39434. "-//o'reilly and associates//dtd html extended relaxed 1.0//",
  39435. "-//sq//dtd html 2.0 hotmetal + extensions//",
  39436. "-//softquad software//dtd hotmetal pro 6.0::19990601::extensions to html 4.0//",
  39437. "-//softquad//dtd hotmetal pro 4.0::19971010::extensions to html 4.0//",
  39438. "-//spyglass//dtd html 2.0 extended//",
  39439. "-//sun microsystems corp.//dtd hotjava html//",
  39440. "-//sun microsystems corp.//dtd hotjava strict html//",
  39441. "-//w3c//dtd html 3 1995-03-24//",
  39442. "-//w3c//dtd html 3.2 draft//",
  39443. "-//w3c//dtd html 3.2 final//",
  39444. "-//w3c//dtd html 3.2//",
  39445. "-//w3c//dtd html 3.2s draft//",
  39446. "-//w3c//dtd html 4.0 frameset//",
  39447. "-//w3c//dtd html 4.0 transitional//",
  39448. "-//w3c//dtd html experimental 19960712//",
  39449. "-//w3c//dtd html experimental 970421//",
  39450. "-//w3c//dtd w3 html//",
  39451. "-//w3o//dtd w3 html 3.0//",
  39452. "-//webtechs//dtd mozilla html 2.0//",
  39453. "-//webtechs//dtd mozilla html//"
  39454. ];
  39455. var QUIRKS_MODE_NO_SYSTEM_ID_PUBLIC_ID_PREFIXES = [
  39456. ...QUIRKS_MODE_PUBLIC_ID_PREFIXES,
  39457. "-//w3c//dtd html 4.01 frameset//",
  39458. "-//w3c//dtd html 4.01 transitional//"
  39459. ];
  39460. var QUIRKS_MODE_PUBLIC_IDS = /* @__PURE__ */ new Set([
  39461. "-//w3o//dtd w3 html strict 3.0//en//",
  39462. "-/w3c/dtd html 4.0 transitional/en",
  39463. "html"
  39464. ]);
  39465. var LIMITED_QUIRKS_PUBLIC_ID_PREFIXES = ["-//w3c//dtd xhtml 1.0 frameset//", "-//w3c//dtd xhtml 1.0 transitional//"];
  39466. var LIMITED_QUIRKS_WITH_SYSTEM_ID_PUBLIC_ID_PREFIXES = [
  39467. ...LIMITED_QUIRKS_PUBLIC_ID_PREFIXES,
  39468. "-//w3c//dtd html 4.01 frameset//",
  39469. "-//w3c//dtd html 4.01 transitional//"
  39470. ];
  39471. function hasPrefix(publicId, prefixes) {
  39472. return prefixes.some((prefix) => publicId.startsWith(prefix));
  39473. }
  39474. function isConforming(token) {
  39475. return token.name === VALID_DOCTYPE_NAME && token.publicId === null && (token.systemId === null || token.systemId === VALID_SYSTEM_ID);
  39476. }
  39477. function getDocumentMode(token) {
  39478. if (token.name !== VALID_DOCTYPE_NAME) {
  39479. return DOCUMENT_MODE.QUIRKS;
  39480. }
  39481. const { systemId } = token;
  39482. if (systemId && systemId.toLowerCase() === QUIRKS_MODE_SYSTEM_ID) {
  39483. return DOCUMENT_MODE.QUIRKS;
  39484. }
  39485. let { publicId } = token;
  39486. if (publicId !== null) {
  39487. publicId = publicId.toLowerCase();
  39488. if (QUIRKS_MODE_PUBLIC_IDS.has(publicId)) {
  39489. return DOCUMENT_MODE.QUIRKS;
  39490. }
  39491. let prefixes = systemId === null ? QUIRKS_MODE_NO_SYSTEM_ID_PUBLIC_ID_PREFIXES : QUIRKS_MODE_PUBLIC_ID_PREFIXES;
  39492. if (hasPrefix(publicId, prefixes)) {
  39493. return DOCUMENT_MODE.QUIRKS;
  39494. }
  39495. prefixes = systemId === null ? LIMITED_QUIRKS_PUBLIC_ID_PREFIXES : LIMITED_QUIRKS_WITH_SYSTEM_ID_PUBLIC_ID_PREFIXES;
  39496. if (hasPrefix(publicId, prefixes)) {
  39497. return DOCUMENT_MODE.LIMITED_QUIRKS;
  39498. }
  39499. }
  39500. return DOCUMENT_MODE.NO_QUIRKS;
  39501. }
  39502. // node_modules/parse5/dist/common/foreign-content.js
  39503. var foreign_content_exports = {};
  39504. __export(foreign_content_exports, {
  39505. SVG_TAG_NAMES_ADJUSTMENT_MAP: () => SVG_TAG_NAMES_ADJUSTMENT_MAP,
  39506. adjustTokenMathMLAttrs: () => adjustTokenMathMLAttrs,
  39507. adjustTokenSVGAttrs: () => adjustTokenSVGAttrs,
  39508. adjustTokenSVGTagName: () => adjustTokenSVGTagName,
  39509. adjustTokenXMLAttrs: () => adjustTokenXMLAttrs,
  39510. causesExit: () => causesExit,
  39511. isIntegrationPoint: () => isIntegrationPoint
  39512. });
  39513. var MIME_TYPES = {
  39514. TEXT_HTML: "text/html",
  39515. APPLICATION_XML: "application/xhtml+xml"
  39516. };
  39517. var DEFINITION_URL_ATTR = "definitionurl";
  39518. var ADJUSTED_DEFINITION_URL_ATTR = "definitionURL";
  39519. var SVG_ATTRS_ADJUSTMENT_MAP = new Map([
  39520. "attributeName",
  39521. "attributeType",
  39522. "baseFrequency",
  39523. "baseProfile",
  39524. "calcMode",
  39525. "clipPathUnits",
  39526. "diffuseConstant",
  39527. "edgeMode",
  39528. "filterUnits",
  39529. "glyphRef",
  39530. "gradientTransform",
  39531. "gradientUnits",
  39532. "kernelMatrix",
  39533. "kernelUnitLength",
  39534. "keyPoints",
  39535. "keySplines",
  39536. "keyTimes",
  39537. "lengthAdjust",
  39538. "limitingConeAngle",
  39539. "markerHeight",
  39540. "markerUnits",
  39541. "markerWidth",
  39542. "maskContentUnits",
  39543. "maskUnits",
  39544. "numOctaves",
  39545. "pathLength",
  39546. "patternContentUnits",
  39547. "patternTransform",
  39548. "patternUnits",
  39549. "pointsAtX",
  39550. "pointsAtY",
  39551. "pointsAtZ",
  39552. "preserveAlpha",
  39553. "preserveAspectRatio",
  39554. "primitiveUnits",
  39555. "refX",
  39556. "refY",
  39557. "repeatCount",
  39558. "repeatDur",
  39559. "requiredExtensions",
  39560. "requiredFeatures",
  39561. "specularConstant",
  39562. "specularExponent",
  39563. "spreadMethod",
  39564. "startOffset",
  39565. "stdDeviation",
  39566. "stitchTiles",
  39567. "surfaceScale",
  39568. "systemLanguage",
  39569. "tableValues",
  39570. "targetX",
  39571. "targetY",
  39572. "textLength",
  39573. "viewBox",
  39574. "viewTarget",
  39575. "xChannelSelector",
  39576. "yChannelSelector",
  39577. "zoomAndPan"
  39578. ].map((attr) => [attr.toLowerCase(), attr]));
  39579. var XML_ATTRS_ADJUSTMENT_MAP = /* @__PURE__ */ new Map([
  39580. ["xlink:actuate", { prefix: "xlink", name: "actuate", namespace: NS.XLINK }],
  39581. ["xlink:arcrole", { prefix: "xlink", name: "arcrole", namespace: NS.XLINK }],
  39582. ["xlink:href", { prefix: "xlink", name: "href", namespace: NS.XLINK }],
  39583. ["xlink:role", { prefix: "xlink", name: "role", namespace: NS.XLINK }],
  39584. ["xlink:show", { prefix: "xlink", name: "show", namespace: NS.XLINK }],
  39585. ["xlink:title", { prefix: "xlink", name: "title", namespace: NS.XLINK }],
  39586. ["xlink:type", { prefix: "xlink", name: "type", namespace: NS.XLINK }],
  39587. ["xml:base", { prefix: "xml", name: "base", namespace: NS.XML }],
  39588. ["xml:lang", { prefix: "xml", name: "lang", namespace: NS.XML }],
  39589. ["xml:space", { prefix: "xml", name: "space", namespace: NS.XML }],
  39590. ["xmlns", { prefix: "", name: "xmlns", namespace: NS.XMLNS }],
  39591. ["xmlns:xlink", { prefix: "xmlns", name: "xlink", namespace: NS.XMLNS }]
  39592. ]);
  39593. var SVG_TAG_NAMES_ADJUSTMENT_MAP = new Map([
  39594. "altGlyph",
  39595. "altGlyphDef",
  39596. "altGlyphItem",
  39597. "animateColor",
  39598. "animateMotion",
  39599. "animateTransform",
  39600. "clipPath",
  39601. "feBlend",
  39602. "feColorMatrix",
  39603. "feComponentTransfer",
  39604. "feComposite",
  39605. "feConvolveMatrix",
  39606. "feDiffuseLighting",
  39607. "feDisplacementMap",
  39608. "feDistantLight",
  39609. "feFlood",
  39610. "feFuncA",
  39611. "feFuncB",
  39612. "feFuncG",
  39613. "feFuncR",
  39614. "feGaussianBlur",
  39615. "feImage",
  39616. "feMerge",
  39617. "feMergeNode",
  39618. "feMorphology",
  39619. "feOffset",
  39620. "fePointLight",
  39621. "feSpecularLighting",
  39622. "feSpotLight",
  39623. "feTile",
  39624. "feTurbulence",
  39625. "foreignObject",
  39626. "glyphRef",
  39627. "linearGradient",
  39628. "radialGradient",
  39629. "textPath"
  39630. ].map((tn) => [tn.toLowerCase(), tn]));
  39631. var EXITS_FOREIGN_CONTENT = /* @__PURE__ */ new Set([
  39632. TAG_ID.B,
  39633. TAG_ID.BIG,
  39634. TAG_ID.BLOCKQUOTE,
  39635. TAG_ID.BODY,
  39636. TAG_ID.BR,
  39637. TAG_ID.CENTER,
  39638. TAG_ID.CODE,
  39639. TAG_ID.DD,
  39640. TAG_ID.DIV,
  39641. TAG_ID.DL,
  39642. TAG_ID.DT,
  39643. TAG_ID.EM,
  39644. TAG_ID.EMBED,
  39645. TAG_ID.H1,
  39646. TAG_ID.H2,
  39647. TAG_ID.H3,
  39648. TAG_ID.H4,
  39649. TAG_ID.H5,
  39650. TAG_ID.H6,
  39651. TAG_ID.HEAD,
  39652. TAG_ID.HR,
  39653. TAG_ID.I,
  39654. TAG_ID.IMG,
  39655. TAG_ID.LI,
  39656. TAG_ID.LISTING,
  39657. TAG_ID.MENU,
  39658. TAG_ID.META,
  39659. TAG_ID.NOBR,
  39660. TAG_ID.OL,
  39661. TAG_ID.P,
  39662. TAG_ID.PRE,
  39663. TAG_ID.RUBY,
  39664. TAG_ID.S,
  39665. TAG_ID.SMALL,
  39666. TAG_ID.SPAN,
  39667. TAG_ID.STRONG,
  39668. TAG_ID.STRIKE,
  39669. TAG_ID.SUB,
  39670. TAG_ID.SUP,
  39671. TAG_ID.TABLE,
  39672. TAG_ID.TT,
  39673. TAG_ID.U,
  39674. TAG_ID.UL,
  39675. TAG_ID.VAR
  39676. ]);
  39677. function causesExit(startTagToken) {
  39678. const tn = startTagToken.tagID;
  39679. const isFontWithAttrs = tn === TAG_ID.FONT && startTagToken.attrs.some(({ name }) => name === ATTRS.COLOR || name === ATTRS.SIZE || name === ATTRS.FACE);
  39680. return isFontWithAttrs || EXITS_FOREIGN_CONTENT.has(tn);
  39681. }
  39682. function adjustTokenMathMLAttrs(token) {
  39683. for (let i = 0; i < token.attrs.length; i++) {
  39684. if (token.attrs[i].name === DEFINITION_URL_ATTR) {
  39685. token.attrs[i].name = ADJUSTED_DEFINITION_URL_ATTR;
  39686. break;
  39687. }
  39688. }
  39689. }
  39690. function adjustTokenSVGAttrs(token) {
  39691. for (let i = 0; i < token.attrs.length; i++) {
  39692. const adjustedAttrName = SVG_ATTRS_ADJUSTMENT_MAP.get(token.attrs[i].name);
  39693. if (adjustedAttrName != null) {
  39694. token.attrs[i].name = adjustedAttrName;
  39695. }
  39696. }
  39697. }
  39698. function adjustTokenXMLAttrs(token) {
  39699. for (let i = 0; i < token.attrs.length; i++) {
  39700. const adjustedAttrEntry = XML_ATTRS_ADJUSTMENT_MAP.get(token.attrs[i].name);
  39701. if (adjustedAttrEntry) {
  39702. token.attrs[i].prefix = adjustedAttrEntry.prefix;
  39703. token.attrs[i].name = adjustedAttrEntry.name;
  39704. token.attrs[i].namespace = adjustedAttrEntry.namespace;
  39705. }
  39706. }
  39707. }
  39708. function adjustTokenSVGTagName(token) {
  39709. const adjustedTagName = SVG_TAG_NAMES_ADJUSTMENT_MAP.get(token.tagName);
  39710. if (adjustedTagName != null) {
  39711. token.tagName = adjustedTagName;
  39712. token.tagID = getTagID(token.tagName);
  39713. }
  39714. }
  39715. function isMathMLTextIntegrationPoint(tn, ns) {
  39716. return ns === NS.MATHML && (tn === TAG_ID.MI || tn === TAG_ID.MO || tn === TAG_ID.MN || tn === TAG_ID.MS || tn === TAG_ID.MTEXT);
  39717. }
  39718. function isHtmlIntegrationPoint(tn, ns, attrs) {
  39719. if (ns === NS.MATHML && tn === TAG_ID.ANNOTATION_XML) {
  39720. for (let i = 0; i < attrs.length; i++) {
  39721. if (attrs[i].name === ATTRS.ENCODING) {
  39722. const value = attrs[i].value.toLowerCase();
  39723. return value === MIME_TYPES.TEXT_HTML || value === MIME_TYPES.APPLICATION_XML;
  39724. }
  39725. }
  39726. }
  39727. return ns === NS.SVG && (tn === TAG_ID.FOREIGN_OBJECT || tn === TAG_ID.DESC || tn === TAG_ID.TITLE);
  39728. }
  39729. function isIntegrationPoint(tn, ns, attrs, foreignNS) {
  39730. return (!foreignNS || foreignNS === NS.HTML) && isHtmlIntegrationPoint(tn, ns, attrs) || (!foreignNS || foreignNS === NS.MATHML) && isMathMLTextIntegrationPoint(tn, ns);
  39731. }
  39732. // node_modules/parse5/dist/parser/index.js
  39733. var HIDDEN_INPUT_TYPE = "hidden";
  39734. var AA_OUTER_LOOP_ITER = 8;
  39735. var AA_INNER_LOOP_ITER = 3;
  39736. var InsertionMode;
  39737. (function(InsertionMode2) {
  39738. InsertionMode2[InsertionMode2["INITIAL"] = 0] = "INITIAL";
  39739. InsertionMode2[InsertionMode2["BEFORE_HTML"] = 1] = "BEFORE_HTML";
  39740. InsertionMode2[InsertionMode2["BEFORE_HEAD"] = 2] = "BEFORE_HEAD";
  39741. InsertionMode2[InsertionMode2["IN_HEAD"] = 3] = "IN_HEAD";
  39742. InsertionMode2[InsertionMode2["IN_HEAD_NO_SCRIPT"] = 4] = "IN_HEAD_NO_SCRIPT";
  39743. InsertionMode2[InsertionMode2["AFTER_HEAD"] = 5] = "AFTER_HEAD";
  39744. InsertionMode2[InsertionMode2["IN_BODY"] = 6] = "IN_BODY";
  39745. InsertionMode2[InsertionMode2["TEXT"] = 7] = "TEXT";
  39746. InsertionMode2[InsertionMode2["IN_TABLE"] = 8] = "IN_TABLE";
  39747. InsertionMode2[InsertionMode2["IN_TABLE_TEXT"] = 9] = "IN_TABLE_TEXT";
  39748. InsertionMode2[InsertionMode2["IN_CAPTION"] = 10] = "IN_CAPTION";
  39749. InsertionMode2[InsertionMode2["IN_COLUMN_GROUP"] = 11] = "IN_COLUMN_GROUP";
  39750. InsertionMode2[InsertionMode2["IN_TABLE_BODY"] = 12] = "IN_TABLE_BODY";
  39751. InsertionMode2[InsertionMode2["IN_ROW"] = 13] = "IN_ROW";
  39752. InsertionMode2[InsertionMode2["IN_CELL"] = 14] = "IN_CELL";
  39753. InsertionMode2[InsertionMode2["IN_SELECT"] = 15] = "IN_SELECT";
  39754. InsertionMode2[InsertionMode2["IN_SELECT_IN_TABLE"] = 16] = "IN_SELECT_IN_TABLE";
  39755. InsertionMode2[InsertionMode2["IN_TEMPLATE"] = 17] = "IN_TEMPLATE";
  39756. InsertionMode2[InsertionMode2["AFTER_BODY"] = 18] = "AFTER_BODY";
  39757. InsertionMode2[InsertionMode2["IN_FRAMESET"] = 19] = "IN_FRAMESET";
  39758. InsertionMode2[InsertionMode2["AFTER_FRAMESET"] = 20] = "AFTER_FRAMESET";
  39759. InsertionMode2[InsertionMode2["AFTER_AFTER_BODY"] = 21] = "AFTER_AFTER_BODY";
  39760. InsertionMode2[InsertionMode2["AFTER_AFTER_FRAMESET"] = 22] = "AFTER_AFTER_FRAMESET";
  39761. })(InsertionMode || (InsertionMode = {}));
  39762. var BASE_LOC = {
  39763. startLine: -1,
  39764. startCol: -1,
  39765. startOffset: -1,
  39766. endLine: -1,
  39767. endCol: -1,
  39768. endOffset: -1
  39769. };
  39770. var TABLE_STRUCTURE_TAGS = /* @__PURE__ */ new Set([TAG_ID.TABLE, TAG_ID.TBODY, TAG_ID.TFOOT, TAG_ID.THEAD, TAG_ID.TR]);
  39771. var defaultParserOptions = {
  39772. scriptingEnabled: true,
  39773. sourceCodeLocationInfo: false,
  39774. treeAdapter: defaultTreeAdapter,
  39775. onParseError: null
  39776. };
  39777. var Parser = class {
  39778. constructor(options, document, fragmentContext = null, scriptHandler = null) {
  39779. this.fragmentContext = fragmentContext;
  39780. this.scriptHandler = scriptHandler;
  39781. this.currentToken = null;
  39782. this.stopped = false;
  39783. this.insertionMode = InsertionMode.INITIAL;
  39784. this.originalInsertionMode = InsertionMode.INITIAL;
  39785. this.headElement = null;
  39786. this.formElement = null;
  39787. this.currentNotInHTML = false;
  39788. this.tmplInsertionModeStack = [];
  39789. this.pendingCharacterTokens = [];
  39790. this.hasNonWhitespacePendingCharacterToken = false;
  39791. this.framesetOk = true;
  39792. this.skipNextNewLine = false;
  39793. this.fosterParentingEnabled = false;
  39794. this.options = {
  39795. ...defaultParserOptions,
  39796. ...options
  39797. };
  39798. this.treeAdapter = this.options.treeAdapter;
  39799. this.onParseError = this.options.onParseError;
  39800. if (this.onParseError) {
  39801. this.options.sourceCodeLocationInfo = true;
  39802. }
  39803. this.document = document !== null && document !== void 0 ? document : this.treeAdapter.createDocument();
  39804. this.tokenizer = new Tokenizer(this.options, this);
  39805. this.activeFormattingElements = new FormattingElementList(this.treeAdapter);
  39806. this.fragmentContextID = fragmentContext ? getTagID(this.treeAdapter.getTagName(fragmentContext)) : TAG_ID.UNKNOWN;
  39807. this._setContextModes(fragmentContext !== null && fragmentContext !== void 0 ? fragmentContext : this.document, this.fragmentContextID);
  39808. this.openElements = new OpenElementStack(this.document, this.treeAdapter, this);
  39809. }
  39810. // API
  39811. static parse(html, options) {
  39812. const parser = new this(options);
  39813. parser.tokenizer.write(html, true);
  39814. return parser.document;
  39815. }
  39816. static getFragmentParser(fragmentContext, options) {
  39817. const opts = {
  39818. ...defaultParserOptions,
  39819. ...options
  39820. };
  39821. fragmentContext !== null && fragmentContext !== void 0 ? fragmentContext : fragmentContext = opts.treeAdapter.createElement(TAG_NAMES.TEMPLATE, NS.HTML, []);
  39822. const documentMock = opts.treeAdapter.createElement("documentmock", NS.HTML, []);
  39823. const parser = new this(opts, documentMock, fragmentContext);
  39824. if (parser.fragmentContextID === TAG_ID.TEMPLATE) {
  39825. parser.tmplInsertionModeStack.unshift(InsertionMode.IN_TEMPLATE);
  39826. }
  39827. parser._initTokenizerForFragmentParsing();
  39828. parser._insertFakeRootElement();
  39829. parser._resetInsertionMode();
  39830. parser._findFormInFragmentContext();
  39831. return parser;
  39832. }
  39833. getFragment() {
  39834. const rootElement = this.treeAdapter.getFirstChild(this.document);
  39835. const fragment = this.treeAdapter.createDocumentFragment();
  39836. this._adoptNodes(rootElement, fragment);
  39837. return fragment;
  39838. }
  39839. //Errors
  39840. _err(token, code, beforeToken) {
  39841. var _a2;
  39842. if (!this.onParseError)
  39843. return;
  39844. const loc = (_a2 = token.location) !== null && _a2 !== void 0 ? _a2 : BASE_LOC;
  39845. const err2 = {
  39846. code,
  39847. startLine: loc.startLine,
  39848. startCol: loc.startCol,
  39849. startOffset: loc.startOffset,
  39850. endLine: beforeToken ? loc.startLine : loc.endLine,
  39851. endCol: beforeToken ? loc.startCol : loc.endCol,
  39852. endOffset: beforeToken ? loc.startOffset : loc.endOffset
  39853. };
  39854. this.onParseError(err2);
  39855. }
  39856. //Stack events
  39857. onItemPush(node, tid, isTop) {
  39858. var _a2, _b;
  39859. (_b = (_a2 = this.treeAdapter).onItemPush) === null || _b === void 0 ? void 0 : _b.call(_a2, node);
  39860. if (isTop && this.openElements.stackTop > 0)
  39861. this._setContextModes(node, tid);
  39862. }
  39863. onItemPop(node, isTop) {
  39864. var _a2, _b;
  39865. if (this.options.sourceCodeLocationInfo) {
  39866. this._setEndLocation(node, this.currentToken);
  39867. }
  39868. (_b = (_a2 = this.treeAdapter).onItemPop) === null || _b === void 0 ? void 0 : _b.call(_a2, node, this.openElements.current);
  39869. if (isTop) {
  39870. let current;
  39871. let currentTagId;
  39872. if (this.openElements.stackTop === 0 && this.fragmentContext) {
  39873. current = this.fragmentContext;
  39874. currentTagId = this.fragmentContextID;
  39875. } else {
  39876. ({ current, currentTagId } = this.openElements);
  39877. }
  39878. this._setContextModes(current, currentTagId);
  39879. }
  39880. }
  39881. _setContextModes(current, tid) {
  39882. const isHTML = current === this.document || this.treeAdapter.getNamespaceURI(current) === NS.HTML;
  39883. this.currentNotInHTML = !isHTML;
  39884. this.tokenizer.inForeignNode = !isHTML && !this._isIntegrationPoint(tid, current);
  39885. }
  39886. _switchToTextParsing(currentToken, nextTokenizerState) {
  39887. this._insertElement(currentToken, NS.HTML);
  39888. this.tokenizer.state = nextTokenizerState;
  39889. this.originalInsertionMode = this.insertionMode;
  39890. this.insertionMode = InsertionMode.TEXT;
  39891. }
  39892. switchToPlaintextParsing() {
  39893. this.insertionMode = InsertionMode.TEXT;
  39894. this.originalInsertionMode = InsertionMode.IN_BODY;
  39895. this.tokenizer.state = TokenizerMode.PLAINTEXT;
  39896. }
  39897. //Fragment parsing
  39898. _getAdjustedCurrentElement() {
  39899. return this.openElements.stackTop === 0 && this.fragmentContext ? this.fragmentContext : this.openElements.current;
  39900. }
  39901. _findFormInFragmentContext() {
  39902. let node = this.fragmentContext;
  39903. while (node) {
  39904. if (this.treeAdapter.getTagName(node) === TAG_NAMES.FORM) {
  39905. this.formElement = node;
  39906. break;
  39907. }
  39908. node = this.treeAdapter.getParentNode(node);
  39909. }
  39910. }
  39911. _initTokenizerForFragmentParsing() {
  39912. if (!this.fragmentContext || this.treeAdapter.getNamespaceURI(this.fragmentContext) !== NS.HTML) {
  39913. return;
  39914. }
  39915. switch (this.fragmentContextID) {
  39916. case TAG_ID.TITLE:
  39917. case TAG_ID.TEXTAREA: {
  39918. this.tokenizer.state = TokenizerMode.RCDATA;
  39919. break;
  39920. }
  39921. case TAG_ID.STYLE:
  39922. case TAG_ID.XMP:
  39923. case TAG_ID.IFRAME:
  39924. case TAG_ID.NOEMBED:
  39925. case TAG_ID.NOFRAMES:
  39926. case TAG_ID.NOSCRIPT: {
  39927. this.tokenizer.state = TokenizerMode.RAWTEXT;
  39928. break;
  39929. }
  39930. case TAG_ID.SCRIPT: {
  39931. this.tokenizer.state = TokenizerMode.SCRIPT_DATA;
  39932. break;
  39933. }
  39934. case TAG_ID.PLAINTEXT: {
  39935. this.tokenizer.state = TokenizerMode.PLAINTEXT;
  39936. break;
  39937. }
  39938. default:
  39939. }
  39940. }
  39941. //Tree mutation
  39942. _setDocumentType(token) {
  39943. const name = token.name || "";
  39944. const publicId = token.publicId || "";
  39945. const systemId = token.systemId || "";
  39946. this.treeAdapter.setDocumentType(this.document, name, publicId, systemId);
  39947. if (token.location) {
  39948. const documentChildren = this.treeAdapter.getChildNodes(this.document);
  39949. const docTypeNode = documentChildren.find((node) => this.treeAdapter.isDocumentTypeNode(node));
  39950. if (docTypeNode) {
  39951. this.treeAdapter.setNodeSourceCodeLocation(docTypeNode, token.location);
  39952. }
  39953. }
  39954. }
  39955. _attachElementToTree(element, location2) {
  39956. if (this.options.sourceCodeLocationInfo) {
  39957. const loc = location2 && {
  39958. ...location2,
  39959. startTag: location2
  39960. };
  39961. this.treeAdapter.setNodeSourceCodeLocation(element, loc);
  39962. }
  39963. if (this._shouldFosterParentOnInsertion()) {
  39964. this._fosterParentElement(element);
  39965. } else {
  39966. const parent = this.openElements.currentTmplContentOrNode;
  39967. this.treeAdapter.appendChild(parent, element);
  39968. }
  39969. }
  39970. _appendElement(token, namespaceURI) {
  39971. const element = this.treeAdapter.createElement(token.tagName, namespaceURI, token.attrs);
  39972. this._attachElementToTree(element, token.location);
  39973. }
  39974. _insertElement(token, namespaceURI) {
  39975. const element = this.treeAdapter.createElement(token.tagName, namespaceURI, token.attrs);
  39976. this._attachElementToTree(element, token.location);
  39977. this.openElements.push(element, token.tagID);
  39978. }
  39979. _insertFakeElement(tagName, tagID) {
  39980. const element = this.treeAdapter.createElement(tagName, NS.HTML, []);
  39981. this._attachElementToTree(element, null);
  39982. this.openElements.push(element, tagID);
  39983. }
  39984. _insertTemplate(token) {
  39985. const tmpl = this.treeAdapter.createElement(token.tagName, NS.HTML, token.attrs);
  39986. const content = this.treeAdapter.createDocumentFragment();
  39987. this.treeAdapter.setTemplateContent(tmpl, content);
  39988. this._attachElementToTree(tmpl, token.location);
  39989. this.openElements.push(tmpl, token.tagID);
  39990. if (this.options.sourceCodeLocationInfo)
  39991. this.treeAdapter.setNodeSourceCodeLocation(content, null);
  39992. }
  39993. _insertFakeRootElement() {
  39994. const element = this.treeAdapter.createElement(TAG_NAMES.HTML, NS.HTML, []);
  39995. if (this.options.sourceCodeLocationInfo)
  39996. this.treeAdapter.setNodeSourceCodeLocation(element, null);
  39997. this.treeAdapter.appendChild(this.openElements.current, element);
  39998. this.openElements.push(element, TAG_ID.HTML);
  39999. }
  40000. _appendCommentNode(token, parent) {
  40001. const commentNode = this.treeAdapter.createCommentNode(token.data);
  40002. this.treeAdapter.appendChild(parent, commentNode);
  40003. if (this.options.sourceCodeLocationInfo) {
  40004. this.treeAdapter.setNodeSourceCodeLocation(commentNode, token.location);
  40005. }
  40006. }
  40007. _insertCharacters(token) {
  40008. let parent;
  40009. let beforeElement;
  40010. if (this._shouldFosterParentOnInsertion()) {
  40011. ({ parent, beforeElement } = this._findFosterParentingLocation());
  40012. if (beforeElement) {
  40013. this.treeAdapter.insertTextBefore(parent, token.chars, beforeElement);
  40014. } else {
  40015. this.treeAdapter.insertText(parent, token.chars);
  40016. }
  40017. } else {
  40018. parent = this.openElements.currentTmplContentOrNode;
  40019. this.treeAdapter.insertText(parent, token.chars);
  40020. }
  40021. if (!token.location)
  40022. return;
  40023. const siblings = this.treeAdapter.getChildNodes(parent);
  40024. const textNodeIdx = beforeElement ? siblings.lastIndexOf(beforeElement) : siblings.length;
  40025. const textNode = siblings[textNodeIdx - 1];
  40026. const tnLoc = this.treeAdapter.getNodeSourceCodeLocation(textNode);
  40027. if (tnLoc) {
  40028. const { endLine, endCol, endOffset } = token.location;
  40029. this.treeAdapter.updateNodeSourceCodeLocation(textNode, { endLine, endCol, endOffset });
  40030. } else if (this.options.sourceCodeLocationInfo) {
  40031. this.treeAdapter.setNodeSourceCodeLocation(textNode, token.location);
  40032. }
  40033. }
  40034. _adoptNodes(donor, recipient) {
  40035. for (let child = this.treeAdapter.getFirstChild(donor); child; child = this.treeAdapter.getFirstChild(donor)) {
  40036. this.treeAdapter.detachNode(child);
  40037. this.treeAdapter.appendChild(recipient, child);
  40038. }
  40039. }
  40040. _setEndLocation(element, closingToken) {
  40041. if (this.treeAdapter.getNodeSourceCodeLocation(element) && closingToken.location) {
  40042. const ctLoc = closingToken.location;
  40043. const tn = this.treeAdapter.getTagName(element);
  40044. const endLoc = (
  40045. // NOTE: For cases like <p> <p> </p> - First 'p' closes without a closing
  40046. // tag and for cases like <td> <p> </td> - 'p' closes without a closing tag.
  40047. closingToken.type === TokenType.END_TAG && tn === closingToken.tagName ? {
  40048. endTag: { ...ctLoc },
  40049. endLine: ctLoc.endLine,
  40050. endCol: ctLoc.endCol,
  40051. endOffset: ctLoc.endOffset
  40052. } : {
  40053. endLine: ctLoc.startLine,
  40054. endCol: ctLoc.startCol,
  40055. endOffset: ctLoc.startOffset
  40056. }
  40057. );
  40058. this.treeAdapter.updateNodeSourceCodeLocation(element, endLoc);
  40059. }
  40060. }
  40061. //Token processing
  40062. shouldProcessStartTagTokenInForeignContent(token) {
  40063. if (!this.currentNotInHTML)
  40064. return false;
  40065. let current;
  40066. let currentTagId;
  40067. if (this.openElements.stackTop === 0 && this.fragmentContext) {
  40068. current = this.fragmentContext;
  40069. currentTagId = this.fragmentContextID;
  40070. } else {
  40071. ({ current, currentTagId } = this.openElements);
  40072. }
  40073. if (token.tagID === TAG_ID.SVG && this.treeAdapter.getTagName(current) === TAG_NAMES.ANNOTATION_XML && this.treeAdapter.getNamespaceURI(current) === NS.MATHML) {
  40074. return false;
  40075. }
  40076. return (
  40077. // Check that `current` is not an integration point for HTML or MathML elements.
  40078. this.tokenizer.inForeignNode || // If it _is_ an integration point, then we might have to check that it is not an HTML
  40079. // integration point.
  40080. (token.tagID === TAG_ID.MGLYPH || token.tagID === TAG_ID.MALIGNMARK) && !this._isIntegrationPoint(currentTagId, current, NS.HTML)
  40081. );
  40082. }
  40083. _processToken(token) {
  40084. switch (token.type) {
  40085. case TokenType.CHARACTER: {
  40086. this.onCharacter(token);
  40087. break;
  40088. }
  40089. case TokenType.NULL_CHARACTER: {
  40090. this.onNullCharacter(token);
  40091. break;
  40092. }
  40093. case TokenType.COMMENT: {
  40094. this.onComment(token);
  40095. break;
  40096. }
  40097. case TokenType.DOCTYPE: {
  40098. this.onDoctype(token);
  40099. break;
  40100. }
  40101. case TokenType.START_TAG: {
  40102. this._processStartTag(token);
  40103. break;
  40104. }
  40105. case TokenType.END_TAG: {
  40106. this.onEndTag(token);
  40107. break;
  40108. }
  40109. case TokenType.EOF: {
  40110. this.onEof(token);
  40111. break;
  40112. }
  40113. case TokenType.WHITESPACE_CHARACTER: {
  40114. this.onWhitespaceCharacter(token);
  40115. break;
  40116. }
  40117. }
  40118. }
  40119. //Integration points
  40120. _isIntegrationPoint(tid, element, foreignNS) {
  40121. const ns = this.treeAdapter.getNamespaceURI(element);
  40122. const attrs = this.treeAdapter.getAttrList(element);
  40123. return isIntegrationPoint(tid, ns, attrs, foreignNS);
  40124. }
  40125. //Active formatting elements reconstruction
  40126. _reconstructActiveFormattingElements() {
  40127. const listLength = this.activeFormattingElements.entries.length;
  40128. if (listLength) {
  40129. const endIndex = this.activeFormattingElements.entries.findIndex((entry) => entry.type === EntryType.Marker || this.openElements.contains(entry.element));
  40130. const unopenIdx = endIndex < 0 ? listLength - 1 : endIndex - 1;
  40131. for (let i = unopenIdx; i >= 0; i--) {
  40132. const entry = this.activeFormattingElements.entries[i];
  40133. this._insertElement(entry.token, this.treeAdapter.getNamespaceURI(entry.element));
  40134. entry.element = this.openElements.current;
  40135. }
  40136. }
  40137. }
  40138. //Close elements
  40139. _closeTableCell() {
  40140. this.openElements.generateImpliedEndTags();
  40141. this.openElements.popUntilTableCellPopped();
  40142. this.activeFormattingElements.clearToLastMarker();
  40143. this.insertionMode = InsertionMode.IN_ROW;
  40144. }
  40145. _closePElement() {
  40146. this.openElements.generateImpliedEndTagsWithExclusion(TAG_ID.P);
  40147. this.openElements.popUntilTagNamePopped(TAG_ID.P);
  40148. }
  40149. //Insertion modes
  40150. _resetInsertionMode() {
  40151. for (let i = this.openElements.stackTop; i >= 0; i--) {
  40152. switch (i === 0 && this.fragmentContext ? this.fragmentContextID : this.openElements.tagIDs[i]) {
  40153. case TAG_ID.TR: {
  40154. this.insertionMode = InsertionMode.IN_ROW;
  40155. return;
  40156. }
  40157. case TAG_ID.TBODY:
  40158. case TAG_ID.THEAD:
  40159. case TAG_ID.TFOOT: {
  40160. this.insertionMode = InsertionMode.IN_TABLE_BODY;
  40161. return;
  40162. }
  40163. case TAG_ID.CAPTION: {
  40164. this.insertionMode = InsertionMode.IN_CAPTION;
  40165. return;
  40166. }
  40167. case TAG_ID.COLGROUP: {
  40168. this.insertionMode = InsertionMode.IN_COLUMN_GROUP;
  40169. return;
  40170. }
  40171. case TAG_ID.TABLE: {
  40172. this.insertionMode = InsertionMode.IN_TABLE;
  40173. return;
  40174. }
  40175. case TAG_ID.BODY: {
  40176. this.insertionMode = InsertionMode.IN_BODY;
  40177. return;
  40178. }
  40179. case TAG_ID.FRAMESET: {
  40180. this.insertionMode = InsertionMode.IN_FRAMESET;
  40181. return;
  40182. }
  40183. case TAG_ID.SELECT: {
  40184. this._resetInsertionModeForSelect(i);
  40185. return;
  40186. }
  40187. case TAG_ID.TEMPLATE: {
  40188. this.insertionMode = this.tmplInsertionModeStack[0];
  40189. return;
  40190. }
  40191. case TAG_ID.HTML: {
  40192. this.insertionMode = this.headElement ? InsertionMode.AFTER_HEAD : InsertionMode.BEFORE_HEAD;
  40193. return;
  40194. }
  40195. case TAG_ID.TD:
  40196. case TAG_ID.TH: {
  40197. if (i > 0) {
  40198. this.insertionMode = InsertionMode.IN_CELL;
  40199. return;
  40200. }
  40201. break;
  40202. }
  40203. case TAG_ID.HEAD: {
  40204. if (i > 0) {
  40205. this.insertionMode = InsertionMode.IN_HEAD;
  40206. return;
  40207. }
  40208. break;
  40209. }
  40210. }
  40211. }
  40212. this.insertionMode = InsertionMode.IN_BODY;
  40213. }
  40214. _resetInsertionModeForSelect(selectIdx) {
  40215. if (selectIdx > 0) {
  40216. for (let i = selectIdx - 1; i > 0; i--) {
  40217. const tn = this.openElements.tagIDs[i];
  40218. if (tn === TAG_ID.TEMPLATE) {
  40219. break;
  40220. } else if (tn === TAG_ID.TABLE) {
  40221. this.insertionMode = InsertionMode.IN_SELECT_IN_TABLE;
  40222. return;
  40223. }
  40224. }
  40225. }
  40226. this.insertionMode = InsertionMode.IN_SELECT;
  40227. }
  40228. //Foster parenting
  40229. _isElementCausesFosterParenting(tn) {
  40230. return TABLE_STRUCTURE_TAGS.has(tn);
  40231. }
  40232. _shouldFosterParentOnInsertion() {
  40233. return this.fosterParentingEnabled && this._isElementCausesFosterParenting(this.openElements.currentTagId);
  40234. }
  40235. _findFosterParentingLocation() {
  40236. for (let i = this.openElements.stackTop; i >= 0; i--) {
  40237. const openElement = this.openElements.items[i];
  40238. switch (this.openElements.tagIDs[i]) {
  40239. case TAG_ID.TEMPLATE: {
  40240. if (this.treeAdapter.getNamespaceURI(openElement) === NS.HTML) {
  40241. return { parent: this.treeAdapter.getTemplateContent(openElement), beforeElement: null };
  40242. }
  40243. break;
  40244. }
  40245. case TAG_ID.TABLE: {
  40246. const parent = this.treeAdapter.getParentNode(openElement);
  40247. if (parent) {
  40248. return { parent, beforeElement: openElement };
  40249. }
  40250. return { parent: this.openElements.items[i - 1], beforeElement: null };
  40251. }
  40252. default:
  40253. }
  40254. }
  40255. return { parent: this.openElements.items[0], beforeElement: null };
  40256. }
  40257. _fosterParentElement(element) {
  40258. const location2 = this._findFosterParentingLocation();
  40259. if (location2.beforeElement) {
  40260. this.treeAdapter.insertBefore(location2.parent, element, location2.beforeElement);
  40261. } else {
  40262. this.treeAdapter.appendChild(location2.parent, element);
  40263. }
  40264. }
  40265. //Special elements
  40266. _isSpecialElement(element, id) {
  40267. const ns = this.treeAdapter.getNamespaceURI(element);
  40268. return SPECIAL_ELEMENTS[ns].has(id);
  40269. }
  40270. onCharacter(token) {
  40271. this.skipNextNewLine = false;
  40272. if (this.tokenizer.inForeignNode) {
  40273. characterInForeignContent(this, token);
  40274. return;
  40275. }
  40276. switch (this.insertionMode) {
  40277. case InsertionMode.INITIAL: {
  40278. tokenInInitialMode(this, token);
  40279. break;
  40280. }
  40281. case InsertionMode.BEFORE_HTML: {
  40282. tokenBeforeHtml(this, token);
  40283. break;
  40284. }
  40285. case InsertionMode.BEFORE_HEAD: {
  40286. tokenBeforeHead(this, token);
  40287. break;
  40288. }
  40289. case InsertionMode.IN_HEAD: {
  40290. tokenInHead(this, token);
  40291. break;
  40292. }
  40293. case InsertionMode.IN_HEAD_NO_SCRIPT: {
  40294. tokenInHeadNoScript(this, token);
  40295. break;
  40296. }
  40297. case InsertionMode.AFTER_HEAD: {
  40298. tokenAfterHead(this, token);
  40299. break;
  40300. }
  40301. case InsertionMode.IN_BODY:
  40302. case InsertionMode.IN_CAPTION:
  40303. case InsertionMode.IN_CELL:
  40304. case InsertionMode.IN_TEMPLATE: {
  40305. characterInBody(this, token);
  40306. break;
  40307. }
  40308. case InsertionMode.TEXT:
  40309. case InsertionMode.IN_SELECT:
  40310. case InsertionMode.IN_SELECT_IN_TABLE: {
  40311. this._insertCharacters(token);
  40312. break;
  40313. }
  40314. case InsertionMode.IN_TABLE:
  40315. case InsertionMode.IN_TABLE_BODY:
  40316. case InsertionMode.IN_ROW: {
  40317. characterInTable(this, token);
  40318. break;
  40319. }
  40320. case InsertionMode.IN_TABLE_TEXT: {
  40321. characterInTableText(this, token);
  40322. break;
  40323. }
  40324. case InsertionMode.IN_COLUMN_GROUP: {
  40325. tokenInColumnGroup(this, token);
  40326. break;
  40327. }
  40328. case InsertionMode.AFTER_BODY: {
  40329. tokenAfterBody(this, token);
  40330. break;
  40331. }
  40332. case InsertionMode.AFTER_AFTER_BODY: {
  40333. tokenAfterAfterBody(this, token);
  40334. break;
  40335. }
  40336. default:
  40337. }
  40338. }
  40339. onNullCharacter(token) {
  40340. this.skipNextNewLine = false;
  40341. if (this.tokenizer.inForeignNode) {
  40342. nullCharacterInForeignContent(this, token);
  40343. return;
  40344. }
  40345. switch (this.insertionMode) {
  40346. case InsertionMode.INITIAL: {
  40347. tokenInInitialMode(this, token);
  40348. break;
  40349. }
  40350. case InsertionMode.BEFORE_HTML: {
  40351. tokenBeforeHtml(this, token);
  40352. break;
  40353. }
  40354. case InsertionMode.BEFORE_HEAD: {
  40355. tokenBeforeHead(this, token);
  40356. break;
  40357. }
  40358. case InsertionMode.IN_HEAD: {
  40359. tokenInHead(this, token);
  40360. break;
  40361. }
  40362. case InsertionMode.IN_HEAD_NO_SCRIPT: {
  40363. tokenInHeadNoScript(this, token);
  40364. break;
  40365. }
  40366. case InsertionMode.AFTER_HEAD: {
  40367. tokenAfterHead(this, token);
  40368. break;
  40369. }
  40370. case InsertionMode.TEXT: {
  40371. this._insertCharacters(token);
  40372. break;
  40373. }
  40374. case InsertionMode.IN_TABLE:
  40375. case InsertionMode.IN_TABLE_BODY:
  40376. case InsertionMode.IN_ROW: {
  40377. characterInTable(this, token);
  40378. break;
  40379. }
  40380. case InsertionMode.IN_COLUMN_GROUP: {
  40381. tokenInColumnGroup(this, token);
  40382. break;
  40383. }
  40384. case InsertionMode.AFTER_BODY: {
  40385. tokenAfterBody(this, token);
  40386. break;
  40387. }
  40388. case InsertionMode.AFTER_AFTER_BODY: {
  40389. tokenAfterAfterBody(this, token);
  40390. break;
  40391. }
  40392. default:
  40393. }
  40394. }
  40395. onComment(token) {
  40396. this.skipNextNewLine = false;
  40397. if (this.currentNotInHTML) {
  40398. appendComment(this, token);
  40399. return;
  40400. }
  40401. switch (this.insertionMode) {
  40402. case InsertionMode.INITIAL:
  40403. case InsertionMode.BEFORE_HTML:
  40404. case InsertionMode.BEFORE_HEAD:
  40405. case InsertionMode.IN_HEAD:
  40406. case InsertionMode.IN_HEAD_NO_SCRIPT:
  40407. case InsertionMode.AFTER_HEAD:
  40408. case InsertionMode.IN_BODY:
  40409. case InsertionMode.IN_TABLE:
  40410. case InsertionMode.IN_CAPTION:
  40411. case InsertionMode.IN_COLUMN_GROUP:
  40412. case InsertionMode.IN_TABLE_BODY:
  40413. case InsertionMode.IN_ROW:
  40414. case InsertionMode.IN_CELL:
  40415. case InsertionMode.IN_SELECT:
  40416. case InsertionMode.IN_SELECT_IN_TABLE:
  40417. case InsertionMode.IN_TEMPLATE:
  40418. case InsertionMode.IN_FRAMESET:
  40419. case InsertionMode.AFTER_FRAMESET: {
  40420. appendComment(this, token);
  40421. break;
  40422. }
  40423. case InsertionMode.IN_TABLE_TEXT: {
  40424. tokenInTableText(this, token);
  40425. break;
  40426. }
  40427. case InsertionMode.AFTER_BODY: {
  40428. appendCommentToRootHtmlElement(this, token);
  40429. break;
  40430. }
  40431. case InsertionMode.AFTER_AFTER_BODY:
  40432. case InsertionMode.AFTER_AFTER_FRAMESET: {
  40433. appendCommentToDocument(this, token);
  40434. break;
  40435. }
  40436. default:
  40437. }
  40438. }
  40439. onDoctype(token) {
  40440. this.skipNextNewLine = false;
  40441. switch (this.insertionMode) {
  40442. case InsertionMode.INITIAL: {
  40443. doctypeInInitialMode(this, token);
  40444. break;
  40445. }
  40446. case InsertionMode.BEFORE_HEAD:
  40447. case InsertionMode.IN_HEAD:
  40448. case InsertionMode.IN_HEAD_NO_SCRIPT:
  40449. case InsertionMode.AFTER_HEAD: {
  40450. this._err(token, ERR.misplacedDoctype);
  40451. break;
  40452. }
  40453. case InsertionMode.IN_TABLE_TEXT: {
  40454. tokenInTableText(this, token);
  40455. break;
  40456. }
  40457. default:
  40458. }
  40459. }
  40460. onStartTag(token) {
  40461. this.skipNextNewLine = false;
  40462. this.currentToken = token;
  40463. this._processStartTag(token);
  40464. if (token.selfClosing && !token.ackSelfClosing) {
  40465. this._err(token, ERR.nonVoidHtmlElementStartTagWithTrailingSolidus);
  40466. }
  40467. }
  40468. /**
  40469. * Processes a given start tag.
  40470. *
  40471. * `onStartTag` checks if a self-closing tag was recognized. When a token
  40472. * is moved inbetween multiple insertion modes, this check for self-closing
  40473. * could lead to false positives. To avoid this, `_processStartTag` is used
  40474. * for nested calls.
  40475. *
  40476. * @param token The token to process.
  40477. */
  40478. _processStartTag(token) {
  40479. if (this.shouldProcessStartTagTokenInForeignContent(token)) {
  40480. startTagInForeignContent(this, token);
  40481. } else {
  40482. this._startTagOutsideForeignContent(token);
  40483. }
  40484. }
  40485. _startTagOutsideForeignContent(token) {
  40486. switch (this.insertionMode) {
  40487. case InsertionMode.INITIAL: {
  40488. tokenInInitialMode(this, token);
  40489. break;
  40490. }
  40491. case InsertionMode.BEFORE_HTML: {
  40492. startTagBeforeHtml(this, token);
  40493. break;
  40494. }
  40495. case InsertionMode.BEFORE_HEAD: {
  40496. startTagBeforeHead(this, token);
  40497. break;
  40498. }
  40499. case InsertionMode.IN_HEAD: {
  40500. startTagInHead(this, token);
  40501. break;
  40502. }
  40503. case InsertionMode.IN_HEAD_NO_SCRIPT: {
  40504. startTagInHeadNoScript(this, token);
  40505. break;
  40506. }
  40507. case InsertionMode.AFTER_HEAD: {
  40508. startTagAfterHead(this, token);
  40509. break;
  40510. }
  40511. case InsertionMode.IN_BODY: {
  40512. startTagInBody(this, token);
  40513. break;
  40514. }
  40515. case InsertionMode.IN_TABLE: {
  40516. startTagInTable(this, token);
  40517. break;
  40518. }
  40519. case InsertionMode.IN_TABLE_TEXT: {
  40520. tokenInTableText(this, token);
  40521. break;
  40522. }
  40523. case InsertionMode.IN_CAPTION: {
  40524. startTagInCaption(this, token);
  40525. break;
  40526. }
  40527. case InsertionMode.IN_COLUMN_GROUP: {
  40528. startTagInColumnGroup(this, token);
  40529. break;
  40530. }
  40531. case InsertionMode.IN_TABLE_BODY: {
  40532. startTagInTableBody(this, token);
  40533. break;
  40534. }
  40535. case InsertionMode.IN_ROW: {
  40536. startTagInRow(this, token);
  40537. break;
  40538. }
  40539. case InsertionMode.IN_CELL: {
  40540. startTagInCell(this, token);
  40541. break;
  40542. }
  40543. case InsertionMode.IN_SELECT: {
  40544. startTagInSelect(this, token);
  40545. break;
  40546. }
  40547. case InsertionMode.IN_SELECT_IN_TABLE: {
  40548. startTagInSelectInTable(this, token);
  40549. break;
  40550. }
  40551. case InsertionMode.IN_TEMPLATE: {
  40552. startTagInTemplate(this, token);
  40553. break;
  40554. }
  40555. case InsertionMode.AFTER_BODY: {
  40556. startTagAfterBody(this, token);
  40557. break;
  40558. }
  40559. case InsertionMode.IN_FRAMESET: {
  40560. startTagInFrameset(this, token);
  40561. break;
  40562. }
  40563. case InsertionMode.AFTER_FRAMESET: {
  40564. startTagAfterFrameset(this, token);
  40565. break;
  40566. }
  40567. case InsertionMode.AFTER_AFTER_BODY: {
  40568. startTagAfterAfterBody(this, token);
  40569. break;
  40570. }
  40571. case InsertionMode.AFTER_AFTER_FRAMESET: {
  40572. startTagAfterAfterFrameset(this, token);
  40573. break;
  40574. }
  40575. default:
  40576. }
  40577. }
  40578. onEndTag(token) {
  40579. this.skipNextNewLine = false;
  40580. this.currentToken = token;
  40581. if (this.currentNotInHTML) {
  40582. endTagInForeignContent(this, token);
  40583. } else {
  40584. this._endTagOutsideForeignContent(token);
  40585. }
  40586. }
  40587. _endTagOutsideForeignContent(token) {
  40588. switch (this.insertionMode) {
  40589. case InsertionMode.INITIAL: {
  40590. tokenInInitialMode(this, token);
  40591. break;
  40592. }
  40593. case InsertionMode.BEFORE_HTML: {
  40594. endTagBeforeHtml(this, token);
  40595. break;
  40596. }
  40597. case InsertionMode.BEFORE_HEAD: {
  40598. endTagBeforeHead(this, token);
  40599. break;
  40600. }
  40601. case InsertionMode.IN_HEAD: {
  40602. endTagInHead(this, token);
  40603. break;
  40604. }
  40605. case InsertionMode.IN_HEAD_NO_SCRIPT: {
  40606. endTagInHeadNoScript(this, token);
  40607. break;
  40608. }
  40609. case InsertionMode.AFTER_HEAD: {
  40610. endTagAfterHead(this, token);
  40611. break;
  40612. }
  40613. case InsertionMode.IN_BODY: {
  40614. endTagInBody(this, token);
  40615. break;
  40616. }
  40617. case InsertionMode.TEXT: {
  40618. endTagInText(this, token);
  40619. break;
  40620. }
  40621. case InsertionMode.IN_TABLE: {
  40622. endTagInTable(this, token);
  40623. break;
  40624. }
  40625. case InsertionMode.IN_TABLE_TEXT: {
  40626. tokenInTableText(this, token);
  40627. break;
  40628. }
  40629. case InsertionMode.IN_CAPTION: {
  40630. endTagInCaption(this, token);
  40631. break;
  40632. }
  40633. case InsertionMode.IN_COLUMN_GROUP: {
  40634. endTagInColumnGroup(this, token);
  40635. break;
  40636. }
  40637. case InsertionMode.IN_TABLE_BODY: {
  40638. endTagInTableBody(this, token);
  40639. break;
  40640. }
  40641. case InsertionMode.IN_ROW: {
  40642. endTagInRow(this, token);
  40643. break;
  40644. }
  40645. case InsertionMode.IN_CELL: {
  40646. endTagInCell(this, token);
  40647. break;
  40648. }
  40649. case InsertionMode.IN_SELECT: {
  40650. endTagInSelect(this, token);
  40651. break;
  40652. }
  40653. case InsertionMode.IN_SELECT_IN_TABLE: {
  40654. endTagInSelectInTable(this, token);
  40655. break;
  40656. }
  40657. case InsertionMode.IN_TEMPLATE: {
  40658. endTagInTemplate(this, token);
  40659. break;
  40660. }
  40661. case InsertionMode.AFTER_BODY: {
  40662. endTagAfterBody(this, token);
  40663. break;
  40664. }
  40665. case InsertionMode.IN_FRAMESET: {
  40666. endTagInFrameset(this, token);
  40667. break;
  40668. }
  40669. case InsertionMode.AFTER_FRAMESET: {
  40670. endTagAfterFrameset(this, token);
  40671. break;
  40672. }
  40673. case InsertionMode.AFTER_AFTER_BODY: {
  40674. tokenAfterAfterBody(this, token);
  40675. break;
  40676. }
  40677. default:
  40678. }
  40679. }
  40680. onEof(token) {
  40681. switch (this.insertionMode) {
  40682. case InsertionMode.INITIAL: {
  40683. tokenInInitialMode(this, token);
  40684. break;
  40685. }
  40686. case InsertionMode.BEFORE_HTML: {
  40687. tokenBeforeHtml(this, token);
  40688. break;
  40689. }
  40690. case InsertionMode.BEFORE_HEAD: {
  40691. tokenBeforeHead(this, token);
  40692. break;
  40693. }
  40694. case InsertionMode.IN_HEAD: {
  40695. tokenInHead(this, token);
  40696. break;
  40697. }
  40698. case InsertionMode.IN_HEAD_NO_SCRIPT: {
  40699. tokenInHeadNoScript(this, token);
  40700. break;
  40701. }
  40702. case InsertionMode.AFTER_HEAD: {
  40703. tokenAfterHead(this, token);
  40704. break;
  40705. }
  40706. case InsertionMode.IN_BODY:
  40707. case InsertionMode.IN_TABLE:
  40708. case InsertionMode.IN_CAPTION:
  40709. case InsertionMode.IN_COLUMN_GROUP:
  40710. case InsertionMode.IN_TABLE_BODY:
  40711. case InsertionMode.IN_ROW:
  40712. case InsertionMode.IN_CELL:
  40713. case InsertionMode.IN_SELECT:
  40714. case InsertionMode.IN_SELECT_IN_TABLE: {
  40715. eofInBody(this, token);
  40716. break;
  40717. }
  40718. case InsertionMode.TEXT: {
  40719. eofInText(this, token);
  40720. break;
  40721. }
  40722. case InsertionMode.IN_TABLE_TEXT: {
  40723. tokenInTableText(this, token);
  40724. break;
  40725. }
  40726. case InsertionMode.IN_TEMPLATE: {
  40727. eofInTemplate(this, token);
  40728. break;
  40729. }
  40730. case InsertionMode.AFTER_BODY:
  40731. case InsertionMode.IN_FRAMESET:
  40732. case InsertionMode.AFTER_FRAMESET:
  40733. case InsertionMode.AFTER_AFTER_BODY:
  40734. case InsertionMode.AFTER_AFTER_FRAMESET: {
  40735. stopParsing(this, token);
  40736. break;
  40737. }
  40738. default:
  40739. }
  40740. }
  40741. onWhitespaceCharacter(token) {
  40742. if (this.skipNextNewLine) {
  40743. this.skipNextNewLine = false;
  40744. if (token.chars.charCodeAt(0) === CODE_POINTS.LINE_FEED) {
  40745. if (token.chars.length === 1) {
  40746. return;
  40747. }
  40748. token.chars = token.chars.substr(1);
  40749. }
  40750. }
  40751. if (this.tokenizer.inForeignNode) {
  40752. this._insertCharacters(token);
  40753. return;
  40754. }
  40755. switch (this.insertionMode) {
  40756. case InsertionMode.IN_HEAD:
  40757. case InsertionMode.IN_HEAD_NO_SCRIPT:
  40758. case InsertionMode.AFTER_HEAD:
  40759. case InsertionMode.TEXT:
  40760. case InsertionMode.IN_COLUMN_GROUP:
  40761. case InsertionMode.IN_SELECT:
  40762. case InsertionMode.IN_SELECT_IN_TABLE:
  40763. case InsertionMode.IN_FRAMESET:
  40764. case InsertionMode.AFTER_FRAMESET: {
  40765. this._insertCharacters(token);
  40766. break;
  40767. }
  40768. case InsertionMode.IN_BODY:
  40769. case InsertionMode.IN_CAPTION:
  40770. case InsertionMode.IN_CELL:
  40771. case InsertionMode.IN_TEMPLATE:
  40772. case InsertionMode.AFTER_BODY:
  40773. case InsertionMode.AFTER_AFTER_BODY:
  40774. case InsertionMode.AFTER_AFTER_FRAMESET: {
  40775. whitespaceCharacterInBody(this, token);
  40776. break;
  40777. }
  40778. case InsertionMode.IN_TABLE:
  40779. case InsertionMode.IN_TABLE_BODY:
  40780. case InsertionMode.IN_ROW: {
  40781. characterInTable(this, token);
  40782. break;
  40783. }
  40784. case InsertionMode.IN_TABLE_TEXT: {
  40785. whitespaceCharacterInTableText(this, token);
  40786. break;
  40787. }
  40788. default:
  40789. }
  40790. }
  40791. };
  40792. function aaObtainFormattingElementEntry(p, token) {
  40793. let formattingElementEntry = p.activeFormattingElements.getElementEntryInScopeWithTagName(token.tagName);
  40794. if (formattingElementEntry) {
  40795. if (!p.openElements.contains(formattingElementEntry.element)) {
  40796. p.activeFormattingElements.removeEntry(formattingElementEntry);
  40797. formattingElementEntry = null;
  40798. } else if (!p.openElements.hasInScope(token.tagID)) {
  40799. formattingElementEntry = null;
  40800. }
  40801. } else {
  40802. genericEndTagInBody(p, token);
  40803. }
  40804. return formattingElementEntry;
  40805. }
  40806. function aaObtainFurthestBlock(p, formattingElementEntry) {
  40807. let furthestBlock = null;
  40808. let idx = p.openElements.stackTop;
  40809. for (; idx >= 0; idx--) {
  40810. const element = p.openElements.items[idx];
  40811. if (element === formattingElementEntry.element) {
  40812. break;
  40813. }
  40814. if (p._isSpecialElement(element, p.openElements.tagIDs[idx])) {
  40815. furthestBlock = element;
  40816. }
  40817. }
  40818. if (!furthestBlock) {
  40819. p.openElements.shortenToLength(idx < 0 ? 0 : idx);
  40820. p.activeFormattingElements.removeEntry(formattingElementEntry);
  40821. }
  40822. return furthestBlock;
  40823. }
  40824. function aaInnerLoop(p, furthestBlock, formattingElement) {
  40825. let lastElement = furthestBlock;
  40826. let nextElement = p.openElements.getCommonAncestor(furthestBlock);
  40827. for (let i = 0, element = nextElement; element !== formattingElement; i++, element = nextElement) {
  40828. nextElement = p.openElements.getCommonAncestor(element);
  40829. const elementEntry = p.activeFormattingElements.getElementEntry(element);
  40830. const counterOverflow = elementEntry && i >= AA_INNER_LOOP_ITER;
  40831. const shouldRemoveFromOpenElements = !elementEntry || counterOverflow;
  40832. if (shouldRemoveFromOpenElements) {
  40833. if (counterOverflow) {
  40834. p.activeFormattingElements.removeEntry(elementEntry);
  40835. }
  40836. p.openElements.remove(element);
  40837. } else {
  40838. element = aaRecreateElementFromEntry(p, elementEntry);
  40839. if (lastElement === furthestBlock) {
  40840. p.activeFormattingElements.bookmark = elementEntry;
  40841. }
  40842. p.treeAdapter.detachNode(lastElement);
  40843. p.treeAdapter.appendChild(element, lastElement);
  40844. lastElement = element;
  40845. }
  40846. }
  40847. return lastElement;
  40848. }
  40849. function aaRecreateElementFromEntry(p, elementEntry) {
  40850. const ns = p.treeAdapter.getNamespaceURI(elementEntry.element);
  40851. const newElement = p.treeAdapter.createElement(elementEntry.token.tagName, ns, elementEntry.token.attrs);
  40852. p.openElements.replace(elementEntry.element, newElement);
  40853. elementEntry.element = newElement;
  40854. return newElement;
  40855. }
  40856. function aaInsertLastNodeInCommonAncestor(p, commonAncestor, lastElement) {
  40857. const tn = p.treeAdapter.getTagName(commonAncestor);
  40858. const tid = getTagID(tn);
  40859. if (p._isElementCausesFosterParenting(tid)) {
  40860. p._fosterParentElement(lastElement);
  40861. } else {
  40862. const ns = p.treeAdapter.getNamespaceURI(commonAncestor);
  40863. if (tid === TAG_ID.TEMPLATE && ns === NS.HTML) {
  40864. commonAncestor = p.treeAdapter.getTemplateContent(commonAncestor);
  40865. }
  40866. p.treeAdapter.appendChild(commonAncestor, lastElement);
  40867. }
  40868. }
  40869. function aaReplaceFormattingElement(p, furthestBlock, formattingElementEntry) {
  40870. const ns = p.treeAdapter.getNamespaceURI(formattingElementEntry.element);
  40871. const { token } = formattingElementEntry;
  40872. const newElement = p.treeAdapter.createElement(token.tagName, ns, token.attrs);
  40873. p._adoptNodes(furthestBlock, newElement);
  40874. p.treeAdapter.appendChild(furthestBlock, newElement);
  40875. p.activeFormattingElements.insertElementAfterBookmark(newElement, token);
  40876. p.activeFormattingElements.removeEntry(formattingElementEntry);
  40877. p.openElements.remove(formattingElementEntry.element);
  40878. p.openElements.insertAfter(furthestBlock, newElement, token.tagID);
  40879. }
  40880. function callAdoptionAgency(p, token) {
  40881. for (let i = 0; i < AA_OUTER_LOOP_ITER; i++) {
  40882. const formattingElementEntry = aaObtainFormattingElementEntry(p, token);
  40883. if (!formattingElementEntry) {
  40884. break;
  40885. }
  40886. const furthestBlock = aaObtainFurthestBlock(p, formattingElementEntry);
  40887. if (!furthestBlock) {
  40888. break;
  40889. }
  40890. p.activeFormattingElements.bookmark = formattingElementEntry;
  40891. const lastElement = aaInnerLoop(p, furthestBlock, formattingElementEntry.element);
  40892. const commonAncestor = p.openElements.getCommonAncestor(formattingElementEntry.element);
  40893. p.treeAdapter.detachNode(lastElement);
  40894. if (commonAncestor)
  40895. aaInsertLastNodeInCommonAncestor(p, commonAncestor, lastElement);
  40896. aaReplaceFormattingElement(p, furthestBlock, formattingElementEntry);
  40897. }
  40898. }
  40899. function appendComment(p, token) {
  40900. p._appendCommentNode(token, p.openElements.currentTmplContentOrNode);
  40901. }
  40902. function appendCommentToRootHtmlElement(p, token) {
  40903. p._appendCommentNode(token, p.openElements.items[0]);
  40904. }
  40905. function appendCommentToDocument(p, token) {
  40906. p._appendCommentNode(token, p.document);
  40907. }
  40908. function stopParsing(p, token) {
  40909. p.stopped = true;
  40910. if (token.location) {
  40911. const target = p.fragmentContext ? 0 : 2;
  40912. for (let i = p.openElements.stackTop; i >= target; i--) {
  40913. p._setEndLocation(p.openElements.items[i], token);
  40914. }
  40915. if (!p.fragmentContext && p.openElements.stackTop >= 0) {
  40916. const htmlElement = p.openElements.items[0];
  40917. const htmlLocation = p.treeAdapter.getNodeSourceCodeLocation(htmlElement);
  40918. if (htmlLocation && !htmlLocation.endTag) {
  40919. p._setEndLocation(htmlElement, token);
  40920. if (p.openElements.stackTop >= 1) {
  40921. const bodyElement = p.openElements.items[1];
  40922. const bodyLocation = p.treeAdapter.getNodeSourceCodeLocation(bodyElement);
  40923. if (bodyLocation && !bodyLocation.endTag) {
  40924. p._setEndLocation(bodyElement, token);
  40925. }
  40926. }
  40927. }
  40928. }
  40929. }
  40930. }
  40931. function doctypeInInitialMode(p, token) {
  40932. p._setDocumentType(token);
  40933. const mode = token.forceQuirks ? DOCUMENT_MODE.QUIRKS : getDocumentMode(token);
  40934. if (!isConforming(token)) {
  40935. p._err(token, ERR.nonConformingDoctype);
  40936. }
  40937. p.treeAdapter.setDocumentMode(p.document, mode);
  40938. p.insertionMode = InsertionMode.BEFORE_HTML;
  40939. }
  40940. function tokenInInitialMode(p, token) {
  40941. p._err(token, ERR.missingDoctype, true);
  40942. p.treeAdapter.setDocumentMode(p.document, DOCUMENT_MODE.QUIRKS);
  40943. p.insertionMode = InsertionMode.BEFORE_HTML;
  40944. p._processToken(token);
  40945. }
  40946. function startTagBeforeHtml(p, token) {
  40947. if (token.tagID === TAG_ID.HTML) {
  40948. p._insertElement(token, NS.HTML);
  40949. p.insertionMode = InsertionMode.BEFORE_HEAD;
  40950. } else {
  40951. tokenBeforeHtml(p, token);
  40952. }
  40953. }
  40954. function endTagBeforeHtml(p, token) {
  40955. const tn = token.tagID;
  40956. if (tn === TAG_ID.HTML || tn === TAG_ID.HEAD || tn === TAG_ID.BODY || tn === TAG_ID.BR) {
  40957. tokenBeforeHtml(p, token);
  40958. }
  40959. }
  40960. function tokenBeforeHtml(p, token) {
  40961. p._insertFakeRootElement();
  40962. p.insertionMode = InsertionMode.BEFORE_HEAD;
  40963. p._processToken(token);
  40964. }
  40965. function startTagBeforeHead(p, token) {
  40966. switch (token.tagID) {
  40967. case TAG_ID.HTML: {
  40968. startTagInBody(p, token);
  40969. break;
  40970. }
  40971. case TAG_ID.HEAD: {
  40972. p._insertElement(token, NS.HTML);
  40973. p.headElement = p.openElements.current;
  40974. p.insertionMode = InsertionMode.IN_HEAD;
  40975. break;
  40976. }
  40977. default: {
  40978. tokenBeforeHead(p, token);
  40979. }
  40980. }
  40981. }
  40982. function endTagBeforeHead(p, token) {
  40983. const tn = token.tagID;
  40984. if (tn === TAG_ID.HEAD || tn === TAG_ID.BODY || tn === TAG_ID.HTML || tn === TAG_ID.BR) {
  40985. tokenBeforeHead(p, token);
  40986. } else {
  40987. p._err(token, ERR.endTagWithoutMatchingOpenElement);
  40988. }
  40989. }
  40990. function tokenBeforeHead(p, token) {
  40991. p._insertFakeElement(TAG_NAMES.HEAD, TAG_ID.HEAD);
  40992. p.headElement = p.openElements.current;
  40993. p.insertionMode = InsertionMode.IN_HEAD;
  40994. p._processToken(token);
  40995. }
  40996. function startTagInHead(p, token) {
  40997. switch (token.tagID) {
  40998. case TAG_ID.HTML: {
  40999. startTagInBody(p, token);
  41000. break;
  41001. }
  41002. case TAG_ID.BASE:
  41003. case TAG_ID.BASEFONT:
  41004. case TAG_ID.BGSOUND:
  41005. case TAG_ID.LINK:
  41006. case TAG_ID.META: {
  41007. p._appendElement(token, NS.HTML);
  41008. token.ackSelfClosing = true;
  41009. break;
  41010. }
  41011. case TAG_ID.TITLE: {
  41012. p._switchToTextParsing(token, TokenizerMode.RCDATA);
  41013. break;
  41014. }
  41015. case TAG_ID.NOSCRIPT: {
  41016. if (p.options.scriptingEnabled) {
  41017. p._switchToTextParsing(token, TokenizerMode.RAWTEXT);
  41018. } else {
  41019. p._insertElement(token, NS.HTML);
  41020. p.insertionMode = InsertionMode.IN_HEAD_NO_SCRIPT;
  41021. }
  41022. break;
  41023. }
  41024. case TAG_ID.NOFRAMES:
  41025. case TAG_ID.STYLE: {
  41026. p._switchToTextParsing(token, TokenizerMode.RAWTEXT);
  41027. break;
  41028. }
  41029. case TAG_ID.SCRIPT: {
  41030. p._switchToTextParsing(token, TokenizerMode.SCRIPT_DATA);
  41031. break;
  41032. }
  41033. case TAG_ID.TEMPLATE: {
  41034. p._insertTemplate(token);
  41035. p.activeFormattingElements.insertMarker();
  41036. p.framesetOk = false;
  41037. p.insertionMode = InsertionMode.IN_TEMPLATE;
  41038. p.tmplInsertionModeStack.unshift(InsertionMode.IN_TEMPLATE);
  41039. break;
  41040. }
  41041. case TAG_ID.HEAD: {
  41042. p._err(token, ERR.misplacedStartTagForHeadElement);
  41043. break;
  41044. }
  41045. default: {
  41046. tokenInHead(p, token);
  41047. }
  41048. }
  41049. }
  41050. function endTagInHead(p, token) {
  41051. switch (token.tagID) {
  41052. case TAG_ID.HEAD: {
  41053. p.openElements.pop();
  41054. p.insertionMode = InsertionMode.AFTER_HEAD;
  41055. break;
  41056. }
  41057. case TAG_ID.BODY:
  41058. case TAG_ID.BR:
  41059. case TAG_ID.HTML: {
  41060. tokenInHead(p, token);
  41061. break;
  41062. }
  41063. case TAG_ID.TEMPLATE: {
  41064. templateEndTagInHead(p, token);
  41065. break;
  41066. }
  41067. default: {
  41068. p._err(token, ERR.endTagWithoutMatchingOpenElement);
  41069. }
  41070. }
  41071. }
  41072. function templateEndTagInHead(p, token) {
  41073. if (p.openElements.tmplCount > 0) {
  41074. p.openElements.generateImpliedEndTagsThoroughly();
  41075. if (p.openElements.currentTagId !== TAG_ID.TEMPLATE) {
  41076. p._err(token, ERR.closingOfElementWithOpenChildElements);
  41077. }
  41078. p.openElements.popUntilTagNamePopped(TAG_ID.TEMPLATE);
  41079. p.activeFormattingElements.clearToLastMarker();
  41080. p.tmplInsertionModeStack.shift();
  41081. p._resetInsertionMode();
  41082. } else {
  41083. p._err(token, ERR.endTagWithoutMatchingOpenElement);
  41084. }
  41085. }
  41086. function tokenInHead(p, token) {
  41087. p.openElements.pop();
  41088. p.insertionMode = InsertionMode.AFTER_HEAD;
  41089. p._processToken(token);
  41090. }
  41091. function startTagInHeadNoScript(p, token) {
  41092. switch (token.tagID) {
  41093. case TAG_ID.HTML: {
  41094. startTagInBody(p, token);
  41095. break;
  41096. }
  41097. case TAG_ID.BASEFONT:
  41098. case TAG_ID.BGSOUND:
  41099. case TAG_ID.HEAD:
  41100. case TAG_ID.LINK:
  41101. case TAG_ID.META:
  41102. case TAG_ID.NOFRAMES:
  41103. case TAG_ID.STYLE: {
  41104. startTagInHead(p, token);
  41105. break;
  41106. }
  41107. case TAG_ID.NOSCRIPT: {
  41108. p._err(token, ERR.nestedNoscriptInHead);
  41109. break;
  41110. }
  41111. default: {
  41112. tokenInHeadNoScript(p, token);
  41113. }
  41114. }
  41115. }
  41116. function endTagInHeadNoScript(p, token) {
  41117. switch (token.tagID) {
  41118. case TAG_ID.NOSCRIPT: {
  41119. p.openElements.pop();
  41120. p.insertionMode = InsertionMode.IN_HEAD;
  41121. break;
  41122. }
  41123. case TAG_ID.BR: {
  41124. tokenInHeadNoScript(p, token);
  41125. break;
  41126. }
  41127. default: {
  41128. p._err(token, ERR.endTagWithoutMatchingOpenElement);
  41129. }
  41130. }
  41131. }
  41132. function tokenInHeadNoScript(p, token) {
  41133. const errCode = token.type === TokenType.EOF ? ERR.openElementsLeftAfterEof : ERR.disallowedContentInNoscriptInHead;
  41134. p._err(token, errCode);
  41135. p.openElements.pop();
  41136. p.insertionMode = InsertionMode.IN_HEAD;
  41137. p._processToken(token);
  41138. }
  41139. function startTagAfterHead(p, token) {
  41140. switch (token.tagID) {
  41141. case TAG_ID.HTML: {
  41142. startTagInBody(p, token);
  41143. break;
  41144. }
  41145. case TAG_ID.BODY: {
  41146. p._insertElement(token, NS.HTML);
  41147. p.framesetOk = false;
  41148. p.insertionMode = InsertionMode.IN_BODY;
  41149. break;
  41150. }
  41151. case TAG_ID.FRAMESET: {
  41152. p._insertElement(token, NS.HTML);
  41153. p.insertionMode = InsertionMode.IN_FRAMESET;
  41154. break;
  41155. }
  41156. case TAG_ID.BASE:
  41157. case TAG_ID.BASEFONT:
  41158. case TAG_ID.BGSOUND:
  41159. case TAG_ID.LINK:
  41160. case TAG_ID.META:
  41161. case TAG_ID.NOFRAMES:
  41162. case TAG_ID.SCRIPT:
  41163. case TAG_ID.STYLE:
  41164. case TAG_ID.TEMPLATE:
  41165. case TAG_ID.TITLE: {
  41166. p._err(token, ERR.abandonedHeadElementChild);
  41167. p.openElements.push(p.headElement, TAG_ID.HEAD);
  41168. startTagInHead(p, token);
  41169. p.openElements.remove(p.headElement);
  41170. break;
  41171. }
  41172. case TAG_ID.HEAD: {
  41173. p._err(token, ERR.misplacedStartTagForHeadElement);
  41174. break;
  41175. }
  41176. default: {
  41177. tokenAfterHead(p, token);
  41178. }
  41179. }
  41180. }
  41181. function endTagAfterHead(p, token) {
  41182. switch (token.tagID) {
  41183. case TAG_ID.BODY:
  41184. case TAG_ID.HTML:
  41185. case TAG_ID.BR: {
  41186. tokenAfterHead(p, token);
  41187. break;
  41188. }
  41189. case TAG_ID.TEMPLATE: {
  41190. templateEndTagInHead(p, token);
  41191. break;
  41192. }
  41193. default: {
  41194. p._err(token, ERR.endTagWithoutMatchingOpenElement);
  41195. }
  41196. }
  41197. }
  41198. function tokenAfterHead(p, token) {
  41199. p._insertFakeElement(TAG_NAMES.BODY, TAG_ID.BODY);
  41200. p.insertionMode = InsertionMode.IN_BODY;
  41201. modeInBody(p, token);
  41202. }
  41203. function modeInBody(p, token) {
  41204. switch (token.type) {
  41205. case TokenType.CHARACTER: {
  41206. characterInBody(p, token);
  41207. break;
  41208. }
  41209. case TokenType.WHITESPACE_CHARACTER: {
  41210. whitespaceCharacterInBody(p, token);
  41211. break;
  41212. }
  41213. case TokenType.COMMENT: {
  41214. appendComment(p, token);
  41215. break;
  41216. }
  41217. case TokenType.START_TAG: {
  41218. startTagInBody(p, token);
  41219. break;
  41220. }
  41221. case TokenType.END_TAG: {
  41222. endTagInBody(p, token);
  41223. break;
  41224. }
  41225. case TokenType.EOF: {
  41226. eofInBody(p, token);
  41227. break;
  41228. }
  41229. default:
  41230. }
  41231. }
  41232. function whitespaceCharacterInBody(p, token) {
  41233. p._reconstructActiveFormattingElements();
  41234. p._insertCharacters(token);
  41235. }
  41236. function characterInBody(p, token) {
  41237. p._reconstructActiveFormattingElements();
  41238. p._insertCharacters(token);
  41239. p.framesetOk = false;
  41240. }
  41241. function htmlStartTagInBody(p, token) {
  41242. if (p.openElements.tmplCount === 0) {
  41243. p.treeAdapter.adoptAttributes(p.openElements.items[0], token.attrs);
  41244. }
  41245. }
  41246. function bodyStartTagInBody(p, token) {
  41247. const bodyElement = p.openElements.tryPeekProperlyNestedBodyElement();
  41248. if (bodyElement && p.openElements.tmplCount === 0) {
  41249. p.framesetOk = false;
  41250. p.treeAdapter.adoptAttributes(bodyElement, token.attrs);
  41251. }
  41252. }
  41253. function framesetStartTagInBody(p, token) {
  41254. const bodyElement = p.openElements.tryPeekProperlyNestedBodyElement();
  41255. if (p.framesetOk && bodyElement) {
  41256. p.treeAdapter.detachNode(bodyElement);
  41257. p.openElements.popAllUpToHtmlElement();
  41258. p._insertElement(token, NS.HTML);
  41259. p.insertionMode = InsertionMode.IN_FRAMESET;
  41260. }
  41261. }
  41262. function addressStartTagInBody(p, token) {
  41263. if (p.openElements.hasInButtonScope(TAG_ID.P)) {
  41264. p._closePElement();
  41265. }
  41266. p._insertElement(token, NS.HTML);
  41267. }
  41268. function numberedHeaderStartTagInBody(p, token) {
  41269. if (p.openElements.hasInButtonScope(TAG_ID.P)) {
  41270. p._closePElement();
  41271. }
  41272. if (isNumberedHeader(p.openElements.currentTagId)) {
  41273. p.openElements.pop();
  41274. }
  41275. p._insertElement(token, NS.HTML);
  41276. }
  41277. function preStartTagInBody(p, token) {
  41278. if (p.openElements.hasInButtonScope(TAG_ID.P)) {
  41279. p._closePElement();
  41280. }
  41281. p._insertElement(token, NS.HTML);
  41282. p.skipNextNewLine = true;
  41283. p.framesetOk = false;
  41284. }
  41285. function formStartTagInBody(p, token) {
  41286. const inTemplate = p.openElements.tmplCount > 0;
  41287. if (!p.formElement || inTemplate) {
  41288. if (p.openElements.hasInButtonScope(TAG_ID.P)) {
  41289. p._closePElement();
  41290. }
  41291. p._insertElement(token, NS.HTML);
  41292. if (!inTemplate) {
  41293. p.formElement = p.openElements.current;
  41294. }
  41295. }
  41296. }
  41297. function listItemStartTagInBody(p, token) {
  41298. p.framesetOk = false;
  41299. const tn = token.tagID;
  41300. for (let i = p.openElements.stackTop; i >= 0; i--) {
  41301. const elementId = p.openElements.tagIDs[i];
  41302. if (tn === TAG_ID.LI && elementId === TAG_ID.LI || (tn === TAG_ID.DD || tn === TAG_ID.DT) && (elementId === TAG_ID.DD || elementId === TAG_ID.DT)) {
  41303. p.openElements.generateImpliedEndTagsWithExclusion(elementId);
  41304. p.openElements.popUntilTagNamePopped(elementId);
  41305. break;
  41306. }
  41307. if (elementId !== TAG_ID.ADDRESS && elementId !== TAG_ID.DIV && elementId !== TAG_ID.P && p._isSpecialElement(p.openElements.items[i], elementId)) {
  41308. break;
  41309. }
  41310. }
  41311. if (p.openElements.hasInButtonScope(TAG_ID.P)) {
  41312. p._closePElement();
  41313. }
  41314. p._insertElement(token, NS.HTML);
  41315. }
  41316. function plaintextStartTagInBody(p, token) {
  41317. if (p.openElements.hasInButtonScope(TAG_ID.P)) {
  41318. p._closePElement();
  41319. }
  41320. p._insertElement(token, NS.HTML);
  41321. p.tokenizer.state = TokenizerMode.PLAINTEXT;
  41322. }
  41323. function buttonStartTagInBody(p, token) {
  41324. if (p.openElements.hasInScope(TAG_ID.BUTTON)) {
  41325. p.openElements.generateImpliedEndTags();
  41326. p.openElements.popUntilTagNamePopped(TAG_ID.BUTTON);
  41327. }
  41328. p._reconstructActiveFormattingElements();
  41329. p._insertElement(token, NS.HTML);
  41330. p.framesetOk = false;
  41331. }
  41332. function aStartTagInBody(p, token) {
  41333. const activeElementEntry = p.activeFormattingElements.getElementEntryInScopeWithTagName(TAG_NAMES.A);
  41334. if (activeElementEntry) {
  41335. callAdoptionAgency(p, token);
  41336. p.openElements.remove(activeElementEntry.element);
  41337. p.activeFormattingElements.removeEntry(activeElementEntry);
  41338. }
  41339. p._reconstructActiveFormattingElements();
  41340. p._insertElement(token, NS.HTML);
  41341. p.activeFormattingElements.pushElement(p.openElements.current, token);
  41342. }
  41343. function bStartTagInBody(p, token) {
  41344. p._reconstructActiveFormattingElements();
  41345. p._insertElement(token, NS.HTML);
  41346. p.activeFormattingElements.pushElement(p.openElements.current, token);
  41347. }
  41348. function nobrStartTagInBody(p, token) {
  41349. p._reconstructActiveFormattingElements();
  41350. if (p.openElements.hasInScope(TAG_ID.NOBR)) {
  41351. callAdoptionAgency(p, token);
  41352. p._reconstructActiveFormattingElements();
  41353. }
  41354. p._insertElement(token, NS.HTML);
  41355. p.activeFormattingElements.pushElement(p.openElements.current, token);
  41356. }
  41357. function appletStartTagInBody(p, token) {
  41358. p._reconstructActiveFormattingElements();
  41359. p._insertElement(token, NS.HTML);
  41360. p.activeFormattingElements.insertMarker();
  41361. p.framesetOk = false;
  41362. }
  41363. function tableStartTagInBody(p, token) {
  41364. if (p.treeAdapter.getDocumentMode(p.document) !== DOCUMENT_MODE.QUIRKS && p.openElements.hasInButtonScope(TAG_ID.P)) {
  41365. p._closePElement();
  41366. }
  41367. p._insertElement(token, NS.HTML);
  41368. p.framesetOk = false;
  41369. p.insertionMode = InsertionMode.IN_TABLE;
  41370. }
  41371. function areaStartTagInBody(p, token) {
  41372. p._reconstructActiveFormattingElements();
  41373. p._appendElement(token, NS.HTML);
  41374. p.framesetOk = false;
  41375. token.ackSelfClosing = true;
  41376. }
  41377. function isHiddenInput(token) {
  41378. const inputType = getTokenAttr(token, ATTRS.TYPE);
  41379. return inputType != null && inputType.toLowerCase() === HIDDEN_INPUT_TYPE;
  41380. }
  41381. function inputStartTagInBody(p, token) {
  41382. p._reconstructActiveFormattingElements();
  41383. p._appendElement(token, NS.HTML);
  41384. if (!isHiddenInput(token)) {
  41385. p.framesetOk = false;
  41386. }
  41387. token.ackSelfClosing = true;
  41388. }
  41389. function paramStartTagInBody(p, token) {
  41390. p._appendElement(token, NS.HTML);
  41391. token.ackSelfClosing = true;
  41392. }
  41393. function hrStartTagInBody(p, token) {
  41394. if (p.openElements.hasInButtonScope(TAG_ID.P)) {
  41395. p._closePElement();
  41396. }
  41397. p._appendElement(token, NS.HTML);
  41398. p.framesetOk = false;
  41399. token.ackSelfClosing = true;
  41400. }
  41401. function imageStartTagInBody(p, token) {
  41402. token.tagName = TAG_NAMES.IMG;
  41403. token.tagID = TAG_ID.IMG;
  41404. areaStartTagInBody(p, token);
  41405. }
  41406. function textareaStartTagInBody(p, token) {
  41407. p._insertElement(token, NS.HTML);
  41408. p.skipNextNewLine = true;
  41409. p.tokenizer.state = TokenizerMode.RCDATA;
  41410. p.originalInsertionMode = p.insertionMode;
  41411. p.framesetOk = false;
  41412. p.insertionMode = InsertionMode.TEXT;
  41413. }
  41414. function xmpStartTagInBody(p, token) {
  41415. if (p.openElements.hasInButtonScope(TAG_ID.P)) {
  41416. p._closePElement();
  41417. }
  41418. p._reconstructActiveFormattingElements();
  41419. p.framesetOk = false;
  41420. p._switchToTextParsing(token, TokenizerMode.RAWTEXT);
  41421. }
  41422. function iframeStartTagInBody(p, token) {
  41423. p.framesetOk = false;
  41424. p._switchToTextParsing(token, TokenizerMode.RAWTEXT);
  41425. }
  41426. function noembedStartTagInBody(p, token) {
  41427. p._switchToTextParsing(token, TokenizerMode.RAWTEXT);
  41428. }
  41429. function selectStartTagInBody(p, token) {
  41430. p._reconstructActiveFormattingElements();
  41431. p._insertElement(token, NS.HTML);
  41432. p.framesetOk = false;
  41433. p.insertionMode = p.insertionMode === InsertionMode.IN_TABLE || p.insertionMode === InsertionMode.IN_CAPTION || p.insertionMode === InsertionMode.IN_TABLE_BODY || p.insertionMode === InsertionMode.IN_ROW || p.insertionMode === InsertionMode.IN_CELL ? InsertionMode.IN_SELECT_IN_TABLE : InsertionMode.IN_SELECT;
  41434. }
  41435. function optgroupStartTagInBody(p, token) {
  41436. if (p.openElements.currentTagId === TAG_ID.OPTION) {
  41437. p.openElements.pop();
  41438. }
  41439. p._reconstructActiveFormattingElements();
  41440. p._insertElement(token, NS.HTML);
  41441. }
  41442. function rbStartTagInBody(p, token) {
  41443. if (p.openElements.hasInScope(TAG_ID.RUBY)) {
  41444. p.openElements.generateImpliedEndTags();
  41445. }
  41446. p._insertElement(token, NS.HTML);
  41447. }
  41448. function rtStartTagInBody(p, token) {
  41449. if (p.openElements.hasInScope(TAG_ID.RUBY)) {
  41450. p.openElements.generateImpliedEndTagsWithExclusion(TAG_ID.RTC);
  41451. }
  41452. p._insertElement(token, NS.HTML);
  41453. }
  41454. function mathStartTagInBody(p, token) {
  41455. p._reconstructActiveFormattingElements();
  41456. adjustTokenMathMLAttrs(token);
  41457. adjustTokenXMLAttrs(token);
  41458. if (token.selfClosing) {
  41459. p._appendElement(token, NS.MATHML);
  41460. } else {
  41461. p._insertElement(token, NS.MATHML);
  41462. }
  41463. token.ackSelfClosing = true;
  41464. }
  41465. function svgStartTagInBody(p, token) {
  41466. p._reconstructActiveFormattingElements();
  41467. adjustTokenSVGAttrs(token);
  41468. adjustTokenXMLAttrs(token);
  41469. if (token.selfClosing) {
  41470. p._appendElement(token, NS.SVG);
  41471. } else {
  41472. p._insertElement(token, NS.SVG);
  41473. }
  41474. token.ackSelfClosing = true;
  41475. }
  41476. function genericStartTagInBody(p, token) {
  41477. p._reconstructActiveFormattingElements();
  41478. p._insertElement(token, NS.HTML);
  41479. }
  41480. function startTagInBody(p, token) {
  41481. switch (token.tagID) {
  41482. case TAG_ID.I:
  41483. case TAG_ID.S:
  41484. case TAG_ID.B:
  41485. case TAG_ID.U:
  41486. case TAG_ID.EM:
  41487. case TAG_ID.TT:
  41488. case TAG_ID.BIG:
  41489. case TAG_ID.CODE:
  41490. case TAG_ID.FONT:
  41491. case TAG_ID.SMALL:
  41492. case TAG_ID.STRIKE:
  41493. case TAG_ID.STRONG: {
  41494. bStartTagInBody(p, token);
  41495. break;
  41496. }
  41497. case TAG_ID.A: {
  41498. aStartTagInBody(p, token);
  41499. break;
  41500. }
  41501. case TAG_ID.H1:
  41502. case TAG_ID.H2:
  41503. case TAG_ID.H3:
  41504. case TAG_ID.H4:
  41505. case TAG_ID.H5:
  41506. case TAG_ID.H6: {
  41507. numberedHeaderStartTagInBody(p, token);
  41508. break;
  41509. }
  41510. case TAG_ID.P:
  41511. case TAG_ID.DL:
  41512. case TAG_ID.OL:
  41513. case TAG_ID.UL:
  41514. case TAG_ID.DIV:
  41515. case TAG_ID.DIR:
  41516. case TAG_ID.NAV:
  41517. case TAG_ID.MAIN:
  41518. case TAG_ID.MENU:
  41519. case TAG_ID.ASIDE:
  41520. case TAG_ID.CENTER:
  41521. case TAG_ID.FIGURE:
  41522. case TAG_ID.FOOTER:
  41523. case TAG_ID.HEADER:
  41524. case TAG_ID.HGROUP:
  41525. case TAG_ID.DIALOG:
  41526. case TAG_ID.DETAILS:
  41527. case TAG_ID.ADDRESS:
  41528. case TAG_ID.ARTICLE:
  41529. case TAG_ID.SECTION:
  41530. case TAG_ID.SUMMARY:
  41531. case TAG_ID.FIELDSET:
  41532. case TAG_ID.BLOCKQUOTE:
  41533. case TAG_ID.FIGCAPTION: {
  41534. addressStartTagInBody(p, token);
  41535. break;
  41536. }
  41537. case TAG_ID.LI:
  41538. case TAG_ID.DD:
  41539. case TAG_ID.DT: {
  41540. listItemStartTagInBody(p, token);
  41541. break;
  41542. }
  41543. case TAG_ID.BR:
  41544. case TAG_ID.IMG:
  41545. case TAG_ID.WBR:
  41546. case TAG_ID.AREA:
  41547. case TAG_ID.EMBED:
  41548. case TAG_ID.KEYGEN: {
  41549. areaStartTagInBody(p, token);
  41550. break;
  41551. }
  41552. case TAG_ID.HR: {
  41553. hrStartTagInBody(p, token);
  41554. break;
  41555. }
  41556. case TAG_ID.RB:
  41557. case TAG_ID.RTC: {
  41558. rbStartTagInBody(p, token);
  41559. break;
  41560. }
  41561. case TAG_ID.RT:
  41562. case TAG_ID.RP: {
  41563. rtStartTagInBody(p, token);
  41564. break;
  41565. }
  41566. case TAG_ID.PRE:
  41567. case TAG_ID.LISTING: {
  41568. preStartTagInBody(p, token);
  41569. break;
  41570. }
  41571. case TAG_ID.XMP: {
  41572. xmpStartTagInBody(p, token);
  41573. break;
  41574. }
  41575. case TAG_ID.SVG: {
  41576. svgStartTagInBody(p, token);
  41577. break;
  41578. }
  41579. case TAG_ID.HTML: {
  41580. htmlStartTagInBody(p, token);
  41581. break;
  41582. }
  41583. case TAG_ID.BASE:
  41584. case TAG_ID.LINK:
  41585. case TAG_ID.META:
  41586. case TAG_ID.STYLE:
  41587. case TAG_ID.TITLE:
  41588. case TAG_ID.SCRIPT:
  41589. case TAG_ID.BGSOUND:
  41590. case TAG_ID.BASEFONT:
  41591. case TAG_ID.TEMPLATE: {
  41592. startTagInHead(p, token);
  41593. break;
  41594. }
  41595. case TAG_ID.BODY: {
  41596. bodyStartTagInBody(p, token);
  41597. break;
  41598. }
  41599. case TAG_ID.FORM: {
  41600. formStartTagInBody(p, token);
  41601. break;
  41602. }
  41603. case TAG_ID.NOBR: {
  41604. nobrStartTagInBody(p, token);
  41605. break;
  41606. }
  41607. case TAG_ID.MATH: {
  41608. mathStartTagInBody(p, token);
  41609. break;
  41610. }
  41611. case TAG_ID.TABLE: {
  41612. tableStartTagInBody(p, token);
  41613. break;
  41614. }
  41615. case TAG_ID.INPUT: {
  41616. inputStartTagInBody(p, token);
  41617. break;
  41618. }
  41619. case TAG_ID.PARAM:
  41620. case TAG_ID.TRACK:
  41621. case TAG_ID.SOURCE: {
  41622. paramStartTagInBody(p, token);
  41623. break;
  41624. }
  41625. case TAG_ID.IMAGE: {
  41626. imageStartTagInBody(p, token);
  41627. break;
  41628. }
  41629. case TAG_ID.BUTTON: {
  41630. buttonStartTagInBody(p, token);
  41631. break;
  41632. }
  41633. case TAG_ID.APPLET:
  41634. case TAG_ID.OBJECT:
  41635. case TAG_ID.MARQUEE: {
  41636. appletStartTagInBody(p, token);
  41637. break;
  41638. }
  41639. case TAG_ID.IFRAME: {
  41640. iframeStartTagInBody(p, token);
  41641. break;
  41642. }
  41643. case TAG_ID.SELECT: {
  41644. selectStartTagInBody(p, token);
  41645. break;
  41646. }
  41647. case TAG_ID.OPTION:
  41648. case TAG_ID.OPTGROUP: {
  41649. optgroupStartTagInBody(p, token);
  41650. break;
  41651. }
  41652. case TAG_ID.NOEMBED: {
  41653. noembedStartTagInBody(p, token);
  41654. break;
  41655. }
  41656. case TAG_ID.FRAMESET: {
  41657. framesetStartTagInBody(p, token);
  41658. break;
  41659. }
  41660. case TAG_ID.TEXTAREA: {
  41661. textareaStartTagInBody(p, token);
  41662. break;
  41663. }
  41664. case TAG_ID.NOSCRIPT: {
  41665. if (p.options.scriptingEnabled) {
  41666. noembedStartTagInBody(p, token);
  41667. } else {
  41668. genericStartTagInBody(p, token);
  41669. }
  41670. break;
  41671. }
  41672. case TAG_ID.PLAINTEXT: {
  41673. plaintextStartTagInBody(p, token);
  41674. break;
  41675. }
  41676. case TAG_ID.COL:
  41677. case TAG_ID.TH:
  41678. case TAG_ID.TD:
  41679. case TAG_ID.TR:
  41680. case TAG_ID.HEAD:
  41681. case TAG_ID.FRAME:
  41682. case TAG_ID.TBODY:
  41683. case TAG_ID.TFOOT:
  41684. case TAG_ID.THEAD:
  41685. case TAG_ID.CAPTION:
  41686. case TAG_ID.COLGROUP: {
  41687. break;
  41688. }
  41689. default: {
  41690. genericStartTagInBody(p, token);
  41691. }
  41692. }
  41693. }
  41694. function bodyEndTagInBody(p, token) {
  41695. if (p.openElements.hasInScope(TAG_ID.BODY)) {
  41696. p.insertionMode = InsertionMode.AFTER_BODY;
  41697. if (p.options.sourceCodeLocationInfo) {
  41698. const bodyElement = p.openElements.tryPeekProperlyNestedBodyElement();
  41699. if (bodyElement) {
  41700. p._setEndLocation(bodyElement, token);
  41701. }
  41702. }
  41703. }
  41704. }
  41705. function htmlEndTagInBody(p, token) {
  41706. if (p.openElements.hasInScope(TAG_ID.BODY)) {
  41707. p.insertionMode = InsertionMode.AFTER_BODY;
  41708. endTagAfterBody(p, token);
  41709. }
  41710. }
  41711. function addressEndTagInBody(p, token) {
  41712. const tn = token.tagID;
  41713. if (p.openElements.hasInScope(tn)) {
  41714. p.openElements.generateImpliedEndTags();
  41715. p.openElements.popUntilTagNamePopped(tn);
  41716. }
  41717. }
  41718. function formEndTagInBody(p) {
  41719. const inTemplate = p.openElements.tmplCount > 0;
  41720. const { formElement } = p;
  41721. if (!inTemplate) {
  41722. p.formElement = null;
  41723. }
  41724. if ((formElement || inTemplate) && p.openElements.hasInScope(TAG_ID.FORM)) {
  41725. p.openElements.generateImpliedEndTags();
  41726. if (inTemplate) {
  41727. p.openElements.popUntilTagNamePopped(TAG_ID.FORM);
  41728. } else if (formElement) {
  41729. p.openElements.remove(formElement);
  41730. }
  41731. }
  41732. }
  41733. function pEndTagInBody(p) {
  41734. if (!p.openElements.hasInButtonScope(TAG_ID.P)) {
  41735. p._insertFakeElement(TAG_NAMES.P, TAG_ID.P);
  41736. }
  41737. p._closePElement();
  41738. }
  41739. function liEndTagInBody(p) {
  41740. if (p.openElements.hasInListItemScope(TAG_ID.LI)) {
  41741. p.openElements.generateImpliedEndTagsWithExclusion(TAG_ID.LI);
  41742. p.openElements.popUntilTagNamePopped(TAG_ID.LI);
  41743. }
  41744. }
  41745. function ddEndTagInBody(p, token) {
  41746. const tn = token.tagID;
  41747. if (p.openElements.hasInScope(tn)) {
  41748. p.openElements.generateImpliedEndTagsWithExclusion(tn);
  41749. p.openElements.popUntilTagNamePopped(tn);
  41750. }
  41751. }
  41752. function numberedHeaderEndTagInBody(p) {
  41753. if (p.openElements.hasNumberedHeaderInScope()) {
  41754. p.openElements.generateImpliedEndTags();
  41755. p.openElements.popUntilNumberedHeaderPopped();
  41756. }
  41757. }
  41758. function appletEndTagInBody(p, token) {
  41759. const tn = token.tagID;
  41760. if (p.openElements.hasInScope(tn)) {
  41761. p.openElements.generateImpliedEndTags();
  41762. p.openElements.popUntilTagNamePopped(tn);
  41763. p.activeFormattingElements.clearToLastMarker();
  41764. }
  41765. }
  41766. function brEndTagInBody(p) {
  41767. p._reconstructActiveFormattingElements();
  41768. p._insertFakeElement(TAG_NAMES.BR, TAG_ID.BR);
  41769. p.openElements.pop();
  41770. p.framesetOk = false;
  41771. }
  41772. function genericEndTagInBody(p, token) {
  41773. const tn = token.tagName;
  41774. const tid = token.tagID;
  41775. for (let i = p.openElements.stackTop; i > 0; i--) {
  41776. const element = p.openElements.items[i];
  41777. const elementId = p.openElements.tagIDs[i];
  41778. if (tid === elementId && (tid !== TAG_ID.UNKNOWN || p.treeAdapter.getTagName(element) === tn)) {
  41779. p.openElements.generateImpliedEndTagsWithExclusion(tid);
  41780. if (p.openElements.stackTop >= i)
  41781. p.openElements.shortenToLength(i);
  41782. break;
  41783. }
  41784. if (p._isSpecialElement(element, elementId)) {
  41785. break;
  41786. }
  41787. }
  41788. }
  41789. function endTagInBody(p, token) {
  41790. switch (token.tagID) {
  41791. case TAG_ID.A:
  41792. case TAG_ID.B:
  41793. case TAG_ID.I:
  41794. case TAG_ID.S:
  41795. case TAG_ID.U:
  41796. case TAG_ID.EM:
  41797. case TAG_ID.TT:
  41798. case TAG_ID.BIG:
  41799. case TAG_ID.CODE:
  41800. case TAG_ID.FONT:
  41801. case TAG_ID.NOBR:
  41802. case TAG_ID.SMALL:
  41803. case TAG_ID.STRIKE:
  41804. case TAG_ID.STRONG: {
  41805. callAdoptionAgency(p, token);
  41806. break;
  41807. }
  41808. case TAG_ID.P: {
  41809. pEndTagInBody(p);
  41810. break;
  41811. }
  41812. case TAG_ID.DL:
  41813. case TAG_ID.UL:
  41814. case TAG_ID.OL:
  41815. case TAG_ID.DIR:
  41816. case TAG_ID.DIV:
  41817. case TAG_ID.NAV:
  41818. case TAG_ID.PRE:
  41819. case TAG_ID.MAIN:
  41820. case TAG_ID.MENU:
  41821. case TAG_ID.ASIDE:
  41822. case TAG_ID.BUTTON:
  41823. case TAG_ID.CENTER:
  41824. case TAG_ID.FIGURE:
  41825. case TAG_ID.FOOTER:
  41826. case TAG_ID.HEADER:
  41827. case TAG_ID.HGROUP:
  41828. case TAG_ID.DIALOG:
  41829. case TAG_ID.ADDRESS:
  41830. case TAG_ID.ARTICLE:
  41831. case TAG_ID.DETAILS:
  41832. case TAG_ID.SECTION:
  41833. case TAG_ID.SUMMARY:
  41834. case TAG_ID.LISTING:
  41835. case TAG_ID.FIELDSET:
  41836. case TAG_ID.BLOCKQUOTE:
  41837. case TAG_ID.FIGCAPTION: {
  41838. addressEndTagInBody(p, token);
  41839. break;
  41840. }
  41841. case TAG_ID.LI: {
  41842. liEndTagInBody(p);
  41843. break;
  41844. }
  41845. case TAG_ID.DD:
  41846. case TAG_ID.DT: {
  41847. ddEndTagInBody(p, token);
  41848. break;
  41849. }
  41850. case TAG_ID.H1:
  41851. case TAG_ID.H2:
  41852. case TAG_ID.H3:
  41853. case TAG_ID.H4:
  41854. case TAG_ID.H5:
  41855. case TAG_ID.H6: {
  41856. numberedHeaderEndTagInBody(p);
  41857. break;
  41858. }
  41859. case TAG_ID.BR: {
  41860. brEndTagInBody(p);
  41861. break;
  41862. }
  41863. case TAG_ID.BODY: {
  41864. bodyEndTagInBody(p, token);
  41865. break;
  41866. }
  41867. case TAG_ID.HTML: {
  41868. htmlEndTagInBody(p, token);
  41869. break;
  41870. }
  41871. case TAG_ID.FORM: {
  41872. formEndTagInBody(p);
  41873. break;
  41874. }
  41875. case TAG_ID.APPLET:
  41876. case TAG_ID.OBJECT:
  41877. case TAG_ID.MARQUEE: {
  41878. appletEndTagInBody(p, token);
  41879. break;
  41880. }
  41881. case TAG_ID.TEMPLATE: {
  41882. templateEndTagInHead(p, token);
  41883. break;
  41884. }
  41885. default: {
  41886. genericEndTagInBody(p, token);
  41887. }
  41888. }
  41889. }
  41890. function eofInBody(p, token) {
  41891. if (p.tmplInsertionModeStack.length > 0) {
  41892. eofInTemplate(p, token);
  41893. } else {
  41894. stopParsing(p, token);
  41895. }
  41896. }
  41897. function endTagInText(p, token) {
  41898. var _a2;
  41899. if (token.tagID === TAG_ID.SCRIPT) {
  41900. (_a2 = p.scriptHandler) === null || _a2 === void 0 ? void 0 : _a2.call(p, p.openElements.current);
  41901. }
  41902. p.openElements.pop();
  41903. p.insertionMode = p.originalInsertionMode;
  41904. }
  41905. function eofInText(p, token) {
  41906. p._err(token, ERR.eofInElementThatCanContainOnlyText);
  41907. p.openElements.pop();
  41908. p.insertionMode = p.originalInsertionMode;
  41909. p.onEof(token);
  41910. }
  41911. function characterInTable(p, token) {
  41912. if (TABLE_STRUCTURE_TAGS.has(p.openElements.currentTagId)) {
  41913. p.pendingCharacterTokens.length = 0;
  41914. p.hasNonWhitespacePendingCharacterToken = false;
  41915. p.originalInsertionMode = p.insertionMode;
  41916. p.insertionMode = InsertionMode.IN_TABLE_TEXT;
  41917. switch (token.type) {
  41918. case TokenType.CHARACTER: {
  41919. characterInTableText(p, token);
  41920. break;
  41921. }
  41922. case TokenType.WHITESPACE_CHARACTER: {
  41923. whitespaceCharacterInTableText(p, token);
  41924. break;
  41925. }
  41926. }
  41927. } else {
  41928. tokenInTable(p, token);
  41929. }
  41930. }
  41931. function captionStartTagInTable(p, token) {
  41932. p.openElements.clearBackToTableContext();
  41933. p.activeFormattingElements.insertMarker();
  41934. p._insertElement(token, NS.HTML);
  41935. p.insertionMode = InsertionMode.IN_CAPTION;
  41936. }
  41937. function colgroupStartTagInTable(p, token) {
  41938. p.openElements.clearBackToTableContext();
  41939. p._insertElement(token, NS.HTML);
  41940. p.insertionMode = InsertionMode.IN_COLUMN_GROUP;
  41941. }
  41942. function colStartTagInTable(p, token) {
  41943. p.openElements.clearBackToTableContext();
  41944. p._insertFakeElement(TAG_NAMES.COLGROUP, TAG_ID.COLGROUP);
  41945. p.insertionMode = InsertionMode.IN_COLUMN_GROUP;
  41946. startTagInColumnGroup(p, token);
  41947. }
  41948. function tbodyStartTagInTable(p, token) {
  41949. p.openElements.clearBackToTableContext();
  41950. p._insertElement(token, NS.HTML);
  41951. p.insertionMode = InsertionMode.IN_TABLE_BODY;
  41952. }
  41953. function tdStartTagInTable(p, token) {
  41954. p.openElements.clearBackToTableContext();
  41955. p._insertFakeElement(TAG_NAMES.TBODY, TAG_ID.TBODY);
  41956. p.insertionMode = InsertionMode.IN_TABLE_BODY;
  41957. startTagInTableBody(p, token);
  41958. }
  41959. function tableStartTagInTable(p, token) {
  41960. if (p.openElements.hasInTableScope(TAG_ID.TABLE)) {
  41961. p.openElements.popUntilTagNamePopped(TAG_ID.TABLE);
  41962. p._resetInsertionMode();
  41963. p._processStartTag(token);
  41964. }
  41965. }
  41966. function inputStartTagInTable(p, token) {
  41967. if (isHiddenInput(token)) {
  41968. p._appendElement(token, NS.HTML);
  41969. } else {
  41970. tokenInTable(p, token);
  41971. }
  41972. token.ackSelfClosing = true;
  41973. }
  41974. function formStartTagInTable(p, token) {
  41975. if (!p.formElement && p.openElements.tmplCount === 0) {
  41976. p._insertElement(token, NS.HTML);
  41977. p.formElement = p.openElements.current;
  41978. p.openElements.pop();
  41979. }
  41980. }
  41981. function startTagInTable(p, token) {
  41982. switch (token.tagID) {
  41983. case TAG_ID.TD:
  41984. case TAG_ID.TH:
  41985. case TAG_ID.TR: {
  41986. tdStartTagInTable(p, token);
  41987. break;
  41988. }
  41989. case TAG_ID.STYLE:
  41990. case TAG_ID.SCRIPT:
  41991. case TAG_ID.TEMPLATE: {
  41992. startTagInHead(p, token);
  41993. break;
  41994. }
  41995. case TAG_ID.COL: {
  41996. colStartTagInTable(p, token);
  41997. break;
  41998. }
  41999. case TAG_ID.FORM: {
  42000. formStartTagInTable(p, token);
  42001. break;
  42002. }
  42003. case TAG_ID.TABLE: {
  42004. tableStartTagInTable(p, token);
  42005. break;
  42006. }
  42007. case TAG_ID.TBODY:
  42008. case TAG_ID.TFOOT:
  42009. case TAG_ID.THEAD: {
  42010. tbodyStartTagInTable(p, token);
  42011. break;
  42012. }
  42013. case TAG_ID.INPUT: {
  42014. inputStartTagInTable(p, token);
  42015. break;
  42016. }
  42017. case TAG_ID.CAPTION: {
  42018. captionStartTagInTable(p, token);
  42019. break;
  42020. }
  42021. case TAG_ID.COLGROUP: {
  42022. colgroupStartTagInTable(p, token);
  42023. break;
  42024. }
  42025. default: {
  42026. tokenInTable(p, token);
  42027. }
  42028. }
  42029. }
  42030. function endTagInTable(p, token) {
  42031. switch (token.tagID) {
  42032. case TAG_ID.TABLE: {
  42033. if (p.openElements.hasInTableScope(TAG_ID.TABLE)) {
  42034. p.openElements.popUntilTagNamePopped(TAG_ID.TABLE);
  42035. p._resetInsertionMode();
  42036. }
  42037. break;
  42038. }
  42039. case TAG_ID.TEMPLATE: {
  42040. templateEndTagInHead(p, token);
  42041. break;
  42042. }
  42043. case TAG_ID.BODY:
  42044. case TAG_ID.CAPTION:
  42045. case TAG_ID.COL:
  42046. case TAG_ID.COLGROUP:
  42047. case TAG_ID.HTML:
  42048. case TAG_ID.TBODY:
  42049. case TAG_ID.TD:
  42050. case TAG_ID.TFOOT:
  42051. case TAG_ID.TH:
  42052. case TAG_ID.THEAD:
  42053. case TAG_ID.TR: {
  42054. break;
  42055. }
  42056. default: {
  42057. tokenInTable(p, token);
  42058. }
  42059. }
  42060. }
  42061. function tokenInTable(p, token) {
  42062. const savedFosterParentingState = p.fosterParentingEnabled;
  42063. p.fosterParentingEnabled = true;
  42064. modeInBody(p, token);
  42065. p.fosterParentingEnabled = savedFosterParentingState;
  42066. }
  42067. function whitespaceCharacterInTableText(p, token) {
  42068. p.pendingCharacterTokens.push(token);
  42069. }
  42070. function characterInTableText(p, token) {
  42071. p.pendingCharacterTokens.push(token);
  42072. p.hasNonWhitespacePendingCharacterToken = true;
  42073. }
  42074. function tokenInTableText(p, token) {
  42075. let i = 0;
  42076. if (p.hasNonWhitespacePendingCharacterToken) {
  42077. for (; i < p.pendingCharacterTokens.length; i++) {
  42078. tokenInTable(p, p.pendingCharacterTokens[i]);
  42079. }
  42080. } else {
  42081. for (; i < p.pendingCharacterTokens.length; i++) {
  42082. p._insertCharacters(p.pendingCharacterTokens[i]);
  42083. }
  42084. }
  42085. p.insertionMode = p.originalInsertionMode;
  42086. p._processToken(token);
  42087. }
  42088. var TABLE_VOID_ELEMENTS = /* @__PURE__ */ new Set([TAG_ID.CAPTION, TAG_ID.COL, TAG_ID.COLGROUP, TAG_ID.TBODY, TAG_ID.TD, TAG_ID.TFOOT, TAG_ID.TH, TAG_ID.THEAD, TAG_ID.TR]);
  42089. function startTagInCaption(p, token) {
  42090. const tn = token.tagID;
  42091. if (TABLE_VOID_ELEMENTS.has(tn)) {
  42092. if (p.openElements.hasInTableScope(TAG_ID.CAPTION)) {
  42093. p.openElements.generateImpliedEndTags();
  42094. p.openElements.popUntilTagNamePopped(TAG_ID.CAPTION);
  42095. p.activeFormattingElements.clearToLastMarker();
  42096. p.insertionMode = InsertionMode.IN_TABLE;
  42097. startTagInTable(p, token);
  42098. }
  42099. } else {
  42100. startTagInBody(p, token);
  42101. }
  42102. }
  42103. function endTagInCaption(p, token) {
  42104. const tn = token.tagID;
  42105. switch (tn) {
  42106. case TAG_ID.CAPTION:
  42107. case TAG_ID.TABLE: {
  42108. if (p.openElements.hasInTableScope(TAG_ID.CAPTION)) {
  42109. p.openElements.generateImpliedEndTags();
  42110. p.openElements.popUntilTagNamePopped(TAG_ID.CAPTION);
  42111. p.activeFormattingElements.clearToLastMarker();
  42112. p.insertionMode = InsertionMode.IN_TABLE;
  42113. if (tn === TAG_ID.TABLE) {
  42114. endTagInTable(p, token);
  42115. }
  42116. }
  42117. break;
  42118. }
  42119. case TAG_ID.BODY:
  42120. case TAG_ID.COL:
  42121. case TAG_ID.COLGROUP:
  42122. case TAG_ID.HTML:
  42123. case TAG_ID.TBODY:
  42124. case TAG_ID.TD:
  42125. case TAG_ID.TFOOT:
  42126. case TAG_ID.TH:
  42127. case TAG_ID.THEAD:
  42128. case TAG_ID.TR: {
  42129. break;
  42130. }
  42131. default: {
  42132. endTagInBody(p, token);
  42133. }
  42134. }
  42135. }
  42136. function startTagInColumnGroup(p, token) {
  42137. switch (token.tagID) {
  42138. case TAG_ID.HTML: {
  42139. startTagInBody(p, token);
  42140. break;
  42141. }
  42142. case TAG_ID.COL: {
  42143. p._appendElement(token, NS.HTML);
  42144. token.ackSelfClosing = true;
  42145. break;
  42146. }
  42147. case TAG_ID.TEMPLATE: {
  42148. startTagInHead(p, token);
  42149. break;
  42150. }
  42151. default: {
  42152. tokenInColumnGroup(p, token);
  42153. }
  42154. }
  42155. }
  42156. function endTagInColumnGroup(p, token) {
  42157. switch (token.tagID) {
  42158. case TAG_ID.COLGROUP: {
  42159. if (p.openElements.currentTagId === TAG_ID.COLGROUP) {
  42160. p.openElements.pop();
  42161. p.insertionMode = InsertionMode.IN_TABLE;
  42162. }
  42163. break;
  42164. }
  42165. case TAG_ID.TEMPLATE: {
  42166. templateEndTagInHead(p, token);
  42167. break;
  42168. }
  42169. case TAG_ID.COL: {
  42170. break;
  42171. }
  42172. default: {
  42173. tokenInColumnGroup(p, token);
  42174. }
  42175. }
  42176. }
  42177. function tokenInColumnGroup(p, token) {
  42178. if (p.openElements.currentTagId === TAG_ID.COLGROUP) {
  42179. p.openElements.pop();
  42180. p.insertionMode = InsertionMode.IN_TABLE;
  42181. p._processToken(token);
  42182. }
  42183. }
  42184. function startTagInTableBody(p, token) {
  42185. switch (token.tagID) {
  42186. case TAG_ID.TR: {
  42187. p.openElements.clearBackToTableBodyContext();
  42188. p._insertElement(token, NS.HTML);
  42189. p.insertionMode = InsertionMode.IN_ROW;
  42190. break;
  42191. }
  42192. case TAG_ID.TH:
  42193. case TAG_ID.TD: {
  42194. p.openElements.clearBackToTableBodyContext();
  42195. p._insertFakeElement(TAG_NAMES.TR, TAG_ID.TR);
  42196. p.insertionMode = InsertionMode.IN_ROW;
  42197. startTagInRow(p, token);
  42198. break;
  42199. }
  42200. case TAG_ID.CAPTION:
  42201. case TAG_ID.COL:
  42202. case TAG_ID.COLGROUP:
  42203. case TAG_ID.TBODY:
  42204. case TAG_ID.TFOOT:
  42205. case TAG_ID.THEAD: {
  42206. if (p.openElements.hasTableBodyContextInTableScope()) {
  42207. p.openElements.clearBackToTableBodyContext();
  42208. p.openElements.pop();
  42209. p.insertionMode = InsertionMode.IN_TABLE;
  42210. startTagInTable(p, token);
  42211. }
  42212. break;
  42213. }
  42214. default: {
  42215. startTagInTable(p, token);
  42216. }
  42217. }
  42218. }
  42219. function endTagInTableBody(p, token) {
  42220. const tn = token.tagID;
  42221. switch (token.tagID) {
  42222. case TAG_ID.TBODY:
  42223. case TAG_ID.TFOOT:
  42224. case TAG_ID.THEAD: {
  42225. if (p.openElements.hasInTableScope(tn)) {
  42226. p.openElements.clearBackToTableBodyContext();
  42227. p.openElements.pop();
  42228. p.insertionMode = InsertionMode.IN_TABLE;
  42229. }
  42230. break;
  42231. }
  42232. case TAG_ID.TABLE: {
  42233. if (p.openElements.hasTableBodyContextInTableScope()) {
  42234. p.openElements.clearBackToTableBodyContext();
  42235. p.openElements.pop();
  42236. p.insertionMode = InsertionMode.IN_TABLE;
  42237. endTagInTable(p, token);
  42238. }
  42239. break;
  42240. }
  42241. case TAG_ID.BODY:
  42242. case TAG_ID.CAPTION:
  42243. case TAG_ID.COL:
  42244. case TAG_ID.COLGROUP:
  42245. case TAG_ID.HTML:
  42246. case TAG_ID.TD:
  42247. case TAG_ID.TH:
  42248. case TAG_ID.TR: {
  42249. break;
  42250. }
  42251. default: {
  42252. endTagInTable(p, token);
  42253. }
  42254. }
  42255. }
  42256. function startTagInRow(p, token) {
  42257. switch (token.tagID) {
  42258. case TAG_ID.TH:
  42259. case TAG_ID.TD: {
  42260. p.openElements.clearBackToTableRowContext();
  42261. p._insertElement(token, NS.HTML);
  42262. p.insertionMode = InsertionMode.IN_CELL;
  42263. p.activeFormattingElements.insertMarker();
  42264. break;
  42265. }
  42266. case TAG_ID.CAPTION:
  42267. case TAG_ID.COL:
  42268. case TAG_ID.COLGROUP:
  42269. case TAG_ID.TBODY:
  42270. case TAG_ID.TFOOT:
  42271. case TAG_ID.THEAD:
  42272. case TAG_ID.TR: {
  42273. if (p.openElements.hasInTableScope(TAG_ID.TR)) {
  42274. p.openElements.clearBackToTableRowContext();
  42275. p.openElements.pop();
  42276. p.insertionMode = InsertionMode.IN_TABLE_BODY;
  42277. startTagInTableBody(p, token);
  42278. }
  42279. break;
  42280. }
  42281. default: {
  42282. startTagInTable(p, token);
  42283. }
  42284. }
  42285. }
  42286. function endTagInRow(p, token) {
  42287. switch (token.tagID) {
  42288. case TAG_ID.TR: {
  42289. if (p.openElements.hasInTableScope(TAG_ID.TR)) {
  42290. p.openElements.clearBackToTableRowContext();
  42291. p.openElements.pop();
  42292. p.insertionMode = InsertionMode.IN_TABLE_BODY;
  42293. }
  42294. break;
  42295. }
  42296. case TAG_ID.TABLE: {
  42297. if (p.openElements.hasInTableScope(TAG_ID.TR)) {
  42298. p.openElements.clearBackToTableRowContext();
  42299. p.openElements.pop();
  42300. p.insertionMode = InsertionMode.IN_TABLE_BODY;
  42301. endTagInTableBody(p, token);
  42302. }
  42303. break;
  42304. }
  42305. case TAG_ID.TBODY:
  42306. case TAG_ID.TFOOT:
  42307. case TAG_ID.THEAD: {
  42308. if (p.openElements.hasInTableScope(token.tagID) || p.openElements.hasInTableScope(TAG_ID.TR)) {
  42309. p.openElements.clearBackToTableRowContext();
  42310. p.openElements.pop();
  42311. p.insertionMode = InsertionMode.IN_TABLE_BODY;
  42312. endTagInTableBody(p, token);
  42313. }
  42314. break;
  42315. }
  42316. case TAG_ID.BODY:
  42317. case TAG_ID.CAPTION:
  42318. case TAG_ID.COL:
  42319. case TAG_ID.COLGROUP:
  42320. case TAG_ID.HTML:
  42321. case TAG_ID.TD:
  42322. case TAG_ID.TH: {
  42323. break;
  42324. }
  42325. default: {
  42326. endTagInTable(p, token);
  42327. }
  42328. }
  42329. }
  42330. function startTagInCell(p, token) {
  42331. const tn = token.tagID;
  42332. if (TABLE_VOID_ELEMENTS.has(tn)) {
  42333. if (p.openElements.hasInTableScope(TAG_ID.TD) || p.openElements.hasInTableScope(TAG_ID.TH)) {
  42334. p._closeTableCell();
  42335. startTagInRow(p, token);
  42336. }
  42337. } else {
  42338. startTagInBody(p, token);
  42339. }
  42340. }
  42341. function endTagInCell(p, token) {
  42342. const tn = token.tagID;
  42343. switch (tn) {
  42344. case TAG_ID.TD:
  42345. case TAG_ID.TH: {
  42346. if (p.openElements.hasInTableScope(tn)) {
  42347. p.openElements.generateImpliedEndTags();
  42348. p.openElements.popUntilTagNamePopped(tn);
  42349. p.activeFormattingElements.clearToLastMarker();
  42350. p.insertionMode = InsertionMode.IN_ROW;
  42351. }
  42352. break;
  42353. }
  42354. case TAG_ID.TABLE:
  42355. case TAG_ID.TBODY:
  42356. case TAG_ID.TFOOT:
  42357. case TAG_ID.THEAD:
  42358. case TAG_ID.TR: {
  42359. if (p.openElements.hasInTableScope(tn)) {
  42360. p._closeTableCell();
  42361. endTagInRow(p, token);
  42362. }
  42363. break;
  42364. }
  42365. case TAG_ID.BODY:
  42366. case TAG_ID.CAPTION:
  42367. case TAG_ID.COL:
  42368. case TAG_ID.COLGROUP:
  42369. case TAG_ID.HTML: {
  42370. break;
  42371. }
  42372. default: {
  42373. endTagInBody(p, token);
  42374. }
  42375. }
  42376. }
  42377. function startTagInSelect(p, token) {
  42378. switch (token.tagID) {
  42379. case TAG_ID.HTML: {
  42380. startTagInBody(p, token);
  42381. break;
  42382. }
  42383. case TAG_ID.OPTION: {
  42384. if (p.openElements.currentTagId === TAG_ID.OPTION) {
  42385. p.openElements.pop();
  42386. }
  42387. p._insertElement(token, NS.HTML);
  42388. break;
  42389. }
  42390. case TAG_ID.OPTGROUP: {
  42391. if (p.openElements.currentTagId === TAG_ID.OPTION) {
  42392. p.openElements.pop();
  42393. }
  42394. if (p.openElements.currentTagId === TAG_ID.OPTGROUP) {
  42395. p.openElements.pop();
  42396. }
  42397. p._insertElement(token, NS.HTML);
  42398. break;
  42399. }
  42400. case TAG_ID.INPUT:
  42401. case TAG_ID.KEYGEN:
  42402. case TAG_ID.TEXTAREA:
  42403. case TAG_ID.SELECT: {
  42404. if (p.openElements.hasInSelectScope(TAG_ID.SELECT)) {
  42405. p.openElements.popUntilTagNamePopped(TAG_ID.SELECT);
  42406. p._resetInsertionMode();
  42407. if (token.tagID !== TAG_ID.SELECT) {
  42408. p._processStartTag(token);
  42409. }
  42410. }
  42411. break;
  42412. }
  42413. case TAG_ID.SCRIPT:
  42414. case TAG_ID.TEMPLATE: {
  42415. startTagInHead(p, token);
  42416. break;
  42417. }
  42418. default:
  42419. }
  42420. }
  42421. function endTagInSelect(p, token) {
  42422. switch (token.tagID) {
  42423. case TAG_ID.OPTGROUP: {
  42424. if (p.openElements.stackTop > 0 && p.openElements.currentTagId === TAG_ID.OPTION && p.openElements.tagIDs[p.openElements.stackTop - 1] === TAG_ID.OPTGROUP) {
  42425. p.openElements.pop();
  42426. }
  42427. if (p.openElements.currentTagId === TAG_ID.OPTGROUP) {
  42428. p.openElements.pop();
  42429. }
  42430. break;
  42431. }
  42432. case TAG_ID.OPTION: {
  42433. if (p.openElements.currentTagId === TAG_ID.OPTION) {
  42434. p.openElements.pop();
  42435. }
  42436. break;
  42437. }
  42438. case TAG_ID.SELECT: {
  42439. if (p.openElements.hasInSelectScope(TAG_ID.SELECT)) {
  42440. p.openElements.popUntilTagNamePopped(TAG_ID.SELECT);
  42441. p._resetInsertionMode();
  42442. }
  42443. break;
  42444. }
  42445. case TAG_ID.TEMPLATE: {
  42446. templateEndTagInHead(p, token);
  42447. break;
  42448. }
  42449. default:
  42450. }
  42451. }
  42452. function startTagInSelectInTable(p, token) {
  42453. const tn = token.tagID;
  42454. if (tn === TAG_ID.CAPTION || tn === TAG_ID.TABLE || tn === TAG_ID.TBODY || tn === TAG_ID.TFOOT || tn === TAG_ID.THEAD || tn === TAG_ID.TR || tn === TAG_ID.TD || tn === TAG_ID.TH) {
  42455. p.openElements.popUntilTagNamePopped(TAG_ID.SELECT);
  42456. p._resetInsertionMode();
  42457. p._processStartTag(token);
  42458. } else {
  42459. startTagInSelect(p, token);
  42460. }
  42461. }
  42462. function endTagInSelectInTable(p, token) {
  42463. const tn = token.tagID;
  42464. if (tn === TAG_ID.CAPTION || tn === TAG_ID.TABLE || tn === TAG_ID.TBODY || tn === TAG_ID.TFOOT || tn === TAG_ID.THEAD || tn === TAG_ID.TR || tn === TAG_ID.TD || tn === TAG_ID.TH) {
  42465. if (p.openElements.hasInTableScope(tn)) {
  42466. p.openElements.popUntilTagNamePopped(TAG_ID.SELECT);
  42467. p._resetInsertionMode();
  42468. p.onEndTag(token);
  42469. }
  42470. } else {
  42471. endTagInSelect(p, token);
  42472. }
  42473. }
  42474. function startTagInTemplate(p, token) {
  42475. switch (token.tagID) {
  42476. case TAG_ID.BASE:
  42477. case TAG_ID.BASEFONT:
  42478. case TAG_ID.BGSOUND:
  42479. case TAG_ID.LINK:
  42480. case TAG_ID.META:
  42481. case TAG_ID.NOFRAMES:
  42482. case TAG_ID.SCRIPT:
  42483. case TAG_ID.STYLE:
  42484. case TAG_ID.TEMPLATE:
  42485. case TAG_ID.TITLE: {
  42486. startTagInHead(p, token);
  42487. break;
  42488. }
  42489. case TAG_ID.CAPTION:
  42490. case TAG_ID.COLGROUP:
  42491. case TAG_ID.TBODY:
  42492. case TAG_ID.TFOOT:
  42493. case TAG_ID.THEAD: {
  42494. p.tmplInsertionModeStack[0] = InsertionMode.IN_TABLE;
  42495. p.insertionMode = InsertionMode.IN_TABLE;
  42496. startTagInTable(p, token);
  42497. break;
  42498. }
  42499. case TAG_ID.COL: {
  42500. p.tmplInsertionModeStack[0] = InsertionMode.IN_COLUMN_GROUP;
  42501. p.insertionMode = InsertionMode.IN_COLUMN_GROUP;
  42502. startTagInColumnGroup(p, token);
  42503. break;
  42504. }
  42505. case TAG_ID.TR: {
  42506. p.tmplInsertionModeStack[0] = InsertionMode.IN_TABLE_BODY;
  42507. p.insertionMode = InsertionMode.IN_TABLE_BODY;
  42508. startTagInTableBody(p, token);
  42509. break;
  42510. }
  42511. case TAG_ID.TD:
  42512. case TAG_ID.TH: {
  42513. p.tmplInsertionModeStack[0] = InsertionMode.IN_ROW;
  42514. p.insertionMode = InsertionMode.IN_ROW;
  42515. startTagInRow(p, token);
  42516. break;
  42517. }
  42518. default: {
  42519. p.tmplInsertionModeStack[0] = InsertionMode.IN_BODY;
  42520. p.insertionMode = InsertionMode.IN_BODY;
  42521. startTagInBody(p, token);
  42522. }
  42523. }
  42524. }
  42525. function endTagInTemplate(p, token) {
  42526. if (token.tagID === TAG_ID.TEMPLATE) {
  42527. templateEndTagInHead(p, token);
  42528. }
  42529. }
  42530. function eofInTemplate(p, token) {
  42531. if (p.openElements.tmplCount > 0) {
  42532. p.openElements.popUntilTagNamePopped(TAG_ID.TEMPLATE);
  42533. p.activeFormattingElements.clearToLastMarker();
  42534. p.tmplInsertionModeStack.shift();
  42535. p._resetInsertionMode();
  42536. p.onEof(token);
  42537. } else {
  42538. stopParsing(p, token);
  42539. }
  42540. }
  42541. function startTagAfterBody(p, token) {
  42542. if (token.tagID === TAG_ID.HTML) {
  42543. startTagInBody(p, token);
  42544. } else {
  42545. tokenAfterBody(p, token);
  42546. }
  42547. }
  42548. function endTagAfterBody(p, token) {
  42549. var _a2;
  42550. if (token.tagID === TAG_ID.HTML) {
  42551. if (!p.fragmentContext) {
  42552. p.insertionMode = InsertionMode.AFTER_AFTER_BODY;
  42553. }
  42554. if (p.options.sourceCodeLocationInfo && p.openElements.tagIDs[0] === TAG_ID.HTML) {
  42555. p._setEndLocation(p.openElements.items[0], token);
  42556. const bodyElement = p.openElements.items[1];
  42557. if (bodyElement && !((_a2 = p.treeAdapter.getNodeSourceCodeLocation(bodyElement)) === null || _a2 === void 0 ? void 0 : _a2.endTag)) {
  42558. p._setEndLocation(bodyElement, token);
  42559. }
  42560. }
  42561. } else {
  42562. tokenAfterBody(p, token);
  42563. }
  42564. }
  42565. function tokenAfterBody(p, token) {
  42566. p.insertionMode = InsertionMode.IN_BODY;
  42567. modeInBody(p, token);
  42568. }
  42569. function startTagInFrameset(p, token) {
  42570. switch (token.tagID) {
  42571. case TAG_ID.HTML: {
  42572. startTagInBody(p, token);
  42573. break;
  42574. }
  42575. case TAG_ID.FRAMESET: {
  42576. p._insertElement(token, NS.HTML);
  42577. break;
  42578. }
  42579. case TAG_ID.FRAME: {
  42580. p._appendElement(token, NS.HTML);
  42581. token.ackSelfClosing = true;
  42582. break;
  42583. }
  42584. case TAG_ID.NOFRAMES: {
  42585. startTagInHead(p, token);
  42586. break;
  42587. }
  42588. default:
  42589. }
  42590. }
  42591. function endTagInFrameset(p, token) {
  42592. if (token.tagID === TAG_ID.FRAMESET && !p.openElements.isRootHtmlElementCurrent()) {
  42593. p.openElements.pop();
  42594. if (!p.fragmentContext && p.openElements.currentTagId !== TAG_ID.FRAMESET) {
  42595. p.insertionMode = InsertionMode.AFTER_FRAMESET;
  42596. }
  42597. }
  42598. }
  42599. function startTagAfterFrameset(p, token) {
  42600. switch (token.tagID) {
  42601. case TAG_ID.HTML: {
  42602. startTagInBody(p, token);
  42603. break;
  42604. }
  42605. case TAG_ID.NOFRAMES: {
  42606. startTagInHead(p, token);
  42607. break;
  42608. }
  42609. default:
  42610. }
  42611. }
  42612. function endTagAfterFrameset(p, token) {
  42613. if (token.tagID === TAG_ID.HTML) {
  42614. p.insertionMode = InsertionMode.AFTER_AFTER_FRAMESET;
  42615. }
  42616. }
  42617. function startTagAfterAfterBody(p, token) {
  42618. if (token.tagID === TAG_ID.HTML) {
  42619. startTagInBody(p, token);
  42620. } else {
  42621. tokenAfterAfterBody(p, token);
  42622. }
  42623. }
  42624. function tokenAfterAfterBody(p, token) {
  42625. p.insertionMode = InsertionMode.IN_BODY;
  42626. modeInBody(p, token);
  42627. }
  42628. function startTagAfterAfterFrameset(p, token) {
  42629. switch (token.tagID) {
  42630. case TAG_ID.HTML: {
  42631. startTagInBody(p, token);
  42632. break;
  42633. }
  42634. case TAG_ID.NOFRAMES: {
  42635. startTagInHead(p, token);
  42636. break;
  42637. }
  42638. default:
  42639. }
  42640. }
  42641. function nullCharacterInForeignContent(p, token) {
  42642. token.chars = REPLACEMENT_CHARACTER;
  42643. p._insertCharacters(token);
  42644. }
  42645. function characterInForeignContent(p, token) {
  42646. p._insertCharacters(token);
  42647. p.framesetOk = false;
  42648. }
  42649. function popUntilHtmlOrIntegrationPoint(p) {
  42650. while (p.treeAdapter.getNamespaceURI(p.openElements.current) !== NS.HTML && !p._isIntegrationPoint(p.openElements.currentTagId, p.openElements.current)) {
  42651. p.openElements.pop();
  42652. }
  42653. }
  42654. function startTagInForeignContent(p, token) {
  42655. if (causesExit(token)) {
  42656. popUntilHtmlOrIntegrationPoint(p);
  42657. p._startTagOutsideForeignContent(token);
  42658. } else {
  42659. const current = p._getAdjustedCurrentElement();
  42660. const currentNs = p.treeAdapter.getNamespaceURI(current);
  42661. if (currentNs === NS.MATHML) {
  42662. adjustTokenMathMLAttrs(token);
  42663. } else if (currentNs === NS.SVG) {
  42664. adjustTokenSVGTagName(token);
  42665. adjustTokenSVGAttrs(token);
  42666. }
  42667. adjustTokenXMLAttrs(token);
  42668. if (token.selfClosing) {
  42669. p._appendElement(token, currentNs);
  42670. } else {
  42671. p._insertElement(token, currentNs);
  42672. }
  42673. token.ackSelfClosing = true;
  42674. }
  42675. }
  42676. function endTagInForeignContent(p, token) {
  42677. if (token.tagID === TAG_ID.P || token.tagID === TAG_ID.BR) {
  42678. popUntilHtmlOrIntegrationPoint(p);
  42679. p._endTagOutsideForeignContent(token);
  42680. return;
  42681. }
  42682. for (let i = p.openElements.stackTop; i > 0; i--) {
  42683. const element = p.openElements.items[i];
  42684. if (p.treeAdapter.getNamespaceURI(element) === NS.HTML) {
  42685. p._endTagOutsideForeignContent(token);
  42686. break;
  42687. }
  42688. const tagName = p.treeAdapter.getTagName(element);
  42689. if (tagName.toLowerCase() === token.tagName) {
  42690. token.tagName = tagName;
  42691. p.openElements.shortenToLength(i);
  42692. break;
  42693. }
  42694. }
  42695. }
  42696. // node_modules/entities/lib/esm/escape.js
  42697. var xmlCodeMap = /* @__PURE__ */ new Map([
  42698. [34, "&quot;"],
  42699. [38, "&amp;"],
  42700. [39, "&apos;"],
  42701. [60, "&lt;"],
  42702. [62, "&gt;"]
  42703. ]);
  42704. var getCodePoint = (
  42705. // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
  42706. String.prototype.codePointAt != null ? (str, index) => str.codePointAt(index) : (
  42707. // http://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae
  42708. (c, index) => (c.charCodeAt(index) & 64512) === 55296 ? (c.charCodeAt(index) - 55296) * 1024 + c.charCodeAt(index + 1) - 56320 + 65536 : c.charCodeAt(index)
  42709. )
  42710. );
  42711. function getEscaper(regex, map2) {
  42712. return function escape(data) {
  42713. let match;
  42714. let lastIdx = 0;
  42715. let result = "";
  42716. while (match = regex.exec(data)) {
  42717. if (lastIdx !== match.index) {
  42718. result += data.substring(lastIdx, match.index);
  42719. }
  42720. result += map2.get(match[0].charCodeAt(0));
  42721. lastIdx = match.index + 1;
  42722. }
  42723. return result + data.substring(lastIdx);
  42724. };
  42725. }
  42726. var escapeUTF8 = getEscaper(/[&<>'"]/g, xmlCodeMap);
  42727. var escapeAttribute = getEscaper(/["&\u00A0]/g, /* @__PURE__ */ new Map([
  42728. [34, "&quot;"],
  42729. [38, "&amp;"],
  42730. [160, "&nbsp;"]
  42731. ]));
  42732. var escapeText = getEscaper(/[&<>\u00A0]/g, /* @__PURE__ */ new Map([
  42733. [38, "&amp;"],
  42734. [60, "&lt;"],
  42735. [62, "&gt;"],
  42736. [160, "&nbsp;"]
  42737. ]));
  42738. // node_modules/parse5/dist/serializer/index.js
  42739. var VOID_ELEMENTS = /* @__PURE__ */ new Set([
  42740. TAG_NAMES.AREA,
  42741. TAG_NAMES.BASE,
  42742. TAG_NAMES.BASEFONT,
  42743. TAG_NAMES.BGSOUND,
  42744. TAG_NAMES.BR,
  42745. TAG_NAMES.COL,
  42746. TAG_NAMES.EMBED,
  42747. TAG_NAMES.FRAME,
  42748. TAG_NAMES.HR,
  42749. TAG_NAMES.IMG,
  42750. TAG_NAMES.INPUT,
  42751. TAG_NAMES.KEYGEN,
  42752. TAG_NAMES.LINK,
  42753. TAG_NAMES.META,
  42754. TAG_NAMES.PARAM,
  42755. TAG_NAMES.SOURCE,
  42756. TAG_NAMES.TRACK,
  42757. TAG_NAMES.WBR
  42758. ]);
  42759. // node_modules/parse5/dist/index.js
  42760. function parse(html, options) {
  42761. return Parser.parse(html, options);
  42762. }
  42763. function parseFragment(fragmentContext, html, options) {
  42764. if (typeof fragmentContext === "string") {
  42765. options = html;
  42766. html = fragmentContext;
  42767. fragmentContext = null;
  42768. }
  42769. const parser = Parser.getFragmentParser(fragmentContext, options);
  42770. parser.tokenizer.write(html, true);
  42771. return parser.getFragment();
  42772. }
  42773. // src/mock-doc/parse-util.ts
  42774. var docParser = /* @__PURE__ */ new WeakMap();
  42775. function parseDocumentUtil(ownerDocument, html) {
  42776. const doc = parse(html.trim(), getParser(ownerDocument));
  42777. doc.documentElement = doc.firstElementChild;
  42778. doc.head = doc.documentElement.firstElementChild;
  42779. doc.body = doc.head.nextElementSibling;
  42780. return doc;
  42781. }
  42782. function parseFragmentUtil(ownerDocument, html) {
  42783. if (typeof html === "string") {
  42784. html = html.trim();
  42785. } else {
  42786. html = "";
  42787. }
  42788. const frag = parseFragment(html, getParser(ownerDocument));
  42789. return frag;
  42790. }
  42791. function getParser(ownerDocument) {
  42792. let parseOptions = docParser.get(ownerDocument);
  42793. if (parseOptions != null) {
  42794. return parseOptions;
  42795. }
  42796. const treeAdapter = {
  42797. createDocument() {
  42798. const doc = ownerDocument.createElement("#document" /* DOCUMENT_NODE */);
  42799. doc["x-mode"] = "no-quirks";
  42800. return doc;
  42801. },
  42802. setNodeSourceCodeLocation(node, location2) {
  42803. node.sourceCodeLocation = location2;
  42804. },
  42805. getNodeSourceCodeLocation(node) {
  42806. return node.sourceCodeLocation;
  42807. },
  42808. createDocumentFragment() {
  42809. return ownerDocument.createDocumentFragment();
  42810. },
  42811. createElement(tagName, namespaceURI, attrs) {
  42812. const elm = ownerDocument.createElementNS(namespaceURI, tagName);
  42813. for (let i = 0; i < attrs.length; i++) {
  42814. const attr = attrs[i];
  42815. if (attr.namespace == null || attr.namespace === "http://www.w3.org/1999/xhtml") {
  42816. elm.setAttribute(attr.name, attr.value);
  42817. } else {
  42818. elm.setAttributeNS(attr.namespace, attr.name, attr.value);
  42819. }
  42820. }
  42821. return elm;
  42822. },
  42823. createCommentNode(data) {
  42824. return ownerDocument.createComment(data);
  42825. },
  42826. appendChild(parentNode, newNode) {
  42827. parentNode.appendChild(newNode);
  42828. },
  42829. insertBefore(parentNode, newNode, referenceNode) {
  42830. parentNode.insertBefore(newNode, referenceNode);
  42831. },
  42832. setTemplateContent(templateElement, contentElement) {
  42833. templateElement.content = contentElement;
  42834. },
  42835. getTemplateContent(templateElement) {
  42836. return templateElement.content;
  42837. },
  42838. setDocumentType(doc, name, publicId, systemId) {
  42839. let doctypeNode = doc.childNodes.find((n) => n.nodeType === 10 /* DOCUMENT_TYPE_NODE */);
  42840. if (doctypeNode == null) {
  42841. doctypeNode = ownerDocument.createDocumentTypeNode();
  42842. doc.insertBefore(doctypeNode, doc.firstChild);
  42843. }
  42844. doctypeNode.nodeValue = "!DOCTYPE";
  42845. doctypeNode["x-name"] = name;
  42846. doctypeNode["x-publicId"] = publicId;
  42847. doctypeNode["x-systemId"] = systemId;
  42848. },
  42849. setDocumentMode(doc, mode) {
  42850. doc["x-mode"] = mode;
  42851. },
  42852. getDocumentMode(doc) {
  42853. return doc["x-mode"];
  42854. },
  42855. detachNode(node) {
  42856. node.remove();
  42857. },
  42858. insertText(parentNode, text) {
  42859. const lastChild = parentNode.lastChild;
  42860. if (lastChild != null && lastChild.nodeType === 3 /* TEXT_NODE */) {
  42861. lastChild.nodeValue += text;
  42862. } else {
  42863. parentNode.appendChild(ownerDocument.createTextNode(text));
  42864. }
  42865. },
  42866. insertTextBefore(parentNode, text, referenceNode) {
  42867. const prevNode = parentNode.childNodes[parentNode.childNodes.indexOf(referenceNode) - 1];
  42868. if (prevNode != null && prevNode.nodeType === 3 /* TEXT_NODE */) {
  42869. prevNode.nodeValue += text;
  42870. } else {
  42871. parentNode.insertBefore(ownerDocument.createTextNode(text), referenceNode);
  42872. }
  42873. },
  42874. adoptAttributes(recipient, attrs) {
  42875. for (let i = 0; i < attrs.length; i++) {
  42876. const attr = attrs[i];
  42877. if (recipient.hasAttributeNS(attr.namespace, attr.name) === false) {
  42878. recipient.setAttributeNS(attr.namespace, attr.name, attr.value);
  42879. }
  42880. }
  42881. },
  42882. getFirstChild(node) {
  42883. return node.childNodes[0];
  42884. },
  42885. getChildNodes(node) {
  42886. return node.childNodes;
  42887. },
  42888. getParentNode(node) {
  42889. return node.parentNode;
  42890. },
  42891. getAttrList(element) {
  42892. const attrs = element.attributes.__items.map((attr) => {
  42893. return {
  42894. name: attr.name,
  42895. value: attr.value,
  42896. namespace: attr.namespaceURI,
  42897. prefix: null
  42898. };
  42899. });
  42900. return attrs;
  42901. },
  42902. getTagName(element) {
  42903. if (element.namespaceURI === "http://www.w3.org/1999/xhtml") {
  42904. return element.nodeName.toLowerCase();
  42905. } else {
  42906. return element.nodeName;
  42907. }
  42908. },
  42909. getNamespaceURI(element) {
  42910. return element.namespaceURI;
  42911. },
  42912. getTextNodeContent(textNode) {
  42913. return textNode.nodeValue;
  42914. },
  42915. getCommentNodeContent(commentNode) {
  42916. return commentNode.nodeValue;
  42917. },
  42918. getDocumentTypeNodeName(doctypeNode) {
  42919. return doctypeNode["x-name"];
  42920. },
  42921. getDocumentTypeNodePublicId(doctypeNode) {
  42922. return doctypeNode["x-publicId"];
  42923. },
  42924. getDocumentTypeNodeSystemId(doctypeNode) {
  42925. return doctypeNode["x-systemId"];
  42926. },
  42927. // @ts-ignore - a `MockNode` will never be assignable to a `TreeAdapterTypeMap['text']`. As a result, we cannot
  42928. // complete this function signature
  42929. isTextNode(node) {
  42930. return node.nodeType === 3 /* TEXT_NODE */;
  42931. },
  42932. // @ts-ignore - a `MockNode` will never be assignable to a `TreeAdapterTypeMap['comment']`. As a result, we cannot
  42933. // complete this function signature (which requires its return type to be a type predicate)
  42934. isCommentNode(node) {
  42935. return node.nodeType === 8 /* COMMENT_NODE */;
  42936. },
  42937. // @ts-ignore - a `MockNode` will never be assignable to a `TreeAdapterTypeMap['document']`. As a result, we cannot
  42938. // complete this function signature (which requires its return type to be a type predicate)
  42939. isDocumentTypeNode(node) {
  42940. return node.nodeType === 10 /* DOCUMENT_TYPE_NODE */;
  42941. },
  42942. // @ts-ignore - a `MockNode` will never be assignable to a `TreeAdapterTypeMap['element']`. As a result, we cannot
  42943. // complete this function signature (which requires its return type to be a type predicate)
  42944. isElementNode(node) {
  42945. return node.nodeType === 1 /* ELEMENT_NODE */;
  42946. }
  42947. };
  42948. parseOptions = {
  42949. treeAdapter
  42950. };
  42951. docParser.set(ownerDocument, parseOptions);
  42952. return parseOptions;
  42953. }
  42954. // src/mock-doc/third-party/jquery.ts
  42955. var jquery_default = (
  42956. /*!
  42957. * jQuery JavaScript Library v4.0.0-pre+9352011a7.dirty +selector
  42958. * https://jquery.com/
  42959. *
  42960. * Copyright OpenJS Foundation and other contributors
  42961. * Released under the MIT license
  42962. * https://jquery.org/license
  42963. *
  42964. * Date: 2023-12-11T17:55Z
  42965. */
  42966. function(global2, factory) {
  42967. "use strict";
  42968. if (true) {
  42969. return factory(global2, true);
  42970. } else {
  42971. factory(global2);
  42972. }
  42973. }({
  42974. document: {
  42975. createElement() {
  42976. return {};
  42977. },
  42978. nodeType: 9,
  42979. documentElement: {
  42980. nodeType: 1,
  42981. nodeName: "HTML"
  42982. }
  42983. }
  42984. }, function(window, noGlobal) {
  42985. "use strict";
  42986. if (!window.document) {
  42987. throw new Error("jQuery requires a window with a document");
  42988. }
  42989. var arr = [];
  42990. var getProto = Object.getPrototypeOf;
  42991. var slice = arr.slice;
  42992. var flat = arr.flat ? function(array) {
  42993. return arr.flat.call(array);
  42994. } : function(array) {
  42995. return arr.concat.apply([], array);
  42996. };
  42997. var push = arr.push;
  42998. var indexOf = arr.indexOf;
  42999. var class2type = {};
  43000. var toString = class2type.toString;
  43001. var hasOwn = class2type.hasOwnProperty;
  43002. var fnToString = hasOwn.toString;
  43003. var ObjectFunctionString = fnToString.call(Object);
  43004. var support = {};
  43005. function toType(obj) {
  43006. if (obj == null) {
  43007. return obj + "";
  43008. }
  43009. return typeof obj === "object" ? class2type[toString.call(obj)] || "object" : typeof obj;
  43010. }
  43011. function isWindow(obj) {
  43012. return obj != null && obj === obj.window;
  43013. }
  43014. function isArrayLike(obj) {
  43015. var length = !!obj && obj.length, type = toType(obj);
  43016. if (typeof obj === "function" || isWindow(obj)) {
  43017. return false;
  43018. }
  43019. return type === "array" || length === 0 || typeof length === "number" && length > 0 && length - 1 in obj;
  43020. }
  43021. var document = window.document;
  43022. var preservedScriptAttributes = {
  43023. type: true,
  43024. src: true,
  43025. nonce: true,
  43026. noModule: true
  43027. };
  43028. function DOMEval(code, node, doc) {
  43029. doc = doc || document;
  43030. var i2, script = doc.createElement("script");
  43031. script.text = code;
  43032. if (node) {
  43033. for (i2 in preservedScriptAttributes) {
  43034. if (node[i2]) {
  43035. script[i2] = node[i2];
  43036. }
  43037. }
  43038. }
  43039. doc.head.appendChild(script).parentNode.removeChild(script);
  43040. }
  43041. const jQuery = {};
  43042. var version = "4.0.0-pre+9352011a7.dirty +selector", rhtmlSuffix = /HTML$/i, jQueryOrig = function(selector, context) {
  43043. return new jQuery.fn.init(selector, context);
  43044. };
  43045. jQuery.fn = jQuery.prototype = {
  43046. // The current version of jQuery being used
  43047. jquery: version,
  43048. constructor: jQuery,
  43049. // The default length of a jQuery object is 0
  43050. length: 0,
  43051. toArray: function() {
  43052. return slice.call(this);
  43053. },
  43054. // Get the Nth element in the matched element set OR
  43055. // Get the whole matched element set as a clean array
  43056. get: function(num) {
  43057. if (num == null) {
  43058. return slice.call(this);
  43059. }
  43060. return num < 0 ? this[num + this.length] : this[num];
  43061. },
  43062. // Take an array of elements and push it onto the stack
  43063. // (returning the new matched element set)
  43064. pushStack: function(elems) {
  43065. var ret = jQuery.merge(this.constructor(), elems);
  43066. ret.prevObject = this;
  43067. return ret;
  43068. },
  43069. // Execute a callback for every element in the matched set.
  43070. each: function(callback) {
  43071. return jQuery.each(this, callback);
  43072. },
  43073. map: function(callback) {
  43074. return this.pushStack(jQuery.map(this, function(elem, i2) {
  43075. return callback.call(elem, i2, elem);
  43076. }));
  43077. },
  43078. slice: function() {
  43079. return this.pushStack(slice.apply(this, arguments));
  43080. },
  43081. first: function() {
  43082. return this.eq(0);
  43083. },
  43084. last: function() {
  43085. return this.eq(-1);
  43086. },
  43087. even: function() {
  43088. return this.pushStack(jQuery.grep(this, function(_elem, i2) {
  43089. return (i2 + 1) % 2;
  43090. }));
  43091. },
  43092. odd: function() {
  43093. return this.pushStack(jQuery.grep(this, function(_elem, i2) {
  43094. return i2 % 2;
  43095. }));
  43096. },
  43097. eq: function(i2) {
  43098. var len = this.length, j = +i2 + (i2 < 0 ? len : 0);
  43099. return this.pushStack(j >= 0 && j < len ? [this[j]] : []);
  43100. },
  43101. end: function() {
  43102. return this.prevObject || this.constructor();
  43103. }
  43104. };
  43105. jQuery.extend = jQuery.fn.extend = function() {
  43106. var options, name, src, copy, copyIsArray, clone, target = arguments[0] || {}, i2 = 1, length = arguments.length, deep = false;
  43107. if (typeof target === "boolean") {
  43108. deep = target;
  43109. target = arguments[i2] || {};
  43110. i2++;
  43111. }
  43112. if (typeof target !== "object" && typeof target !== "function") {
  43113. target = {};
  43114. }
  43115. if (i2 === length) {
  43116. target = this;
  43117. i2--;
  43118. }
  43119. for (; i2 < length; i2++) {
  43120. if ((options = arguments[i2]) != null) {
  43121. for (name in options) {
  43122. copy = options[name];
  43123. if (name === "__proto__" || target === copy) {
  43124. continue;
  43125. }
  43126. if (deep && copy && (jQuery.isPlainObject(copy) || (copyIsArray = Array.isArray(copy)))) {
  43127. src = target[name];
  43128. if (copyIsArray && !Array.isArray(src)) {
  43129. clone = [];
  43130. } else if (!copyIsArray && !jQuery.isPlainObject(src)) {
  43131. clone = {};
  43132. } else {
  43133. clone = src;
  43134. }
  43135. copyIsArray = false;
  43136. target[name] = jQuery.extend(deep, clone, copy);
  43137. } else if (copy !== void 0) {
  43138. target[name] = copy;
  43139. }
  43140. }
  43141. }
  43142. }
  43143. return target;
  43144. };
  43145. jQuery.extend({
  43146. // Unique for each copy of jQuery on the page
  43147. expando: "jQuery" + (version + Math.random()).replace(/\D/g, ""),
  43148. // Assume jQuery is ready without the ready module
  43149. isReady: true,
  43150. error: function(msg) {
  43151. throw new Error(msg);
  43152. },
  43153. noop: function() {
  43154. },
  43155. isPlainObject: function(obj) {
  43156. var proto, Ctor;
  43157. if (!obj || toString.call(obj) !== "[object Object]") {
  43158. return false;
  43159. }
  43160. proto = getProto(obj);
  43161. if (!proto) {
  43162. return true;
  43163. }
  43164. Ctor = hasOwn.call(proto, "constructor") && proto.constructor;
  43165. return typeof Ctor === "function" && fnToString.call(Ctor) === ObjectFunctionString;
  43166. },
  43167. isEmptyObject: function(obj) {
  43168. var name;
  43169. for (name in obj) {
  43170. return false;
  43171. }
  43172. return true;
  43173. },
  43174. // Evaluates a script in a provided context; falls back to the global one
  43175. // if not specified.
  43176. globalEval: function(code, options, doc) {
  43177. DOMEval(code, { nonce: options && options.nonce }, doc);
  43178. },
  43179. each: function(obj, callback) {
  43180. var length, i2 = 0;
  43181. if (isArrayLike(obj)) {
  43182. length = obj.length;
  43183. for (; i2 < length; i2++) {
  43184. if (callback.call(obj[i2], i2, obj[i2]) === false) {
  43185. break;
  43186. }
  43187. }
  43188. } else {
  43189. for (i2 in obj) {
  43190. if (callback.call(obj[i2], i2, obj[i2]) === false) {
  43191. break;
  43192. }
  43193. }
  43194. }
  43195. return obj;
  43196. },
  43197. // Retrieve the text value of an array of DOM nodes
  43198. text: function(elem) {
  43199. var node, ret = "", i2 = 0, nodeType = elem.nodeType;
  43200. if (!nodeType) {
  43201. while (node = elem[i2++]) {
  43202. ret += jQuery.text(node);
  43203. }
  43204. }
  43205. if (nodeType === 1 || nodeType === 11) {
  43206. return elem.textContent;
  43207. }
  43208. if (nodeType === 9) {
  43209. return elem.documentElement.textContent;
  43210. }
  43211. if (nodeType === 3 || nodeType === 4) {
  43212. return elem.nodeValue;
  43213. }
  43214. return ret;
  43215. },
  43216. // results is for internal usage only
  43217. makeArray: function(arr2, results) {
  43218. var ret = results || [];
  43219. if (arr2 != null) {
  43220. if (isArrayLike(Object(arr2))) {
  43221. jQuery.merge(
  43222. ret,
  43223. typeof arr2 === "string" ? [arr2] : arr2
  43224. );
  43225. } else {
  43226. push.call(ret, arr2);
  43227. }
  43228. }
  43229. return ret;
  43230. },
  43231. inArray: function(elem, arr2, i2) {
  43232. return arr2 == null ? -1 : indexOf.call(arr2, elem, i2);
  43233. },
  43234. isXMLDoc: function(elem) {
  43235. var namespace = elem && elem.namespaceURI, docElem = elem && (elem.ownerDocument || elem).documentElement;
  43236. return !rhtmlSuffix.test(namespace || docElem && docElem.nodeName || "HTML");
  43237. },
  43238. // Note: an element does not contain itself
  43239. contains: function(a, b) {
  43240. var bup = b && b.parentNode;
  43241. return a === bup || !!(bup && bup.nodeType === 1 && // Support: IE 9 - 11+
  43242. // IE doesn't have `contains` on SVG.
  43243. (a.contains ? a.contains(bup) : a.compareDocumentPosition && a.compareDocumentPosition(bup) & 16));
  43244. },
  43245. merge: function(first, second) {
  43246. var len = +second.length, j = 0, i2 = first.length;
  43247. for (; j < len; j++) {
  43248. first[i2++] = second[j];
  43249. }
  43250. first.length = i2;
  43251. return first;
  43252. },
  43253. grep: function(elems, callback, invert) {
  43254. var callbackInverse, matches3 = [], i2 = 0, length = elems.length, callbackExpect = !invert;
  43255. for (; i2 < length; i2++) {
  43256. callbackInverse = !callback(elems[i2], i2);
  43257. if (callbackInverse !== callbackExpect) {
  43258. matches3.push(elems[i2]);
  43259. }
  43260. }
  43261. return matches3;
  43262. },
  43263. // arg is for internal usage only
  43264. map: function(elems, callback, arg) {
  43265. var length, value, i2 = 0, ret = [];
  43266. if (isArrayLike(elems)) {
  43267. length = elems.length;
  43268. for (; i2 < length; i2++) {
  43269. value = callback(elems[i2], i2, arg);
  43270. if (value != null) {
  43271. ret.push(value);
  43272. }
  43273. }
  43274. } else {
  43275. for (i2 in elems) {
  43276. value = callback(elems[i2], i2, arg);
  43277. if (value != null) {
  43278. ret.push(value);
  43279. }
  43280. }
  43281. }
  43282. return flat(ret);
  43283. },
  43284. // A global GUID counter for objects
  43285. guid: 1,
  43286. // jQuery.support is not used in Core but other projects attach their
  43287. // properties to it so it needs to exist.
  43288. support
  43289. });
  43290. if (typeof Symbol === "function") {
  43291. jQuery.fn[Symbol.iterator] = arr[Symbol.iterator];
  43292. }
  43293. jQuery.each(
  43294. "Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),
  43295. function(_i, name) {
  43296. class2type["[object " + name + "]"] = name.toLowerCase();
  43297. }
  43298. );
  43299. function nodeName(elem, name) {
  43300. return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
  43301. }
  43302. var pop = arr.pop;
  43303. var whitespace = "[\\x20\\t\\r\\n\\f]";
  43304. var isIE = document.documentMode;
  43305. try {
  43306. document.querySelector(":has(*,:jqfake)");
  43307. support.cssHas = false;
  43308. } catch (e) {
  43309. support.cssHas = true;
  43310. }
  43311. var rbuggyQSA = [];
  43312. if (isIE) {
  43313. rbuggyQSA.push(
  43314. // Support: IE 9 - 11+
  43315. // IE's :disabled selector does not pick up the children of disabled fieldsets
  43316. ":enabled",
  43317. ":disabled",
  43318. // Support: IE 11+
  43319. // IE 11 doesn't find elements on a `[name='']` query in some cases.
  43320. // Adding a temporary attribute to the document before the selection works
  43321. // around the issue.
  43322. "\\[" + whitespace + "*name" + whitespace + "*=" + whitespace + `*(?:''|"")`
  43323. );
  43324. }
  43325. if (!support.cssHas) {
  43326. rbuggyQSA.push(":has");
  43327. }
  43328. rbuggyQSA = rbuggyQSA.length && new RegExp(rbuggyQSA.join("|"));
  43329. var rtrimCSS = new RegExp(
  43330. "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$",
  43331. "g"
  43332. );
  43333. var identifier = "(?:\\\\[\\da-fA-F]{1,6}" + whitespace + "?|\\\\[^\\r\\n\\f]|[\\w-]|[^\0-\\x7f])+";
  43334. var booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped";
  43335. var rleadingCombinator = new RegExp("^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*");
  43336. var rdescend = new RegExp(whitespace + "|>");
  43337. var rsibling = /[+~]/;
  43338. var documentElement = document.documentElement;
  43339. var matches2 = documentElement.matches || documentElement.msMatchesSelector;
  43340. function createCache() {
  43341. var keys = [];
  43342. function cache(key, value) {
  43343. if (keys.push(key + " ") > jQuery.expr.cacheLength) {
  43344. delete cache[keys.shift()];
  43345. }
  43346. return cache[key + " "] = value;
  43347. }
  43348. return cache;
  43349. }
  43350. function testContext(context) {
  43351. return context && typeof context.getElementsByTagName !== "undefined" && context;
  43352. }
  43353. var attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace + // Operator (capture 2)
  43354. "*([*^$|!~]?=)" + whitespace + // "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]"
  43355. `*(?:'((?:\\\\.|[^\\\\'])*)'|"((?:\\\\.|[^\\\\"])*)"|(` + identifier + "))|)" + whitespace + "*\\]";
  43356. var pseudos = ":(" + identifier + `)(?:\\((('((?:\\\\.|[^\\\\'])*)'|"((?:\\\\.|[^\\\\"])*)")|((?:\\\\.|[^\\\\()[\\]]|` + attributes + ")*)|.*)\\)|)";
  43357. var filterMatchExpr = {
  43358. ID: new RegExp("^#(" + identifier + ")"),
  43359. CLASS: new RegExp("^\\.(" + identifier + ")"),
  43360. TAG: new RegExp("^(" + identifier + "|[*])"),
  43361. ATTR: new RegExp("^" + attributes),
  43362. PSEUDO: new RegExp("^" + pseudos),
  43363. CHILD: new RegExp(
  43364. "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace + "*(\\d+)|))" + whitespace + "*\\)|)",
  43365. "i"
  43366. )
  43367. };
  43368. var rpseudo = new RegExp(pseudos);
  43369. var runescape = new RegExp("\\\\[\\da-fA-F]{1,6}" + whitespace + "?|\\\\([^\\r\\n\\f])", "g"), funescape = function(escape, nonHex) {
  43370. var high = "0x" + escape.slice(1) - 65536;
  43371. if (nonHex) {
  43372. return nonHex;
  43373. }
  43374. return high < 0 ? String.fromCharCode(high + 65536) : String.fromCharCode(high >> 10 | 55296, high & 1023 | 56320);
  43375. };
  43376. function unescapeSelector(sel) {
  43377. return sel.replace(runescape, funescape);
  43378. }
  43379. function selectorError(msg) {
  43380. jQuery.error("Syntax error, unrecognized expression: " + msg);
  43381. }
  43382. var rcomma = new RegExp("^" + whitespace + "*," + whitespace + "*");
  43383. var tokenCache = createCache();
  43384. function tokenize(selector, parseOnly) {
  43385. var matched, match, tokens, type, soFar, groups, preFilters, cached = tokenCache[selector + " "];
  43386. if (cached) {
  43387. return parseOnly ? 0 : cached.slice(0);
  43388. }
  43389. soFar = selector;
  43390. groups = [];
  43391. preFilters = jQuery.expr.preFilter;
  43392. while (soFar) {
  43393. if (!matched || (match = rcomma.exec(soFar))) {
  43394. if (match) {
  43395. soFar = soFar.slice(match[0].length) || soFar;
  43396. }
  43397. groups.push(tokens = []);
  43398. }
  43399. matched = false;
  43400. if (match = rleadingCombinator.exec(soFar)) {
  43401. matched = match.shift();
  43402. tokens.push({
  43403. value: matched,
  43404. // Cast descendant combinators to space
  43405. type: match[0].replace(rtrimCSS, " ")
  43406. });
  43407. soFar = soFar.slice(matched.length);
  43408. }
  43409. for (type in filterMatchExpr) {
  43410. if ((match = jQuery.expr.match[type].exec(soFar)) && (!preFilters[type] || (match = preFilters[type](match)))) {
  43411. matched = match.shift();
  43412. tokens.push({
  43413. value: matched,
  43414. type,
  43415. matches: match
  43416. });
  43417. soFar = soFar.slice(matched.length);
  43418. }
  43419. }
  43420. if (!matched) {
  43421. break;
  43422. }
  43423. }
  43424. if (parseOnly) {
  43425. return soFar.length;
  43426. }
  43427. return soFar ? selectorError(selector) : (
  43428. // Cache the tokens
  43429. tokenCache(selector, groups).slice(0)
  43430. );
  43431. }
  43432. var preFilter = {
  43433. ATTR: function(match) {
  43434. match[1] = unescapeSelector(match[1]);
  43435. match[3] = unescapeSelector(match[3] || match[4] || match[5] || "");
  43436. if (match[2] === "~=") {
  43437. match[3] = " " + match[3] + " ";
  43438. }
  43439. return match.slice(0, 4);
  43440. },
  43441. CHILD: function(match) {
  43442. match[1] = match[1].toLowerCase();
  43443. if (match[1].slice(0, 3) === "nth") {
  43444. if (!match[3]) {
  43445. selectorError(match[0]);
  43446. }
  43447. match[4] = +(match[4] ? match[5] + (match[6] || 1) : 2 * (match[3] === "even" || match[3] === "odd"));
  43448. match[5] = +(match[7] + match[8] || match[3] === "odd");
  43449. } else if (match[3]) {
  43450. selectorError(match[0]);
  43451. }
  43452. return match;
  43453. },
  43454. PSEUDO: function(match) {
  43455. var excess, unquoted = !match[6] && match[2];
  43456. if (filterMatchExpr.CHILD.test(match[0])) {
  43457. return null;
  43458. }
  43459. if (match[3]) {
  43460. match[2] = match[4] || match[5] || "";
  43461. } else if (unquoted && rpseudo.test(unquoted) && // Get excess from tokenize (recursively)
  43462. (excess = tokenize(unquoted, true)) && // advance to the next closing parenthesis
  43463. (excess = unquoted.indexOf(")", unquoted.length - excess) - unquoted.length)) {
  43464. match[0] = match[0].slice(0, excess);
  43465. match[2] = unquoted.slice(0, excess);
  43466. }
  43467. return match.slice(0, 3);
  43468. }
  43469. };
  43470. function toSelector(tokens) {
  43471. var i2 = 0, len = tokens.length, selector = "";
  43472. for (; i2 < len; i2++) {
  43473. selector += tokens[i2].value;
  43474. }
  43475. return selector;
  43476. }
  43477. var rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\x80-\uFFFF\w-]/g;
  43478. function fcssescape(ch, asCodePoint) {
  43479. if (asCodePoint) {
  43480. if (ch === "\0") {
  43481. return "\uFFFD";
  43482. }
  43483. return ch.slice(0, -1) + "\\" + ch.charCodeAt(ch.length - 1).toString(16) + " ";
  43484. }
  43485. return "\\" + ch;
  43486. }
  43487. jQuery.escapeSelector = function(sel) {
  43488. return (sel + "").replace(rcssescape, fcssescape);
  43489. };
  43490. var sort = arr.sort;
  43491. var splice = arr.splice;
  43492. var hasDuplicate;
  43493. function sortOrder(a, b) {
  43494. if (a === b) {
  43495. hasDuplicate = true;
  43496. return 0;
  43497. }
  43498. var compare = !a.compareDocumentPosition - !b.compareDocumentPosition;
  43499. if (compare) {
  43500. return compare;
  43501. }
  43502. compare = (a.ownerDocument || a) == (b.ownerDocument || b) ? a.compareDocumentPosition(b) : (
  43503. // Otherwise we know they are disconnected
  43504. 1
  43505. );
  43506. if (compare & 1) {
  43507. if (a == document || a.ownerDocument == document && jQuery.contains(document, a)) {
  43508. return -1;
  43509. }
  43510. if (b == document || b.ownerDocument == document && jQuery.contains(document, b)) {
  43511. return 1;
  43512. }
  43513. return 0;
  43514. }
  43515. return compare & 4 ? -1 : 1;
  43516. }
  43517. jQuery.uniqueSort = function(results) {
  43518. var elem, duplicates = [], j = 0, i2 = 0;
  43519. hasDuplicate = false;
  43520. sort.call(results, sortOrder);
  43521. if (hasDuplicate) {
  43522. while (elem = results[i2++]) {
  43523. if (elem === results[i2]) {
  43524. j = duplicates.push(i2);
  43525. }
  43526. }
  43527. while (j--) {
  43528. splice.call(results, duplicates[j], 1);
  43529. }
  43530. }
  43531. return results;
  43532. };
  43533. jQuery.fn.uniqueSort = function() {
  43534. return this.pushStack(jQuery.uniqueSort(slice.apply(this)));
  43535. };
  43536. var i, outermostContext, document$1, documentElement$1, documentIsHTML, dirruns = 0, done = 0, classCache = createCache(), compilerCache = createCache(), nonnativeSelectorCache = createCache(), rwhitespace = new RegExp(whitespace + "+", "g"), ridentifier = new RegExp("^" + identifier + "$"), matchExpr = jQuery.extend({
  43537. bool: new RegExp("^(?:" + booleans + ")$", "i"),
  43538. // For use in libraries implementing .is()
  43539. // We use this for POS matching in `select`
  43540. needsContext: new RegExp("^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i")
  43541. }, filterMatchExpr), rinputs = /^(?:input|select|textarea|button)$/i, rheader = /^h\d$/i, rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, unloadHandler = function() {
  43542. setDocument();
  43543. }, inDisabledFieldset = addCombinator(
  43544. function(elem) {
  43545. return elem.disabled === true && nodeName(elem, "fieldset");
  43546. },
  43547. { dir: "parentNode", next: "legend" }
  43548. );
  43549. function find(selector, context, results, seed) {
  43550. var m, i2, elem, nid, match, groups, newSelector, newContext = context && context.ownerDocument, nodeType = context ? context.nodeType : 9;
  43551. results = results || [];
  43552. if (typeof selector !== "string" || !selector || nodeType !== 1 && nodeType !== 9 && nodeType !== 11) {
  43553. return results;
  43554. }
  43555. if (false) {
  43556. setDocument(context);
  43557. context = context || document$1;
  43558. if (documentIsHTML) {
  43559. if (nodeType !== 11 && (match = rquickExpr.exec(selector))) {
  43560. if (m = match[1]) {
  43561. if (nodeType === 9) {
  43562. if (elem = context.getElementById(m)) {
  43563. push.call(results, elem);
  43564. }
  43565. return results;
  43566. } else {
  43567. if (newContext && (elem = newContext.getElementById(m)) && jQuery.contains(context, elem)) {
  43568. push.call(results, elem);
  43569. return results;
  43570. }
  43571. }
  43572. } else if (match[2]) {
  43573. push.apply(results, context.getElementsByTagName(selector));
  43574. return results;
  43575. } else if ((m = match[3]) && context.getElementsByClassName) {
  43576. push.apply(results, context.getElementsByClassName(m));
  43577. return results;
  43578. }
  43579. }
  43580. if (!nonnativeSelectorCache[selector + " "] && (!rbuggyQSA || !rbuggyQSA.test(selector))) {
  43581. newSelector = selector;
  43582. newContext = context;
  43583. if (nodeType === 1 && (rdescend.test(selector) || rleadingCombinator.test(selector))) {
  43584. newContext = rsibling.test(selector) && testContext(context.parentNode) || context;
  43585. if (newContext != context || isIE) {
  43586. if (nid = context.getAttribute("id")) {
  43587. nid = jQuery.escapeSelector(nid);
  43588. } else {
  43589. context.setAttribute("id", nid = jQuery.expando);
  43590. }
  43591. }
  43592. groups = tokenize(selector);
  43593. i2 = groups.length;
  43594. while (i2--) {
  43595. groups[i2] = (nid ? "#" + nid : ":scope") + " " + toSelector(groups[i2]);
  43596. }
  43597. newSelector = groups.join(",");
  43598. }
  43599. try {
  43600. push.apply(
  43601. results,
  43602. newContext.querySelectorAll(newSelector)
  43603. );
  43604. return results;
  43605. } catch (qsaError) {
  43606. nonnativeSelectorCache(selector, true);
  43607. } finally {
  43608. if (nid === jQuery.expando) {
  43609. context.removeAttribute("id");
  43610. }
  43611. }
  43612. }
  43613. }
  43614. }
  43615. return select(selector.replace(rtrimCSS, "$1"), context, results, seed);
  43616. }
  43617. function markFunction(fn) {
  43618. fn[jQuery.expando] = true;
  43619. return fn;
  43620. }
  43621. function createInputPseudo(type) {
  43622. return function(elem) {
  43623. return nodeName(elem, "input") && elem.type === type;
  43624. };
  43625. }
  43626. function createButtonPseudo(type) {
  43627. return function(elem) {
  43628. return (nodeName(elem, "input") || nodeName(elem, "button")) && elem.type === type;
  43629. };
  43630. }
  43631. function createDisabledPseudo(disabled) {
  43632. return function(elem) {
  43633. if ("form" in elem) {
  43634. if (elem.parentNode && elem.disabled === false) {
  43635. if ("label" in elem) {
  43636. if ("label" in elem.parentNode) {
  43637. return elem.parentNode.disabled === disabled;
  43638. } else {
  43639. return elem.disabled === disabled;
  43640. }
  43641. }
  43642. return elem.isDisabled === disabled || // Where there is no isDisabled, check manually
  43643. elem.isDisabled !== !disabled && inDisabledFieldset(elem) === disabled;
  43644. }
  43645. return elem.disabled === disabled;
  43646. } else if ("label" in elem) {
  43647. return elem.disabled === disabled;
  43648. }
  43649. return false;
  43650. };
  43651. }
  43652. function createPositionalPseudo(fn) {
  43653. return markFunction(function(argument) {
  43654. argument = +argument;
  43655. return markFunction(function(seed, matches3) {
  43656. var j, matchIndexes = fn([], seed.length, argument), i2 = matchIndexes.length;
  43657. while (i2--) {
  43658. if (seed[j = matchIndexes[i2]]) {
  43659. seed[j] = !(matches3[j] = seed[j]);
  43660. }
  43661. }
  43662. });
  43663. });
  43664. }
  43665. function setDocument(node) {
  43666. var subWindow, doc = node ? node.ownerDocument || node : document;
  43667. if (doc == document$1 || doc.nodeType !== 9) {
  43668. return;
  43669. }
  43670. document$1 = doc;
  43671. documentElement$1 = document$1.documentElement;
  43672. documentIsHTML = !jQuery.isXMLDoc(document$1);
  43673. if (isIE && document != document$1 && (subWindow = document$1.defaultView) && subWindow.top !== subWindow) {
  43674. subWindow.addEventListener("unload", unloadHandler);
  43675. }
  43676. }
  43677. find.matches = function(expr, elements) {
  43678. return find(expr, null, null, elements);
  43679. };
  43680. find.matchesSelector = function(elem, expr) {
  43681. setDocument(elem);
  43682. if (documentIsHTML && !nonnativeSelectorCache[expr + " "] && (!rbuggyQSA || !rbuggyQSA.test(expr))) {
  43683. try {
  43684. return matches2.call(elem, expr);
  43685. } catch (e) {
  43686. nonnativeSelectorCache(expr, true);
  43687. }
  43688. }
  43689. return find(expr, document$1, null, [elem]).length > 0;
  43690. };
  43691. jQuery.expr = {
  43692. // Can be adjusted by the user
  43693. cacheLength: 50,
  43694. createPseudo: markFunction,
  43695. match: matchExpr,
  43696. find: {
  43697. ID: function(id, context) {
  43698. if (typeof context.getElementById !== "undefined" && documentIsHTML) {
  43699. var elem = context.getElementById(id);
  43700. return elem ? [elem] : [];
  43701. }
  43702. },
  43703. TAG: function(tag, context) {
  43704. if (typeof context.getElementsByTagName !== "undefined") {
  43705. return context.getElementsByTagName(tag);
  43706. } else {
  43707. return context.querySelectorAll(tag);
  43708. }
  43709. },
  43710. CLASS: function(className, context) {
  43711. if (typeof context.getElementsByClassName !== "undefined" && documentIsHTML) {
  43712. return context.getElementsByClassName(className);
  43713. }
  43714. }
  43715. },
  43716. relative: {
  43717. ">": { dir: "parentNode", first: true },
  43718. " ": { dir: "parentNode" },
  43719. "+": { dir: "previousSibling", first: true },
  43720. "~": { dir: "previousSibling" }
  43721. },
  43722. preFilter,
  43723. filter: {
  43724. ID: function(id) {
  43725. var attrId = unescapeSelector(id);
  43726. return function(elem) {
  43727. return elem.getAttribute("id") === attrId;
  43728. };
  43729. },
  43730. TAG: function(nodeNameSelector) {
  43731. var expectedNodeName = unescapeSelector(nodeNameSelector).toLowerCase();
  43732. return nodeNameSelector === "*" ? function() {
  43733. return true;
  43734. } : function(elem) {
  43735. return nodeName(elem, expectedNodeName);
  43736. };
  43737. },
  43738. CLASS: function(className) {
  43739. var pattern = classCache[className + " "];
  43740. return pattern || (pattern = new RegExp("(^|" + whitespace + ")" + className + "(" + whitespace + "|$)")) && classCache(className, function(elem) {
  43741. return pattern.test(
  43742. typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== "undefined" && elem.getAttribute("class") || ""
  43743. );
  43744. });
  43745. },
  43746. ATTR: function(name, operator, check) {
  43747. return function(elem) {
  43748. var result = elem.getAttribute(name);
  43749. if (result == null) {
  43750. return operator === "!=";
  43751. }
  43752. if (!operator) {
  43753. return true;
  43754. }
  43755. result += "";
  43756. if (operator === "=") {
  43757. return result === check;
  43758. }
  43759. if (operator === "!=") {
  43760. return result !== check;
  43761. }
  43762. if (operator === "^=") {
  43763. return check && result.indexOf(check) === 0;
  43764. }
  43765. if (operator === "*=") {
  43766. return check && result.indexOf(check) > -1;
  43767. }
  43768. if (operator === "$=") {
  43769. return check && result.slice(-check.length) === check;
  43770. }
  43771. if (operator === "~=") {
  43772. return (" " + result.replace(rwhitespace, " ") + " ").indexOf(check) > -1;
  43773. }
  43774. if (operator === "|=") {
  43775. return result === check || result.slice(0, check.length + 1) === check + "-";
  43776. }
  43777. return false;
  43778. };
  43779. },
  43780. CHILD: function(type, what, _argument, first, last) {
  43781. var simple = type.slice(0, 3) !== "nth", forward = type.slice(-4) !== "last", ofType = what === "of-type";
  43782. return first === 1 && last === 0 ? (
  43783. // Shortcut for :nth-*(n)
  43784. function(elem) {
  43785. return !!elem.parentNode;
  43786. }
  43787. ) : function(elem, _context, xml) {
  43788. var cache, outerCache, node, nodeIndex, start, dir = simple !== forward ? "nextSibling" : "previousSibling", parent = elem.parentNode, name = ofType && elem.nodeName.toLowerCase(), useCache = !xml && !ofType, diff = false;
  43789. if (parent) {
  43790. if (simple) {
  43791. while (dir) {
  43792. node = elem;
  43793. while (node = node[dir]) {
  43794. if (ofType ? nodeName(node, name) : node.nodeType === 1) {
  43795. return false;
  43796. }
  43797. }
  43798. start = dir = type === "only" && !start && "nextSibling";
  43799. }
  43800. return true;
  43801. }
  43802. start = [forward ? parent.firstChild : parent.lastChild];
  43803. if (forward && useCache) {
  43804. outerCache = parent[jQuery.expando] || (parent[jQuery.expando] = {});
  43805. cache = outerCache[type] || [];
  43806. nodeIndex = cache[0] === dirruns && cache[1];
  43807. diff = nodeIndex && cache[2];
  43808. node = nodeIndex && parent.childNodes[nodeIndex];
  43809. while (node = ++nodeIndex && node && node[dir] || // Fallback to seeking `elem` from the start
  43810. (diff = nodeIndex = 0) || start.pop()) {
  43811. if (node.nodeType === 1 && ++diff && node === elem) {
  43812. outerCache[type] = [dirruns, nodeIndex, diff];
  43813. break;
  43814. }
  43815. }
  43816. } else {
  43817. if (useCache) {
  43818. outerCache = elem[jQuery.expando] || (elem[jQuery.expando] = {});
  43819. cache = outerCache[type] || [];
  43820. nodeIndex = cache[0] === dirruns && cache[1];
  43821. diff = nodeIndex;
  43822. }
  43823. if (diff === false) {
  43824. while (node = ++nodeIndex && node && node[dir] || (diff = nodeIndex = 0) || start.pop()) {
  43825. if ((ofType ? nodeName(node, name) : node.nodeType === 1) && ++diff) {
  43826. if (useCache) {
  43827. outerCache = node[jQuery.expando] || (node[jQuery.expando] = {});
  43828. outerCache[type] = [dirruns, diff];
  43829. }
  43830. if (node === elem) {
  43831. break;
  43832. }
  43833. }
  43834. }
  43835. }
  43836. }
  43837. diff -= last;
  43838. return diff === first || diff % first === 0 && diff / first >= 0;
  43839. }
  43840. };
  43841. },
  43842. PSEUDO: function(pseudo, argument) {
  43843. var fn = jQuery.expr.pseudos[pseudo] || jQuery.expr.setFilters[pseudo.toLowerCase()] || selectorError("unsupported pseudo: " + pseudo);
  43844. if (fn[jQuery.expando]) {
  43845. return fn(argument);
  43846. }
  43847. return fn;
  43848. }
  43849. },
  43850. pseudos: {
  43851. // Potentially complex pseudos
  43852. not: markFunction(function(selector) {
  43853. var input = [], results = [], matcher = compile(selector.replace(rtrimCSS, "$1"));
  43854. return matcher[jQuery.expando] ? markFunction(function(seed, matches3, _context, xml) {
  43855. var elem, unmatched = matcher(seed, null, xml, []), i2 = seed.length;
  43856. while (i2--) {
  43857. if (elem = unmatched[i2]) {
  43858. seed[i2] = !(matches3[i2] = elem);
  43859. }
  43860. }
  43861. }) : function(elem, _context, xml) {
  43862. input[0] = elem;
  43863. matcher(input, null, xml, results);
  43864. input[0] = null;
  43865. return !results.pop();
  43866. };
  43867. }),
  43868. has: markFunction(function(selector) {
  43869. return function(elem) {
  43870. return find(selector, elem).length > 0;
  43871. };
  43872. }),
  43873. contains: markFunction(function(text) {
  43874. text = unescapeSelector(text);
  43875. return function(elem) {
  43876. return (elem.textContent || jQuery.text(elem)).indexOf(text) > -1;
  43877. };
  43878. }),
  43879. // "Whether an element is represented by a :lang() selector
  43880. // is based solely on the element's language value
  43881. // being equal to the identifier C,
  43882. // or beginning with the identifier C immediately followed by "-".
  43883. // The matching of C against the element's language value is performed case-insensitively.
  43884. // The identifier C does not have to be a valid language name."
  43885. // https://www.w3.org/TR/selectors/#lang-pseudo
  43886. lang: markFunction(function(lang) {
  43887. if (!ridentifier.test(lang || "")) {
  43888. selectorError("unsupported lang: " + lang);
  43889. }
  43890. lang = unescapeSelector(lang).toLowerCase();
  43891. return function(elem) {
  43892. var elemLang;
  43893. do {
  43894. if (elemLang = documentIsHTML ? elem.lang : elem.getAttribute("xml:lang") || elem.getAttribute("lang")) {
  43895. elemLang = elemLang.toLowerCase();
  43896. return elemLang === lang || elemLang.indexOf(lang + "-") === 0;
  43897. }
  43898. } while ((elem = elem.parentNode) && elem.nodeType === 1);
  43899. return false;
  43900. };
  43901. }),
  43902. // Miscellaneous
  43903. target: function(elem) {
  43904. var hash = window.location && window.location.hash;
  43905. return hash && hash.slice(1) === elem.id;
  43906. },
  43907. root: function(elem) {
  43908. return elem === documentElement$1;
  43909. },
  43910. focus: function(elem) {
  43911. return elem === document$1.activeElement && document$1.hasFocus() && !!(elem.type || elem.href || ~elem.tabIndex);
  43912. },
  43913. // Boolean properties
  43914. enabled: createDisabledPseudo(false),
  43915. disabled: createDisabledPseudo(true),
  43916. checked: function(elem) {
  43917. return nodeName(elem, "input") && !!elem.checked || nodeName(elem, "option") && !!elem.selected;
  43918. },
  43919. selected: function(elem) {
  43920. if (isIE && elem.parentNode) {
  43921. elem.parentNode.selectedIndex;
  43922. }
  43923. return elem.selected === true;
  43924. },
  43925. // Contents
  43926. empty: function(elem) {
  43927. for (elem = elem.firstChild; elem; elem = elem.nextSibling) {
  43928. if (elem.nodeType < 6) {
  43929. return false;
  43930. }
  43931. }
  43932. return true;
  43933. },
  43934. parent: function(elem) {
  43935. return !jQuery.expr.pseudos.empty(elem);
  43936. },
  43937. // Element/input types
  43938. header: function(elem) {
  43939. return rheader.test(elem.nodeName);
  43940. },
  43941. input: function(elem) {
  43942. return rinputs.test(elem.nodeName);
  43943. },
  43944. button: function(elem) {
  43945. return nodeName(elem, "input") && elem.type === "button" || nodeName(elem, "button");
  43946. },
  43947. text: function(elem) {
  43948. return nodeName(elem, "input") && elem.type === "text";
  43949. },
  43950. // Position-in-collection
  43951. first: createPositionalPseudo(function() {
  43952. return [0];
  43953. }),
  43954. last: createPositionalPseudo(function(_matchIndexes, length) {
  43955. return [length - 1];
  43956. }),
  43957. eq: createPositionalPseudo(function(_matchIndexes, length, argument) {
  43958. return [argument < 0 ? argument + length : argument];
  43959. }),
  43960. even: createPositionalPseudo(function(matchIndexes, length) {
  43961. var i2 = 0;
  43962. for (; i2 < length; i2 += 2) {
  43963. matchIndexes.push(i2);
  43964. }
  43965. return matchIndexes;
  43966. }),
  43967. odd: createPositionalPseudo(function(matchIndexes, length) {
  43968. var i2 = 1;
  43969. for (; i2 < length; i2 += 2) {
  43970. matchIndexes.push(i2);
  43971. }
  43972. return matchIndexes;
  43973. }),
  43974. lt: createPositionalPseudo(function(matchIndexes, length, argument) {
  43975. var i2;
  43976. if (argument < 0) {
  43977. i2 = argument + length;
  43978. } else if (argument > length) {
  43979. i2 = length;
  43980. } else {
  43981. i2 = argument;
  43982. }
  43983. for (; --i2 >= 0; ) {
  43984. matchIndexes.push(i2);
  43985. }
  43986. return matchIndexes;
  43987. }),
  43988. gt: createPositionalPseudo(function(matchIndexes, length, argument) {
  43989. var i2 = argument < 0 ? argument + length : argument;
  43990. for (; ++i2 < length; ) {
  43991. matchIndexes.push(i2);
  43992. }
  43993. return matchIndexes;
  43994. })
  43995. }
  43996. };
  43997. jQuery.expr.pseudos.nth = jQuery.expr.pseudos.eq;
  43998. for (i in { radio: true, checkbox: true, file: true, password: true, image: true }) {
  43999. jQuery.expr.pseudos[i] = createInputPseudo(i);
  44000. }
  44001. for (i in { submit: true, reset: true }) {
  44002. jQuery.expr.pseudos[i] = createButtonPseudo(i);
  44003. }
  44004. function setFilters() {
  44005. }
  44006. setFilters.prototype = jQuery.expr.filters = jQuery.expr.pseudos;
  44007. jQuery.expr.setFilters = new setFilters();
  44008. function addCombinator(matcher, combinator, base) {
  44009. var dir = combinator.dir, skip = combinator.next, key = skip || dir, checkNonElements = base && key === "parentNode", doneName = done++;
  44010. return combinator.first ? (
  44011. // Check against closest ancestor/preceding element
  44012. function(elem, context, xml) {
  44013. while (elem = elem[dir]) {
  44014. if (elem.nodeType === 1 || checkNonElements) {
  44015. return matcher(elem, context, xml);
  44016. }
  44017. }
  44018. return false;
  44019. }
  44020. ) : (
  44021. // Check against all ancestor/preceding elements
  44022. function(elem, context, xml) {
  44023. var oldCache, outerCache, newCache = [dirruns, doneName];
  44024. if (xml) {
  44025. while (elem = elem[dir]) {
  44026. if (elem.nodeType === 1 || checkNonElements) {
  44027. if (matcher(elem, context, xml)) {
  44028. return true;
  44029. }
  44030. }
  44031. }
  44032. } else {
  44033. while (elem = elem[dir]) {
  44034. if (elem.nodeType === 1 || checkNonElements) {
  44035. outerCache = elem[jQuery.expando] || (elem[jQuery.expando] = {});
  44036. if (skip && nodeName(elem, skip)) {
  44037. elem = elem[dir] || elem;
  44038. } else if ((oldCache = outerCache[key]) && oldCache[0] === dirruns && oldCache[1] === doneName) {
  44039. return newCache[2] = oldCache[2];
  44040. } else {
  44041. outerCache[key] = newCache;
  44042. if (newCache[2] = matcher(elem, context, xml)) {
  44043. return true;
  44044. }
  44045. }
  44046. }
  44047. }
  44048. }
  44049. return false;
  44050. }
  44051. );
  44052. }
  44053. function elementMatcher(matchers) {
  44054. return matchers.length > 1 ? function(elem, context, xml) {
  44055. var i2 = matchers.length;
  44056. while (i2--) {
  44057. if (!matchers[i2](elem, context, xml)) {
  44058. return false;
  44059. }
  44060. }
  44061. return true;
  44062. } : matchers[0];
  44063. }
  44064. function multipleContexts(selector, contexts, results) {
  44065. var i2 = 0, len = contexts.length;
  44066. for (; i2 < len; i2++) {
  44067. find(selector, contexts[i2], results);
  44068. }
  44069. return results;
  44070. }
  44071. function condense(unmatched, map2, filter, context, xml) {
  44072. var elem, newUnmatched = [], i2 = 0, len = unmatched.length, mapped = map2 != null;
  44073. for (; i2 < len; i2++) {
  44074. if (elem = unmatched[i2]) {
  44075. if (!filter || filter(elem, context, xml)) {
  44076. newUnmatched.push(elem);
  44077. if (mapped) {
  44078. map2.push(i2);
  44079. }
  44080. }
  44081. }
  44082. }
  44083. return newUnmatched;
  44084. }
  44085. function setMatcher(preFilter2, selector, matcher, postFilter, postFinder, postSelector) {
  44086. if (postFilter && !postFilter[jQuery.expando]) {
  44087. postFilter = setMatcher(postFilter);
  44088. }
  44089. if (postFinder && !postFinder[jQuery.expando]) {
  44090. postFinder = setMatcher(postFinder, postSelector);
  44091. }
  44092. return markFunction(function(seed, results, context, xml) {
  44093. var temp, i2, elem, matcherOut, preMap = [], postMap = [], preexisting = results.length, elems = seed || multipleContexts(
  44094. selector || "*",
  44095. context.nodeType ? [context] : context,
  44096. []
  44097. ), matcherIn = preFilter2 && (seed || !selector) ? condense(elems, preMap, preFilter2, context, xml) : elems;
  44098. if (matcher) {
  44099. matcherOut = postFinder || (seed ? preFilter2 : preexisting || postFilter) ? (
  44100. // ...intermediate processing is necessary
  44101. []
  44102. ) : (
  44103. // ...otherwise use results directly
  44104. results
  44105. );
  44106. matcher(matcherIn, matcherOut, context, xml);
  44107. } else {
  44108. matcherOut = matcherIn;
  44109. }
  44110. if (postFilter) {
  44111. temp = condense(matcherOut, postMap);
  44112. postFilter(temp, [], context, xml);
  44113. i2 = temp.length;
  44114. while (i2--) {
  44115. if (elem = temp[i2]) {
  44116. matcherOut[postMap[i2]] = !(matcherIn[postMap[i2]] = elem);
  44117. }
  44118. }
  44119. }
  44120. if (seed) {
  44121. if (postFinder || preFilter2) {
  44122. if (postFinder) {
  44123. temp = [];
  44124. i2 = matcherOut.length;
  44125. while (i2--) {
  44126. if (elem = matcherOut[i2]) {
  44127. temp.push(matcherIn[i2] = elem);
  44128. }
  44129. }
  44130. postFinder(null, matcherOut = [], temp, xml);
  44131. }
  44132. i2 = matcherOut.length;
  44133. while (i2--) {
  44134. if ((elem = matcherOut[i2]) && (temp = postFinder ? indexOf.call(seed, elem) : preMap[i2]) > -1) {
  44135. seed[temp] = !(results[temp] = elem);
  44136. }
  44137. }
  44138. }
  44139. } else {
  44140. matcherOut = condense(
  44141. matcherOut === results ? matcherOut.splice(preexisting, matcherOut.length) : matcherOut
  44142. );
  44143. if (postFinder) {
  44144. postFinder(null, results, matcherOut, xml);
  44145. } else {
  44146. push.apply(results, matcherOut);
  44147. }
  44148. }
  44149. });
  44150. }
  44151. function matcherFromTokens(tokens) {
  44152. var checkContext, matcher, j, len = tokens.length, leadingRelative = jQuery.expr.relative[tokens[0].type], implicitRelative = leadingRelative || jQuery.expr.relative[" "], i2 = leadingRelative ? 1 : 0, matchContext = addCombinator(function(elem) {
  44153. return elem === checkContext;
  44154. }, implicitRelative, true), matchAnyContext = addCombinator(function(elem) {
  44155. return indexOf.call(checkContext, elem) > -1;
  44156. }, implicitRelative, true), matchers = [function(elem, context, xml) {
  44157. var ret = !leadingRelative && (xml || context != outermostContext) || ((checkContext = context).nodeType ? matchContext(elem, context, xml) : matchAnyContext(elem, context, xml));
  44158. checkContext = null;
  44159. return ret;
  44160. }];
  44161. for (; i2 < len; i2++) {
  44162. if (matcher = jQuery.expr.relative[tokens[i2].type]) {
  44163. matchers = [addCombinator(elementMatcher(matchers), matcher)];
  44164. } else {
  44165. matcher = jQuery.expr.filter[tokens[i2].type].apply(null, tokens[i2].matches);
  44166. if (matcher[jQuery.expando]) {
  44167. j = ++i2;
  44168. for (; j < len; j++) {
  44169. if (jQuery.expr.relative[tokens[j].type]) {
  44170. break;
  44171. }
  44172. }
  44173. return setMatcher(
  44174. i2 > 1 && elementMatcher(matchers),
  44175. i2 > 1 && toSelector(
  44176. // If the preceding token was a descendant combinator, insert an implicit any-element `*`
  44177. tokens.slice(0, i2 - 1).concat({ value: tokens[i2 - 2].type === " " ? "*" : "" })
  44178. ).replace(rtrimCSS, "$1"),
  44179. matcher,
  44180. i2 < j && matcherFromTokens(tokens.slice(i2, j)),
  44181. j < len && matcherFromTokens(tokens = tokens.slice(j)),
  44182. j < len && toSelector(tokens)
  44183. );
  44184. }
  44185. matchers.push(matcher);
  44186. }
  44187. }
  44188. return elementMatcher(matchers);
  44189. }
  44190. function matcherFromGroupMatchers(elementMatchers, setMatchers) {
  44191. var bySet = setMatchers.length > 0, byElement = elementMatchers.length > 0, superMatcher = function(seed, context, xml, results, outermost) {
  44192. var elem, j, matcher, matchedCount = 0, i2 = "0", unmatched = seed && [], setMatched = [], contextBackup = outermostContext, elems = seed || byElement && jQuery.expr.find.TAG("*", outermost), dirrunsUnique = dirruns += contextBackup == null ? 1 : Math.random() || 0.1;
  44193. if (outermost) {
  44194. outermostContext = context == document$1 || context || outermost;
  44195. }
  44196. for (; (elem = elems[i2]) != null; i2++) {
  44197. if (byElement && elem) {
  44198. j = 0;
  44199. if (!context && elem.ownerDocument != document$1) {
  44200. setDocument(elem);
  44201. xml = !documentIsHTML;
  44202. }
  44203. while (matcher = elementMatchers[j++]) {
  44204. if (matcher(elem, context || document$1, xml)) {
  44205. push.call(results, elem);
  44206. break;
  44207. }
  44208. }
  44209. if (outermost) {
  44210. dirruns = dirrunsUnique;
  44211. }
  44212. }
  44213. if (bySet) {
  44214. if (elem = !matcher && elem) {
  44215. matchedCount--;
  44216. }
  44217. if (seed) {
  44218. unmatched.push(elem);
  44219. }
  44220. }
  44221. }
  44222. matchedCount += i2;
  44223. if (bySet && i2 !== matchedCount) {
  44224. j = 0;
  44225. while (matcher = setMatchers[j++]) {
  44226. matcher(unmatched, setMatched, context, xml);
  44227. }
  44228. if (seed) {
  44229. if (matchedCount > 0) {
  44230. while (i2--) {
  44231. if (!(unmatched[i2] || setMatched[i2])) {
  44232. setMatched[i2] = pop.call(results);
  44233. }
  44234. }
  44235. }
  44236. setMatched = condense(setMatched);
  44237. }
  44238. push.apply(results, setMatched);
  44239. if (outermost && !seed && setMatched.length > 0 && matchedCount + setMatchers.length > 1) {
  44240. jQuery.uniqueSort(results);
  44241. }
  44242. }
  44243. if (outermost) {
  44244. dirruns = dirrunsUnique;
  44245. outermostContext = contextBackup;
  44246. }
  44247. return unmatched;
  44248. };
  44249. return bySet ? markFunction(superMatcher) : superMatcher;
  44250. }
  44251. function compile(selector, match) {
  44252. var i2, setMatchers = [], elementMatchers = [], cached = compilerCache[selector + " "];
  44253. if (!cached) {
  44254. if (!match) {
  44255. match = tokenize(selector);
  44256. }
  44257. i2 = match.length;
  44258. while (i2--) {
  44259. cached = matcherFromTokens(match[i2]);
  44260. if (cached[jQuery.expando]) {
  44261. setMatchers.push(cached);
  44262. } else {
  44263. elementMatchers.push(cached);
  44264. }
  44265. }
  44266. cached = compilerCache(
  44267. selector,
  44268. matcherFromGroupMatchers(elementMatchers, setMatchers)
  44269. );
  44270. cached.selector = selector;
  44271. }
  44272. return cached;
  44273. }
  44274. function select(selector, context, results, seed) {
  44275. var i2, tokens, token, type, find2, compiled = typeof selector === "function" && selector, match = !seed && tokenize(selector = compiled.selector || selector);
  44276. results = results || [];
  44277. if (match.length === 1) {
  44278. tokens = match[0] = match[0].slice(0);
  44279. if (tokens.length > 2 && (token = tokens[0]).type === "ID" && context.nodeType === 9 && documentIsHTML && jQuery.expr.relative[tokens[1].type]) {
  44280. context = (jQuery.expr.find.ID(
  44281. unescapeSelector(token.matches[0]),
  44282. context
  44283. ) || [])[0];
  44284. if (!context) {
  44285. return results;
  44286. } else if (compiled) {
  44287. context = context.parentNode;
  44288. }
  44289. selector = selector.slice(tokens.shift().value.length);
  44290. }
  44291. i2 = matchExpr.needsContext.test(selector) ? 0 : tokens.length;
  44292. while (i2--) {
  44293. token = tokens[i2];
  44294. if (jQuery.expr.relative[type = token.type]) {
  44295. break;
  44296. }
  44297. if (find2 = jQuery.expr.find[type]) {
  44298. if (seed = find2(
  44299. unescapeSelector(token.matches[0]),
  44300. rsibling.test(tokens[0].type) && testContext(context.parentNode) || context
  44301. )) {
  44302. tokens.splice(i2, 1);
  44303. selector = seed.length && toSelector(tokens);
  44304. if (!selector) {
  44305. push.apply(results, seed);
  44306. return results;
  44307. }
  44308. break;
  44309. }
  44310. }
  44311. }
  44312. }
  44313. (compiled || compile(selector, match))(
  44314. seed,
  44315. context,
  44316. !documentIsHTML,
  44317. results,
  44318. !context || rsibling.test(selector) && testContext(context.parentNode) || context
  44319. );
  44320. return results;
  44321. }
  44322. setDocument();
  44323. jQuery.find = find;
  44324. find.compile = compile;
  44325. find.select = select;
  44326. find.setDocument = setDocument;
  44327. find.tokenize = tokenize;
  44328. return jQuery;
  44329. })
  44330. );
  44331. // src/mock-doc/selector.ts
  44332. function matches(selector, elm) {
  44333. try {
  44334. const r = jquery_default.find(selector, void 0, void 0, [elm]);
  44335. return r.length > 0;
  44336. } catch (e) {
  44337. updateSelectorError(selector, e);
  44338. throw e;
  44339. }
  44340. }
  44341. function selectOne(selector, elm) {
  44342. try {
  44343. const r = jquery_default.find(selector, elm, void 0, void 0);
  44344. return r[0] || null;
  44345. } catch (e) {
  44346. updateSelectorError(selector, e);
  44347. throw e;
  44348. }
  44349. }
  44350. function selectAll(selector, elm) {
  44351. try {
  44352. return jquery_default.find(selector, elm, void 0, void 0);
  44353. } catch (e) {
  44354. updateSelectorError(selector, e);
  44355. throw e;
  44356. }
  44357. }
  44358. var PROBLEMATIC_SELECTORS = [":scope", ":where", ":is"];
  44359. function updateSelectorError(selector, e) {
  44360. const selectorsPresent = PROBLEMATIC_SELECTORS.filter((s) => selector.includes(s));
  44361. if (selectorsPresent.length > 0 && e.message) {
  44362. e.message = `At present jQuery does not support the ${humanReadableList(selectorsPresent)} ${selectorsPresent.length === 1 ? "selector" : "selectors"}.
  44363. If you need this in your test, consider writing an end-to-end test instead.
  44364. ` + e.message;
  44365. }
  44366. }
  44367. function humanReadableList(items) {
  44368. if (items.length <= 1) {
  44369. return items.join("");
  44370. }
  44371. return `${items.slice(0, items.length - 1).join(", ")} and ${items[items.length - 1]}`;
  44372. }
  44373. // src/mock-doc/serialize-node.ts
  44374. function normalizeSerializationOptions(opts = {}) {
  44375. return {
  44376. ...opts,
  44377. outerHtml: typeof opts.outerHtml !== "boolean" ? false : opts.outerHtml,
  44378. ...opts.prettyHtml ? {
  44379. indentSpaces: typeof opts.indentSpaces !== "number" ? 2 : opts.indentSpaces,
  44380. newLines: typeof opts.newLines !== "boolean" ? true : opts.newLines
  44381. } : {
  44382. prettyHtml: false,
  44383. indentSpaces: typeof opts.indentSpaces !== "number" ? 0 : opts.indentSpaces,
  44384. newLines: typeof opts.newLines !== "boolean" ? false : opts.newLines
  44385. },
  44386. approximateLineWidth: typeof opts.approximateLineWidth !== "number" ? -1 : opts.approximateLineWidth,
  44387. removeEmptyAttributes: typeof opts.removeEmptyAttributes !== "boolean" ? true : opts.removeEmptyAttributes,
  44388. removeAttributeQuotes: typeof opts.removeAttributeQuotes !== "boolean" ? false : opts.removeAttributeQuotes,
  44389. removeBooleanAttributeQuotes: typeof opts.removeBooleanAttributeQuotes !== "boolean" ? false : opts.removeBooleanAttributeQuotes,
  44390. removeHtmlComments: typeof opts.removeHtmlComments !== "boolean" ? false : opts.removeHtmlComments,
  44391. serializeShadowRoot: typeof opts.serializeShadowRoot !== "boolean" ? true : opts.serializeShadowRoot,
  44392. fullDocument: typeof opts.fullDocument !== "boolean" ? true : opts.fullDocument
  44393. };
  44394. }
  44395. function serializeNodeToHtml(elm, serializationOptions = {}) {
  44396. const opts = normalizeSerializationOptions(serializationOptions);
  44397. const output = {
  44398. currentLineWidth: 0,
  44399. indent: 0,
  44400. isWithinBody: false,
  44401. text: []
  44402. };
  44403. let renderedNode = "";
  44404. const children = !opts.fullDocument && elm.body ? Array.from(elm.body.childNodes) : opts.outerHtml ? [elm] : Array.from(elm.childNodes);
  44405. for (let i = 0, ii = children.length; i < ii; i++) {
  44406. const child = children[i];
  44407. const chunks = Array.from(streamToHtml(child, opts, output));
  44408. renderedNode += chunks.join("");
  44409. }
  44410. return renderedNode.trim();
  44411. }
  44412. var shadowRootTag = "mock:shadow-root";
  44413. function* streamToHtml(node, opts, output) {
  44414. var _a2, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p;
  44415. const isShadowRoot = node.nodeType === 11 /* DOCUMENT_FRAGMENT_NODE */;
  44416. if (node.nodeType === 1 /* ELEMENT_NODE */ || isShadowRoot) {
  44417. const tagName = isShadowRoot ? shadowRootTag : getTagName(node);
  44418. if (tagName === "body") {
  44419. output.isWithinBody = true;
  44420. }
  44421. const ignoreTag = opts.excludeTags != null && opts.excludeTags.includes(tagName);
  44422. if (ignoreTag === false) {
  44423. const isWithinWhitespaceSensitiveNode = opts.newLines || ((_a2 = opts.indentSpaces) != null ? _a2 : 0) > 0 ? isWithinWhitespaceSensitive(node) : false;
  44424. if (opts.newLines && !isWithinWhitespaceSensitiveNode) {
  44425. yield "\n";
  44426. output.currentLineWidth = 0;
  44427. }
  44428. if (((_b = opts.indentSpaces) != null ? _b : 0) > 0 && !isWithinWhitespaceSensitiveNode) {
  44429. for (let i = 0; i < output.indent; i++) {
  44430. yield " ";
  44431. }
  44432. output.currentLineWidth += output.indent;
  44433. }
  44434. const tag = tagName === shadowRootTag ? "template" : tagName;
  44435. yield "<" + tag;
  44436. output.currentLineWidth += tag.length + 1;
  44437. if (tag === "template") {
  44438. const mode = ` shadowrootmode="open"`;
  44439. yield mode;
  44440. output.currentLineWidth += mode.length;
  44441. }
  44442. const attrsLength = node.attributes.length;
  44443. const attributes = opts.prettyHtml && attrsLength > 1 ? cloneAttributes(node.attributes, true) : node.attributes;
  44444. for (let i = 0; i < attrsLength; i++) {
  44445. const attr = attributes.item(i);
  44446. const attrName = attr.name;
  44447. if (attrName === "style") {
  44448. continue;
  44449. }
  44450. let attrValue = attr.value;
  44451. if (opts.removeEmptyAttributes && attrValue === "" && REMOVE_EMPTY_ATTR.has(attrName)) {
  44452. continue;
  44453. }
  44454. const attrNamespaceURI = attr.namespaceURI;
  44455. if (attrNamespaceURI == null) {
  44456. output.currentLineWidth += attrName.length + 1;
  44457. if (opts.approximateLineWidth && opts.approximateLineWidth > 0 && output.currentLineWidth > opts.approximateLineWidth) {
  44458. yield "\n" + attrName;
  44459. output.currentLineWidth = 0;
  44460. } else {
  44461. yield " " + attrName;
  44462. }
  44463. } else if (attrNamespaceURI === "http://www.w3.org/XML/1998/namespace") {
  44464. yield " xml:" + attrName;
  44465. output.currentLineWidth += attrName.length + 5;
  44466. } else if (attrNamespaceURI === "http://www.w3.org/2000/xmlns/") {
  44467. if (attrName !== "xmlns") {
  44468. yield " xmlns:" + attrName;
  44469. output.currentLineWidth += attrName.length + 7;
  44470. } else {
  44471. yield " " + attrName;
  44472. output.currentLineWidth += attrName.length + 1;
  44473. }
  44474. } else if (attrNamespaceURI === XLINK_NS) {
  44475. yield " xlink:" + attrName;
  44476. output.currentLineWidth += attrName.length + 7;
  44477. } else {
  44478. yield " " + attrNamespaceURI + ":" + attrName;
  44479. output.currentLineWidth += attrNamespaceURI.length + attrName.length + 2;
  44480. }
  44481. if (opts.prettyHtml && attrName === "class") {
  44482. attrValue = attr.value = attrValue.split(" ").filter((t) => t !== "").sort().join(" ").trim();
  44483. }
  44484. if (attrValue === "") {
  44485. if (opts.removeBooleanAttributeQuotes && BOOLEAN_ATTR.has(attrName)) {
  44486. continue;
  44487. }
  44488. if (opts.removeEmptyAttributes && attrName.startsWith("data-")) {
  44489. continue;
  44490. }
  44491. }
  44492. if (opts.removeAttributeQuotes && CAN_REMOVE_ATTR_QUOTES.test(attrValue)) {
  44493. yield "=" + escapeString(attrValue, true);
  44494. output.currentLineWidth += attrValue.length + 1;
  44495. } else {
  44496. yield '="' + escapeString(attrValue, true) + '"';
  44497. output.currentLineWidth += attrValue.length + 3;
  44498. }
  44499. }
  44500. if (node.hasAttribute("style")) {
  44501. const cssText = node.style.cssText;
  44502. if (opts.approximateLineWidth && opts.approximateLineWidth > 0 && output.currentLineWidth + cssText.length + 10 > opts.approximateLineWidth) {
  44503. yield `
  44504. style="${cssText}">`;
  44505. output.currentLineWidth = 0;
  44506. } else {
  44507. yield ` style="${cssText}">`;
  44508. output.currentLineWidth += cssText.length + 10;
  44509. }
  44510. } else {
  44511. yield ">";
  44512. output.currentLineWidth += 1;
  44513. }
  44514. }
  44515. if (EMPTY_ELEMENTS.has(tagName) === false) {
  44516. const shadowRoot = node.shadowRoot;
  44517. if (shadowRoot != null && opts.serializeShadowRoot) {
  44518. output.indent = output.indent + ((_c = opts.indentSpaces) != null ? _c : 0);
  44519. yield* streamToHtml(shadowRoot, opts, output);
  44520. output.indent = output.indent - ((_d = opts.indentSpaces) != null ? _d : 0);
  44521. if (opts.newLines && (node.childNodes.length === 0 || node.childNodes.length === 1 && node.childNodes[0].nodeType === 3 /* TEXT_NODE */ && ((_e = node.childNodes[0].nodeValue) == null ? void 0 : _e.trim()) === "")) {
  44522. yield "\n";
  44523. output.currentLineWidth = 0;
  44524. for (let i = 0; i < output.indent; i++) {
  44525. yield " ";
  44526. }
  44527. output.currentLineWidth += output.indent;
  44528. }
  44529. }
  44530. if (opts.excludeTagContent == null || opts.excludeTagContent.includes(tagName) === false) {
  44531. const tag = tagName === shadowRootTag ? "template" : tagName;
  44532. const childNodes = tagName === "template" ? node.content.childNodes : node.childNodes;
  44533. const childNodeLength = childNodes.length;
  44534. if (childNodeLength > 0) {
  44535. if (childNodeLength === 1 && childNodes[0].nodeType === 3 /* TEXT_NODE */ && (typeof childNodes[0].nodeValue !== "string" || childNodes[0].nodeValue.trim() === "")) {
  44536. } else {
  44537. const isWithinWhitespaceSensitiveNode = opts.newLines || ((_f = opts.indentSpaces) != null ? _f : 0) > 0 ? isWithinWhitespaceSensitive(node) : false;
  44538. if (!isWithinWhitespaceSensitiveNode && ((_g = opts.indentSpaces) != null ? _g : 0) > 0 && ignoreTag === false) {
  44539. output.indent = output.indent + ((_h = opts.indentSpaces) != null ? _h : 0);
  44540. }
  44541. for (let i = 0; i < childNodeLength; i++) {
  44542. yield* streamToHtml(childNodes[i], opts, output);
  44543. }
  44544. if (ignoreTag === false) {
  44545. if (opts.newLines && !isWithinWhitespaceSensitiveNode) {
  44546. yield "\n";
  44547. output.currentLineWidth = 0;
  44548. }
  44549. if (((_i = opts.indentSpaces) != null ? _i : 0) > 0 && !isWithinWhitespaceSensitiveNode) {
  44550. output.indent = output.indent - ((_j = opts.indentSpaces) != null ? _j : 0);
  44551. for (let i = 0; i < output.indent; i++) {
  44552. yield " ";
  44553. }
  44554. output.currentLineWidth += output.indent;
  44555. }
  44556. }
  44557. }
  44558. }
  44559. if (ignoreTag === false) {
  44560. yield "</" + tag + ">";
  44561. output.currentLineWidth += tag.length + 3;
  44562. }
  44563. }
  44564. }
  44565. if (((_k = opts.approximateLineWidth) != null ? _k : 0) > 0 && STRUCTURE_ELEMENTS.has(tagName)) {
  44566. yield "\n";
  44567. output.currentLineWidth = 0;
  44568. }
  44569. if (tagName === "body") {
  44570. output.isWithinBody = false;
  44571. }
  44572. } else if (node.nodeType === 3 /* TEXT_NODE */) {
  44573. let textContent = node.nodeValue;
  44574. if (typeof textContent === "string") {
  44575. const trimmedTextContent = textContent.trim();
  44576. if (trimmedTextContent === "") {
  44577. if (isWithinWhitespaceSensitive(node)) {
  44578. yield textContent;
  44579. output.currentLineWidth += textContent.length;
  44580. } else if (((_l = opts.approximateLineWidth) != null ? _l : 0) > 0 && !output.isWithinBody) {
  44581. } else if (!opts.prettyHtml) {
  44582. output.currentLineWidth += 1;
  44583. if (opts.approximateLineWidth && opts.approximateLineWidth > 0 && output.currentLineWidth > opts.approximateLineWidth) {
  44584. yield "\n";
  44585. output.currentLineWidth = 0;
  44586. } else {
  44587. yield " ";
  44588. }
  44589. }
  44590. } else {
  44591. const isWithinWhitespaceSensitiveNode = opts.newLines || ((_m = opts.indentSpaces) != null ? _m : 0) > 0 || opts.prettyHtml ? isWithinWhitespaceSensitive(node) : false;
  44592. if (opts.newLines && !isWithinWhitespaceSensitiveNode) {
  44593. yield "\n";
  44594. output.currentLineWidth = 0;
  44595. }
  44596. if (((_n = opts.indentSpaces) != null ? _n : 0) > 0 && !isWithinWhitespaceSensitiveNode) {
  44597. for (let i = 0; i < output.indent; i++) {
  44598. yield " ";
  44599. }
  44600. output.currentLineWidth += output.indent;
  44601. }
  44602. let textContentLength = textContent.length;
  44603. if (textContentLength > 0) {
  44604. const parentTagName = node.parentNode != null && node.parentNode.nodeType === 1 /* ELEMENT_NODE */ ? node.parentNode.nodeName : null;
  44605. if (typeof parentTagName === "string" && NON_ESCAPABLE_CONTENT.has(parentTagName)) {
  44606. if (isWithinWhitespaceSensitive(node)) {
  44607. yield textContent;
  44608. } else {
  44609. yield trimmedTextContent;
  44610. textContentLength = trimmedTextContent.length;
  44611. }
  44612. output.currentLineWidth += textContentLength;
  44613. } else {
  44614. if (opts.prettyHtml && !isWithinWhitespaceSensitiveNode) {
  44615. yield escapeString(textContent.replace(/\s\s+/g, " ").trim(), false);
  44616. output.currentLineWidth += textContentLength;
  44617. } else {
  44618. if (isWithinWhitespaceSensitive(node)) {
  44619. output.currentLineWidth += textContentLength;
  44620. } else {
  44621. if (/\s/.test(textContent.charAt(0))) {
  44622. textContent = " " + textContent.trimLeft();
  44623. }
  44624. textContentLength = textContent.length;
  44625. if (textContentLength > 1) {
  44626. if (/\s/.test(textContent.charAt(textContentLength - 1))) {
  44627. if (opts.approximateLineWidth && opts.approximateLineWidth > 0 && output.currentLineWidth + textContentLength > opts.approximateLineWidth) {
  44628. textContent = textContent.trimRight() + "\n";
  44629. output.currentLineWidth = 0;
  44630. } else {
  44631. textContent = textContent.trimRight() + " ";
  44632. }
  44633. }
  44634. }
  44635. output.currentLineWidth += textContentLength;
  44636. }
  44637. yield escapeString(textContent, false);
  44638. }
  44639. }
  44640. }
  44641. }
  44642. }
  44643. } else if (node.nodeType === 8 /* COMMENT_NODE */) {
  44644. const nodeValue = node.nodeValue;
  44645. const isHydrateAnnotation = (nodeValue == null ? void 0 : nodeValue.startsWith(CONTENT_REF_ID + ".")) || (nodeValue == null ? void 0 : nodeValue.startsWith(ORG_LOCATION_ID + ".")) || (nodeValue == null ? void 0 : nodeValue.startsWith(SLOT_NODE_ID + ".")) || (nodeValue == null ? void 0 : nodeValue.startsWith(TEXT_NODE_ID + "."));
  44646. if (opts.removeHtmlComments && !isHydrateAnnotation) {
  44647. return;
  44648. }
  44649. const isWithinWhitespaceSensitiveNode = opts.newLines || ((_o = opts.indentSpaces) != null ? _o : 0) > 0 ? isWithinWhitespaceSensitive(node) : false;
  44650. if (opts.newLines && !isWithinWhitespaceSensitiveNode) {
  44651. yield "\n";
  44652. output.currentLineWidth = 0;
  44653. }
  44654. if (((_p = opts.indentSpaces) != null ? _p : 0) > 0 && !isWithinWhitespaceSensitiveNode) {
  44655. for (let i = 0; i < output.indent; i++) {
  44656. yield " ";
  44657. }
  44658. output.currentLineWidth += output.indent;
  44659. }
  44660. yield "<!--" + nodeValue + "-->";
  44661. if (nodeValue) {
  44662. output.currentLineWidth += nodeValue.length + 7;
  44663. }
  44664. } else if (node.nodeType === 10 /* DOCUMENT_TYPE_NODE */) {
  44665. yield "<!doctype html>";
  44666. }
  44667. }
  44668. var AMP_REGEX = /&/g;
  44669. var NBSP_REGEX = /\u00a0/g;
  44670. var DOUBLE_QUOTE_REGEX = /"/g;
  44671. var LT_REGEX = /</g;
  44672. var GT_REGEX = />/g;
  44673. var CAN_REMOVE_ATTR_QUOTES = /^[^ \t\n\f\r"'`=<>\/\\-]+$/;
  44674. function getTagName(element) {
  44675. if (element.namespaceURI === "http://www.w3.org/1999/xhtml") {
  44676. return element.nodeName.toLowerCase();
  44677. } else {
  44678. return element.nodeName;
  44679. }
  44680. }
  44681. function escapeString(str, attrMode) {
  44682. str = str.replace(AMP_REGEX, "&amp;").replace(NBSP_REGEX, "&nbsp;");
  44683. if (attrMode) {
  44684. return str.replace(DOUBLE_QUOTE_REGEX, "&quot;");
  44685. }
  44686. return str.replace(LT_REGEX, "&lt;").replace(GT_REGEX, "&gt;");
  44687. }
  44688. function isWithinWhitespaceSensitive(node) {
  44689. let _node = node;
  44690. while (_node == null ? void 0 : _node.nodeName) {
  44691. if (WHITESPACE_SENSITIVE.has(_node.nodeName)) {
  44692. return true;
  44693. }
  44694. _node = _node.parentNode;
  44695. }
  44696. return false;
  44697. }
  44698. var NON_ESCAPABLE_CONTENT = /* @__PURE__ */ new Set([
  44699. "STYLE",
  44700. "SCRIPT",
  44701. "IFRAME",
  44702. "NOSCRIPT",
  44703. "XMP",
  44704. "NOEMBED",
  44705. "NOFRAMES",
  44706. "PLAINTEXT"
  44707. ]);
  44708. var WHITESPACE_SENSITIVE = /* @__PURE__ */ new Set([
  44709. "CODE",
  44710. "OUTPUT",
  44711. "PLAINTEXT",
  44712. "PRE",
  44713. "SCRIPT",
  44714. "TEMPLATE",
  44715. "TEXTAREA"
  44716. ]);
  44717. var EMPTY_ELEMENTS = /* @__PURE__ */ new Set([
  44718. "area",
  44719. "base",
  44720. "basefont",
  44721. "bgsound",
  44722. "br",
  44723. "col",
  44724. "embed",
  44725. "frame",
  44726. "hr",
  44727. "img",
  44728. "input",
  44729. "keygen",
  44730. "link",
  44731. "meta",
  44732. "param",
  44733. "source",
  44734. "trace",
  44735. "track",
  44736. "wbr"
  44737. ]);
  44738. var REMOVE_EMPTY_ATTR = /* @__PURE__ */ new Set(["class", "dir", "id", "lang", "name", "title"]);
  44739. var BOOLEAN_ATTR = /* @__PURE__ */ new Set([
  44740. "allowfullscreen",
  44741. "async",
  44742. "autofocus",
  44743. "autoplay",
  44744. "checked",
  44745. "compact",
  44746. "controls",
  44747. "declare",
  44748. "default",
  44749. "defaultchecked",
  44750. "defaultmuted",
  44751. "defaultselected",
  44752. "defer",
  44753. "disabled",
  44754. "enabled",
  44755. "formnovalidate",
  44756. "hidden",
  44757. "indeterminate",
  44758. "inert",
  44759. "ismap",
  44760. "itemscope",
  44761. "loop",
  44762. "multiple",
  44763. "muted",
  44764. "nohref",
  44765. "nomodule",
  44766. "noresize",
  44767. "noshade",
  44768. "novalidate",
  44769. "nowrap",
  44770. "open",
  44771. "pauseonexit",
  44772. "readonly",
  44773. "required",
  44774. "reversed",
  44775. "scoped",
  44776. "seamless",
  44777. "selected",
  44778. "sortable",
  44779. "truespeed",
  44780. "typemustmatch",
  44781. "visible"
  44782. ]);
  44783. var STRUCTURE_ELEMENTS = /* @__PURE__ */ new Set([
  44784. "html",
  44785. "body",
  44786. "head",
  44787. "iframe",
  44788. "meta",
  44789. "link",
  44790. "base",
  44791. "title",
  44792. "script",
  44793. "style"
  44794. ]);
  44795. // src/mock-doc/node.ts
  44796. var MockNode2 = class {
  44797. constructor(ownerDocument, nodeType, nodeName, nodeValue) {
  44798. this.ownerDocument = ownerDocument;
  44799. this.nodeType = nodeType;
  44800. this.nodeName = nodeName;
  44801. this._nodeValue = nodeValue;
  44802. this.parentNode = null;
  44803. this.childNodes = [];
  44804. }
  44805. appendChild(newNode) {
  44806. if (newNode.nodeType === 11 /* DOCUMENT_FRAGMENT_NODE */) {
  44807. const nodes = newNode.childNodes.slice();
  44808. for (const child of nodes) {
  44809. this.appendChild(child);
  44810. }
  44811. } else {
  44812. newNode.remove();
  44813. newNode.parentNode = this;
  44814. this.childNodes.push(newNode);
  44815. connectNode(this.ownerDocument, newNode);
  44816. }
  44817. return newNode;
  44818. }
  44819. append(...items) {
  44820. items.forEach((item) => {
  44821. const isNode = typeof item === "object" && item !== null && "nodeType" in item;
  44822. this.appendChild(isNode ? item : this.ownerDocument.createTextNode(String(item)));
  44823. });
  44824. }
  44825. prepend(...items) {
  44826. const firstChild = this.firstChild;
  44827. items.forEach((item) => {
  44828. const isNode = typeof item === "object" && item !== null && "nodeType" in item;
  44829. if (firstChild) {
  44830. this.insertBefore(isNode ? item : this.ownerDocument.createTextNode(String(item)), firstChild);
  44831. }
  44832. });
  44833. }
  44834. cloneNode(deep) {
  44835. throw new Error(`invalid node type to clone: ${this.nodeType}, deep: ${deep}`);
  44836. }
  44837. compareDocumentPosition(_other) {
  44838. return -1;
  44839. }
  44840. get firstChild() {
  44841. return this.childNodes[0] || null;
  44842. }
  44843. insertBefore(newNode, referenceNode) {
  44844. if (newNode.nodeType === 11 /* DOCUMENT_FRAGMENT_NODE */) {
  44845. for (let i = 0, ii = newNode.childNodes.length; i < ii; i++) {
  44846. insertBefore(this, newNode.childNodes[i], referenceNode);
  44847. }
  44848. } else {
  44849. insertBefore(this, newNode, referenceNode);
  44850. }
  44851. return newNode;
  44852. }
  44853. get isConnected() {
  44854. let node = this;
  44855. while (node != null) {
  44856. if (node.nodeType === 9 /* DOCUMENT_NODE */) {
  44857. return true;
  44858. }
  44859. node = node.parentNode;
  44860. if (node != null && node.nodeType === 11 /* DOCUMENT_FRAGMENT_NODE */) {
  44861. node = node.host;
  44862. }
  44863. }
  44864. return false;
  44865. }
  44866. isSameNode(node) {
  44867. return this === node;
  44868. }
  44869. get lastChild() {
  44870. return this.childNodes[this.childNodes.length - 1] || null;
  44871. }
  44872. get nextSibling() {
  44873. if (this.parentNode != null) {
  44874. const index = this.parentNode.childNodes.indexOf(this) + 1;
  44875. return this.parentNode.childNodes[index] || null;
  44876. }
  44877. return null;
  44878. }
  44879. get nodeValue() {
  44880. var _a2;
  44881. return (_a2 = this._nodeValue) != null ? _a2 : "";
  44882. }
  44883. set nodeValue(value) {
  44884. this._nodeValue = value;
  44885. }
  44886. get parentElement() {
  44887. return this.parentNode || null;
  44888. }
  44889. set parentElement(value) {
  44890. this.parentNode = value;
  44891. }
  44892. get previousSibling() {
  44893. if (this.parentNode != null) {
  44894. const index = this.parentNode.childNodes.indexOf(this) - 1;
  44895. return this.parentNode.childNodes[index] || null;
  44896. }
  44897. return null;
  44898. }
  44899. contains(otherNode) {
  44900. if (otherNode === this) {
  44901. return true;
  44902. }
  44903. const childNodes = Array.from(this.childNodes);
  44904. if (childNodes.includes(otherNode)) {
  44905. return true;
  44906. }
  44907. return childNodes.some((node) => this.contains.bind(node)(otherNode));
  44908. }
  44909. removeChild(childNode) {
  44910. const index = this.childNodes.indexOf(childNode);
  44911. if (index > -1) {
  44912. this.childNodes.splice(index, 1);
  44913. if (this.nodeType === 1 /* ELEMENT_NODE */) {
  44914. const wasConnected = this.isConnected;
  44915. childNode.parentNode = null;
  44916. if (wasConnected === true) {
  44917. disconnectNode(childNode);
  44918. }
  44919. } else {
  44920. childNode.parentNode = null;
  44921. }
  44922. } else {
  44923. throw new Error(`node not found within childNodes during removeChild`);
  44924. }
  44925. return childNode;
  44926. }
  44927. remove() {
  44928. if (this.parentNode != null) {
  44929. this.parentNode.removeChild(this);
  44930. }
  44931. }
  44932. replaceChild(newChild, oldChild) {
  44933. if (oldChild.parentNode === this) {
  44934. this.insertBefore(newChild, oldChild);
  44935. oldChild.remove();
  44936. return newChild;
  44937. }
  44938. return null;
  44939. }
  44940. get textContent() {
  44941. var _a2;
  44942. return (_a2 = this._nodeValue) != null ? _a2 : "";
  44943. }
  44944. set textContent(value) {
  44945. this._nodeValue = String(value);
  44946. }
  44947. };
  44948. MockNode2.ELEMENT_NODE = 1;
  44949. MockNode2.TEXT_NODE = 3;
  44950. MockNode2.PROCESSING_INSTRUCTION_NODE = 7;
  44951. MockNode2.COMMENT_NODE = 8;
  44952. MockNode2.DOCUMENT_NODE = 9;
  44953. MockNode2.DOCUMENT_TYPE_NODE = 10;
  44954. MockNode2.DOCUMENT_FRAGMENT_NODE = 11;
  44955. var MockNodeList = class {
  44956. constructor(ownerDocument, childNodes, length) {
  44957. this.ownerDocument = ownerDocument;
  44958. this.childNodes = childNodes;
  44959. this.length = length;
  44960. }
  44961. };
  44962. var MockElement = class extends MockNode2 {
  44963. attachInternals() {
  44964. return new Proxy({}, {
  44965. get: function(_target, prop, _receiver) {
  44966. console.error(
  44967. `NOTE: Property ${String(prop)} was accessed on ElementInternals, but this property is not implemented.
  44968. Testing components with ElementInternals is fully supported in e2e tests.`
  44969. );
  44970. }
  44971. });
  44972. }
  44973. constructor(ownerDocument, nodeName, namespaceURI = null) {
  44974. super(ownerDocument, 1 /* ELEMENT_NODE */, typeof nodeName === "string" ? nodeName : null, null);
  44975. this.__namespaceURI = namespaceURI;
  44976. this.__shadowRoot = null;
  44977. this.__attributeMap = null;
  44978. }
  44979. addEventListener(type, handler) {
  44980. addEventListener(this, type, handler);
  44981. }
  44982. attachShadow(_opts) {
  44983. const shadowRoot = this.ownerDocument.createDocumentFragment();
  44984. this.shadowRoot = shadowRoot;
  44985. return shadowRoot;
  44986. }
  44987. blur() {
  44988. dispatchEvent(
  44989. this,
  44990. new MockFocusEvent("blur", { relatedTarget: null, bubbles: true, cancelable: true, composed: true })
  44991. );
  44992. }
  44993. get localName() {
  44994. if (!this.nodeName) {
  44995. throw new Error(`Can't compute elements localName without nodeName`);
  44996. }
  44997. return this.nodeName.toLocaleLowerCase();
  44998. }
  44999. get namespaceURI() {
  45000. return this.__namespaceURI;
  45001. }
  45002. get shadowRoot() {
  45003. return this.__shadowRoot || null;
  45004. }
  45005. /**
  45006. * Set shadow root for element
  45007. * @param shadowRoot - ShadowRoot to set
  45008. */
  45009. set shadowRoot(shadowRoot) {
  45010. if (shadowRoot != null) {
  45011. shadowRoot.host = this;
  45012. this.__shadowRoot = shadowRoot;
  45013. } else {
  45014. delete this.__shadowRoot;
  45015. }
  45016. }
  45017. get attributes() {
  45018. if (this.__attributeMap == null) {
  45019. const attrMap = createAttributeProxy(false);
  45020. this.__attributeMap = attrMap;
  45021. return attrMap;
  45022. }
  45023. return this.__attributeMap;
  45024. }
  45025. set attributes(attrs) {
  45026. this.__attributeMap = attrs;
  45027. }
  45028. get children() {
  45029. return this.childNodes.filter((n) => n.nodeType === 1 /* ELEMENT_NODE */);
  45030. }
  45031. get childElementCount() {
  45032. return this.childNodes.filter((n) => n.nodeType === 1 /* ELEMENT_NODE */).length;
  45033. }
  45034. get className() {
  45035. return this.getAttributeNS(null, "class") || "";
  45036. }
  45037. set className(value) {
  45038. this.setAttributeNS(null, "class", value);
  45039. }
  45040. get classList() {
  45041. return new MockClassList(this);
  45042. }
  45043. click() {
  45044. dispatchEvent(this, new MockEvent("click", { bubbles: true, cancelable: true, composed: true }));
  45045. }
  45046. cloneNode(_deep) {
  45047. return null;
  45048. }
  45049. closest(selector) {
  45050. let elm = this;
  45051. while (elm != null) {
  45052. if (elm.matches(selector)) {
  45053. return elm;
  45054. }
  45055. elm = elm.parentNode;
  45056. }
  45057. return null;
  45058. }
  45059. get dataset() {
  45060. return dataset(this);
  45061. }
  45062. get dir() {
  45063. return this.getAttributeNS(null, "dir") || "";
  45064. }
  45065. set dir(value) {
  45066. this.setAttributeNS(null, "dir", value);
  45067. }
  45068. dispatchEvent(ev) {
  45069. return dispatchEvent(this, ev);
  45070. }
  45071. get firstElementChild() {
  45072. return this.children[0] || null;
  45073. }
  45074. focus(_options) {
  45075. dispatchEvent(
  45076. this,
  45077. new MockFocusEvent("focus", { relatedTarget: null, bubbles: true, cancelable: true, composed: true })
  45078. );
  45079. }
  45080. getAttribute(attrName) {
  45081. if (attrName === "style") {
  45082. if (this.__style != null && this.__style.length > 0) {
  45083. return this.style.cssText;
  45084. }
  45085. return null;
  45086. }
  45087. const attr = this.attributes.getNamedItem(attrName);
  45088. if (attr != null) {
  45089. return attr.value;
  45090. }
  45091. return null;
  45092. }
  45093. getAttributeNS(namespaceURI, attrName) {
  45094. const attr = this.attributes.getNamedItemNS(namespaceURI, attrName);
  45095. if (attr != null) {
  45096. return attr.value;
  45097. }
  45098. return null;
  45099. }
  45100. getAttributeNode(attrName) {
  45101. if (!this.hasAttribute(attrName)) {
  45102. return null;
  45103. }
  45104. return new MockAttr(attrName, this.getAttribute(attrName));
  45105. }
  45106. getBoundingClientRect() {
  45107. return { bottom: 0, height: 0, left: 0, right: 0, top: 0, width: 0, x: 0, y: 0 };
  45108. }
  45109. getRootNode(opts) {
  45110. const isComposed = opts != null && opts.composed === true;
  45111. let node = this;
  45112. while (node.parentNode != null) {
  45113. node = node.parentNode;
  45114. if (isComposed === true && node.parentNode == null && node.host != null) {
  45115. node = node.host;
  45116. }
  45117. }
  45118. return node;
  45119. }
  45120. get draggable() {
  45121. return this.getAttributeNS(null, "draggable") === "true";
  45122. }
  45123. set draggable(value) {
  45124. this.setAttributeNS(null, "draggable", value);
  45125. }
  45126. hasChildNodes() {
  45127. return this.childNodes.length > 0;
  45128. }
  45129. get id() {
  45130. return this.getAttributeNS(null, "id") || "";
  45131. }
  45132. set id(value) {
  45133. this.setAttributeNS(null, "id", value);
  45134. }
  45135. get innerHTML() {
  45136. if (this.childNodes.length === 0) {
  45137. return "";
  45138. }
  45139. return serializeNodeToHtml(this, {
  45140. newLines: false,
  45141. indentSpaces: 0
  45142. });
  45143. }
  45144. set innerHTML(html) {
  45145. var _a2;
  45146. if (NON_ESCAPABLE_CONTENT.has((_a2 = this.nodeName) != null ? _a2 : "") === true) {
  45147. setTextContent(this, html);
  45148. } else {
  45149. for (let i = this.childNodes.length - 1; i >= 0; i--) {
  45150. this.removeChild(this.childNodes[i]);
  45151. }
  45152. if (typeof html === "string") {
  45153. const frag = parseFragmentUtil(this.ownerDocument, html);
  45154. while (frag.childNodes.length > 0) {
  45155. this.appendChild(frag.childNodes[0]);
  45156. }
  45157. }
  45158. }
  45159. }
  45160. get innerText() {
  45161. const text = [];
  45162. getTextContent(this.childNodes, text);
  45163. return text.join("");
  45164. }
  45165. set innerText(value) {
  45166. setTextContent(this, value);
  45167. }
  45168. insertAdjacentElement(position, elm) {
  45169. if (position === "beforebegin" && this.parentNode) {
  45170. insertBefore(this.parentNode, elm, this);
  45171. } else if (position === "afterbegin") {
  45172. this.prepend(elm);
  45173. } else if (position === "beforeend") {
  45174. this.appendChild(elm);
  45175. } else if (position === "afterend" && this.parentNode) {
  45176. insertBefore(this.parentNode, elm, this.nextSibling);
  45177. }
  45178. return elm;
  45179. }
  45180. insertAdjacentHTML(position, html) {
  45181. const frag = parseFragmentUtil(this.ownerDocument, html);
  45182. if (position === "beforebegin") {
  45183. while (frag.childNodes.length > 0) {
  45184. if (this.parentNode) {
  45185. insertBefore(this.parentNode, frag.childNodes[0], this);
  45186. }
  45187. }
  45188. } else if (position === "afterbegin") {
  45189. while (frag.childNodes.length > 0) {
  45190. this.prepend(frag.childNodes[frag.childNodes.length - 1]);
  45191. }
  45192. } else if (position === "beforeend") {
  45193. while (frag.childNodes.length > 0) {
  45194. this.appendChild(frag.childNodes[0]);
  45195. }
  45196. } else if (position === "afterend") {
  45197. while (frag.childNodes.length > 0) {
  45198. if (this.parentNode) {
  45199. insertBefore(this.parentNode, frag.childNodes[frag.childNodes.length - 1], this.nextSibling);
  45200. }
  45201. }
  45202. }
  45203. }
  45204. insertAdjacentText(position, text) {
  45205. const elm = this.ownerDocument.createTextNode(text);
  45206. if (position === "beforebegin" && this.parentNode) {
  45207. insertBefore(this.parentNode, elm, this);
  45208. } else if (position === "afterbegin") {
  45209. this.prepend(elm);
  45210. } else if (position === "beforeend") {
  45211. this.appendChild(elm);
  45212. } else if (position === "afterend" && this.parentNode) {
  45213. insertBefore(this.parentNode, elm, this.nextSibling);
  45214. }
  45215. }
  45216. hasAttribute(attrName) {
  45217. if (attrName === "style") {
  45218. return this.__style != null && this.__style.length > 0;
  45219. }
  45220. return this.getAttribute(attrName) !== null;
  45221. }
  45222. hasAttributeNS(namespaceURI, name) {
  45223. return this.getAttributeNS(namespaceURI, name) !== null;
  45224. }
  45225. get hidden() {
  45226. return this.hasAttributeNS(null, "hidden");
  45227. }
  45228. set hidden(isHidden) {
  45229. if (isHidden === true) {
  45230. this.setAttributeNS(null, "hidden", "");
  45231. } else {
  45232. this.removeAttributeNS(null, "hidden");
  45233. }
  45234. }
  45235. get lang() {
  45236. return this.getAttributeNS(null, "lang") || "";
  45237. }
  45238. set lang(value) {
  45239. this.setAttributeNS(null, "lang", value);
  45240. }
  45241. get lastElementChild() {
  45242. const children = this.children;
  45243. return children[children.length - 1] || null;
  45244. }
  45245. matches(selector) {
  45246. return matches(selector, this);
  45247. }
  45248. get nextElementSibling() {
  45249. const parentElement = this.parentElement;
  45250. if (parentElement != null && (parentElement.nodeType === 1 /* ELEMENT_NODE */ || parentElement.nodeType === 11 /* DOCUMENT_FRAGMENT_NODE */ || parentElement.nodeType === 9 /* DOCUMENT_NODE */)) {
  45251. const children = parentElement.children;
  45252. const index = children.indexOf(this) + 1;
  45253. return parentElement.children[index] || null;
  45254. }
  45255. return null;
  45256. }
  45257. get outerHTML() {
  45258. return serializeNodeToHtml(this, {
  45259. newLines: false,
  45260. outerHtml: true,
  45261. indentSpaces: 0
  45262. });
  45263. }
  45264. get previousElementSibling() {
  45265. const parentElement = this.parentElement;
  45266. if (parentElement != null && (parentElement.nodeType === 1 /* ELEMENT_NODE */ || parentElement.nodeType === 11 /* DOCUMENT_FRAGMENT_NODE */ || parentElement.nodeType === 9 /* DOCUMENT_NODE */)) {
  45267. const children = parentElement.children;
  45268. const index = children.indexOf(this) - 1;
  45269. return parentElement.children[index] || null;
  45270. }
  45271. return null;
  45272. }
  45273. getElementsByClassName(classNames) {
  45274. const classes = classNames.trim().split(" ").filter((c) => c.length > 0);
  45275. const results = [];
  45276. getElementsByClassName(this, classes, results);
  45277. return results;
  45278. }
  45279. getElementsByTagName(tagName) {
  45280. const results = [];
  45281. getElementsByTagName(this, tagName.toLowerCase(), results);
  45282. return results;
  45283. }
  45284. querySelector(selector) {
  45285. return selectOne(selector, this);
  45286. }
  45287. querySelectorAll(selector) {
  45288. return selectAll(selector, this);
  45289. }
  45290. removeAttribute(attrName) {
  45291. if (attrName === "style") {
  45292. delete this.__style;
  45293. } else {
  45294. const attr = this.attributes.getNamedItem(attrName);
  45295. if (attr != null) {
  45296. this.attributes.removeNamedItemNS(attr);
  45297. if (checkAttributeChanged(this) === true) {
  45298. attributeChanged(this, attrName, attr.value, null);
  45299. }
  45300. }
  45301. }
  45302. }
  45303. removeAttributeNS(namespaceURI, attrName) {
  45304. const attr = this.attributes.getNamedItemNS(namespaceURI, attrName);
  45305. if (attr != null) {
  45306. this.attributes.removeNamedItemNS(attr);
  45307. if (checkAttributeChanged(this) === true) {
  45308. attributeChanged(this, attrName, attr.value, null);
  45309. }
  45310. }
  45311. }
  45312. removeEventListener(type, handler) {
  45313. removeEventListener(this, type, handler);
  45314. }
  45315. setAttribute(attrName, value) {
  45316. if (attrName === "style") {
  45317. this.style = value;
  45318. } else {
  45319. const attributes = this.attributes;
  45320. let attr = attributes.getNamedItem(attrName);
  45321. const checkAttrChanged = checkAttributeChanged(this);
  45322. if (attr != null) {
  45323. if (checkAttrChanged === true) {
  45324. const oldValue = attr.value;
  45325. attr.value = value;
  45326. if (oldValue !== attr.value) {
  45327. attributeChanged(this, attr.name, oldValue, attr.value);
  45328. }
  45329. } else {
  45330. attr.value = value;
  45331. }
  45332. } else {
  45333. if (attributes.caseInsensitive) {
  45334. attrName = attrName.toLowerCase();
  45335. }
  45336. attr = new MockAttr(attrName, value);
  45337. attributes.__items.push(attr);
  45338. if (checkAttrChanged === true) {
  45339. attributeChanged(this, attrName, null, attr.value);
  45340. }
  45341. }
  45342. }
  45343. }
  45344. setAttributeNS(namespaceURI, attrName, value) {
  45345. const attributes = this.attributes;
  45346. let attr = attributes.getNamedItemNS(namespaceURI, attrName);
  45347. const checkAttrChanged = checkAttributeChanged(this);
  45348. if (attr != null) {
  45349. if (checkAttrChanged === true) {
  45350. const oldValue = attr.value;
  45351. attr.value = value;
  45352. if (oldValue !== attr.value) {
  45353. attributeChanged(this, attr.name, oldValue, attr.value);
  45354. }
  45355. } else {
  45356. attr.value = value;
  45357. }
  45358. } else {
  45359. attr = new MockAttr(attrName, value, namespaceURI);
  45360. attributes.__items.push(attr);
  45361. if (checkAttrChanged === true) {
  45362. attributeChanged(this, attrName, null, attr.value);
  45363. }
  45364. }
  45365. }
  45366. get style() {
  45367. if (this.__style == null) {
  45368. this.__style = createCSSStyleDeclaration();
  45369. }
  45370. return this.__style;
  45371. }
  45372. set style(val) {
  45373. if (typeof val === "string") {
  45374. if (this.__style == null) {
  45375. this.__style = createCSSStyleDeclaration();
  45376. }
  45377. this.__style.cssText = val;
  45378. } else {
  45379. this.__style = val;
  45380. }
  45381. }
  45382. get tabIndex() {
  45383. return parseInt(this.getAttributeNS(null, "tabindex") || "-1", 10);
  45384. }
  45385. set tabIndex(value) {
  45386. this.setAttributeNS(null, "tabindex", value);
  45387. }
  45388. get tagName() {
  45389. var _a2;
  45390. return (_a2 = this.nodeName) != null ? _a2 : "";
  45391. }
  45392. set tagName(value) {
  45393. this.nodeName = value;
  45394. }
  45395. get textContent() {
  45396. const text = [];
  45397. getTextContent(this.childNodes, text);
  45398. return text.join("");
  45399. }
  45400. set textContent(value) {
  45401. setTextContent(this, value);
  45402. }
  45403. get title() {
  45404. return this.getAttributeNS(null, "title") || "";
  45405. }
  45406. set title(value) {
  45407. this.setAttributeNS(null, "title", value);
  45408. }
  45409. animate() {
  45410. }
  45411. onanimationstart() {
  45412. }
  45413. onanimationend() {
  45414. }
  45415. onanimationiteration() {
  45416. }
  45417. onabort() {
  45418. }
  45419. onauxclick() {
  45420. }
  45421. onbeforecopy() {
  45422. }
  45423. onbeforecut() {
  45424. }
  45425. onbeforepaste() {
  45426. }
  45427. onblur() {
  45428. }
  45429. oncancel() {
  45430. }
  45431. oncanplay() {
  45432. }
  45433. oncanplaythrough() {
  45434. }
  45435. onchange() {
  45436. }
  45437. onclick() {
  45438. }
  45439. onclose() {
  45440. }
  45441. oncontextmenu() {
  45442. }
  45443. oncopy() {
  45444. }
  45445. oncuechange() {
  45446. }
  45447. oncut() {
  45448. }
  45449. ondblclick() {
  45450. }
  45451. ondrag() {
  45452. }
  45453. ondragend() {
  45454. }
  45455. ondragenter() {
  45456. }
  45457. ondragleave() {
  45458. }
  45459. ondragover() {
  45460. }
  45461. ondragstart() {
  45462. }
  45463. ondrop() {
  45464. }
  45465. ondurationchange() {
  45466. }
  45467. onemptied() {
  45468. }
  45469. onended() {
  45470. }
  45471. onerror() {
  45472. }
  45473. onfocus() {
  45474. }
  45475. onfocusin() {
  45476. }
  45477. onfocusout() {
  45478. }
  45479. onformdata() {
  45480. }
  45481. onfullscreenchange() {
  45482. }
  45483. onfullscreenerror() {
  45484. }
  45485. ongotpointercapture() {
  45486. }
  45487. oninput() {
  45488. }
  45489. oninvalid() {
  45490. }
  45491. onkeydown() {
  45492. }
  45493. onkeypress() {
  45494. }
  45495. onkeyup() {
  45496. }
  45497. onload() {
  45498. }
  45499. onloadeddata() {
  45500. }
  45501. onloadedmetadata() {
  45502. }
  45503. onloadstart() {
  45504. }
  45505. onlostpointercapture() {
  45506. }
  45507. onmousedown() {
  45508. }
  45509. onmouseenter() {
  45510. }
  45511. onmouseleave() {
  45512. }
  45513. onmousemove() {
  45514. }
  45515. onmouseout() {
  45516. }
  45517. onmouseover() {
  45518. }
  45519. onmouseup() {
  45520. }
  45521. onmousewheel() {
  45522. }
  45523. onpaste() {
  45524. }
  45525. onpause() {
  45526. }
  45527. onplay() {
  45528. }
  45529. onplaying() {
  45530. }
  45531. onpointercancel() {
  45532. }
  45533. onpointerdown() {
  45534. }
  45535. onpointerenter() {
  45536. }
  45537. onpointerleave() {
  45538. }
  45539. onpointermove() {
  45540. }
  45541. onpointerout() {
  45542. }
  45543. onpointerover() {
  45544. }
  45545. onpointerup() {
  45546. }
  45547. onprogress() {
  45548. }
  45549. onratechange() {
  45550. }
  45551. onreset() {
  45552. }
  45553. onresize() {
  45554. }
  45555. onscroll() {
  45556. }
  45557. onsearch() {
  45558. }
  45559. onseeked() {
  45560. }
  45561. onseeking() {
  45562. }
  45563. onselect() {
  45564. }
  45565. onselectstart() {
  45566. }
  45567. onstalled() {
  45568. }
  45569. onsubmit() {
  45570. }
  45571. onsuspend() {
  45572. }
  45573. ontimeupdate() {
  45574. }
  45575. ontoggle() {
  45576. }
  45577. onvolumechange() {
  45578. }
  45579. onwaiting() {
  45580. }
  45581. onwebkitfullscreenchange() {
  45582. }
  45583. onwebkitfullscreenerror() {
  45584. }
  45585. onwheel() {
  45586. }
  45587. requestFullscreen() {
  45588. }
  45589. scrollBy() {
  45590. }
  45591. scrollTo() {
  45592. }
  45593. scrollIntoView() {
  45594. }
  45595. toString(opts) {
  45596. return serializeNodeToHtml(this, opts);
  45597. }
  45598. };
  45599. function getElementsByClassName(elm, classNames, foundElms) {
  45600. const children = elm.children;
  45601. for (let i = 0, ii = children.length; i < ii; i++) {
  45602. const childElm = children[i];
  45603. for (let j = 0, jj = classNames.length; j < jj; j++) {
  45604. if (childElm.classList.contains(classNames[j])) {
  45605. foundElms.push(childElm);
  45606. }
  45607. }
  45608. getElementsByClassName(childElm, classNames, foundElms);
  45609. }
  45610. }
  45611. function getElementsByTagName(elm, tagName, foundElms) {
  45612. var _a2;
  45613. const children = elm.children;
  45614. for (let i = 0, ii = children.length; i < ii; i++) {
  45615. const childElm = children[i];
  45616. if (tagName === "*" || ((_a2 = childElm.nodeName) != null ? _a2 : "").toLowerCase() === tagName) {
  45617. foundElms.push(childElm);
  45618. }
  45619. getElementsByTagName(childElm, tagName, foundElms);
  45620. }
  45621. }
  45622. function resetElement(elm) {
  45623. resetEventListeners(elm);
  45624. delete elm.__attributeMap;
  45625. delete elm.__shadowRoot;
  45626. delete elm.__style;
  45627. }
  45628. function insertBefore(parentNode, newNode, referenceNode) {
  45629. if (newNode !== referenceNode) {
  45630. newNode.remove();
  45631. newNode.parentNode = parentNode;
  45632. newNode.ownerDocument = parentNode.ownerDocument;
  45633. if (referenceNode != null) {
  45634. const index = parentNode.childNodes.indexOf(referenceNode);
  45635. if (index > -1) {
  45636. parentNode.childNodes.splice(index, 0, newNode);
  45637. } else {
  45638. throw new Error(`referenceNode not found in parentNode.childNodes`);
  45639. }
  45640. } else {
  45641. parentNode.childNodes.push(newNode);
  45642. }
  45643. connectNode(parentNode.ownerDocument, newNode);
  45644. }
  45645. return newNode;
  45646. }
  45647. var MockHTMLElement = class extends MockElement {
  45648. constructor(ownerDocument, nodeName) {
  45649. super(ownerDocument, typeof nodeName === "string" ? nodeName.toUpperCase() : null);
  45650. this.__namespaceURI = "http://www.w3.org/1999/xhtml";
  45651. }
  45652. get tagName() {
  45653. var _a2;
  45654. return (_a2 = this.nodeName) != null ? _a2 : "";
  45655. }
  45656. set tagName(value) {
  45657. this.nodeName = value;
  45658. }
  45659. /**
  45660. * A node’s parent of type Element is known as its parent element.
  45661. * If the node has a parent of a different type, its parent element
  45662. * is null.
  45663. * @returns MockElement
  45664. */
  45665. get parentElement() {
  45666. if (this.nodeName === "HTML") {
  45667. return null;
  45668. }
  45669. return super.parentElement;
  45670. }
  45671. get attributes() {
  45672. if (this.__attributeMap == null) {
  45673. const attrMap = createAttributeProxy(true);
  45674. this.__attributeMap = attrMap;
  45675. return attrMap;
  45676. }
  45677. return this.__attributeMap;
  45678. }
  45679. set attributes(attrs) {
  45680. this.__attributeMap = attrs;
  45681. }
  45682. };
  45683. var MockTextNode = class _MockTextNode extends MockNode2 {
  45684. constructor(ownerDocument, text) {
  45685. super(ownerDocument, 3 /* TEXT_NODE */, "#text" /* TEXT_NODE */, text);
  45686. }
  45687. cloneNode(_deep) {
  45688. return new _MockTextNode(null, this.nodeValue);
  45689. }
  45690. get textContent() {
  45691. return this.nodeValue;
  45692. }
  45693. set textContent(text) {
  45694. this.nodeValue = text;
  45695. }
  45696. get data() {
  45697. return this.nodeValue;
  45698. }
  45699. set data(text) {
  45700. this.nodeValue = text;
  45701. }
  45702. get wholeText() {
  45703. if (this.parentNode != null) {
  45704. const text = [];
  45705. for (let i = 0, ii = this.parentNode.childNodes.length; i < ii; i++) {
  45706. const childNode = this.parentNode.childNodes[i];
  45707. if (childNode.nodeType === 3 /* TEXT_NODE */) {
  45708. text.push(childNode.nodeValue);
  45709. }
  45710. }
  45711. return text.join("");
  45712. }
  45713. return this.nodeValue;
  45714. }
  45715. };
  45716. function getTextContent(childNodes, text) {
  45717. for (let i = 0, ii = childNodes.length; i < ii; i++) {
  45718. const childNode = childNodes[i];
  45719. if (childNode.nodeType === 3 /* TEXT_NODE */) {
  45720. text.push(childNode.nodeValue);
  45721. } else if (childNode.nodeType === 1 /* ELEMENT_NODE */) {
  45722. getTextContent(childNode.childNodes, text);
  45723. }
  45724. }
  45725. }
  45726. function setTextContent(elm, text) {
  45727. for (let i = elm.childNodes.length - 1; i >= 0; i--) {
  45728. elm.removeChild(elm.childNodes[i]);
  45729. }
  45730. const textNode = new MockTextNode(elm.ownerDocument, text);
  45731. elm.appendChild(textNode);
  45732. }
  45733. // src/mock-doc/comment-node.ts
  45734. var MockComment = class _MockComment extends MockNode2 {
  45735. constructor(ownerDocument, data) {
  45736. super(ownerDocument, 8 /* COMMENT_NODE */, "#comment" /* COMMENT_NODE */, data);
  45737. }
  45738. cloneNode(_deep) {
  45739. return new _MockComment(null, this.nodeValue);
  45740. }
  45741. get textContent() {
  45742. return this.nodeValue;
  45743. }
  45744. set textContent(text) {
  45745. this.nodeValue = text;
  45746. }
  45747. };
  45748. // src/mock-doc/document-fragment.ts
  45749. var MockDocumentFragment = class _MockDocumentFragment extends MockHTMLElement {
  45750. constructor(ownerDocument) {
  45751. super(ownerDocument, null);
  45752. this.nodeName = "#document-fragment" /* DOCUMENT_FRAGMENT_NODE */;
  45753. this.nodeType = 11 /* DOCUMENT_FRAGMENT_NODE */;
  45754. }
  45755. getElementById(id) {
  45756. return getElementById(this, id);
  45757. }
  45758. cloneNode(deep) {
  45759. const cloned = new _MockDocumentFragment(null);
  45760. if (deep) {
  45761. for (let i = 0, ii = this.childNodes.length; i < ii; i++) {
  45762. const childNode = this.childNodes[i];
  45763. if (childNode.nodeType === 1 /* ELEMENT_NODE */ || childNode.nodeType === 3 /* TEXT_NODE */ || childNode.nodeType === 8 /* COMMENT_NODE */) {
  45764. const clonedChildNode = this.childNodes[i].cloneNode(true);
  45765. cloned.appendChild(clonedChildNode);
  45766. }
  45767. }
  45768. }
  45769. return cloned;
  45770. }
  45771. };
  45772. // src/mock-doc/document-type-node.ts
  45773. var MockDocumentTypeNode = class extends MockHTMLElement {
  45774. constructor(ownerDocument) {
  45775. super(ownerDocument, "!DOCTYPE");
  45776. this.nodeType = 10 /* DOCUMENT_TYPE_NODE */;
  45777. this.setAttribute("html", "");
  45778. }
  45779. };
  45780. // src/mock-doc/css-style-sheet.ts
  45781. var MockCSSRule = class {
  45782. constructor(parentStyleSheet) {
  45783. this.parentStyleSheet = parentStyleSheet;
  45784. this.cssText = "";
  45785. this.type = 0;
  45786. }
  45787. };
  45788. var MockCSSStyleSheet = class {
  45789. constructor(ownerNode) {
  45790. this.type = "text/css";
  45791. this.parentStyleSheet = null;
  45792. this.cssRules = [];
  45793. this.ownerNode = ownerNode;
  45794. }
  45795. get rules() {
  45796. return this.cssRules;
  45797. }
  45798. set rules(rules) {
  45799. this.cssRules = rules;
  45800. }
  45801. deleteRule(index) {
  45802. if (index >= 0 && index < this.cssRules.length) {
  45803. this.cssRules.splice(index, 1);
  45804. updateStyleTextNode(this.ownerNode);
  45805. }
  45806. }
  45807. insertRule(rule, index = 0) {
  45808. if (typeof index !== "number") {
  45809. index = 0;
  45810. }
  45811. if (index < 0) {
  45812. index = 0;
  45813. }
  45814. if (index > this.cssRules.length) {
  45815. index = this.cssRules.length;
  45816. }
  45817. const cssRule = new MockCSSRule(this);
  45818. cssRule.cssText = rule;
  45819. this.cssRules.splice(index, 0, cssRule);
  45820. updateStyleTextNode(this.ownerNode);
  45821. return index;
  45822. }
  45823. };
  45824. function getStyleElementText(styleElm) {
  45825. const output = [];
  45826. for (let i = 0; i < styleElm.childNodes.length; i++) {
  45827. output.push(styleElm.childNodes[i].nodeValue);
  45828. }
  45829. return output.join("");
  45830. }
  45831. function setStyleElementText(styleElm, text) {
  45832. const sheet = styleElm.sheet;
  45833. sheet.cssRules.length = 0;
  45834. sheet.insertRule(text);
  45835. updateStyleTextNode(styleElm);
  45836. }
  45837. function updateStyleTextNode(styleElm) {
  45838. const childNodeLen = styleElm.childNodes.length;
  45839. if (childNodeLen > 1) {
  45840. for (let i = childNodeLen - 1; i >= 1; i--) {
  45841. styleElm.removeChild(styleElm.childNodes[i]);
  45842. }
  45843. } else if (childNodeLen < 1) {
  45844. styleElm.appendChild(styleElm.ownerDocument.createTextNode(""));
  45845. }
  45846. const textNode = styleElm.childNodes[0];
  45847. textNode.nodeValue = styleElm.sheet.cssRules.map((r) => r.cssText).join("\n");
  45848. }
  45849. // src/mock-doc/element.ts
  45850. function createElement(ownerDocument, tagName) {
  45851. if (typeof tagName !== "string" || tagName === "" || !/^[a-z0-9-_:]+$/i.test(tagName)) {
  45852. throw new Error(`The tag name provided (${tagName}) is not a valid name.`);
  45853. }
  45854. tagName = tagName.toLowerCase();
  45855. switch (tagName) {
  45856. case "a":
  45857. return new MockAnchorElement(ownerDocument);
  45858. case "base":
  45859. return new MockBaseElement(ownerDocument);
  45860. case "button":
  45861. return new MockButtonElement(ownerDocument);
  45862. case "canvas":
  45863. return new MockCanvasElement(ownerDocument);
  45864. case "form":
  45865. return new MockFormElement(ownerDocument);
  45866. case "img":
  45867. return new MockImageElement(ownerDocument);
  45868. case "input":
  45869. return new MockInputElement(ownerDocument);
  45870. case "link":
  45871. return new MockLinkElement(ownerDocument);
  45872. case "meta":
  45873. return new MockMetaElement(ownerDocument);
  45874. case "script":
  45875. return new MockScriptElement(ownerDocument);
  45876. case "style":
  45877. return new MockStyleElement(ownerDocument);
  45878. case "template":
  45879. return new MockTemplateElement(ownerDocument);
  45880. case "title":
  45881. return new MockTitleElement(ownerDocument);
  45882. case "ul":
  45883. return new MockUListElement(ownerDocument);
  45884. }
  45885. if (ownerDocument != null && tagName.includes("-")) {
  45886. const win = ownerDocument.defaultView;
  45887. if (win != null && win.customElements != null) {
  45888. return createCustomElement(win.customElements, ownerDocument, tagName);
  45889. }
  45890. }
  45891. return new MockHTMLElement(ownerDocument, tagName);
  45892. }
  45893. function createElementNS(ownerDocument, namespaceURI, tagName) {
  45894. if (namespaceURI === "http://www.w3.org/1999/xhtml") {
  45895. return createElement(ownerDocument, tagName);
  45896. } else if (namespaceURI === "http://www.w3.org/2000/svg") {
  45897. switch (tagName.toLowerCase()) {
  45898. case "text":
  45899. case "tspan":
  45900. case "tref":
  45901. case "altglyph":
  45902. case "textpath":
  45903. return new MockSVGTextContentElement(ownerDocument, tagName);
  45904. case "circle":
  45905. case "ellipse":
  45906. case "image":
  45907. case "line":
  45908. case "path":
  45909. case "polygon":
  45910. case "polyline":
  45911. case "rect":
  45912. case "use":
  45913. return new MockSVGGraphicsElement(ownerDocument, tagName);
  45914. case "svg":
  45915. return new MockSVGSVGElement(ownerDocument, tagName);
  45916. default:
  45917. return new MockSVGElement(ownerDocument, tagName);
  45918. }
  45919. } else {
  45920. return new MockElement(ownerDocument, tagName, namespaceURI);
  45921. }
  45922. }
  45923. var MockAnchorElement = class extends MockHTMLElement {
  45924. constructor(ownerDocument) {
  45925. super(ownerDocument, "a");
  45926. }
  45927. get href() {
  45928. return fullUrl(this, "href");
  45929. }
  45930. set href(value) {
  45931. this.setAttribute("href", value);
  45932. }
  45933. get pathname() {
  45934. return new URL(this.href).pathname;
  45935. }
  45936. };
  45937. var MockButtonElement = class extends MockHTMLElement {
  45938. constructor(ownerDocument) {
  45939. super(ownerDocument, "button");
  45940. }
  45941. };
  45942. patchPropAttributes(
  45943. MockButtonElement.prototype,
  45944. {
  45945. type: String
  45946. },
  45947. {
  45948. type: "submit"
  45949. }
  45950. );
  45951. var MockImageElement = class extends MockHTMLElement {
  45952. constructor(ownerDocument) {
  45953. super(ownerDocument, "img");
  45954. }
  45955. get draggable() {
  45956. return this.getAttributeNS(null, "draggable") !== "false";
  45957. }
  45958. set draggable(value) {
  45959. this.setAttributeNS(null, "draggable", value);
  45960. }
  45961. get src() {
  45962. return fullUrl(this, "src");
  45963. }
  45964. set src(value) {
  45965. this.setAttribute("src", value);
  45966. }
  45967. };
  45968. patchPropAttributes(MockImageElement.prototype, {
  45969. height: Number,
  45970. width: Number
  45971. });
  45972. var MockInputElement = class extends MockHTMLElement {
  45973. constructor(ownerDocument) {
  45974. super(ownerDocument, "input");
  45975. }
  45976. get list() {
  45977. const listId = this.getAttribute("list");
  45978. if (listId) {
  45979. return this.ownerDocument.getElementById(listId);
  45980. }
  45981. return null;
  45982. }
  45983. };
  45984. patchPropAttributes(
  45985. MockInputElement.prototype,
  45986. {
  45987. accept: String,
  45988. autocomplete: String,
  45989. autofocus: Boolean,
  45990. capture: String,
  45991. checked: Boolean,
  45992. disabled: Boolean,
  45993. form: String,
  45994. formaction: String,
  45995. formenctype: String,
  45996. formmethod: String,
  45997. formnovalidate: String,
  45998. formtarget: String,
  45999. height: Number,
  46000. inputmode: String,
  46001. max: String,
  46002. maxLength: Number,
  46003. min: String,
  46004. minLength: Number,
  46005. multiple: Boolean,
  46006. name: String,
  46007. pattern: String,
  46008. placeholder: String,
  46009. required: Boolean,
  46010. readOnly: Boolean,
  46011. size: Number,
  46012. spellCheck: Boolean,
  46013. src: String,
  46014. step: String,
  46015. type: String,
  46016. value: String,
  46017. width: Number
  46018. },
  46019. {
  46020. type: "text"
  46021. }
  46022. );
  46023. var MockFormElement = class extends MockHTMLElement {
  46024. constructor(ownerDocument) {
  46025. super(ownerDocument, "form");
  46026. }
  46027. };
  46028. patchPropAttributes(MockFormElement.prototype, {
  46029. name: String
  46030. });
  46031. var MockLinkElement = class extends MockHTMLElement {
  46032. constructor(ownerDocument) {
  46033. super(ownerDocument, "link");
  46034. }
  46035. get href() {
  46036. return fullUrl(this, "href");
  46037. }
  46038. set href(value) {
  46039. this.setAttribute("href", value);
  46040. }
  46041. };
  46042. patchPropAttributes(MockLinkElement.prototype, {
  46043. crossorigin: String,
  46044. media: String,
  46045. rel: String,
  46046. type: String
  46047. });
  46048. var MockMetaElement = class extends MockHTMLElement {
  46049. constructor(ownerDocument) {
  46050. super(ownerDocument, "meta");
  46051. }
  46052. };
  46053. patchPropAttributes(MockMetaElement.prototype, {
  46054. charset: String,
  46055. content: String,
  46056. name: String
  46057. });
  46058. var MockScriptElement = class extends MockHTMLElement {
  46059. constructor(ownerDocument) {
  46060. super(ownerDocument, "script");
  46061. }
  46062. get src() {
  46063. return fullUrl(this, "src");
  46064. }
  46065. set src(value) {
  46066. this.setAttribute("src", value);
  46067. }
  46068. };
  46069. patchPropAttributes(MockScriptElement.prototype, {
  46070. type: String
  46071. });
  46072. var MockDOMMatrix = class _MockDOMMatrix {
  46073. constructor() {
  46074. this.a = 1;
  46075. this.b = 0;
  46076. this.c = 0;
  46077. this.d = 1;
  46078. this.e = 0;
  46079. this.f = 0;
  46080. this.m11 = 1;
  46081. this.m12 = 0;
  46082. this.m13 = 0;
  46083. this.m14 = 0;
  46084. this.m21 = 0;
  46085. this.m22 = 1;
  46086. this.m23 = 0;
  46087. this.m24 = 0;
  46088. this.m31 = 0;
  46089. this.m32 = 0;
  46090. this.m33 = 1;
  46091. this.m34 = 0;
  46092. this.m41 = 0;
  46093. this.m42 = 0;
  46094. this.m43 = 0;
  46095. this.m44 = 1;
  46096. this.is2D = true;
  46097. this.isIdentity = true;
  46098. }
  46099. static fromMatrix() {
  46100. return new _MockDOMMatrix();
  46101. }
  46102. inverse() {
  46103. return new _MockDOMMatrix();
  46104. }
  46105. flipX() {
  46106. return new _MockDOMMatrix();
  46107. }
  46108. flipY() {
  46109. return new _MockDOMMatrix();
  46110. }
  46111. multiply() {
  46112. return new _MockDOMMatrix();
  46113. }
  46114. rotate() {
  46115. return new _MockDOMMatrix();
  46116. }
  46117. rotateAxisAngle() {
  46118. return new _MockDOMMatrix();
  46119. }
  46120. rotateFromVector() {
  46121. return new _MockDOMMatrix();
  46122. }
  46123. scale() {
  46124. return new _MockDOMMatrix();
  46125. }
  46126. scaleNonUniform() {
  46127. return new _MockDOMMatrix();
  46128. }
  46129. skewX() {
  46130. return new _MockDOMMatrix();
  46131. }
  46132. skewY() {
  46133. return new _MockDOMMatrix();
  46134. }
  46135. toJSON() {
  46136. }
  46137. toString() {
  46138. }
  46139. transformPoint() {
  46140. return new MockDOMPoint();
  46141. }
  46142. translate() {
  46143. return new _MockDOMMatrix();
  46144. }
  46145. };
  46146. var MockDOMPoint = class {
  46147. constructor() {
  46148. this.w = 1;
  46149. this.x = 0;
  46150. this.y = 0;
  46151. this.z = 0;
  46152. }
  46153. toJSON() {
  46154. }
  46155. matrixTransform() {
  46156. return new MockDOMMatrix();
  46157. }
  46158. };
  46159. var MockSVGRect = class {
  46160. constructor() {
  46161. this.height = 10;
  46162. this.width = 10;
  46163. this.x = 0;
  46164. this.y = 0;
  46165. }
  46166. };
  46167. var MockStyleElement = class extends MockHTMLElement {
  46168. constructor(ownerDocument) {
  46169. super(ownerDocument, "style");
  46170. this.sheet = new MockCSSStyleSheet(this);
  46171. }
  46172. get innerHTML() {
  46173. return getStyleElementText(this);
  46174. }
  46175. set innerHTML(value) {
  46176. setStyleElementText(this, value);
  46177. }
  46178. get innerText() {
  46179. return getStyleElementText(this);
  46180. }
  46181. set innerText(value) {
  46182. setStyleElementText(this, value);
  46183. }
  46184. get textContent() {
  46185. return getStyleElementText(this);
  46186. }
  46187. set textContent(value) {
  46188. setStyleElementText(this, value);
  46189. }
  46190. };
  46191. var MockSVGElement = class extends MockElement {
  46192. constructor() {
  46193. super(...arguments);
  46194. this.__namespaceURI = "http://www.w3.org/2000/svg";
  46195. }
  46196. // SVGElement properties and methods
  46197. get ownerSVGElement() {
  46198. return null;
  46199. }
  46200. get viewportElement() {
  46201. return null;
  46202. }
  46203. onunload() {
  46204. }
  46205. // SVGGeometryElement properties and methods
  46206. get pathLength() {
  46207. return 0;
  46208. }
  46209. isPointInFill(_pt) {
  46210. return false;
  46211. }
  46212. isPointInStroke(_pt) {
  46213. return false;
  46214. }
  46215. getTotalLength() {
  46216. return 0;
  46217. }
  46218. };
  46219. var MockSVGGraphicsElement = class extends MockSVGElement {
  46220. getBBox(_options) {
  46221. return new MockSVGRect();
  46222. }
  46223. getCTM() {
  46224. return new MockDOMMatrix();
  46225. }
  46226. getScreenCTM() {
  46227. return new MockDOMMatrix();
  46228. }
  46229. };
  46230. var MockSVGSVGElement = class extends MockSVGGraphicsElement {
  46231. createSVGPoint() {
  46232. return new MockDOMPoint();
  46233. }
  46234. };
  46235. var MockSVGTextContentElement = class extends MockSVGGraphicsElement {
  46236. getComputedTextLength() {
  46237. return 0;
  46238. }
  46239. };
  46240. var MockBaseElement = class extends MockHTMLElement {
  46241. constructor(ownerDocument) {
  46242. super(ownerDocument, "base");
  46243. }
  46244. get href() {
  46245. return fullUrl(this, "href");
  46246. }
  46247. set href(value) {
  46248. this.setAttribute("href", value);
  46249. }
  46250. };
  46251. var MockTemplateElement = class _MockTemplateElement extends MockHTMLElement {
  46252. constructor(ownerDocument) {
  46253. super(ownerDocument, "template");
  46254. this.content = new MockDocumentFragment(ownerDocument);
  46255. }
  46256. get innerHTML() {
  46257. return this.content.innerHTML;
  46258. }
  46259. set innerHTML(html) {
  46260. this.content.innerHTML = html;
  46261. }
  46262. cloneNode(deep) {
  46263. const cloned = new _MockTemplateElement(null);
  46264. cloned.attributes = cloneAttributes(this.attributes);
  46265. const styleCssText = this.getAttribute("style");
  46266. if (styleCssText != null && styleCssText.length > 0) {
  46267. cloned.setAttribute("style", styleCssText);
  46268. }
  46269. cloned.content = this.content.cloneNode(deep);
  46270. if (deep) {
  46271. for (let i = 0, ii = this.childNodes.length; i < ii; i++) {
  46272. const clonedChildNode = this.childNodes[i].cloneNode(true);
  46273. cloned.appendChild(clonedChildNode);
  46274. }
  46275. }
  46276. return cloned;
  46277. }
  46278. };
  46279. var MockTitleElement = class extends MockHTMLElement {
  46280. constructor(ownerDocument) {
  46281. super(ownerDocument, "title");
  46282. }
  46283. get text() {
  46284. return this.textContent;
  46285. }
  46286. set text(value) {
  46287. this.textContent = value;
  46288. }
  46289. };
  46290. var MockUListElement = class extends MockHTMLElement {
  46291. constructor(ownerDocument) {
  46292. super(ownerDocument, "ul");
  46293. }
  46294. };
  46295. var CanvasRenderingContext = class {
  46296. constructor(context, contextAttributes) {
  46297. this.context = context;
  46298. this.contextAttributes = contextAttributes;
  46299. }
  46300. fillRect() {
  46301. return;
  46302. }
  46303. clearRect() {
  46304. }
  46305. getImageData(_, __, w, h) {
  46306. return {
  46307. data: new Array(w * h * 4)
  46308. };
  46309. }
  46310. toDataURL() {
  46311. return "data:,";
  46312. }
  46313. putImageData() {
  46314. }
  46315. createImageData() {
  46316. return {};
  46317. }
  46318. setTransform() {
  46319. }
  46320. drawImage() {
  46321. }
  46322. save() {
  46323. }
  46324. fillText() {
  46325. }
  46326. restore() {
  46327. }
  46328. beginPath() {
  46329. }
  46330. moveTo() {
  46331. }
  46332. lineTo() {
  46333. }
  46334. closePath() {
  46335. }
  46336. stroke() {
  46337. }
  46338. translate() {
  46339. }
  46340. scale() {
  46341. }
  46342. rotate() {
  46343. }
  46344. arc() {
  46345. }
  46346. fill() {
  46347. }
  46348. measureText() {
  46349. return { width: 0 };
  46350. }
  46351. transform() {
  46352. }
  46353. rect() {
  46354. }
  46355. clip() {
  46356. }
  46357. };
  46358. var MockCanvasElement = class extends MockHTMLElement {
  46359. constructor(ownerDocument) {
  46360. super(ownerDocument, "canvas");
  46361. }
  46362. getContext(context, contextAttributes) {
  46363. return new CanvasRenderingContext(context, contextAttributes);
  46364. }
  46365. };
  46366. function fullUrl(elm, attrName) {
  46367. const val = elm.getAttribute(attrName) || "";
  46368. if (elm.ownerDocument != null) {
  46369. const win = elm.ownerDocument.defaultView;
  46370. if (win != null) {
  46371. const loc = win.location;
  46372. if (loc != null) {
  46373. try {
  46374. const url = new URL(val, loc.href);
  46375. return url.href;
  46376. } catch (e) {
  46377. }
  46378. }
  46379. }
  46380. }
  46381. return val.replace(/\'|\"/g, "").trim();
  46382. }
  46383. function patchPropAttributes(prototype, attrs, defaults = {}) {
  46384. Object.keys(attrs).forEach((propName) => {
  46385. const attr = attrs[propName];
  46386. const defaultValue = defaults[propName];
  46387. if (attr === Boolean) {
  46388. Object.defineProperty(prototype, propName, {
  46389. get() {
  46390. return this.hasAttribute(propName);
  46391. },
  46392. set(value) {
  46393. if (value) {
  46394. this.setAttribute(propName, "");
  46395. } else {
  46396. this.removeAttribute(propName);
  46397. }
  46398. }
  46399. });
  46400. } else if (attr === Number) {
  46401. Object.defineProperty(prototype, propName, {
  46402. get() {
  46403. const value = this.getAttribute(propName);
  46404. return value ? parseInt(value, 10) : defaultValue === void 0 ? 0 : defaultValue;
  46405. },
  46406. set(value) {
  46407. this.setAttribute(propName, value);
  46408. }
  46409. });
  46410. } else {
  46411. Object.defineProperty(prototype, propName, {
  46412. get() {
  46413. return this.hasAttribute(propName) ? this.getAttribute(propName) : defaultValue || "";
  46414. },
  46415. set(value) {
  46416. this.setAttribute(propName, value);
  46417. }
  46418. });
  46419. }
  46420. });
  46421. }
  46422. MockElement.prototype.cloneNode = function(deep) {
  46423. const cloned = createElement(this.ownerDocument, this.nodeName);
  46424. cloned.attributes = cloneAttributes(this.attributes);
  46425. const styleCssText = this.getAttribute("style");
  46426. if (styleCssText != null && styleCssText.length > 0) {
  46427. cloned.setAttribute("style", styleCssText);
  46428. }
  46429. if (deep) {
  46430. for (let i = 0, ii = this.childNodes.length; i < ii; i++) {
  46431. const clonedChildNode = this.childNodes[i].cloneNode(true);
  46432. cloned.appendChild(clonedChildNode);
  46433. }
  46434. }
  46435. return cloned;
  46436. };
  46437. // src/mock-doc/parse-html.ts
  46438. var sharedDocument;
  46439. function parseHtmlToDocument(html, ownerDocument = null) {
  46440. if (ownerDocument == null) {
  46441. if (sharedDocument == null) {
  46442. sharedDocument = new MockDocument();
  46443. }
  46444. ownerDocument = sharedDocument;
  46445. }
  46446. return parseDocumentUtil(ownerDocument, html);
  46447. }
  46448. // src/mock-doc/console.ts
  46449. var consoleNoop = () => {
  46450. };
  46451. function createConsole() {
  46452. return {
  46453. debug: consoleNoop,
  46454. error: consoleNoop,
  46455. info: consoleNoop,
  46456. log: consoleNoop,
  46457. warn: consoleNoop,
  46458. dir: consoleNoop,
  46459. dirxml: consoleNoop,
  46460. table: consoleNoop,
  46461. trace: consoleNoop,
  46462. group: consoleNoop,
  46463. groupCollapsed: consoleNoop,
  46464. groupEnd: consoleNoop,
  46465. clear: consoleNoop,
  46466. count: consoleNoop,
  46467. countReset: consoleNoop,
  46468. assert: consoleNoop,
  46469. profile: consoleNoop,
  46470. profileEnd: consoleNoop,
  46471. time: consoleNoop,
  46472. timeLog: consoleNoop,
  46473. timeEnd: consoleNoop,
  46474. timeStamp: consoleNoop,
  46475. context: consoleNoop,
  46476. memory: consoleNoop
  46477. };
  46478. }
  46479. // src/mock-doc/headers.ts
  46480. var MockHeaders = class {
  46481. constructor(init) {
  46482. this._values = [];
  46483. if (typeof init === "object") {
  46484. if (typeof init[Symbol.iterator] === "function") {
  46485. const kvs = [];
  46486. for (const kv of init) {
  46487. if (typeof kv[Symbol.iterator] === "function") {
  46488. kvs.push([...kv]);
  46489. }
  46490. }
  46491. for (const kv of kvs) {
  46492. this.append(kv[0], kv[1]);
  46493. }
  46494. } else {
  46495. for (const key in init) {
  46496. this.append(key, init[key]);
  46497. }
  46498. }
  46499. }
  46500. }
  46501. append(key, value) {
  46502. this._values.push([key, value + ""]);
  46503. }
  46504. delete(key) {
  46505. key = key.toLowerCase();
  46506. for (let i = this._values.length - 1; i >= 0; i--) {
  46507. if (this._values[i][0].toLowerCase() === key) {
  46508. this._values.splice(i, 1);
  46509. }
  46510. }
  46511. }
  46512. entries() {
  46513. const entries = [];
  46514. for (const kv of this.keys()) {
  46515. entries.push([kv, this.get(kv)]);
  46516. }
  46517. let index = -1;
  46518. return {
  46519. next() {
  46520. index++;
  46521. return {
  46522. value: entries[index],
  46523. done: !entries[index]
  46524. };
  46525. },
  46526. [Symbol.iterator]() {
  46527. return this;
  46528. }
  46529. };
  46530. }
  46531. forEach(cb) {
  46532. for (const kv of this.entries()) {
  46533. cb(kv[1], kv[0]);
  46534. }
  46535. }
  46536. get(key) {
  46537. const rtn = [];
  46538. key = key.toLowerCase();
  46539. for (const kv of this._values) {
  46540. if (kv[0].toLowerCase() === key) {
  46541. rtn.push(kv[1]);
  46542. }
  46543. }
  46544. return rtn.length > 0 ? rtn.join(", ") : null;
  46545. }
  46546. has(key) {
  46547. key = key.toLowerCase();
  46548. for (const kv of this._values) {
  46549. if (kv[0].toLowerCase() === key) {
  46550. return true;
  46551. }
  46552. }
  46553. return false;
  46554. }
  46555. keys() {
  46556. const keys = [];
  46557. for (const kv of this._values) {
  46558. const key = kv[0].toLowerCase();
  46559. if (!keys.includes(key)) {
  46560. keys.push(key);
  46561. }
  46562. }
  46563. let index = -1;
  46564. return {
  46565. next() {
  46566. index++;
  46567. return {
  46568. value: keys[index],
  46569. done: !keys[index]
  46570. };
  46571. },
  46572. [Symbol.iterator]() {
  46573. return this;
  46574. }
  46575. };
  46576. }
  46577. set(key, value) {
  46578. for (const kv of this._values) {
  46579. if (kv[0].toLowerCase() === key.toLowerCase()) {
  46580. kv[1] = value + "";
  46581. return;
  46582. }
  46583. }
  46584. this.append(key, value);
  46585. }
  46586. values() {
  46587. const values = this._values;
  46588. let index = -1;
  46589. return {
  46590. next() {
  46591. index++;
  46592. const done = !values[index];
  46593. return {
  46594. value: done ? void 0 : values[index][1],
  46595. done
  46596. };
  46597. },
  46598. [Symbol.iterator]() {
  46599. return this;
  46600. }
  46601. };
  46602. }
  46603. [Symbol.iterator]() {
  46604. return this.entries();
  46605. }
  46606. };
  46607. // src/mock-doc/parser.ts
  46608. var MockDOMParser = class {
  46609. parseFromString(htmlToParse, mimeType) {
  46610. if (mimeType !== "text/html") {
  46611. console.error("XML parsing not implemented yet, continuing as html");
  46612. }
  46613. return parseHtmlToDocument(htmlToParse);
  46614. }
  46615. };
  46616. // src/mock-doc/request-response.ts
  46617. var MockRequest = class _MockRequest {
  46618. constructor(input, init = {}) {
  46619. this._method = "GET";
  46620. this._url = "/";
  46621. this.bodyUsed = false;
  46622. this.cache = "default";
  46623. this.credentials = "same-origin";
  46624. this.integrity = "";
  46625. this.keepalive = false;
  46626. this.mode = "cors";
  46627. this.redirect = "follow";
  46628. this.referrer = "about:client";
  46629. this.referrerPolicy = "";
  46630. if (typeof input === "string") {
  46631. this.url = input;
  46632. } else if (input) {
  46633. Object.assign(this, input);
  46634. this.headers = new MockHeaders(input.headers);
  46635. }
  46636. Object.assign(this, init);
  46637. if (init.headers) {
  46638. this.headers = new MockHeaders(init.headers);
  46639. }
  46640. if (!this.headers) {
  46641. this.headers = new MockHeaders();
  46642. }
  46643. }
  46644. get url() {
  46645. if (typeof this._url === "string") {
  46646. return new URL(this._url, location.href).href;
  46647. }
  46648. return new URL("/", location.href).href;
  46649. }
  46650. set url(value) {
  46651. this._url = value;
  46652. }
  46653. get method() {
  46654. if (typeof this._method === "string") {
  46655. return this._method.toUpperCase();
  46656. }
  46657. return "GET";
  46658. }
  46659. set method(value) {
  46660. this._method = value;
  46661. }
  46662. clone() {
  46663. const clone = { ...this };
  46664. clone.headers = new MockHeaders(this.headers);
  46665. return new _MockRequest(clone);
  46666. }
  46667. };
  46668. var MockResponse = class _MockResponse {
  46669. constructor(body, init = {}) {
  46670. this.ok = true;
  46671. this.status = 200;
  46672. this.statusText = "";
  46673. this.type = "default";
  46674. this.url = "";
  46675. this._body = body;
  46676. if (init) {
  46677. Object.assign(this, init);
  46678. }
  46679. this.headers = new MockHeaders(init.headers);
  46680. }
  46681. async json() {
  46682. return JSON.parse(this._body);
  46683. }
  46684. async text() {
  46685. return this._body;
  46686. }
  46687. clone() {
  46688. const initClone = { ...this };
  46689. initClone.headers = new MockHeaders(this.headers);
  46690. return new _MockResponse(this._body, initClone);
  46691. }
  46692. };
  46693. // src/mock-doc/global.ts
  46694. function patchWindow(winToBePatched) {
  46695. const mockWin = new MockWindow(false);
  46696. WINDOW_FUNCTIONS.forEach((fnName) => {
  46697. if (typeof winToBePatched[fnName] !== "function") {
  46698. winToBePatched[fnName] = mockWin[fnName].bind(mockWin);
  46699. }
  46700. });
  46701. WINDOW_PROPS.forEach((propName) => {
  46702. if (winToBePatched === void 0) {
  46703. Object.defineProperty(winToBePatched, propName, {
  46704. get() {
  46705. return mockWin[propName];
  46706. },
  46707. set(val) {
  46708. mockWin[propName] = val;
  46709. },
  46710. configurable: true,
  46711. enumerable: true
  46712. });
  46713. }
  46714. });
  46715. }
  46716. function addGlobalsToWindowPrototype(mockWinPrototype) {
  46717. GLOBAL_CONSTRUCTORS.forEach(([cstrName, Cstr]) => {
  46718. Object.defineProperty(mockWinPrototype, cstrName, {
  46719. get() {
  46720. return this["__" + cstrName] || Cstr;
  46721. },
  46722. set(cstr) {
  46723. this["__" + cstrName] = cstr;
  46724. },
  46725. configurable: true,
  46726. enumerable: true
  46727. });
  46728. });
  46729. }
  46730. var WINDOW_FUNCTIONS = [
  46731. "addEventListener",
  46732. "alert",
  46733. "blur",
  46734. "cancelAnimationFrame",
  46735. "cancelIdleCallback",
  46736. "clearInterval",
  46737. "clearTimeout",
  46738. "close",
  46739. "confirm",
  46740. "dispatchEvent",
  46741. "focus",
  46742. "getComputedStyle",
  46743. "matchMedia",
  46744. "open",
  46745. "prompt",
  46746. "removeEventListener",
  46747. "requestAnimationFrame",
  46748. "requestIdleCallback",
  46749. "URL"
  46750. ];
  46751. var WINDOW_PROPS = [
  46752. "customElements",
  46753. "devicePixelRatio",
  46754. "document",
  46755. "history",
  46756. "innerHeight",
  46757. "innerWidth",
  46758. "localStorage",
  46759. "location",
  46760. "navigator",
  46761. "pageXOffset",
  46762. "pageYOffset",
  46763. "performance",
  46764. "screenLeft",
  46765. "screenTop",
  46766. "screenX",
  46767. "screenY",
  46768. "scrollX",
  46769. "scrollY",
  46770. "sessionStorage",
  46771. "CSS",
  46772. "CustomEvent",
  46773. "Event",
  46774. "Element",
  46775. "HTMLElement",
  46776. "Node",
  46777. "NodeList",
  46778. "FocusEvent",
  46779. "KeyboardEvent",
  46780. "MouseEvent"
  46781. ];
  46782. var GLOBAL_CONSTRUCTORS = [
  46783. ["CustomEvent", MockCustomEvent],
  46784. ["DocumentFragment", MockDocumentFragment],
  46785. ["DOMParser", MockDOMParser],
  46786. ["Event", MockEvent],
  46787. ["FocusEvent", MockFocusEvent],
  46788. ["Headers", MockHeaders],
  46789. ["KeyboardEvent", MockKeyboardEvent],
  46790. ["MouseEvent", MockMouseEvent],
  46791. ["Request", MockRequest],
  46792. ["Response", MockResponse],
  46793. ["ShadowRoot", MockDocumentFragment],
  46794. ["HTMLAnchorElement", MockAnchorElement],
  46795. ["HTMLBaseElement", MockBaseElement],
  46796. ["HTMLButtonElement", MockButtonElement],
  46797. ["HTMLCanvasElement", MockCanvasElement],
  46798. ["HTMLFormElement", MockFormElement],
  46799. ["HTMLImageElement", MockImageElement],
  46800. ["HTMLInputElement", MockInputElement],
  46801. ["HTMLLinkElement", MockLinkElement],
  46802. ["HTMLMetaElement", MockMetaElement],
  46803. ["HTMLScriptElement", MockScriptElement],
  46804. ["HTMLStyleElement", MockStyleElement],
  46805. ["HTMLTemplateElement", MockTemplateElement],
  46806. ["HTMLTitleElement", MockTitleElement],
  46807. ["HTMLUListElement", MockUListElement]
  46808. ];
  46809. // src/mock-doc/history.ts
  46810. var MockHistory = class {
  46811. constructor() {
  46812. this.items = [];
  46813. }
  46814. get length() {
  46815. return this.items.length;
  46816. }
  46817. back() {
  46818. this.go(-1);
  46819. }
  46820. forward() {
  46821. this.go(1);
  46822. }
  46823. go(_value) {
  46824. }
  46825. pushState(_state, _title, _url) {
  46826. }
  46827. replaceState(_state, _title, _url) {
  46828. }
  46829. };
  46830. // src/mock-doc/intersection-observer.ts
  46831. var MockIntersectionObserver = class {
  46832. constructor() {
  46833. }
  46834. disconnect() {
  46835. }
  46836. observe() {
  46837. }
  46838. takeRecords() {
  46839. return [];
  46840. }
  46841. unobserve() {
  46842. }
  46843. };
  46844. // src/mock-doc/location.ts
  46845. var MockLocation = class {
  46846. constructor() {
  46847. this.ancestorOrigins = null;
  46848. this.protocol = "";
  46849. this.host = "";
  46850. this.hostname = "";
  46851. this.port = "";
  46852. this.pathname = "";
  46853. this.search = "";
  46854. this.hash = "";
  46855. this.username = "";
  46856. this.password = "";
  46857. this.origin = "";
  46858. this._href = "";
  46859. }
  46860. get href() {
  46861. return this._href;
  46862. }
  46863. set href(value) {
  46864. const url = new URL(value, "http://mockdoc.stenciljs.com");
  46865. this._href = url.href;
  46866. this.protocol = url.protocol;
  46867. this.host = url.host;
  46868. this.hostname = url.hostname;
  46869. this.port = url.port;
  46870. this.pathname = url.pathname;
  46871. this.search = url.search;
  46872. this.hash = url.hash;
  46873. this.username = url.username;
  46874. this.password = url.password;
  46875. this.origin = url.origin;
  46876. }
  46877. assign(_url) {
  46878. }
  46879. reload(_forcedReload) {
  46880. }
  46881. replace(_url) {
  46882. }
  46883. toString() {
  46884. return this.href;
  46885. }
  46886. };
  46887. // src/mock-doc/navigator.ts
  46888. var MockNavigator = class {
  46889. constructor() {
  46890. this.appCodeName = "MockNavigator";
  46891. this.appName = "MockNavigator";
  46892. this.appVersion = "MockNavigator";
  46893. this.platform = "MockNavigator";
  46894. this.userAgent = "MockNavigator";
  46895. }
  46896. };
  46897. // src/mock-doc/performance.ts
  46898. var MockPerformance = class {
  46899. constructor() {
  46900. this.timeOrigin = Date.now();
  46901. this.eventCounts = /* @__PURE__ */ new Map();
  46902. }
  46903. addEventListener() {
  46904. }
  46905. clearMarks() {
  46906. }
  46907. clearMeasures() {
  46908. }
  46909. clearResourceTimings() {
  46910. }
  46911. dispatchEvent() {
  46912. return true;
  46913. }
  46914. getEntries() {
  46915. return [];
  46916. }
  46917. getEntriesByName() {
  46918. return [];
  46919. }
  46920. getEntriesByType() {
  46921. return [];
  46922. }
  46923. // Stencil's implementation of `mark` is non-compliant with the `Performance` interface. Because Stencil will
  46924. // instantiate an instance of this class and may attempt to assign it to a variable of type `Performance`, the return
  46925. // type must match the `Performance` interface (rather than typing this function as returning `void` and ignoring the
  46926. // associated errors returned by the type checker)
  46927. // @ts-ignore
  46928. mark() {
  46929. }
  46930. // Stencil's implementation of `measure` is non-compliant with the `Performance` interface. Because Stencil will
  46931. // instantiate an instance of this class and may attempt to assign it to a variable of type `Performance`, the return
  46932. // type must match the `Performance` interface (rather than typing this function as returning `void` and ignoring the
  46933. // associated errors returned by the type checker)
  46934. // @ts-ignore
  46935. measure() {
  46936. }
  46937. get navigation() {
  46938. return {};
  46939. }
  46940. now() {
  46941. return Date.now() - this.timeOrigin;
  46942. }
  46943. get onresourcetimingbufferfull() {
  46944. return null;
  46945. }
  46946. removeEventListener() {
  46947. }
  46948. setResourceTimingBufferSize() {
  46949. }
  46950. get timing() {
  46951. return {};
  46952. }
  46953. toJSON() {
  46954. }
  46955. };
  46956. function resetPerformance(perf) {
  46957. if (perf != null) {
  46958. try {
  46959. perf.timeOrigin = Date.now();
  46960. } catch (e) {
  46961. }
  46962. }
  46963. }
  46964. // src/mock-doc/storage.ts
  46965. var MockStorage = class {
  46966. constructor() {
  46967. this.items = /* @__PURE__ */ new Map();
  46968. }
  46969. key(_value) {
  46970. }
  46971. getItem(key) {
  46972. key = String(key);
  46973. if (this.items.has(key)) {
  46974. return this.items.get(key);
  46975. }
  46976. return null;
  46977. }
  46978. setItem(key, value) {
  46979. if (value == null) {
  46980. value = "null";
  46981. }
  46982. this.items.set(String(key), String(value));
  46983. }
  46984. removeItem(key) {
  46985. this.items.delete(String(key));
  46986. }
  46987. clear() {
  46988. this.items.clear();
  46989. }
  46990. };
  46991. // src/mock-doc/window.ts
  46992. var nativeClearInterval = clearInterval;
  46993. var nativeClearTimeout = clearTimeout;
  46994. var nativeSetInterval = setInterval;
  46995. var nativeSetTimeout = setTimeout;
  46996. var nativeURL = URL;
  46997. var nativeWindow = globalThis.window;
  46998. var MockWindow = class {
  46999. constructor(html = null) {
  47000. if (html !== false) {
  47001. this.document = new MockDocument(html, this);
  47002. } else {
  47003. this.document = null;
  47004. }
  47005. this.performance = new MockPerformance();
  47006. this.customElements = new MockCustomElementRegistry(this);
  47007. this.console = createConsole();
  47008. resetWindowDefaults(this);
  47009. resetWindowDimensions(this);
  47010. }
  47011. addEventListener(type, handler) {
  47012. addEventListener(this, type, handler);
  47013. }
  47014. alert(msg) {
  47015. if (this.console) {
  47016. this.console.debug(msg);
  47017. } else {
  47018. console.debug(msg);
  47019. }
  47020. }
  47021. blur() {
  47022. }
  47023. cancelAnimationFrame(id) {
  47024. this.__clearTimeout.call(nativeWindow || this, id);
  47025. }
  47026. cancelIdleCallback(id) {
  47027. this.__clearTimeout.call(nativeWindow || this, id);
  47028. }
  47029. get CharacterData() {
  47030. if (this.__charDataCstr == null) {
  47031. const ownerDocument = this.document;
  47032. this.__charDataCstr = class extends MockNode2 {
  47033. constructor() {
  47034. super(ownerDocument, 0, "test", "");
  47035. throw new Error("Illegal constructor: cannot construct CharacterData");
  47036. }
  47037. };
  47038. }
  47039. return this.__charDataCstr;
  47040. }
  47041. set CharacterData(charDataCstr) {
  47042. this.__charDataCstr = charDataCstr;
  47043. }
  47044. clearInterval(id) {
  47045. this.__clearInterval.call(nativeWindow || this, id);
  47046. }
  47047. clearTimeout(id) {
  47048. this.__clearTimeout.call(nativeWindow || this, id);
  47049. }
  47050. close() {
  47051. resetWindow(this);
  47052. }
  47053. confirm() {
  47054. return false;
  47055. }
  47056. get CSS() {
  47057. return {
  47058. supports: () => true
  47059. };
  47060. }
  47061. get Document() {
  47062. if (this.__docCstr == null) {
  47063. const win = this;
  47064. this.__docCstr = class extends MockDocument {
  47065. constructor() {
  47066. super(false, win);
  47067. throw new Error("Illegal constructor: cannot construct Document");
  47068. }
  47069. };
  47070. }
  47071. return this.__docCstr;
  47072. }
  47073. set Document(docCstr) {
  47074. this.__docCstr = docCstr;
  47075. }
  47076. get DocumentFragment() {
  47077. if (this.__docFragCstr == null) {
  47078. const ownerDocument = this.document;
  47079. this.__docFragCstr = class extends MockDocumentFragment {
  47080. constructor() {
  47081. super(ownerDocument);
  47082. throw new Error("Illegal constructor: cannot construct DocumentFragment");
  47083. }
  47084. };
  47085. }
  47086. return this.__docFragCstr;
  47087. }
  47088. set DocumentFragment(docFragCstr) {
  47089. this.__docFragCstr = docFragCstr;
  47090. }
  47091. get DocumentType() {
  47092. if (this.__docTypeCstr == null) {
  47093. const ownerDocument = this.document;
  47094. this.__docTypeCstr = class extends MockNode2 {
  47095. constructor() {
  47096. super(ownerDocument, 0, "test", "");
  47097. throw new Error("Illegal constructor: cannot construct DocumentType");
  47098. }
  47099. };
  47100. }
  47101. return this.__docTypeCstr;
  47102. }
  47103. set DocumentType(docTypeCstr) {
  47104. this.__docTypeCstr = docTypeCstr;
  47105. }
  47106. get DOMTokenList() {
  47107. if (this.__domTokenListCstr == null) {
  47108. this.__domTokenListCstr = class MockDOMTokenList {
  47109. };
  47110. }
  47111. return this.__domTokenListCstr;
  47112. }
  47113. set DOMTokenList(domTokenListCstr) {
  47114. this.__domTokenListCstr = domTokenListCstr;
  47115. }
  47116. dispatchEvent(ev) {
  47117. return dispatchEvent(this, ev);
  47118. }
  47119. get Element() {
  47120. if (this.__elementCstr == null) {
  47121. const ownerDocument = this.document;
  47122. this.__elementCstr = class extends MockElement {
  47123. constructor() {
  47124. super(ownerDocument, "");
  47125. throw new Error("Illegal constructor: cannot construct Element");
  47126. }
  47127. };
  47128. }
  47129. return this.__elementCstr;
  47130. }
  47131. fetch(input, init) {
  47132. if (typeof fetch === "function") {
  47133. return fetch(input, init);
  47134. }
  47135. throw new Error(`fetch() not implemented`);
  47136. }
  47137. focus() {
  47138. }
  47139. getComputedStyle(_) {
  47140. return {
  47141. cssText: "",
  47142. length: 0,
  47143. parentRule: null,
  47144. getPropertyPriority() {
  47145. return null;
  47146. },
  47147. getPropertyValue() {
  47148. return "";
  47149. },
  47150. item() {
  47151. return null;
  47152. },
  47153. removeProperty() {
  47154. return null;
  47155. },
  47156. setProperty() {
  47157. return null;
  47158. }
  47159. };
  47160. }
  47161. get globalThis() {
  47162. return this;
  47163. }
  47164. get history() {
  47165. if (this.__history == null) {
  47166. this.__history = new MockHistory();
  47167. }
  47168. return this.__history;
  47169. }
  47170. set history(hsty) {
  47171. this.__history = hsty;
  47172. }
  47173. get JSON() {
  47174. return JSON;
  47175. }
  47176. get HTMLElement() {
  47177. if (this.__htmlElementCstr == null) {
  47178. const ownerDocument = this.document;
  47179. this.__htmlElementCstr = class extends MockHTMLElement {
  47180. constructor() {
  47181. super(ownerDocument, "");
  47182. const observedAttributes = this.constructor.observedAttributes;
  47183. if (Array.isArray(observedAttributes) && typeof this.attributeChangedCallback === "function") {
  47184. observedAttributes.forEach((attrName) => {
  47185. const attrValue = this.getAttribute(attrName);
  47186. if (attrValue != null) {
  47187. this.attributeChangedCallback(attrName, null, attrValue);
  47188. }
  47189. });
  47190. }
  47191. }
  47192. };
  47193. }
  47194. return this.__htmlElementCstr;
  47195. }
  47196. set HTMLElement(htmlElementCstr) {
  47197. this.__htmlElementCstr = htmlElementCstr;
  47198. }
  47199. get IntersectionObserver() {
  47200. return MockIntersectionObserver;
  47201. }
  47202. get localStorage() {
  47203. if (this.__localStorage == null) {
  47204. this.__localStorage = new MockStorage();
  47205. }
  47206. return this.__localStorage;
  47207. }
  47208. set localStorage(locStorage) {
  47209. this.__localStorage = locStorage;
  47210. }
  47211. get location() {
  47212. if (this.__location == null) {
  47213. this.__location = new MockLocation();
  47214. }
  47215. return this.__location;
  47216. }
  47217. set location(val) {
  47218. if (typeof val === "string") {
  47219. if (this.__location == null) {
  47220. this.__location = new MockLocation();
  47221. }
  47222. this.__location.href = val;
  47223. } else {
  47224. this.__location = val;
  47225. }
  47226. }
  47227. matchMedia(media) {
  47228. return {
  47229. media,
  47230. matches: false,
  47231. addListener: (_handler) => {
  47232. },
  47233. removeListener: (_handler) => {
  47234. },
  47235. addEventListener: (_type, _handler) => {
  47236. },
  47237. removeEventListener: (_type, _handler) => {
  47238. },
  47239. dispatchEvent: (_ev) => {
  47240. },
  47241. onchange: null
  47242. };
  47243. }
  47244. get Node() {
  47245. if (this.__nodeCstr == null) {
  47246. const ownerDocument = this.document;
  47247. this.__nodeCstr = class extends MockNode2 {
  47248. constructor() {
  47249. super(ownerDocument, 0, "test", "");
  47250. throw new Error("Illegal constructor: cannot construct Node");
  47251. }
  47252. };
  47253. }
  47254. return this.__nodeCstr;
  47255. }
  47256. get NodeList() {
  47257. if (this.__nodeListCstr == null) {
  47258. const ownerDocument = this.document;
  47259. this.__nodeListCstr = class extends MockNodeList {
  47260. constructor() {
  47261. super(ownerDocument, [], 0);
  47262. throw new Error("Illegal constructor: cannot construct NodeList");
  47263. }
  47264. };
  47265. }
  47266. return this.__nodeListCstr;
  47267. }
  47268. get navigator() {
  47269. if (this.__navigator == null) {
  47270. this.__navigator = new MockNavigator();
  47271. }
  47272. return this.__navigator;
  47273. }
  47274. set navigator(nav) {
  47275. this.__navigator = nav;
  47276. }
  47277. get parent() {
  47278. return null;
  47279. }
  47280. prompt() {
  47281. return "";
  47282. }
  47283. open() {
  47284. return null;
  47285. }
  47286. get origin() {
  47287. return this.location.origin;
  47288. }
  47289. removeEventListener(type, handler) {
  47290. removeEventListener(this, type, handler);
  47291. }
  47292. requestAnimationFrame(callback) {
  47293. return this.setTimeout(() => {
  47294. callback(Date.now());
  47295. }, 0);
  47296. }
  47297. requestIdleCallback(callback) {
  47298. return this.setTimeout(() => {
  47299. callback({
  47300. didTimeout: false,
  47301. timeRemaining: () => 0
  47302. });
  47303. }, 0);
  47304. }
  47305. scroll(_x, _y) {
  47306. }
  47307. scrollBy(_x, _y) {
  47308. }
  47309. scrollTo(_x, _y) {
  47310. }
  47311. get self() {
  47312. return this;
  47313. }
  47314. get sessionStorage() {
  47315. if (this.__sessionStorage == null) {
  47316. this.__sessionStorage = new MockStorage();
  47317. }
  47318. return this.__sessionStorage;
  47319. }
  47320. set sessionStorage(locStorage) {
  47321. this.__sessionStorage = locStorage;
  47322. }
  47323. setInterval(callback, ms, ...args) {
  47324. if (this.__timeouts == null) {
  47325. this.__timeouts = /* @__PURE__ */ new Set();
  47326. }
  47327. ms = Math.min(ms, this.__maxTimeout);
  47328. if (this.__allowInterval) {
  47329. const intervalId = this.__setInterval(() => {
  47330. if (this.__timeouts) {
  47331. this.__timeouts.delete(intervalId);
  47332. try {
  47333. callback(...args);
  47334. } catch (e) {
  47335. if (this.console) {
  47336. this.console.error(e);
  47337. } else {
  47338. console.error(e);
  47339. }
  47340. }
  47341. }
  47342. }, ms);
  47343. if (this.__timeouts) {
  47344. this.__timeouts.add(intervalId);
  47345. }
  47346. return intervalId;
  47347. }
  47348. const timeoutId = this.__setTimeout.call(
  47349. nativeWindow || this,
  47350. () => {
  47351. if (this.__timeouts) {
  47352. this.__timeouts.delete(timeoutId);
  47353. try {
  47354. callback(...args);
  47355. } catch (e) {
  47356. if (this.console) {
  47357. this.console.error(e);
  47358. } else {
  47359. console.error(e);
  47360. }
  47361. }
  47362. }
  47363. },
  47364. ms
  47365. );
  47366. if (this.__timeouts) {
  47367. this.__timeouts.add(timeoutId);
  47368. }
  47369. return timeoutId;
  47370. }
  47371. setTimeout(callback, ms, ...args) {
  47372. if (this.__timeouts == null) {
  47373. this.__timeouts = /* @__PURE__ */ new Set();
  47374. }
  47375. ms = Math.min(ms, this.__maxTimeout);
  47376. const timeoutId = this.__setTimeout.call(
  47377. nativeWindow || this,
  47378. () => {
  47379. if (this.__timeouts) {
  47380. this.__timeouts.delete(timeoutId);
  47381. try {
  47382. callback(...args);
  47383. } catch (e) {
  47384. if (this.console) {
  47385. this.console.error(e);
  47386. } else {
  47387. console.error(e);
  47388. }
  47389. }
  47390. }
  47391. },
  47392. ms
  47393. );
  47394. if (this.__timeouts) {
  47395. this.__timeouts.add(timeoutId);
  47396. }
  47397. return timeoutId;
  47398. }
  47399. get top() {
  47400. return this;
  47401. }
  47402. get window() {
  47403. return this;
  47404. }
  47405. onanimationstart() {
  47406. }
  47407. onanimationend() {
  47408. }
  47409. onanimationiteration() {
  47410. }
  47411. onabort() {
  47412. }
  47413. onauxclick() {
  47414. }
  47415. onbeforecopy() {
  47416. }
  47417. onbeforecut() {
  47418. }
  47419. onbeforepaste() {
  47420. }
  47421. onblur() {
  47422. }
  47423. oncancel() {
  47424. }
  47425. oncanplay() {
  47426. }
  47427. oncanplaythrough() {
  47428. }
  47429. onchange() {
  47430. }
  47431. onclick() {
  47432. }
  47433. onclose() {
  47434. }
  47435. oncontextmenu() {
  47436. }
  47437. oncopy() {
  47438. }
  47439. oncuechange() {
  47440. }
  47441. oncut() {
  47442. }
  47443. ondblclick() {
  47444. }
  47445. ondrag() {
  47446. }
  47447. ondragend() {
  47448. }
  47449. ondragenter() {
  47450. }
  47451. ondragleave() {
  47452. }
  47453. ondragover() {
  47454. }
  47455. ondragstart() {
  47456. }
  47457. ondrop() {
  47458. }
  47459. ondurationchange() {
  47460. }
  47461. onemptied() {
  47462. }
  47463. onended() {
  47464. }
  47465. onerror() {
  47466. }
  47467. onfocus() {
  47468. }
  47469. onfocusin() {
  47470. }
  47471. onfocusout() {
  47472. }
  47473. onformdata() {
  47474. }
  47475. onfullscreenchange() {
  47476. }
  47477. onfullscreenerror() {
  47478. }
  47479. ongotpointercapture() {
  47480. }
  47481. oninput() {
  47482. }
  47483. oninvalid() {
  47484. }
  47485. onkeydown() {
  47486. }
  47487. onkeypress() {
  47488. }
  47489. onkeyup() {
  47490. }
  47491. onload() {
  47492. }
  47493. onloadeddata() {
  47494. }
  47495. onloadedmetadata() {
  47496. }
  47497. onloadstart() {
  47498. }
  47499. onlostpointercapture() {
  47500. }
  47501. onmousedown() {
  47502. }
  47503. onmouseenter() {
  47504. }
  47505. onmouseleave() {
  47506. }
  47507. onmousemove() {
  47508. }
  47509. onmouseout() {
  47510. }
  47511. onmouseover() {
  47512. }
  47513. onmouseup() {
  47514. }
  47515. onmousewheel() {
  47516. }
  47517. onpaste() {
  47518. }
  47519. onpause() {
  47520. }
  47521. onplay() {
  47522. }
  47523. onplaying() {
  47524. }
  47525. onpointercancel() {
  47526. }
  47527. onpointerdown() {
  47528. }
  47529. onpointerenter() {
  47530. }
  47531. onpointerleave() {
  47532. }
  47533. onpointermove() {
  47534. }
  47535. onpointerout() {
  47536. }
  47537. onpointerover() {
  47538. }
  47539. onpointerup() {
  47540. }
  47541. onprogress() {
  47542. }
  47543. onratechange() {
  47544. }
  47545. onreset() {
  47546. }
  47547. onresize() {
  47548. }
  47549. onscroll() {
  47550. }
  47551. onsearch() {
  47552. }
  47553. onseeked() {
  47554. }
  47555. onseeking() {
  47556. }
  47557. onselect() {
  47558. }
  47559. onselectstart() {
  47560. }
  47561. onstalled() {
  47562. }
  47563. onsubmit() {
  47564. }
  47565. onsuspend() {
  47566. }
  47567. ontimeupdate() {
  47568. }
  47569. ontoggle() {
  47570. }
  47571. onvolumechange() {
  47572. }
  47573. onwaiting() {
  47574. }
  47575. onwebkitfullscreenchange() {
  47576. }
  47577. onwebkitfullscreenerror() {
  47578. }
  47579. onwheel() {
  47580. }
  47581. };
  47582. addGlobalsToWindowPrototype(MockWindow.prototype);
  47583. function resetWindowDefaults(win) {
  47584. win.__clearInterval = nativeClearInterval;
  47585. win.__clearTimeout = nativeClearTimeout;
  47586. win.__setInterval = nativeSetInterval;
  47587. win.__setTimeout = nativeSetTimeout;
  47588. win.__maxTimeout = 3e4;
  47589. win.__allowInterval = true;
  47590. win.URL = nativeURL;
  47591. }
  47592. function cloneWindow(srcWin, opts = {}) {
  47593. if (srcWin == null) {
  47594. return null;
  47595. }
  47596. const clonedWin = new MockWindow(false);
  47597. if (!opts.customElementProxy) {
  47598. srcWin.customElements = null;
  47599. }
  47600. if (srcWin.document != null) {
  47601. const clonedDoc = new MockDocument(false, clonedWin);
  47602. clonedWin.document = clonedDoc;
  47603. clonedDoc.documentElement = srcWin.document.documentElement.cloneNode(true);
  47604. } else {
  47605. clonedWin.document = new MockDocument(null, clonedWin);
  47606. }
  47607. return clonedWin;
  47608. }
  47609. function constrainTimeouts(win) {
  47610. win.__allowInterval = false;
  47611. win.__maxTimeout = 0;
  47612. }
  47613. function resetWindow(win) {
  47614. if (win != null) {
  47615. if (win.__timeouts) {
  47616. win.__timeouts.forEach((timeoutId) => {
  47617. nativeClearInterval(timeoutId);
  47618. nativeClearTimeout(timeoutId);
  47619. });
  47620. win.__timeouts.clear();
  47621. }
  47622. if (win.customElements && win.customElements.clear) {
  47623. win.customElements.clear();
  47624. }
  47625. resetDocument(win.document);
  47626. resetPerformance(win.performance);
  47627. for (const key in win) {
  47628. if (win.hasOwnProperty(key) && key !== "document" && key !== "performance" && key !== "customElements") {
  47629. delete win[key];
  47630. }
  47631. }
  47632. resetWindowDefaults(win);
  47633. resetWindowDimensions(win);
  47634. resetEventListeners(win);
  47635. if (win.document != null) {
  47636. try {
  47637. win.document.defaultView = win;
  47638. } catch (e) {
  47639. }
  47640. }
  47641. win.fetch = null;
  47642. win.Headers = null;
  47643. win.Request = null;
  47644. win.Response = null;
  47645. win.FetchError = null;
  47646. }
  47647. }
  47648. function resetWindowDimensions(win) {
  47649. try {
  47650. win.devicePixelRatio = 1;
  47651. win.innerHeight = 768;
  47652. win.innerWidth = 1366;
  47653. win.pageXOffset = 0;
  47654. win.pageYOffset = 0;
  47655. win.screenLeft = 0;
  47656. win.screenTop = 0;
  47657. win.screenX = 0;
  47658. win.screenY = 0;
  47659. win.scrollX = 0;
  47660. win.scrollY = 0;
  47661. win.screen = {
  47662. availHeight: win.innerHeight,
  47663. availLeft: 0,
  47664. availTop: 0,
  47665. availWidth: win.innerWidth,
  47666. colorDepth: 24,
  47667. height: win.innerHeight,
  47668. keepAwake: false,
  47669. orientation: {
  47670. angle: 0,
  47671. type: "portrait-primary"
  47672. },
  47673. pixelDepth: 24,
  47674. width: win.innerWidth
  47675. };
  47676. } catch (e) {
  47677. }
  47678. }
  47679. // src/mock-doc/document.ts
  47680. var MockDocument = class _MockDocument extends MockHTMLElement {
  47681. constructor(html = null, win = null) {
  47682. super(null, null);
  47683. this.nodeName = "#document" /* DOCUMENT_NODE */;
  47684. this.nodeType = 9 /* DOCUMENT_NODE */;
  47685. this.defaultView = win;
  47686. this.cookie = "";
  47687. this.referrer = "";
  47688. this.appendChild(this.createDocumentTypeNode());
  47689. if (typeof html === "string") {
  47690. const parsedDoc = parseDocumentUtil(this, html);
  47691. const documentElement = parsedDoc.children.find((elm) => elm.nodeName === "HTML");
  47692. if (documentElement != null) {
  47693. this.appendChild(documentElement);
  47694. setOwnerDocument(documentElement, this);
  47695. }
  47696. } else if (html !== false) {
  47697. const documentElement = new MockHTMLElement(this, "html");
  47698. this.appendChild(documentElement);
  47699. documentElement.appendChild(new MockHTMLElement(this, "head"));
  47700. documentElement.appendChild(new MockHTMLElement(this, "body"));
  47701. }
  47702. }
  47703. get dir() {
  47704. return this.documentElement.dir;
  47705. }
  47706. set dir(value) {
  47707. this.documentElement.dir = value;
  47708. }
  47709. get localName() {
  47710. throw new Error("Unimplemented");
  47711. }
  47712. get location() {
  47713. if (this.defaultView != null) {
  47714. return this.defaultView.location;
  47715. }
  47716. return null;
  47717. }
  47718. set location(val) {
  47719. if (this.defaultView != null) {
  47720. this.defaultView.location = val;
  47721. }
  47722. }
  47723. get baseURI() {
  47724. const baseNode = this.head.childNodes.find((node) => node.nodeName === "BASE");
  47725. if (baseNode) {
  47726. return baseNode.href;
  47727. }
  47728. return this.URL;
  47729. }
  47730. get URL() {
  47731. return this.location.href;
  47732. }
  47733. get styleSheets() {
  47734. return this.querySelectorAll("style");
  47735. }
  47736. get scripts() {
  47737. return this.querySelectorAll("script");
  47738. }
  47739. get forms() {
  47740. return this.querySelectorAll("form");
  47741. }
  47742. get images() {
  47743. return this.querySelectorAll("img");
  47744. }
  47745. get scrollingElement() {
  47746. return this.documentElement;
  47747. }
  47748. get documentElement() {
  47749. for (let i = this.childNodes.length - 1; i >= 0; i--) {
  47750. if (this.childNodes[i].nodeName === "HTML") {
  47751. return this.childNodes[i];
  47752. }
  47753. }
  47754. const documentElement = new MockHTMLElement(this, "html");
  47755. this.appendChild(documentElement);
  47756. return documentElement;
  47757. }
  47758. set documentElement(documentElement) {
  47759. for (let i = this.childNodes.length - 1; i >= 0; i--) {
  47760. if (this.childNodes[i].nodeType !== 10 /* DOCUMENT_TYPE_NODE */) {
  47761. this.childNodes[i].remove();
  47762. }
  47763. }
  47764. if (documentElement != null) {
  47765. this.appendChild(documentElement);
  47766. setOwnerDocument(documentElement, this);
  47767. }
  47768. }
  47769. get head() {
  47770. const documentElement = this.documentElement;
  47771. for (let i = 0; i < documentElement.childNodes.length; i++) {
  47772. if (documentElement.childNodes[i].nodeName === "HEAD") {
  47773. return documentElement.childNodes[i];
  47774. }
  47775. }
  47776. const head = new MockHTMLElement(this, "head");
  47777. documentElement.insertBefore(head, documentElement.firstChild);
  47778. return head;
  47779. }
  47780. set head(head) {
  47781. const documentElement = this.documentElement;
  47782. for (let i = documentElement.childNodes.length - 1; i >= 0; i--) {
  47783. if (documentElement.childNodes[i].nodeName === "HEAD") {
  47784. documentElement.childNodes[i].remove();
  47785. }
  47786. }
  47787. if (head != null) {
  47788. documentElement.insertBefore(head, documentElement.firstChild);
  47789. setOwnerDocument(head, this);
  47790. }
  47791. }
  47792. get body() {
  47793. const documentElement = this.documentElement;
  47794. for (let i = documentElement.childNodes.length - 1; i >= 0; i--) {
  47795. if (documentElement.childNodes[i].nodeName === "BODY") {
  47796. return documentElement.childNodes[i];
  47797. }
  47798. }
  47799. const body = new MockHTMLElement(this, "body");
  47800. documentElement.appendChild(body);
  47801. return body;
  47802. }
  47803. set body(body) {
  47804. const documentElement = this.documentElement;
  47805. for (let i = documentElement.childNodes.length - 1; i >= 0; i--) {
  47806. if (documentElement.childNodes[i].nodeName === "BODY") {
  47807. documentElement.childNodes[i].remove();
  47808. }
  47809. }
  47810. if (body != null) {
  47811. documentElement.appendChild(body);
  47812. setOwnerDocument(body, this);
  47813. }
  47814. }
  47815. appendChild(newNode) {
  47816. newNode.remove();
  47817. newNode.parentNode = this;
  47818. this.childNodes.push(newNode);
  47819. return newNode;
  47820. }
  47821. createComment(data) {
  47822. return new MockComment(this, data);
  47823. }
  47824. createAttribute(attrName) {
  47825. return new MockAttr(attrName.toLowerCase(), "");
  47826. }
  47827. createAttributeNS(namespaceURI, attrName) {
  47828. return new MockAttr(attrName, "", namespaceURI);
  47829. }
  47830. createElement(tagName) {
  47831. if (tagName === "#document" /* DOCUMENT_NODE */) {
  47832. const doc = new _MockDocument(false);
  47833. doc.nodeName = tagName;
  47834. doc.parentNode = null;
  47835. return doc;
  47836. }
  47837. return createElement(this, tagName);
  47838. }
  47839. createElementNS(namespaceURI, tagName) {
  47840. const elmNs = createElementNS(this, namespaceURI, tagName);
  47841. return elmNs;
  47842. }
  47843. createTextNode(text) {
  47844. return new MockTextNode(this, text);
  47845. }
  47846. createDocumentFragment() {
  47847. return new MockDocumentFragment(this);
  47848. }
  47849. createDocumentTypeNode() {
  47850. return new MockDocumentTypeNode(this);
  47851. }
  47852. getElementById(id) {
  47853. return getElementById(this, id);
  47854. }
  47855. getElementsByName(elmName) {
  47856. return getElementsByName(this, elmName.toLowerCase());
  47857. }
  47858. get title() {
  47859. const title = this.head.childNodes.find((elm) => elm.nodeName === "TITLE");
  47860. if (title != null && typeof title.textContent === "string") {
  47861. return title.textContent.trim();
  47862. }
  47863. return "";
  47864. }
  47865. set title(value) {
  47866. const head = this.head;
  47867. let title = head.childNodes.find((elm) => elm.nodeName === "TITLE");
  47868. if (title == null) {
  47869. title = this.createElement("title");
  47870. head.appendChild(title);
  47871. }
  47872. title.textContent = value;
  47873. }
  47874. };
  47875. function resetDocument(doc) {
  47876. if (doc != null) {
  47877. resetEventListeners(doc);
  47878. const documentElement = doc.documentElement;
  47879. if (documentElement != null) {
  47880. resetElement(documentElement);
  47881. for (let i = 0, ii = documentElement.childNodes.length; i < ii; i++) {
  47882. const childNode = documentElement.childNodes[i];
  47883. resetElement(childNode);
  47884. childNode.childNodes.length = 0;
  47885. }
  47886. }
  47887. for (const key in doc) {
  47888. if (doc.hasOwnProperty(key) && !DOC_KEY_KEEPERS.has(key)) {
  47889. delete doc[key];
  47890. }
  47891. }
  47892. try {
  47893. doc.nodeName = "#document" /* DOCUMENT_NODE */;
  47894. } catch (e) {
  47895. }
  47896. try {
  47897. doc.nodeType = 9 /* DOCUMENT_NODE */;
  47898. } catch (e) {
  47899. }
  47900. try {
  47901. doc.cookie = "";
  47902. } catch (e) {
  47903. }
  47904. try {
  47905. doc.referrer = "";
  47906. } catch (e) {
  47907. }
  47908. }
  47909. }
  47910. var DOC_KEY_KEEPERS = /* @__PURE__ */ new Set([
  47911. "nodeName",
  47912. "nodeType",
  47913. "nodeValue",
  47914. "ownerDocument",
  47915. "parentNode",
  47916. "childNodes",
  47917. "_shadowRoot"
  47918. ]);
  47919. function getElementById(elm, id) {
  47920. const children = elm.children;
  47921. for (let i = 0, ii = children.length; i < ii; i++) {
  47922. const childElm = children[i];
  47923. if (childElm.id === id) {
  47924. return childElm;
  47925. }
  47926. const childElmFound = getElementById(childElm, id);
  47927. if (childElmFound != null) {
  47928. return childElmFound;
  47929. }
  47930. }
  47931. return null;
  47932. }
  47933. function getElementsByName(elm, elmName, foundElms = []) {
  47934. const children = elm.children;
  47935. for (let i = 0, ii = children.length; i < ii; i++) {
  47936. const childElm = children[i];
  47937. if (childElm.name && childElm.name.toLowerCase() === elmName) {
  47938. foundElms.push(childElm);
  47939. }
  47940. getElementsByName(childElm, elmName, foundElms);
  47941. }
  47942. return foundElms;
  47943. }
  47944. function setOwnerDocument(elm, ownerDocument) {
  47945. for (let i = 0, ii = elm.childNodes.length; i < ii; i++) {
  47946. elm.childNodes[i].ownerDocument = ownerDocument;
  47947. if (elm.childNodes[i].nodeType === 1 /* ELEMENT_NODE */) {
  47948. setOwnerDocument(elm.childNodes[i], ownerDocument);
  47949. }
  47950. }
  47951. }
  47952. // src/hydrate/runner/create-window.ts
  47953. var templateWindows = /* @__PURE__ */ new Map();
  47954. function createWindowFromHtml(templateHtml, uniqueId) {
  47955. let templateWindow = templateWindows.get(uniqueId);
  47956. if (templateWindow == null) {
  47957. templateWindow = new MockWindow(templateHtml);
  47958. templateWindows.set(uniqueId, templateWindow);
  47959. }
  47960. const win = cloneWindow(templateWindow);
  47961. return win;
  47962. }
  47963. // src/utils/helpers.ts
  47964. var isString = (v) => typeof v === "string";
  47965. // src/utils/message-utils.ts
  47966. var catchError = (diagnostics, err2, msg) => {
  47967. const diagnostic = {
  47968. level: "error",
  47969. type: "build",
  47970. header: "Build Error",
  47971. messageText: "build error",
  47972. lines: []
  47973. };
  47974. if (isString(msg)) {
  47975. diagnostic.messageText = msg.length ? msg : "UNKNOWN ERROR";
  47976. } else if (err2 != null) {
  47977. if (err2.stack != null) {
  47978. diagnostic.messageText = err2.stack.toString();
  47979. } else {
  47980. if (err2.message != null) {
  47981. diagnostic.messageText = err2.message.length ? err2.message : "UNKNOWN ERROR";
  47982. } else {
  47983. diagnostic.messageText = err2.toString();
  47984. }
  47985. }
  47986. }
  47987. if (diagnostics != null && !shouldIgnoreError(diagnostic.messageText)) {
  47988. diagnostics.push(diagnostic);
  47989. }
  47990. return diagnostic;
  47991. };
  47992. var hasError = (diagnostics) => {
  47993. if (diagnostics == null || diagnostics.length === 0) {
  47994. return false;
  47995. }
  47996. return diagnostics.some((d) => d.level === "error" && d.type !== "runtime");
  47997. };
  47998. var shouldIgnoreError = (msg) => {
  47999. return msg === TASK_CANCELED_MSG;
  48000. };
  48001. var TASK_CANCELED_MSG = `task canceled`;
  48002. // src/utils/result.ts
  48003. var result_exports = {};
  48004. __export(result_exports, {
  48005. err: () => err,
  48006. map: () => map,
  48007. ok: () => ok,
  48008. unwrap: () => unwrap,
  48009. unwrapErr: () => unwrapErr
  48010. });
  48011. var ok = (value) => ({
  48012. isOk: true,
  48013. isErr: false,
  48014. value
  48015. });
  48016. var err = (value) => ({
  48017. isOk: false,
  48018. isErr: true,
  48019. value
  48020. });
  48021. function map(result, fn) {
  48022. if (result.isOk) {
  48023. const val = fn(result.value);
  48024. if (val instanceof Promise) {
  48025. return val.then((newVal) => ok(newVal));
  48026. } else {
  48027. return ok(val);
  48028. }
  48029. }
  48030. if (result.isErr) {
  48031. const value = result.value;
  48032. return err(value);
  48033. }
  48034. throw "should never get here";
  48035. }
  48036. var unwrap = (result) => {
  48037. if (result.isOk) {
  48038. return result.value;
  48039. } else {
  48040. throw result.value;
  48041. }
  48042. };
  48043. var unwrapErr = (result) => {
  48044. if (result.isErr) {
  48045. return result.value;
  48046. } else {
  48047. throw result.value;
  48048. }
  48049. };
  48050. // src/compiler/html/canonical-link.ts
  48051. var updateCanonicalLink = (doc, href) => {
  48052. var _a2;
  48053. let canonicalLinkElm = doc.head.querySelector('link[rel="canonical"]');
  48054. if (typeof href === "string") {
  48055. if (canonicalLinkElm == null) {
  48056. canonicalLinkElm = doc.createElement("link");
  48057. canonicalLinkElm.setAttribute("rel", "canonical");
  48058. doc.head.appendChild(canonicalLinkElm);
  48059. }
  48060. canonicalLinkElm.setAttribute("href", href);
  48061. } else {
  48062. if (canonicalLinkElm != null) {
  48063. const existingHref = canonicalLinkElm.getAttribute("href");
  48064. if (!existingHref) {
  48065. (_a2 = canonicalLinkElm.parentNode) == null ? void 0 : _a2.removeChild(canonicalLinkElm);
  48066. }
  48067. }
  48068. }
  48069. };
  48070. // src/compiler/html/relocate-meta-charset.ts
  48071. var relocateMetaCharset = (doc) => {
  48072. const head = doc.head;
  48073. let charsetElm = head.querySelector("meta[charset]");
  48074. if (charsetElm == null) {
  48075. charsetElm = doc.createElement("meta");
  48076. charsetElm.setAttribute("charset", "utf-8");
  48077. } else {
  48078. charsetElm.remove();
  48079. }
  48080. head.insertBefore(charsetElm, head.firstChild);
  48081. };
  48082. // src/compiler/style/css-parser/parse-css.ts
  48083. var parseCss = (css, filePath) => {
  48084. let lineno = 1;
  48085. let column = 1;
  48086. const diagnostics = [];
  48087. const updatePosition = (str) => {
  48088. const lines = str.match(/\n/g);
  48089. if (lines) lineno += lines.length;
  48090. const i = str.lastIndexOf("\n");
  48091. column = ~i ? str.length - i : column + str.length;
  48092. };
  48093. const position = () => {
  48094. const start = { line: lineno, column };
  48095. return (node) => {
  48096. node.position = new ParsePosition(start);
  48097. whitespace();
  48098. return node;
  48099. };
  48100. };
  48101. const error = (msg) => {
  48102. const srcLines = css.split("\n");
  48103. const d = {
  48104. level: "error",
  48105. type: "css",
  48106. language: "css",
  48107. header: "CSS Parse",
  48108. messageText: msg,
  48109. absFilePath: filePath,
  48110. lines: [
  48111. {
  48112. lineIndex: lineno - 1,
  48113. lineNumber: lineno,
  48114. errorCharStart: column,
  48115. text: css[lineno - 1]
  48116. }
  48117. ]
  48118. };
  48119. if (lineno > 1) {
  48120. const previousLine = {
  48121. lineIndex: lineno - 1,
  48122. lineNumber: lineno - 1,
  48123. text: css[lineno - 2],
  48124. errorCharStart: -1,
  48125. errorLength: -1
  48126. };
  48127. d.lines.unshift(previousLine);
  48128. }
  48129. if (lineno + 2 < srcLines.length) {
  48130. const nextLine = {
  48131. lineIndex: lineno,
  48132. lineNumber: lineno + 1,
  48133. text: srcLines[lineno],
  48134. errorCharStart: -1,
  48135. errorLength: -1
  48136. };
  48137. d.lines.push(nextLine);
  48138. }
  48139. diagnostics.push(d);
  48140. return null;
  48141. };
  48142. const stylesheet = () => {
  48143. const rulesList = rules();
  48144. return {
  48145. type: 14 /* StyleSheet */,
  48146. stylesheet: {
  48147. source: filePath,
  48148. rules: rulesList
  48149. }
  48150. };
  48151. };
  48152. const open = () => match(/^{\s*/);
  48153. const close = () => match(/^}/);
  48154. const match = (re) => {
  48155. const m = re.exec(css);
  48156. if (!m) return;
  48157. const str = m[0];
  48158. updatePosition(str);
  48159. css = css.slice(str.length);
  48160. return m;
  48161. };
  48162. const rules = () => {
  48163. let node;
  48164. const rules2 = [];
  48165. whitespace();
  48166. comments(rules2);
  48167. while (css.length && css.charAt(0) !== "}" && (node = atrule() || rule())) {
  48168. rules2.push(node);
  48169. comments(rules2);
  48170. }
  48171. return rules2;
  48172. };
  48173. const whitespace = () => match(/^\s*/);
  48174. const comments = (rules2) => {
  48175. let c;
  48176. rules2 = rules2 || [];
  48177. while (c = comment()) {
  48178. rules2.push(c);
  48179. }
  48180. return rules2;
  48181. };
  48182. const comment = () => {
  48183. const pos = position();
  48184. if ("/" !== css.charAt(0) || "*" !== css.charAt(1)) return null;
  48185. let i = 2;
  48186. while ("" !== css.charAt(i) && ("*" !== css.charAt(i) || "/" !== css.charAt(i + 1))) ++i;
  48187. i += 2;
  48188. if ("" === css.charAt(i - 1)) {
  48189. return error("End of comment missing");
  48190. }
  48191. const comment2 = css.slice(2, i - 2);
  48192. column += 2;
  48193. updatePosition(comment2);
  48194. css = css.slice(i);
  48195. column += 2;
  48196. return pos({
  48197. type: 1 /* Comment */,
  48198. comment: comment2
  48199. });
  48200. };
  48201. const selector = () => {
  48202. const m = match(/^([^{]+)/);
  48203. if (!m) return null;
  48204. return trim(m[0]).replace(/\/\*([^*]|[\r\n]|(\*+([^*/]|[\r\n])))*\*\/+/g, "").replace(/"(?:\\"|[^"])*"|'(?:\\'|[^'])*'/g, function(m2) {
  48205. return m2.replace(/,/g, "\u200C");
  48206. }).split(/\s*(?![^(]*\)),\s*/).map(function(s) {
  48207. return s.replace(/\u200C/g, ",");
  48208. });
  48209. };
  48210. const declaration = () => {
  48211. const pos = position();
  48212. let prop = match(/^(\*?[-#\/\*\\\w]+(\[[0-9a-z_-]+\])?)\s*/);
  48213. if (!prop) return null;
  48214. prop = trim(prop[0]);
  48215. if (!match(/^:\s*/)) return error(`property missing ':'`);
  48216. const val = match(/^((?:'(?:\\'|.)*?'|"(?:\\"|.)*?"|\([^\)]*?\)|[^};])+)/);
  48217. const ret = pos({
  48218. type: 4 /* Declaration */,
  48219. property: prop.replace(commentre, ""),
  48220. value: val ? trim(val[0]).replace(commentre, "") : ""
  48221. });
  48222. match(/^[;\s]*/);
  48223. return ret;
  48224. };
  48225. const declarations = () => {
  48226. const decls = [];
  48227. if (!open()) return error(`missing '{'`);
  48228. comments(decls);
  48229. let decl;
  48230. while (decl = declaration()) {
  48231. decls.push(decl);
  48232. comments(decls);
  48233. }
  48234. if (!close()) return error(`missing '}'`);
  48235. return decls;
  48236. };
  48237. const keyframe = () => {
  48238. let m;
  48239. const values = [];
  48240. const pos = position();
  48241. while (m = match(/^((\d+\.\d+|\.\d+|\d+)%?|[a-z]+)\s*/)) {
  48242. values.push(m[1]);
  48243. match(/^,\s*/);
  48244. }
  48245. if (!values.length) return null;
  48246. return pos({
  48247. type: 9 /* KeyFrame */,
  48248. values,
  48249. declarations: declarations()
  48250. });
  48251. };
  48252. const atkeyframes = () => {
  48253. const pos = position();
  48254. let m = match(/^@([-\w]+)?keyframes\s*/);
  48255. if (!m) return null;
  48256. const vendor = m[1];
  48257. m = match(/^([-\w]+)\s*/);
  48258. if (!m) return error(`@keyframes missing name`);
  48259. const name = m[1];
  48260. if (!open()) return error(`@keyframes missing '{'`);
  48261. let frame;
  48262. let frames = comments();
  48263. while (frame = keyframe()) {
  48264. frames.push(frame);
  48265. frames = frames.concat(comments());
  48266. }
  48267. if (!close()) return error(`@keyframes missing '}'`);
  48268. return pos({
  48269. type: 8 /* KeyFrames */,
  48270. name,
  48271. vendor,
  48272. keyframes: frames
  48273. });
  48274. };
  48275. const atsupports = () => {
  48276. const pos = position();
  48277. const m = match(/^@supports *([^{]+)/);
  48278. if (!m) return null;
  48279. const supports = trim(m[1]);
  48280. if (!open()) return error(`@supports missing '{'`);
  48281. const style = comments().concat(rules());
  48282. if (!close()) return error(`@supports missing '}'`);
  48283. return pos({
  48284. type: 15 /* Supports */,
  48285. supports,
  48286. rules: style
  48287. });
  48288. };
  48289. const athost = () => {
  48290. const pos = position();
  48291. const m = match(/^@host\s*/);
  48292. if (!m) return null;
  48293. if (!open()) return error(`@host missing '{'`);
  48294. const style = comments().concat(rules());
  48295. if (!close()) return error(`@host missing '}'`);
  48296. return pos({
  48297. type: 6 /* Host */,
  48298. rules: style
  48299. });
  48300. };
  48301. const atmedia = () => {
  48302. const pos = position();
  48303. const m = match(/^@media *([^{]+)/);
  48304. if (!m) return null;
  48305. const media = trim(m[1]);
  48306. if (!open()) return error(`@media missing '{'`);
  48307. const style = comments().concat(rules());
  48308. if (!close()) return error(`@media missing '}'`);
  48309. return pos({
  48310. type: 10 /* Media */,
  48311. media,
  48312. rules: style
  48313. });
  48314. };
  48315. const atcustommedia = () => {
  48316. const pos = position();
  48317. const m = match(/^@custom-media\s+(--[^\s]+)\s*([^{;]+);/);
  48318. if (!m) return null;
  48319. return pos({
  48320. type: 2 /* CustomMedia */,
  48321. name: trim(m[1]),
  48322. media: trim(m[2])
  48323. });
  48324. };
  48325. const atpage = () => {
  48326. const pos = position();
  48327. const m = match(/^@page */);
  48328. if (!m) return null;
  48329. const sel = selector() || [];
  48330. if (!open()) return error(`@page missing '{'`);
  48331. let decls = comments();
  48332. let decl;
  48333. while (decl = declaration()) {
  48334. decls.push(decl);
  48335. decls = decls.concat(comments());
  48336. }
  48337. if (!close()) return error(`@page missing '}'`);
  48338. return pos({
  48339. type: 12 /* Page */,
  48340. selectors: sel,
  48341. declarations: decls
  48342. });
  48343. };
  48344. const atdocument = () => {
  48345. const pos = position();
  48346. const m = match(/^@([-\w]+)?document *([^{]+)/);
  48347. if (!m) return null;
  48348. const vendor = trim(m[1]);
  48349. const doc = trim(m[2]);
  48350. if (!open()) return error(`@document missing '{'`);
  48351. const style = comments().concat(rules());
  48352. if (!close()) return error(`@document missing '}'`);
  48353. return pos({
  48354. type: 3 /* Document */,
  48355. document: doc,
  48356. vendor,
  48357. rules: style
  48358. });
  48359. };
  48360. const atfontface = () => {
  48361. const pos = position();
  48362. const m = match(/^@font-face\s*/);
  48363. if (!m) return null;
  48364. if (!open()) return error(`@font-face missing '{'`);
  48365. let decls = comments();
  48366. let decl;
  48367. while (decl = declaration()) {
  48368. decls.push(decl);
  48369. decls = decls.concat(comments());
  48370. }
  48371. if (!close()) return error(`@font-face missing '}'`);
  48372. return pos({
  48373. type: 5 /* FontFace */,
  48374. declarations: decls
  48375. });
  48376. };
  48377. const compileAtrule = (nodeName, nodeType) => {
  48378. const re = new RegExp("^@" + nodeName + "\\s*([^;]+);");
  48379. return () => {
  48380. const pos = position();
  48381. const m = match(re);
  48382. if (!m) return null;
  48383. const node = {
  48384. type: nodeType
  48385. };
  48386. node[nodeName] = m[1].trim();
  48387. return pos(node);
  48388. };
  48389. };
  48390. const atimport = compileAtrule("import", 7 /* Import */);
  48391. const atcharset = compileAtrule("charset", 0 /* Charset */);
  48392. const atnamespace = compileAtrule("namespace", 11 /* Namespace */);
  48393. const atrule = () => {
  48394. if (css[0] !== "@") return null;
  48395. return atkeyframes() || atmedia() || atcustommedia() || atsupports() || atimport() || atcharset() || atnamespace() || atdocument() || atpage() || athost() || atfontface();
  48396. };
  48397. const rule = () => {
  48398. const pos = position();
  48399. const sel = selector();
  48400. if (!sel) return error("selector missing");
  48401. comments();
  48402. return pos({
  48403. type: 13 /* Rule */,
  48404. selectors: sel,
  48405. declarations: declarations()
  48406. });
  48407. };
  48408. class ParsePosition {
  48409. constructor(start) {
  48410. this.start = start;
  48411. this.end = { line: lineno, column };
  48412. this.source = filePath;
  48413. }
  48414. }
  48415. ParsePosition.prototype.content = css;
  48416. return {
  48417. diagnostics,
  48418. ...addParent(stylesheet())
  48419. };
  48420. };
  48421. var trim = (str) => str ? str.trim() : "";
  48422. var addParent = (obj, parent) => {
  48423. const isNode = obj && typeof obj.type === "string";
  48424. const childParent = isNode ? obj : parent;
  48425. for (const k in obj) {
  48426. const value = obj[k];
  48427. if (Array.isArray(value)) {
  48428. value.forEach(function(v) {
  48429. addParent(v, childParent);
  48430. });
  48431. } else if (value && typeof value === "object") {
  48432. addParent(value, childParent);
  48433. }
  48434. }
  48435. if (isNode) {
  48436. Object.defineProperty(obj, "parent", {
  48437. configurable: true,
  48438. writable: true,
  48439. enumerable: false,
  48440. value: parent || null
  48441. });
  48442. }
  48443. return obj;
  48444. };
  48445. var commentre = /\/\*[^*]*\*+([^/*][^*]*\*+)*\//g;
  48446. // src/compiler/style/css-parser/get-css-selectors.ts
  48447. var getCssSelectors = (sel) => {
  48448. SELECTORS.all.length = SELECTORS.tags.length = SELECTORS.classNames.length = SELECTORS.ids.length = SELECTORS.attrs.length = 0;
  48449. sel = sel.replace(/\./g, " .").replace(/\#/g, " #").replace(/\[/g, " [").replace(/\>/g, " > ").replace(/\+/g, " + ").replace(/\~/g, " ~ ").replace(/\*/g, " * ").replace(/\:not\((.*?)\)/g, " ");
  48450. const items = sel.split(" ");
  48451. for (let i = 0, l = items.length; i < l; i++) {
  48452. items[i] = items[i].split(":")[0];
  48453. if (items[i].length === 0) continue;
  48454. if (items[i].charAt(0) === ".") {
  48455. SELECTORS.classNames.push(items[i].slice(1));
  48456. } else if (items[i].charAt(0) === "#") {
  48457. SELECTORS.ids.push(items[i].slice(1));
  48458. } else if (items[i].charAt(0) === "[") {
  48459. items[i] = items[i].slice(1).split("=")[0].split("]")[0].trim();
  48460. SELECTORS.attrs.push(items[i].toLowerCase());
  48461. } else if (/[a-z]/g.test(items[i].charAt(0))) {
  48462. SELECTORS.tags.push(items[i].toLowerCase());
  48463. }
  48464. }
  48465. SELECTORS.classNames = SELECTORS.classNames.sort((a, b) => {
  48466. if (a.length < b.length) return -1;
  48467. if (a.length > b.length) return 1;
  48468. return 0;
  48469. });
  48470. return SELECTORS;
  48471. };
  48472. var SELECTORS = {
  48473. all: [],
  48474. tags: [],
  48475. classNames: [],
  48476. ids: [],
  48477. attrs: []
  48478. };
  48479. // src/compiler/style/css-parser/serialize-css.ts
  48480. var serializeCss = (stylesheet, serializeOpts) => {
  48481. const usedSelectors = serializeOpts.usedSelectors || null;
  48482. const opts = {
  48483. usedSelectors: usedSelectors || null,
  48484. hasUsedAttrs: !!usedSelectors && usedSelectors.attrs.size > 0,
  48485. hasUsedClassNames: !!usedSelectors && usedSelectors.classNames.size > 0,
  48486. hasUsedIds: !!usedSelectors && usedSelectors.ids.size > 0,
  48487. hasUsedTags: !!usedSelectors && usedSelectors.tags.size > 0
  48488. };
  48489. const rules = stylesheet.rules;
  48490. if (!rules) {
  48491. return "";
  48492. }
  48493. const rulesLen = rules.length;
  48494. const out = [];
  48495. for (let i = 0; i < rulesLen; i++) {
  48496. out.push(serializeCssVisitNode(opts, rules[i], i, rulesLen));
  48497. }
  48498. return out.join("");
  48499. };
  48500. var serializeCssVisitNode = (opts, node, index, len) => {
  48501. var _a2;
  48502. const nodeType = node.type;
  48503. if (nodeType === 4 /* Declaration */) {
  48504. return serializeCssDeclaration(node, index, len);
  48505. }
  48506. if (nodeType === 13 /* Rule */) {
  48507. return serializeCssRule(opts, node);
  48508. }
  48509. if (nodeType === 1 /* Comment */) {
  48510. if (((_a2 = node.comment) == null ? void 0 : _a2[0]) === "!") {
  48511. return `/*${node.comment}*/`;
  48512. } else {
  48513. return "";
  48514. }
  48515. }
  48516. if (nodeType === 10 /* Media */) {
  48517. return serializeCssMedia(opts, node);
  48518. }
  48519. if (nodeType === 8 /* KeyFrames */) {
  48520. return serializeCssKeyframes(opts, node);
  48521. }
  48522. if (nodeType === 9 /* KeyFrame */) {
  48523. return serializeCssKeyframe(opts, node);
  48524. }
  48525. if (nodeType === 5 /* FontFace */) {
  48526. return serializeCssFontFace(opts, node);
  48527. }
  48528. if (nodeType === 15 /* Supports */) {
  48529. return serializeCssSupports(opts, node);
  48530. }
  48531. if (nodeType === 7 /* Import */) {
  48532. return "@import " + node.import + ";";
  48533. }
  48534. if (nodeType === 0 /* Charset */) {
  48535. return "@charset " + node.charset + ";";
  48536. }
  48537. if (nodeType === 12 /* Page */) {
  48538. return serializeCssPage(opts, node);
  48539. }
  48540. if (nodeType === 6 /* Host */) {
  48541. return "@host{" + serializeCssMapVisit(opts, node.rules) + "}";
  48542. }
  48543. if (nodeType === 2 /* CustomMedia */) {
  48544. return "@custom-media " + node.name + " " + node.media + ";";
  48545. }
  48546. if (nodeType === 3 /* Document */) {
  48547. return serializeCssDocument(opts, node);
  48548. }
  48549. if (nodeType === 11 /* Namespace */) {
  48550. return "@namespace " + node.namespace + ";";
  48551. }
  48552. return "";
  48553. };
  48554. var serializeCssRule = (opts, node) => {
  48555. var _a2, _b;
  48556. const decls = node.declarations;
  48557. const usedSelectors = opts.usedSelectors;
  48558. const selectors = (_b = (_a2 = node.selectors) == null ? void 0 : _a2.slice()) != null ? _b : [];
  48559. if (decls == null || decls.length === 0) {
  48560. return "";
  48561. }
  48562. if (usedSelectors) {
  48563. let i;
  48564. let j;
  48565. let include = true;
  48566. for (i = selectors.length - 1; i >= 0; i--) {
  48567. const sel = getCssSelectors(selectors[i]);
  48568. include = true;
  48569. let jlen = sel.classNames.length;
  48570. if (jlen > 0 && opts.hasUsedClassNames) {
  48571. for (j = 0; j < jlen; j++) {
  48572. if (!usedSelectors.classNames.has(sel.classNames[j])) {
  48573. include = false;
  48574. break;
  48575. }
  48576. }
  48577. }
  48578. if (include && opts.hasUsedTags) {
  48579. jlen = sel.tags.length;
  48580. if (jlen > 0) {
  48581. for (j = 0; j < jlen; j++) {
  48582. if (!usedSelectors.tags.has(sel.tags[j])) {
  48583. include = false;
  48584. break;
  48585. }
  48586. }
  48587. }
  48588. }
  48589. if (include && opts.hasUsedAttrs) {
  48590. jlen = sel.attrs.length;
  48591. if (jlen > 0) {
  48592. for (j = 0; j < jlen; j++) {
  48593. if (!usedSelectors.attrs.has(sel.attrs[j])) {
  48594. include = false;
  48595. break;
  48596. }
  48597. }
  48598. }
  48599. }
  48600. if (include && opts.hasUsedIds) {
  48601. jlen = sel.ids.length;
  48602. if (jlen > 0) {
  48603. for (j = 0; j < jlen; j++) {
  48604. if (!usedSelectors.ids.has(sel.ids[j])) {
  48605. include = false;
  48606. break;
  48607. }
  48608. }
  48609. }
  48610. }
  48611. if (!include) {
  48612. selectors.splice(i, 1);
  48613. }
  48614. }
  48615. }
  48616. if (selectors.length === 0) {
  48617. return "";
  48618. }
  48619. const cleanedSelectors = [];
  48620. let cleanedSelector = "";
  48621. if (node.selectors) {
  48622. for (const selector of node.selectors) {
  48623. cleanedSelector = removeSelectorWhitespace(selector);
  48624. if (!cleanedSelectors.includes(cleanedSelector)) {
  48625. cleanedSelectors.push(cleanedSelector);
  48626. }
  48627. }
  48628. }
  48629. return `${cleanedSelectors}{${serializeCssMapVisit(opts, decls)}}`;
  48630. };
  48631. var serializeCssDeclaration = (node, index, len) => {
  48632. if (node.value === "") {
  48633. return "";
  48634. }
  48635. if (len - 1 === index) {
  48636. return node.property + ":" + node.value;
  48637. }
  48638. return node.property + ":" + node.value + ";";
  48639. };
  48640. var serializeCssMedia = (opts, node) => {
  48641. const mediaCss = serializeCssMapVisit(opts, node.rules);
  48642. if (mediaCss === "") {
  48643. return "";
  48644. }
  48645. return "@media " + removeMediaWhitespace(node.media) + "{" + mediaCss + "}";
  48646. };
  48647. var serializeCssKeyframes = (opts, node) => {
  48648. const keyframesCss = serializeCssMapVisit(opts, node.keyframes);
  48649. if (keyframesCss === "") {
  48650. return "";
  48651. }
  48652. return "@" + (node.vendor || "") + "keyframes " + node.name + "{" + keyframesCss + "}";
  48653. };
  48654. var serializeCssKeyframe = (opts, node) => {
  48655. var _a2, _b;
  48656. return ((_b = (_a2 = node.values) == null ? void 0 : _a2.join(",")) != null ? _b : "") + "{" + serializeCssMapVisit(opts, node.declarations) + "}";
  48657. };
  48658. var serializeCssFontFace = (opts, node) => {
  48659. const fontCss = serializeCssMapVisit(opts, node.declarations);
  48660. if (fontCss === "") {
  48661. return "";
  48662. }
  48663. return "@font-face{" + fontCss + "}";
  48664. };
  48665. var serializeCssSupports = (opts, node) => {
  48666. const supportsCss = serializeCssMapVisit(opts, node.rules);
  48667. if (supportsCss === "") {
  48668. return "";
  48669. }
  48670. return "@supports " + node.supports + "{" + supportsCss + "}";
  48671. };
  48672. var serializeCssPage = (opts, node) => {
  48673. var _a2, _b;
  48674. const sel = (_b = (_a2 = node.selectors) == null ? void 0 : _a2.join(", ")) != null ? _b : "";
  48675. return "@page " + sel + "{" + serializeCssMapVisit(opts, node.declarations) + "}";
  48676. };
  48677. var serializeCssDocument = (opts, node) => {
  48678. const documentCss = serializeCssMapVisit(opts, node.rules);
  48679. const doc = "@" + (node.vendor || "") + "document " + node.document;
  48680. if (documentCss === "") {
  48681. return "";
  48682. }
  48683. return doc + "{" + documentCss + "}";
  48684. };
  48685. var serializeCssMapVisit = (opts, nodes) => {
  48686. let rtn = "";
  48687. if (nodes) {
  48688. for (let i = 0, len = nodes.length; i < len; i++) {
  48689. rtn += serializeCssVisitNode(opts, nodes[i], i, len);
  48690. }
  48691. }
  48692. return rtn;
  48693. };
  48694. var removeSelectorWhitespace = (selector) => {
  48695. let rtn = "";
  48696. let char = "";
  48697. let inAttr = false;
  48698. selector = selector.trim();
  48699. for (let i = 0, l = selector.length; i < l; i++) {
  48700. char = selector[i];
  48701. if (char === "[" && rtn[rtn.length - 1] !== "\\") {
  48702. inAttr = true;
  48703. } else if (char === "]" && rtn[rtn.length - 1] !== "\\") {
  48704. inAttr = false;
  48705. }
  48706. if (!inAttr && CSS_WS_REG.test(char)) {
  48707. if (CSS_NEXT_CHAR_REG.test(selector[i + 1])) {
  48708. continue;
  48709. }
  48710. if (CSS_PREV_CHAR_REG.test(rtn[rtn.length - 1])) {
  48711. continue;
  48712. }
  48713. rtn += " ";
  48714. } else {
  48715. rtn += char;
  48716. }
  48717. }
  48718. return rtn;
  48719. };
  48720. var removeMediaWhitespace = (media) => {
  48721. var _a2;
  48722. let rtn = "";
  48723. let char = "";
  48724. media = (_a2 = media == null ? void 0 : media.trim()) != null ? _a2 : "";
  48725. for (let i = 0, l = media.length; i < l; i++) {
  48726. char = media[i];
  48727. if (CSS_WS_REG.test(char)) {
  48728. if (CSS_WS_REG.test(rtn[rtn.length - 1])) {
  48729. continue;
  48730. }
  48731. rtn += " ";
  48732. } else {
  48733. rtn += char;
  48734. }
  48735. }
  48736. return rtn;
  48737. };
  48738. var CSS_WS_REG = /\s/;
  48739. var CSS_NEXT_CHAR_REG = /[>\(\)\~\,\+\s]/;
  48740. var CSS_PREV_CHAR_REG = /[>\(\~\,\+]/;
  48741. // src/compiler/style/css-parser/used-selectors.ts
  48742. var getUsedSelectors = (elm) => {
  48743. const usedSelectors = {
  48744. attrs: /* @__PURE__ */ new Set(),
  48745. classNames: /* @__PURE__ */ new Set(),
  48746. ids: /* @__PURE__ */ new Set(),
  48747. tags: /* @__PURE__ */ new Set()
  48748. };
  48749. collectUsedSelectors(usedSelectors, elm);
  48750. return usedSelectors;
  48751. };
  48752. var collectUsedSelectors = (usedSelectors, elm) => {
  48753. if (elm != null && elm.nodeType === 1) {
  48754. const children = elm.children;
  48755. const tagName = elm.nodeName.toLowerCase();
  48756. usedSelectors.tags.add(tagName);
  48757. const attributes = elm.attributes;
  48758. for (let i = 0, l = attributes.length; i < l; i++) {
  48759. const attr = attributes.item(i);
  48760. const attrName = attr.name.toLowerCase();
  48761. usedSelectors.attrs.add(attrName);
  48762. if (attrName === "class") {
  48763. const classList = elm.classList;
  48764. for (let i2 = 0, l2 = classList.length; i2 < l2; i2++) {
  48765. usedSelectors.classNames.add(classList.item(i2));
  48766. }
  48767. } else if (attrName === "id") {
  48768. usedSelectors.ids.add(attr.value);
  48769. }
  48770. }
  48771. if (children) {
  48772. for (let i = 0, l = children.length; i < l; i++) {
  48773. collectUsedSelectors(usedSelectors, children[i]);
  48774. }
  48775. }
  48776. }
  48777. };
  48778. // src/compiler/html/remove-unused-styles.ts
  48779. var removeUnusedStyles = (doc, diagnostics) => {
  48780. try {
  48781. const styleElms = doc.head.querySelectorAll(`style[data-styles]`);
  48782. const styleLen = styleElms.length;
  48783. if (styleLen > 0) {
  48784. const usedSelectors = getUsedSelectors(doc.documentElement);
  48785. for (let i = 0; i < styleLen; i++) {
  48786. removeUnusedStyleText(usedSelectors, diagnostics, styleElms[i]);
  48787. }
  48788. }
  48789. } catch (e) {
  48790. catchError(diagnostics, e);
  48791. }
  48792. };
  48793. var removeUnusedStyleText = (usedSelectors, diagnostics, styleElm) => {
  48794. try {
  48795. const parseResults = parseCss(styleElm.innerHTML);
  48796. diagnostics.push(...parseResults.diagnostics);
  48797. if (hasError(diagnostics)) {
  48798. return;
  48799. }
  48800. try {
  48801. styleElm.innerHTML = serializeCss(parseResults.stylesheet, {
  48802. usedSelectors
  48803. });
  48804. } catch (e) {
  48805. diagnostics.push({
  48806. level: "warn",
  48807. type: "css",
  48808. header: "CSS Stringify",
  48809. messageText: e,
  48810. lines: []
  48811. });
  48812. }
  48813. } catch (e) {
  48814. diagnostics.push({
  48815. level: "warn",
  48816. type: "css",
  48817. header: "CSS Parse",
  48818. messageText: e,
  48819. lines: []
  48820. });
  48821. }
  48822. };
  48823. // src/hydrate/runner/inspect-element.ts
  48824. function inspectElement(results, elm, depth) {
  48825. const children = [...Array.from(elm.children), ...Array.from(elm.shadowRoot ? elm.shadowRoot.children : [])];
  48826. for (let i = 0, ii = children.length; i < ii; i++) {
  48827. const childElm = children[i];
  48828. const tagName = childElm.nodeName.toLowerCase();
  48829. if (tagName.includes("-")) {
  48830. const cmp = results.components.find((c) => c.tag === tagName);
  48831. if (cmp != null) {
  48832. cmp.count++;
  48833. if (depth > cmp.depth) {
  48834. cmp.depth = depth;
  48835. }
  48836. }
  48837. } else {
  48838. switch (tagName) {
  48839. case "a":
  48840. const anchor = collectAttributes(childElm);
  48841. anchor.href = childElm.href;
  48842. if (typeof anchor.href === "string") {
  48843. if (!results.anchors.some((a) => a.href === anchor.href)) {
  48844. results.anchors.push(anchor);
  48845. }
  48846. }
  48847. break;
  48848. case "img":
  48849. const img = collectAttributes(childElm);
  48850. img.src = childElm.src;
  48851. if (typeof img.src === "string") {
  48852. if (!results.imgs.some((a) => a.src === img.src)) {
  48853. results.imgs.push(img);
  48854. }
  48855. }
  48856. break;
  48857. case "link":
  48858. const link = collectAttributes(childElm);
  48859. link.href = childElm.href;
  48860. if (typeof link.rel === "string" && link.rel.toLowerCase() === "stylesheet") {
  48861. if (typeof link.href === "string") {
  48862. if (!results.styles.some((s) => s.link === link.href)) {
  48863. delete link.rel;
  48864. delete link.type;
  48865. results.styles.push(link);
  48866. }
  48867. }
  48868. }
  48869. break;
  48870. case "script":
  48871. const script = collectAttributes(childElm);
  48872. if (childElm.hasAttribute("src")) {
  48873. script.src = childElm.src;
  48874. if (typeof script.src === "string") {
  48875. if (!results.scripts.some((s) => s.src === script.src)) {
  48876. results.scripts.push(script);
  48877. }
  48878. }
  48879. } else {
  48880. const staticDataKey = childElm.getAttribute("data-stencil-static");
  48881. if (staticDataKey) {
  48882. results.staticData.push({
  48883. id: staticDataKey,
  48884. type: childElm.getAttribute("type"),
  48885. content: childElm.textContent
  48886. });
  48887. }
  48888. }
  48889. break;
  48890. }
  48891. }
  48892. depth++;
  48893. inspectElement(results, childElm, depth);
  48894. }
  48895. }
  48896. function collectAttributes(node) {
  48897. const parsedElm = {};
  48898. const attrs = node.attributes;
  48899. for (let i = 0, ii = attrs.length; i < ii; i++) {
  48900. const attr = attrs.item(i);
  48901. const attrName = attr.nodeName.toLowerCase();
  48902. if (SKIP_ATTRS.has(attrName)) {
  48903. continue;
  48904. }
  48905. const attrValue = attr.nodeValue;
  48906. if (attrName === "class" && attrValue === "") {
  48907. continue;
  48908. }
  48909. parsedElm[attrName] = attrValue;
  48910. }
  48911. return parsedElm;
  48912. }
  48913. var SKIP_ATTRS = /* @__PURE__ */ new Set(["s-id", "c-id"]);
  48914. // src/hydrate/runner/patch-dom-implementation.ts
  48915. function patchDomImplementation(doc, opts) {
  48916. let win;
  48917. if (doc.defaultView != null) {
  48918. opts.destroyWindow = true;
  48919. patchWindow(doc.defaultView);
  48920. win = doc.defaultView;
  48921. } else {
  48922. opts.destroyWindow = true;
  48923. opts.destroyDocument = false;
  48924. win = new MockWindow(false);
  48925. }
  48926. if (win.document !== doc) {
  48927. win.document = doc;
  48928. }
  48929. if (doc.defaultView !== win) {
  48930. doc.defaultView = win;
  48931. }
  48932. const HTMLElement = doc.documentElement.constructor.prototype;
  48933. if (typeof HTMLElement.getRootNode !== "function") {
  48934. const elm = doc.createElement("unknown-element");
  48935. const HTMLUnknownElement = elm.constructor.prototype;
  48936. HTMLUnknownElement.getRootNode = getRootNode;
  48937. }
  48938. if (typeof doc.createEvent === "function") {
  48939. const CustomEvent = doc.createEvent("CustomEvent").constructor;
  48940. if (win.CustomEvent !== CustomEvent) {
  48941. win.CustomEvent = CustomEvent;
  48942. }
  48943. }
  48944. try {
  48945. win.__stencil_baseURI = doc.baseURI;
  48946. } catch (e) {
  48947. Object.defineProperty(doc, "baseURI", {
  48948. get() {
  48949. const baseElm = doc.querySelector("base[href]");
  48950. if (baseElm) {
  48951. return new URL(baseElm.getAttribute("href"), win.location.href).href;
  48952. }
  48953. return win.location.href;
  48954. }
  48955. });
  48956. }
  48957. return win;
  48958. }
  48959. function getRootNode(opts) {
  48960. const isComposed = opts != null && opts.composed === true;
  48961. let node = this;
  48962. while (node.parentNode != null) {
  48963. node = node.parentNode;
  48964. if (isComposed === true && node.parentNode == null && node.host != null) {
  48965. node = node.host;
  48966. }
  48967. }
  48968. return node;
  48969. }
  48970. // src/hydrate/runner/render-utils.ts
  48971. function normalizeHydrateOptions(inputOpts) {
  48972. const outputOpts = Object.assign(
  48973. {
  48974. serializeToHtml: false,
  48975. destroyWindow: false,
  48976. destroyDocument: false
  48977. },
  48978. inputOpts || {}
  48979. );
  48980. if (typeof outputOpts.clientHydrateAnnotations !== "boolean") {
  48981. outputOpts.clientHydrateAnnotations = true;
  48982. }
  48983. if (typeof outputOpts.constrainTimeouts !== "boolean") {
  48984. outputOpts.constrainTimeouts = true;
  48985. }
  48986. if (typeof outputOpts.maxHydrateCount !== "number") {
  48987. outputOpts.maxHydrateCount = 300;
  48988. }
  48989. if (typeof outputOpts.runtimeLogging !== "boolean") {
  48990. outputOpts.runtimeLogging = false;
  48991. }
  48992. if (typeof outputOpts.timeout !== "number") {
  48993. outputOpts.timeout = 15e3;
  48994. }
  48995. if (Array.isArray(outputOpts.excludeComponents)) {
  48996. outputOpts.excludeComponents = outputOpts.excludeComponents.filter(filterValidTags).map(mapValidTags);
  48997. } else {
  48998. outputOpts.excludeComponents = [];
  48999. }
  49000. if (Array.isArray(outputOpts.staticComponents)) {
  49001. outputOpts.staticComponents = outputOpts.staticComponents.filter(filterValidTags).map(mapValidTags);
  49002. } else {
  49003. outputOpts.staticComponents = [];
  49004. }
  49005. return outputOpts;
  49006. }
  49007. function filterValidTags(tag) {
  49008. return typeof tag === "string" && tag.includes("-");
  49009. }
  49010. function mapValidTags(tag) {
  49011. return tag.trim().toLowerCase();
  49012. }
  49013. function generateHydrateResults(opts) {
  49014. if (typeof opts.url !== "string") {
  49015. opts.url = `https://hydrate.stenciljs.com/`;
  49016. }
  49017. if (typeof opts.buildId !== "string") {
  49018. opts.buildId = createHydrateBuildId();
  49019. }
  49020. const results = {
  49021. buildId: opts.buildId,
  49022. diagnostics: [],
  49023. url: opts.url,
  49024. host: null,
  49025. hostname: null,
  49026. href: null,
  49027. pathname: null,
  49028. port: null,
  49029. search: null,
  49030. hash: null,
  49031. html: null,
  49032. httpStatus: null,
  49033. hydratedCount: 0,
  49034. anchors: [],
  49035. components: [],
  49036. imgs: [],
  49037. scripts: [],
  49038. staticData: [],
  49039. styles: [],
  49040. title: null
  49041. };
  49042. try {
  49043. const url = new URL(opts.url, `https://hydrate.stenciljs.com/`);
  49044. results.url = url.href;
  49045. results.host = url.host;
  49046. results.hostname = url.hostname;
  49047. results.href = url.href;
  49048. results.port = url.port;
  49049. results.pathname = url.pathname;
  49050. results.search = url.search;
  49051. results.hash = url.hash;
  49052. } catch (e) {
  49053. renderCatchError(results, e);
  49054. }
  49055. return results;
  49056. }
  49057. var createHydrateBuildId = () => {
  49058. let chars = "abcdefghijklmnopqrstuvwxyz";
  49059. let buildId = "";
  49060. while (buildId.length < 8) {
  49061. const char = chars[Math.floor(Math.random() * chars.length)];
  49062. buildId += char;
  49063. if (buildId.length === 1) {
  49064. chars += "0123456789";
  49065. }
  49066. }
  49067. return buildId;
  49068. };
  49069. function renderBuildDiagnostic(results, level, header, msg) {
  49070. const diagnostic = {
  49071. level,
  49072. type: "build",
  49073. header,
  49074. messageText: msg,
  49075. relFilePath: void 0,
  49076. absFilePath: void 0,
  49077. lines: []
  49078. };
  49079. if (results.pathname) {
  49080. if (results.pathname !== "/") {
  49081. diagnostic.header += ": " + results.pathname;
  49082. }
  49083. } else if (results.url) {
  49084. diagnostic.header += ": " + results.url;
  49085. }
  49086. results.diagnostics.push(diagnostic);
  49087. return diagnostic;
  49088. }
  49089. function renderBuildError(results, msg) {
  49090. return renderBuildDiagnostic(results, "error", "Hydrate Error", msg || "");
  49091. }
  49092. function renderCatchError(results, err2) {
  49093. const diagnostic = renderBuildError(results);
  49094. if (err2 != null) {
  49095. if (err2.stack != null) {
  49096. diagnostic.messageText = err2.stack.toString();
  49097. } else {
  49098. if (err2.message != null) {
  49099. diagnostic.messageText = err2.message.toString();
  49100. } else {
  49101. diagnostic.messageText = err2.toString();
  49102. }
  49103. }
  49104. }
  49105. return diagnostic;
  49106. }
  49107. // src/hydrate/runner/runtime-log.ts
  49108. function runtimeLogging(win, opts, results) {
  49109. try {
  49110. const pathname = win.location.pathname;
  49111. win.console.error = (...msgs) => {
  49112. const errMsg = msgs.reduce((errMsg2, m) => {
  49113. if (m) {
  49114. if (m.stack != null) {
  49115. return errMsg2 + " " + String(m.stack);
  49116. } else {
  49117. if (m.message != null) {
  49118. return errMsg2 + " " + String(m.message);
  49119. }
  49120. }
  49121. }
  49122. return String(m);
  49123. }, "").trim();
  49124. if (errMsg !== "") {
  49125. renderCatchError(results, errMsg);
  49126. if (opts.runtimeLogging) {
  49127. runtimeLog(pathname, "error", [errMsg]);
  49128. }
  49129. }
  49130. };
  49131. win.console.debug = (...msgs) => {
  49132. renderBuildDiagnostic(results, "debug", "Hydrate Debug", [...msgs].join(", "));
  49133. if (opts.runtimeLogging) {
  49134. runtimeLog(pathname, "debug", msgs);
  49135. }
  49136. };
  49137. if (opts.runtimeLogging) {
  49138. ["log", "warn", "assert", "info", "trace"].forEach((type) => {
  49139. win.console[type] = (...msgs) => {
  49140. runtimeLog(pathname, type, msgs);
  49141. };
  49142. });
  49143. }
  49144. } catch (e) {
  49145. renderCatchError(results, e);
  49146. }
  49147. }
  49148. function runtimeLog(pathname, type, msgs) {
  49149. global.console[type].apply(global.console, [`[ ${pathname} ${type} ] `, ...msgs]);
  49150. }
  49151. // src/hydrate/runner/window-initialize.ts
  49152. function initializeWindow(win, doc, opts, results) {
  49153. if (typeof opts.url === "string") {
  49154. try {
  49155. win.location.href = opts.url;
  49156. } catch (e) {
  49157. }
  49158. }
  49159. if (typeof opts.userAgent === "string") {
  49160. try {
  49161. win.navigator.userAgent = opts.userAgent;
  49162. } catch (e) {
  49163. }
  49164. }
  49165. if (typeof opts.cookie === "string") {
  49166. try {
  49167. doc.cookie = opts.cookie;
  49168. } catch (e) {
  49169. }
  49170. }
  49171. if (typeof opts.referrer === "string") {
  49172. try {
  49173. doc.referrer = opts.referrer;
  49174. } catch (e) {
  49175. }
  49176. }
  49177. if (typeof opts.direction === "string") {
  49178. try {
  49179. doc.documentElement.setAttribute("dir", opts.direction);
  49180. } catch (e) {
  49181. }
  49182. }
  49183. if (typeof opts.language === "string") {
  49184. try {
  49185. doc.documentElement.setAttribute("lang", opts.language);
  49186. } catch (e) {
  49187. }
  49188. }
  49189. if (typeof opts.buildId === "string") {
  49190. try {
  49191. doc.documentElement.setAttribute("data-stencil-build", opts.buildId);
  49192. } catch (e) {
  49193. }
  49194. }
  49195. try {
  49196. win.customElements = null;
  49197. } catch (e) {
  49198. }
  49199. if (opts.constrainTimeouts) {
  49200. constrainTimeouts(win);
  49201. }
  49202. runtimeLogging(win, opts, results);
  49203. return win;
  49204. }
  49205. // src/hydrate/runner/render.ts
  49206. var NOOP = () => {
  49207. };
  49208. function streamToString(html, option) {
  49209. return renderToString(html, option, true);
  49210. }
  49211. function renderToString(html, options, asStream) {
  49212. const opts = normalizeHydrateOptions(options);
  49213. opts.serializeToHtml = true;
  49214. opts.fullDocument = typeof opts.fullDocument === "boolean" ? opts.fullDocument : true;
  49215. opts.serializeShadowRoot = typeof opts.serializeShadowRoot === "boolean" ? opts.serializeShadowRoot : true;
  49216. opts.constrainTimeouts = false;
  49217. return hydrateDocument(html, opts, asStream);
  49218. }
  49219. function hydrateDocument(doc, options, asStream) {
  49220. const opts = normalizeHydrateOptions(options);
  49221. let win = null;
  49222. const results = generateHydrateResults(opts);
  49223. if (hasError(results.diagnostics)) {
  49224. return Promise.resolve(results);
  49225. }
  49226. if (typeof doc === "string") {
  49227. try {
  49228. opts.destroyWindow = true;
  49229. opts.destroyDocument = true;
  49230. win = new MockWindow(doc);
  49231. if (!asStream) {
  49232. return render(win, opts, results).then(() => results);
  49233. }
  49234. return renderStream(win, opts, results);
  49235. } catch (e) {
  49236. if (win && win.close) {
  49237. win.close();
  49238. }
  49239. win = null;
  49240. renderCatchError(results, e);
  49241. return Promise.resolve(results);
  49242. }
  49243. }
  49244. if (isValidDocument(doc)) {
  49245. try {
  49246. opts.destroyDocument = false;
  49247. win = patchDomImplementation(doc, opts);
  49248. if (!asStream) {
  49249. return render(win, opts, results).then(() => results);
  49250. }
  49251. return renderStream(win, opts, results);
  49252. } catch (e) {
  49253. if (win && win.close) {
  49254. win.close();
  49255. }
  49256. win = null;
  49257. renderCatchError(results, e);
  49258. return Promise.resolve(results);
  49259. }
  49260. }
  49261. renderBuildError(results, `Invalid html or document. Must be either a valid "html" string, or DOM "document".`);
  49262. return Promise.resolve(results);
  49263. }
  49264. async function render(win, opts, results) {
  49265. if ("process" in globalThis && typeof process.on === "function" && !process.__stencilErrors) {
  49266. process.__stencilErrors = true;
  49267. process.on("unhandledRejection", (e) => {
  49268. console.log("unhandledRejection", e);
  49269. });
  49270. }
  49271. initializeWindow(win, win.document, opts, results);
  49272. const beforeHydrateFn = typeof opts.beforeHydrate === "function" ? opts.beforeHydrate : NOOP;
  49273. try {
  49274. await Promise.resolve(beforeHydrateFn(win.document));
  49275. return new Promise((resolve) => hydrateFactory(win, opts, results, afterHydrate, resolve));
  49276. } catch (e) {
  49277. renderCatchError(results, e);
  49278. return finalizeHydrate(win, win.document, opts, results);
  49279. }
  49280. }
  49281. function renderStream(win, opts, results) {
  49282. async function* processRender() {
  49283. const renderResult = await render(win, opts, results);
  49284. yield renderResult.html;
  49285. }
  49286. return stream.Readable.from(processRender());
  49287. }
  49288. async function afterHydrate(win, opts, results, resolve) {
  49289. const afterHydrateFn = typeof opts.afterHydrate === "function" ? opts.afterHydrate : NOOP;
  49290. try {
  49291. await Promise.resolve(afterHydrateFn(win.document));
  49292. return resolve(finalizeHydrate(win, win.document, opts, results));
  49293. } catch (e) {
  49294. renderCatchError(results, e);
  49295. return resolve(finalizeHydrate(win, win.document, opts, results));
  49296. }
  49297. }
  49298. function finalizeHydrate(win, doc, opts, results) {
  49299. try {
  49300. inspectElement(results, doc.documentElement, 0);
  49301. if (opts.removeUnusedStyles !== false) {
  49302. try {
  49303. removeUnusedStyles(doc, results.diagnostics);
  49304. } catch (e) {
  49305. renderCatchError(results, e);
  49306. }
  49307. }
  49308. if (typeof opts.title === "string") {
  49309. try {
  49310. doc.title = opts.title;
  49311. } catch (e) {
  49312. renderCatchError(results, e);
  49313. }
  49314. }
  49315. results.title = doc.title;
  49316. if (opts.removeScripts) {
  49317. removeScripts(doc.documentElement);
  49318. }
  49319. try {
  49320. updateCanonicalLink(doc, opts.canonicalUrl);
  49321. } catch (e) {
  49322. renderCatchError(results, e);
  49323. }
  49324. try {
  49325. relocateMetaCharset(doc);
  49326. } catch (e) {
  49327. }
  49328. if (!hasError(results.diagnostics)) {
  49329. results.httpStatus = 200;
  49330. }
  49331. try {
  49332. const metaStatus = doc.head.querySelector('meta[http-equiv="status"]');
  49333. if (metaStatus != null) {
  49334. const metaStatusContent = metaStatus.getAttribute("content");
  49335. if (metaStatusContent && metaStatusContent.length > 0) {
  49336. results.httpStatus = parseInt(metaStatusContent, 10);
  49337. }
  49338. }
  49339. } catch (e) {
  49340. }
  49341. if (opts.clientHydrateAnnotations) {
  49342. doc.documentElement.classList.add("hydrated");
  49343. }
  49344. if (opts.serializeToHtml) {
  49345. results.html = serializeDocumentToString(doc, opts);
  49346. }
  49347. } catch (e) {
  49348. renderCatchError(results, e);
  49349. }
  49350. destroyWindow(win, doc, opts, results);
  49351. return results;
  49352. }
  49353. function destroyWindow(win, doc, opts, results) {
  49354. if (!opts.destroyWindow) {
  49355. return;
  49356. }
  49357. try {
  49358. if (!opts.destroyDocument) {
  49359. win.document = null;
  49360. doc.defaultView = null;
  49361. }
  49362. if (win.close) {
  49363. win.close();
  49364. }
  49365. } catch (e) {
  49366. renderCatchError(results, e);
  49367. }
  49368. }
  49369. function serializeDocumentToString(doc, opts) {
  49370. return serializeNodeToHtml(doc, {
  49371. approximateLineWidth: opts.approximateLineWidth,
  49372. outerHtml: false,
  49373. prettyHtml: opts.prettyHtml,
  49374. removeAttributeQuotes: opts.removeAttributeQuotes,
  49375. removeBooleanAttributeQuotes: opts.removeBooleanAttributeQuotes,
  49376. removeEmptyAttributes: opts.removeEmptyAttributes,
  49377. removeHtmlComments: opts.removeHtmlComments,
  49378. serializeShadowRoot: opts.serializeShadowRoot,
  49379. fullDocument: opts.fullDocument
  49380. });
  49381. }
  49382. function isValidDocument(doc) {
  49383. return doc != null && doc.nodeType === 9 && doc.documentElement != null && doc.documentElement.nodeType === 1 && doc.body != null && doc.body.nodeType === 1;
  49384. }
  49385. function removeScripts(elm) {
  49386. const children = elm.children;
  49387. for (let i = children.length - 1; i >= 0; i--) {
  49388. const child = children[i];
  49389. removeScripts(child);
  49390. if (child.nodeName === "SCRIPT" || child.nodeName === "LINK" && child.getAttribute("rel") === "modulepreload") {
  49391. child.remove();
  49392. }
  49393. }
  49394. }
  49395. exports.createWindowFromHtml = createWindowFromHtml;
  49396. exports.hydrateDocument = hydrateDocument;
  49397. exports.renderToString = renderToString;
  49398. exports.serializeDocumentToString = serializeDocumentToString;
  49399. exports.streamToString = streamToString;