index.mjs 2.3 MB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621762276237624762576267627762876297630763176327633763476357636763776387639764076417642764376447645764676477648764976507651765276537654765576567657765876597660766176627663766476657666766776687669767076717672767376747675767676777678767976807681768276837684768576867687768876897690769176927693769476957696769776987699770077017702770377047705770677077708770977107711771277137714771577167717771877197720772177227723772477257726772777287729773077317732773377347735773677377738773977407741774277437744774577467747774877497750775177527753775477557756775777587759776077617762776377647765776677677768776977707771777277737774777577767777777877797780778177827783778477857786778777887789779077917792779377947795779677977798779978007801780278037804780578067807780878097810781178127813781478157816781778187819782078217822782378247825782678277828782978307831783278337834783578367837783878397840784178427843784478457846784778487849785078517852785378547855785678577858785978607861786278637864786578667867786878697870787178727873787478757876787778787879788078817882788378847885788678877888788978907891789278937894789578967897789878997900790179027903790479057906790779087909791079117912791379147915791679177918791979207921792279237924792579267927792879297930793179327933793479357936793779387939794079417942794379447945794679477948794979507951795279537954795579567957795879597960796179627963796479657966796779687969797079717972797379747975797679777978797979807981798279837984798579867987798879897990799179927993799479957996799779987999800080018002800380048005800680078008800980108011801280138014801580168017801880198020802180228023802480258026802780288029803080318032803380348035803680378038803980408041804280438044804580468047804880498050805180528053805480558056805780588059806080618062806380648065806680678068806980708071807280738074807580768077807880798080808180828083808480858086808780888089809080918092809380948095809680978098809981008101810281038104810581068107810881098110811181128113811481158116811781188119812081218122812381248125812681278128812981308131813281338134813581368137813881398140814181428143814481458146814781488149815081518152815381548155815681578158815981608161816281638164816581668167816881698170817181728173817481758176817781788179818081818182818381848185818681878188818981908191819281938194819581968197819881998200820182028203820482058206820782088209821082118212821382148215821682178218821982208221822282238224822582268227822882298230823182328233823482358236823782388239824082418242824382448245824682478248824982508251825282538254825582568257825882598260826182628263826482658266826782688269827082718272827382748275827682778278827982808281828282838284828582868287828882898290829182928293829482958296829782988299830083018302830383048305830683078308830983108311831283138314831583168317831883198320832183228323832483258326832783288329833083318332833383348335833683378338833983408341834283438344834583468347834883498350835183528353835483558356835783588359836083618362836383648365836683678368836983708371837283738374837583768377837883798380838183828383838483858386838783888389839083918392839383948395839683978398839984008401840284038404840584068407840884098410841184128413841484158416841784188419842084218422842384248425842684278428842984308431843284338434843584368437843884398440844184428443844484458446844784488449845084518452845384548455845684578458845984608461846284638464846584668467846884698470847184728473847484758476847784788479848084818482848384848485848684878488848984908491849284938494849584968497849884998500850185028503850485058506850785088509851085118512851385148515851685178518851985208521852285238524852585268527852885298530853185328533853485358536853785388539854085418542854385448545854685478548854985508551855285538554855585568557855885598560856185628563856485658566856785688569857085718572857385748575857685778578857985808581858285838584858585868587858885898590859185928593859485958596859785988599860086018602860386048605860686078608860986108611861286138614861586168617861886198620862186228623862486258626862786288629863086318632863386348635863686378638863986408641864286438644864586468647864886498650865186528653865486558656865786588659866086618662866386648665866686678668866986708671867286738674867586768677867886798680868186828683868486858686868786888689869086918692869386948695869686978698869987008701870287038704870587068707870887098710871187128713871487158716871787188719872087218722872387248725872687278728872987308731873287338734873587368737873887398740874187428743874487458746874787488749875087518752875387548755875687578758875987608761876287638764876587668767876887698770877187728773877487758776877787788779878087818782878387848785878687878788878987908791879287938794879587968797879887998800880188028803880488058806880788088809881088118812881388148815881688178818881988208821882288238824882588268827882888298830883188328833883488358836883788388839884088418842884388448845884688478848884988508851885288538854885588568857885888598860886188628863886488658866886788688869887088718872887388748875887688778878887988808881888288838884888588868887888888898890889188928893889488958896889788988899890089018902890389048905890689078908890989108911891289138914891589168917891889198920892189228923892489258926892789288929893089318932893389348935893689378938893989408941894289438944894589468947894889498950895189528953895489558956895789588959896089618962896389648965896689678968896989708971897289738974897589768977897889798980898189828983898489858986898789888989899089918992899389948995899689978998899990009001900290039004900590069007900890099010901190129013901490159016901790189019902090219022902390249025902690279028902990309031903290339034903590369037903890399040904190429043904490459046904790489049905090519052905390549055905690579058905990609061906290639064906590669067906890699070907190729073907490759076907790789079908090819082908390849085908690879088908990909091909290939094909590969097909890999100910191029103910491059106910791089109911091119112911391149115911691179118911991209121912291239124912591269127912891299130913191329133913491359136913791389139914091419142914391449145914691479148914991509151915291539154915591569157915891599160916191629163916491659166916791689169917091719172917391749175917691779178917991809181918291839184918591869187918891899190919191929193919491959196919791989199920092019202920392049205920692079208920992109211921292139214921592169217921892199220922192229223922492259226922792289229923092319232923392349235923692379238923992409241924292439244924592469247924892499250925192529253925492559256925792589259926092619262926392649265926692679268926992709271927292739274927592769277927892799280928192829283928492859286928792889289929092919292929392949295929692979298929993009301930293039304930593069307930893099310931193129313931493159316931793189319932093219322932393249325932693279328932993309331933293339334933593369337933893399340934193429343934493459346934793489349935093519352935393549355935693579358935993609361936293639364936593669367936893699370937193729373937493759376937793789379938093819382938393849385938693879388938993909391939293939394939593969397939893999400940194029403940494059406940794089409941094119412941394149415941694179418941994209421942294239424942594269427942894299430943194329433943494359436943794389439944094419442944394449445944694479448944994509451945294539454945594569457945894599460946194629463946494659466946794689469947094719472947394749475947694779478947994809481948294839484948594869487948894899490949194929493949494959496949794989499950095019502950395049505950695079508950995109511951295139514951595169517951895199520952195229523952495259526952795289529953095319532953395349535953695379538953995409541954295439544954595469547954895499550955195529553955495559556955795589559956095619562956395649565956695679568956995709571957295739574957595769577957895799580958195829583958495859586958795889589959095919592959395949595959695979598959996009601960296039604960596069607960896099610961196129613961496159616961796189619962096219622962396249625962696279628962996309631963296339634963596369637963896399640964196429643964496459646964796489649965096519652965396549655965696579658965996609661966296639664966596669667966896699670967196729673967496759676967796789679968096819682968396849685968696879688968996909691969296939694969596969697969896999700970197029703970497059706970797089709971097119712971397149715971697179718971997209721972297239724972597269727972897299730973197329733973497359736973797389739974097419742974397449745974697479748974997509751975297539754975597569757975897599760976197629763976497659766976797689769977097719772977397749775977697779778977997809781978297839784978597869787978897899790979197929793979497959796979797989799980098019802980398049805980698079808980998109811981298139814981598169817981898199820982198229823982498259826982798289829983098319832983398349835983698379838983998409841984298439844984598469847984898499850985198529853985498559856985798589859986098619862986398649865986698679868986998709871987298739874987598769877987898799880988198829883988498859886988798889889989098919892989398949895989698979898989999009901990299039904990599069907990899099910991199129913991499159916991799189919992099219922992399249925992699279928992999309931993299339934993599369937993899399940994199429943994499459946994799489949995099519952995399549955995699579958995999609961996299639964996599669967996899699970997199729973997499759976997799789979998099819982998399849985998699879988998999909991999299939994999599969997999899991000010001100021000310004100051000610007100081000910010100111001210013100141001510016100171001810019100201002110022100231002410025100261002710028100291003010031100321003310034100351003610037100381003910040100411004210043100441004510046100471004810049100501005110052100531005410055100561005710058100591006010061100621006310064100651006610067100681006910070100711007210073100741007510076100771007810079100801008110082100831008410085100861008710088100891009010091100921009310094100951009610097100981009910100101011010210103101041010510106101071010810109101101011110112101131011410115101161011710118101191012010121101221012310124101251012610127101281012910130101311013210133101341013510136101371013810139101401014110142101431014410145101461014710148101491015010151101521015310154101551015610157101581015910160101611016210163101641016510166101671016810169101701017110172101731017410175101761017710178101791018010181101821018310184101851018610187101881018910190101911019210193101941019510196101971019810199102001020110202102031020410205102061020710208102091021010211102121021310214102151021610217102181021910220102211022210223102241022510226102271022810229102301023110232102331023410235102361023710238102391024010241102421024310244102451024610247102481024910250102511025210253102541025510256102571025810259102601026110262102631026410265102661026710268102691027010271102721027310274102751027610277102781027910280102811028210283102841028510286102871028810289102901029110292102931029410295102961029710298102991030010301103021030310304103051030610307103081030910310103111031210313103141031510316103171031810319103201032110322103231032410325103261032710328103291033010331103321033310334103351033610337103381033910340103411034210343103441034510346103471034810349103501035110352103531035410355103561035710358103591036010361103621036310364103651036610367103681036910370103711037210373103741037510376103771037810379103801038110382103831038410385103861038710388103891039010391103921039310394103951039610397103981039910400104011040210403104041040510406104071040810409104101041110412104131041410415104161041710418104191042010421104221042310424104251042610427104281042910430104311043210433104341043510436104371043810439104401044110442104431044410445104461044710448104491045010451104521045310454104551045610457104581045910460104611046210463104641046510466104671046810469104701047110472104731047410475104761047710478104791048010481104821048310484104851048610487104881048910490104911049210493104941049510496104971049810499105001050110502105031050410505105061050710508105091051010511105121051310514105151051610517105181051910520105211052210523105241052510526105271052810529105301053110532105331053410535105361053710538105391054010541105421054310544105451054610547105481054910550105511055210553105541055510556105571055810559105601056110562105631056410565105661056710568105691057010571105721057310574105751057610577105781057910580105811058210583105841058510586105871058810589105901059110592105931059410595105961059710598105991060010601106021060310604106051060610607106081060910610106111061210613106141061510616106171061810619106201062110622106231062410625106261062710628106291063010631106321063310634106351063610637106381063910640106411064210643106441064510646106471064810649106501065110652106531065410655106561065710658106591066010661106621066310664106651066610667106681066910670106711067210673106741067510676106771067810679106801068110682106831068410685106861068710688106891069010691106921069310694106951069610697106981069910700107011070210703107041070510706107071070810709107101071110712107131071410715107161071710718107191072010721107221072310724107251072610727107281072910730107311073210733107341073510736107371073810739107401074110742107431074410745107461074710748107491075010751107521075310754107551075610757107581075910760107611076210763107641076510766107671076810769107701077110772107731077410775107761077710778107791078010781107821078310784107851078610787107881078910790107911079210793107941079510796107971079810799108001080110802108031080410805108061080710808108091081010811108121081310814108151081610817108181081910820108211082210823108241082510826108271082810829108301083110832108331083410835108361083710838108391084010841108421084310844108451084610847108481084910850108511085210853108541085510856108571085810859108601086110862108631086410865108661086710868108691087010871108721087310874108751087610877108781087910880108811088210883108841088510886108871088810889108901089110892108931089410895108961089710898108991090010901109021090310904109051090610907109081090910910109111091210913109141091510916109171091810919109201092110922109231092410925109261092710928109291093010931109321093310934109351093610937109381093910940109411094210943109441094510946109471094810949109501095110952109531095410955109561095710958109591096010961109621096310964109651096610967109681096910970109711097210973109741097510976109771097810979109801098110982109831098410985109861098710988109891099010991109921099310994109951099610997109981099911000110011100211003110041100511006110071100811009110101101111012110131101411015110161101711018110191102011021110221102311024110251102611027110281102911030110311103211033110341103511036110371103811039110401104111042110431104411045110461104711048110491105011051110521105311054110551105611057110581105911060110611106211063110641106511066110671106811069110701107111072110731107411075110761107711078110791108011081110821108311084110851108611087110881108911090110911109211093110941109511096110971109811099111001110111102111031110411105111061110711108111091111011111111121111311114111151111611117111181111911120111211112211123111241112511126111271112811129111301113111132111331113411135111361113711138111391114011141111421114311144111451114611147111481114911150111511115211153111541115511156111571115811159111601116111162111631116411165111661116711168111691117011171111721117311174111751117611177111781117911180111811118211183111841118511186111871118811189111901119111192111931119411195111961119711198111991120011201112021120311204112051120611207112081120911210112111121211213112141121511216112171121811219112201122111222112231122411225112261122711228112291123011231112321123311234112351123611237112381123911240112411124211243112441124511246112471124811249112501125111252112531125411255112561125711258112591126011261112621126311264112651126611267112681126911270112711127211273112741127511276112771127811279112801128111282112831128411285112861128711288112891129011291112921129311294112951129611297112981129911300113011130211303113041130511306113071130811309113101131111312113131131411315113161131711318113191132011321113221132311324113251132611327113281132911330113311133211333113341133511336113371133811339113401134111342113431134411345113461134711348113491135011351113521135311354113551135611357113581135911360113611136211363113641136511366113671136811369113701137111372113731137411375113761137711378113791138011381113821138311384113851138611387113881138911390113911139211393113941139511396113971139811399114001140111402114031140411405114061140711408114091141011411114121141311414114151141611417114181141911420114211142211423114241142511426114271142811429114301143111432114331143411435114361143711438114391144011441114421144311444114451144611447114481144911450114511145211453114541145511456114571145811459114601146111462114631146411465114661146711468114691147011471114721147311474114751147611477114781147911480114811148211483114841148511486114871148811489114901149111492114931149411495114961149711498114991150011501115021150311504115051150611507115081150911510115111151211513115141151511516115171151811519115201152111522115231152411525115261152711528115291153011531115321153311534115351153611537115381153911540115411154211543115441154511546115471154811549115501155111552115531155411555115561155711558115591156011561115621156311564115651156611567115681156911570115711157211573115741157511576115771157811579115801158111582115831158411585115861158711588115891159011591115921159311594115951159611597115981159911600116011160211603116041160511606116071160811609116101161111612116131161411615116161161711618116191162011621116221162311624116251162611627116281162911630116311163211633116341163511636116371163811639116401164111642116431164411645116461164711648116491165011651116521165311654116551165611657116581165911660116611166211663116641166511666116671166811669116701167111672116731167411675116761167711678116791168011681116821168311684116851168611687116881168911690116911169211693116941169511696116971169811699117001170111702117031170411705117061170711708117091171011711117121171311714117151171611717117181171911720117211172211723117241172511726117271172811729117301173111732117331173411735117361173711738117391174011741117421174311744117451174611747117481174911750117511175211753117541175511756117571175811759117601176111762117631176411765117661176711768117691177011771117721177311774117751177611777117781177911780117811178211783117841178511786117871178811789117901179111792117931179411795117961179711798117991180011801118021180311804118051180611807118081180911810118111181211813118141181511816118171181811819118201182111822118231182411825118261182711828118291183011831118321183311834118351183611837118381183911840118411184211843118441184511846118471184811849118501185111852118531185411855118561185711858118591186011861118621186311864118651186611867118681186911870118711187211873118741187511876118771187811879118801188111882118831188411885118861188711888118891189011891118921189311894118951189611897118981189911900119011190211903119041190511906119071190811909119101191111912119131191411915119161191711918119191192011921119221192311924119251192611927119281192911930119311193211933119341193511936119371193811939119401194111942119431194411945119461194711948119491195011951119521195311954119551195611957119581195911960119611196211963119641196511966119671196811969119701197111972119731197411975119761197711978119791198011981119821198311984119851198611987119881198911990119911199211993119941199511996119971199811999120001200112002120031200412005120061200712008120091201012011120121201312014120151201612017120181201912020120211202212023120241202512026120271202812029120301203112032120331203412035120361203712038120391204012041120421204312044120451204612047120481204912050120511205212053120541205512056120571205812059120601206112062120631206412065120661206712068120691207012071120721207312074120751207612077120781207912080120811208212083120841208512086120871208812089120901209112092120931209412095120961209712098120991210012101121021210312104121051210612107121081210912110121111211212113121141211512116121171211812119121201212112122121231212412125121261212712128121291213012131121321213312134121351213612137121381213912140121411214212143121441214512146121471214812149121501215112152121531215412155121561215712158121591216012161121621216312164121651216612167121681216912170121711217212173121741217512176121771217812179121801218112182121831218412185121861218712188121891219012191121921219312194121951219612197121981219912200122011220212203122041220512206122071220812209122101221112212122131221412215122161221712218122191222012221122221222312224122251222612227122281222912230122311223212233122341223512236122371223812239122401224112242122431224412245122461224712248122491225012251122521225312254122551225612257122581225912260122611226212263122641226512266122671226812269122701227112272122731227412275122761227712278122791228012281122821228312284122851228612287122881228912290122911229212293122941229512296122971229812299123001230112302123031230412305123061230712308123091231012311123121231312314123151231612317123181231912320123211232212323123241232512326123271232812329123301233112332123331233412335123361233712338123391234012341123421234312344123451234612347123481234912350123511235212353123541235512356123571235812359123601236112362123631236412365123661236712368123691237012371123721237312374123751237612377123781237912380123811238212383123841238512386123871238812389123901239112392123931239412395123961239712398123991240012401124021240312404124051240612407124081240912410124111241212413124141241512416124171241812419124201242112422124231242412425124261242712428124291243012431124321243312434124351243612437124381243912440124411244212443124441244512446124471244812449124501245112452124531245412455124561245712458124591246012461124621246312464124651246612467124681246912470124711247212473124741247512476124771247812479124801248112482124831248412485124861248712488124891249012491124921249312494124951249612497124981249912500125011250212503125041250512506125071250812509125101251112512125131251412515125161251712518125191252012521125221252312524125251252612527125281252912530125311253212533125341253512536125371253812539125401254112542125431254412545125461254712548125491255012551125521255312554125551255612557125581255912560125611256212563125641256512566125671256812569125701257112572125731257412575125761257712578125791258012581125821258312584125851258612587125881258912590125911259212593125941259512596125971259812599126001260112602126031260412605126061260712608126091261012611126121261312614126151261612617126181261912620126211262212623126241262512626126271262812629126301263112632126331263412635126361263712638126391264012641126421264312644126451264612647126481264912650126511265212653126541265512656126571265812659126601266112662126631266412665126661266712668126691267012671126721267312674126751267612677126781267912680126811268212683126841268512686126871268812689126901269112692126931269412695126961269712698126991270012701127021270312704127051270612707127081270912710127111271212713127141271512716127171271812719127201272112722127231272412725127261272712728127291273012731127321273312734127351273612737127381273912740127411274212743127441274512746127471274812749127501275112752127531275412755127561275712758127591276012761127621276312764127651276612767127681276912770127711277212773127741277512776127771277812779127801278112782127831278412785127861278712788127891279012791127921279312794127951279612797127981279912800128011280212803128041280512806128071280812809128101281112812128131281412815128161281712818128191282012821128221282312824128251282612827128281282912830128311283212833128341283512836128371283812839128401284112842128431284412845128461284712848128491285012851128521285312854128551285612857128581285912860128611286212863128641286512866128671286812869128701287112872128731287412875128761287712878128791288012881128821288312884128851288612887128881288912890128911289212893128941289512896128971289812899129001290112902129031290412905129061290712908129091291012911129121291312914129151291612917129181291912920129211292212923129241292512926129271292812929129301293112932129331293412935129361293712938129391294012941129421294312944129451294612947129481294912950129511295212953129541295512956129571295812959129601296112962129631296412965129661296712968129691297012971129721297312974129751297612977129781297912980129811298212983129841298512986129871298812989129901299112992129931299412995129961299712998129991300013001130021300313004130051300613007130081300913010130111301213013130141301513016130171301813019130201302113022130231302413025130261302713028130291303013031130321303313034130351303613037130381303913040130411304213043130441304513046130471304813049130501305113052130531305413055130561305713058130591306013061130621306313064130651306613067130681306913070130711307213073130741307513076130771307813079130801308113082130831308413085130861308713088130891309013091130921309313094130951309613097130981309913100131011310213103131041310513106131071310813109131101311113112131131311413115131161311713118131191312013121131221312313124131251312613127131281312913130131311313213133131341313513136131371313813139131401314113142131431314413145131461314713148131491315013151131521315313154131551315613157131581315913160131611316213163131641316513166131671316813169131701317113172131731317413175131761317713178131791318013181131821318313184131851318613187131881318913190131911319213193131941319513196131971319813199132001320113202132031320413205132061320713208132091321013211132121321313214132151321613217132181321913220132211322213223132241322513226132271322813229132301323113232132331323413235132361323713238132391324013241132421324313244132451324613247132481324913250132511325213253132541325513256132571325813259132601326113262132631326413265132661326713268132691327013271132721327313274132751327613277132781327913280132811328213283132841328513286132871328813289132901329113292132931329413295132961329713298132991330013301133021330313304133051330613307133081330913310133111331213313133141331513316133171331813319133201332113322133231332413325133261332713328133291333013331133321333313334133351333613337133381333913340133411334213343133441334513346133471334813349133501335113352133531335413355133561335713358133591336013361133621336313364133651336613367133681336913370133711337213373133741337513376133771337813379133801338113382133831338413385133861338713388133891339013391133921339313394133951339613397133981339913400134011340213403134041340513406134071340813409134101341113412134131341413415134161341713418134191342013421134221342313424134251342613427134281342913430134311343213433134341343513436134371343813439134401344113442134431344413445134461344713448134491345013451134521345313454134551345613457134581345913460134611346213463134641346513466134671346813469134701347113472134731347413475134761347713478134791348013481134821348313484134851348613487134881348913490134911349213493134941349513496134971349813499135001350113502135031350413505135061350713508135091351013511135121351313514135151351613517135181351913520135211352213523135241352513526135271352813529135301353113532135331353413535135361353713538135391354013541135421354313544135451354613547135481354913550135511355213553135541355513556135571355813559135601356113562135631356413565135661356713568135691357013571135721357313574135751357613577135781357913580135811358213583135841358513586135871358813589135901359113592135931359413595135961359713598135991360013601136021360313604136051360613607136081360913610136111361213613136141361513616136171361813619136201362113622136231362413625136261362713628136291363013631136321363313634136351363613637136381363913640136411364213643136441364513646136471364813649136501365113652136531365413655136561365713658136591366013661136621366313664136651366613667136681366913670136711367213673136741367513676136771367813679136801368113682136831368413685136861368713688136891369013691136921369313694136951369613697136981369913700137011370213703137041370513706137071370813709137101371113712137131371413715137161371713718137191372013721137221372313724137251372613727137281372913730137311373213733137341373513736137371373813739137401374113742137431374413745137461374713748137491375013751137521375313754137551375613757137581375913760137611376213763137641376513766137671376813769137701377113772137731377413775137761377713778137791378013781137821378313784137851378613787137881378913790137911379213793137941379513796137971379813799138001380113802138031380413805138061380713808138091381013811138121381313814138151381613817138181381913820138211382213823138241382513826138271382813829138301383113832138331383413835138361383713838138391384013841138421384313844138451384613847138481384913850138511385213853138541385513856138571385813859138601386113862138631386413865138661386713868138691387013871138721387313874138751387613877138781387913880138811388213883138841388513886138871388813889138901389113892138931389413895138961389713898138991390013901139021390313904139051390613907139081390913910139111391213913139141391513916139171391813919139201392113922139231392413925139261392713928139291393013931139321393313934139351393613937139381393913940139411394213943139441394513946139471394813949139501395113952139531395413955139561395713958139591396013961139621396313964139651396613967139681396913970139711397213973139741397513976139771397813979139801398113982139831398413985139861398713988139891399013991139921399313994139951399613997139981399914000140011400214003140041400514006140071400814009140101401114012140131401414015140161401714018140191402014021140221402314024140251402614027140281402914030140311403214033140341403514036140371403814039140401404114042140431404414045140461404714048140491405014051140521405314054140551405614057140581405914060140611406214063140641406514066140671406814069140701407114072140731407414075140761407714078140791408014081140821408314084140851408614087140881408914090140911409214093140941409514096140971409814099141001410114102141031410414105141061410714108141091411014111141121411314114141151411614117141181411914120141211412214123141241412514126141271412814129141301413114132141331413414135141361413714138141391414014141141421414314144141451414614147141481414914150141511415214153141541415514156141571415814159141601416114162141631416414165141661416714168141691417014171141721417314174141751417614177141781417914180141811418214183141841418514186141871418814189141901419114192141931419414195141961419714198141991420014201142021420314204142051420614207142081420914210142111421214213142141421514216142171421814219142201422114222142231422414225142261422714228142291423014231142321423314234142351423614237142381423914240142411424214243142441424514246142471424814249142501425114252142531425414255142561425714258142591426014261142621426314264142651426614267142681426914270142711427214273142741427514276142771427814279142801428114282142831428414285142861428714288142891429014291142921429314294142951429614297142981429914300143011430214303143041430514306143071430814309143101431114312143131431414315143161431714318143191432014321143221432314324143251432614327143281432914330143311433214333143341433514336143371433814339143401434114342143431434414345143461434714348143491435014351143521435314354143551435614357143581435914360143611436214363143641436514366143671436814369143701437114372143731437414375143761437714378143791438014381143821438314384143851438614387143881438914390143911439214393143941439514396143971439814399144001440114402144031440414405144061440714408144091441014411144121441314414144151441614417144181441914420144211442214423144241442514426144271442814429144301443114432144331443414435144361443714438144391444014441144421444314444144451444614447144481444914450144511445214453144541445514456144571445814459144601446114462144631446414465144661446714468144691447014471144721447314474144751447614477144781447914480144811448214483144841448514486144871448814489144901449114492144931449414495144961449714498144991450014501145021450314504145051450614507145081450914510145111451214513145141451514516145171451814519145201452114522145231452414525145261452714528145291453014531145321453314534145351453614537145381453914540145411454214543145441454514546145471454814549145501455114552145531455414555145561455714558145591456014561145621456314564145651456614567145681456914570145711457214573145741457514576145771457814579145801458114582145831458414585145861458714588145891459014591145921459314594145951459614597145981459914600146011460214603146041460514606146071460814609146101461114612146131461414615146161461714618146191462014621146221462314624146251462614627146281462914630146311463214633146341463514636146371463814639146401464114642146431464414645146461464714648146491465014651146521465314654146551465614657146581465914660146611466214663146641466514666146671466814669146701467114672146731467414675146761467714678146791468014681146821468314684146851468614687146881468914690146911469214693146941469514696146971469814699147001470114702147031470414705147061470714708147091471014711147121471314714147151471614717147181471914720147211472214723147241472514726147271472814729147301473114732147331473414735147361473714738147391474014741147421474314744147451474614747147481474914750147511475214753147541475514756147571475814759147601476114762147631476414765147661476714768147691477014771147721477314774147751477614777147781477914780147811478214783147841478514786147871478814789147901479114792147931479414795147961479714798147991480014801148021480314804148051480614807148081480914810148111481214813148141481514816148171481814819148201482114822148231482414825148261482714828148291483014831148321483314834148351483614837148381483914840148411484214843148441484514846148471484814849148501485114852148531485414855148561485714858148591486014861148621486314864148651486614867148681486914870148711487214873148741487514876148771487814879148801488114882148831488414885148861488714888148891489014891148921489314894148951489614897148981489914900149011490214903149041490514906149071490814909149101491114912149131491414915149161491714918149191492014921149221492314924149251492614927149281492914930149311493214933149341493514936149371493814939149401494114942149431494414945149461494714948149491495014951149521495314954149551495614957149581495914960149611496214963149641496514966149671496814969149701497114972149731497414975149761497714978149791498014981149821498314984149851498614987149881498914990149911499214993149941499514996149971499814999150001500115002150031500415005150061500715008150091501015011150121501315014150151501615017150181501915020150211502215023150241502515026150271502815029150301503115032150331503415035150361503715038150391504015041150421504315044150451504615047150481504915050150511505215053150541505515056150571505815059150601506115062150631506415065150661506715068150691507015071150721507315074150751507615077150781507915080150811508215083150841508515086150871508815089150901509115092150931509415095150961509715098150991510015101151021510315104151051510615107151081510915110151111511215113151141511515116151171511815119151201512115122151231512415125151261512715128151291513015131151321513315134151351513615137151381513915140151411514215143151441514515146151471514815149151501515115152151531515415155151561515715158151591516015161151621516315164151651516615167151681516915170151711517215173151741517515176151771517815179151801518115182151831518415185151861518715188151891519015191151921519315194151951519615197151981519915200152011520215203152041520515206152071520815209152101521115212152131521415215152161521715218152191522015221152221522315224152251522615227152281522915230152311523215233152341523515236152371523815239152401524115242152431524415245152461524715248152491525015251152521525315254152551525615257152581525915260152611526215263152641526515266152671526815269152701527115272152731527415275152761527715278152791528015281152821528315284152851528615287152881528915290152911529215293152941529515296152971529815299153001530115302153031530415305153061530715308153091531015311153121531315314153151531615317153181531915320153211532215323153241532515326153271532815329153301533115332153331533415335153361533715338153391534015341153421534315344153451534615347153481534915350153511535215353153541535515356153571535815359153601536115362153631536415365153661536715368153691537015371153721537315374153751537615377153781537915380153811538215383153841538515386153871538815389153901539115392153931539415395153961539715398153991540015401154021540315404154051540615407154081540915410154111541215413154141541515416154171541815419154201542115422154231542415425154261542715428154291543015431154321543315434154351543615437154381543915440154411544215443154441544515446154471544815449154501545115452154531545415455154561545715458154591546015461154621546315464154651546615467154681546915470154711547215473154741547515476154771547815479154801548115482154831548415485154861548715488154891549015491154921549315494154951549615497154981549915500155011550215503155041550515506155071550815509155101551115512155131551415515155161551715518155191552015521155221552315524155251552615527155281552915530155311553215533155341553515536155371553815539155401554115542155431554415545155461554715548155491555015551155521555315554155551555615557155581555915560155611556215563155641556515566155671556815569155701557115572155731557415575155761557715578155791558015581155821558315584155851558615587155881558915590155911559215593155941559515596155971559815599156001560115602156031560415605156061560715608156091561015611156121561315614156151561615617156181561915620156211562215623156241562515626156271562815629156301563115632156331563415635156361563715638156391564015641156421564315644156451564615647156481564915650156511565215653156541565515656156571565815659156601566115662156631566415665156661566715668156691567015671156721567315674156751567615677156781567915680156811568215683156841568515686156871568815689156901569115692156931569415695156961569715698156991570015701157021570315704157051570615707157081570915710157111571215713157141571515716157171571815719157201572115722157231572415725157261572715728157291573015731157321573315734157351573615737157381573915740157411574215743157441574515746157471574815749157501575115752157531575415755157561575715758157591576015761157621576315764157651576615767157681576915770157711577215773157741577515776157771577815779157801578115782157831578415785157861578715788157891579015791157921579315794157951579615797157981579915800158011580215803158041580515806158071580815809158101581115812158131581415815158161581715818158191582015821158221582315824158251582615827158281582915830158311583215833158341583515836158371583815839158401584115842158431584415845158461584715848158491585015851158521585315854158551585615857158581585915860158611586215863158641586515866158671586815869158701587115872158731587415875158761587715878158791588015881158821588315884158851588615887158881588915890158911589215893158941589515896158971589815899159001590115902159031590415905159061590715908159091591015911159121591315914159151591615917159181591915920159211592215923159241592515926159271592815929159301593115932159331593415935159361593715938159391594015941159421594315944159451594615947159481594915950159511595215953159541595515956159571595815959159601596115962159631596415965159661596715968159691597015971159721597315974159751597615977159781597915980159811598215983159841598515986159871598815989159901599115992159931599415995159961599715998159991600016001160021600316004160051600616007160081600916010160111601216013160141601516016160171601816019160201602116022160231602416025160261602716028160291603016031160321603316034160351603616037160381603916040160411604216043160441604516046160471604816049160501605116052160531605416055160561605716058160591606016061160621606316064160651606616067160681606916070160711607216073160741607516076160771607816079160801608116082160831608416085160861608716088160891609016091160921609316094160951609616097160981609916100161011610216103161041610516106161071610816109161101611116112161131611416115161161611716118161191612016121161221612316124161251612616127161281612916130161311613216133161341613516136161371613816139161401614116142161431614416145161461614716148161491615016151161521615316154161551615616157161581615916160161611616216163161641616516166161671616816169161701617116172161731617416175161761617716178161791618016181161821618316184161851618616187161881618916190161911619216193161941619516196161971619816199162001620116202162031620416205162061620716208162091621016211162121621316214162151621616217162181621916220162211622216223162241622516226162271622816229162301623116232162331623416235162361623716238162391624016241162421624316244162451624616247162481624916250162511625216253162541625516256162571625816259162601626116262162631626416265162661626716268162691627016271162721627316274162751627616277162781627916280162811628216283162841628516286162871628816289162901629116292162931629416295162961629716298162991630016301163021630316304163051630616307163081630916310163111631216313163141631516316163171631816319163201632116322163231632416325163261632716328163291633016331163321633316334163351633616337163381633916340163411634216343163441634516346163471634816349163501635116352163531635416355163561635716358163591636016361163621636316364163651636616367163681636916370163711637216373163741637516376163771637816379163801638116382163831638416385163861638716388163891639016391163921639316394163951639616397163981639916400164011640216403164041640516406164071640816409164101641116412164131641416415164161641716418164191642016421164221642316424164251642616427164281642916430164311643216433164341643516436164371643816439164401644116442164431644416445164461644716448164491645016451164521645316454164551645616457164581645916460164611646216463164641646516466164671646816469164701647116472164731647416475164761647716478164791648016481164821648316484164851648616487164881648916490164911649216493164941649516496164971649816499165001650116502165031650416505165061650716508165091651016511165121651316514165151651616517165181651916520165211652216523165241652516526165271652816529165301653116532165331653416535165361653716538165391654016541165421654316544165451654616547165481654916550165511655216553165541655516556165571655816559165601656116562165631656416565165661656716568165691657016571165721657316574165751657616577165781657916580165811658216583165841658516586165871658816589165901659116592165931659416595165961659716598165991660016601166021660316604166051660616607166081660916610166111661216613166141661516616166171661816619166201662116622166231662416625166261662716628166291663016631166321663316634166351663616637166381663916640166411664216643166441664516646166471664816649166501665116652166531665416655166561665716658166591666016661166621666316664166651666616667166681666916670166711667216673166741667516676166771667816679166801668116682166831668416685166861668716688166891669016691166921669316694166951669616697166981669916700167011670216703167041670516706167071670816709167101671116712167131671416715167161671716718167191672016721167221672316724167251672616727167281672916730167311673216733167341673516736167371673816739167401674116742167431674416745167461674716748167491675016751167521675316754167551675616757167581675916760167611676216763167641676516766167671676816769167701677116772167731677416775167761677716778167791678016781167821678316784167851678616787167881678916790167911679216793167941679516796167971679816799168001680116802168031680416805168061680716808168091681016811168121681316814168151681616817168181681916820168211682216823168241682516826168271682816829168301683116832168331683416835168361683716838168391684016841168421684316844168451684616847168481684916850168511685216853168541685516856168571685816859168601686116862168631686416865168661686716868168691687016871168721687316874168751687616877168781687916880168811688216883168841688516886168871688816889168901689116892168931689416895168961689716898168991690016901169021690316904169051690616907169081690916910169111691216913169141691516916169171691816919169201692116922169231692416925169261692716928169291693016931169321693316934169351693616937169381693916940169411694216943169441694516946169471694816949169501695116952169531695416955169561695716958169591696016961169621696316964169651696616967169681696916970169711697216973169741697516976169771697816979169801698116982169831698416985169861698716988169891699016991169921699316994169951699616997169981699917000170011700217003170041700517006170071700817009170101701117012170131701417015170161701717018170191702017021170221702317024170251702617027170281702917030170311703217033170341703517036170371703817039170401704117042170431704417045170461704717048170491705017051170521705317054170551705617057170581705917060170611706217063170641706517066170671706817069170701707117072170731707417075170761707717078170791708017081170821708317084170851708617087170881708917090170911709217093170941709517096170971709817099171001710117102171031710417105171061710717108171091711017111171121711317114171151711617117171181711917120171211712217123171241712517126171271712817129171301713117132171331713417135171361713717138171391714017141171421714317144171451714617147171481714917150171511715217153171541715517156171571715817159171601716117162171631716417165171661716717168171691717017171171721717317174171751717617177171781717917180171811718217183171841718517186171871718817189171901719117192171931719417195171961719717198171991720017201172021720317204172051720617207172081720917210172111721217213172141721517216172171721817219172201722117222172231722417225172261722717228172291723017231172321723317234172351723617237172381723917240172411724217243172441724517246172471724817249172501725117252172531725417255172561725717258172591726017261172621726317264172651726617267172681726917270172711727217273172741727517276172771727817279172801728117282172831728417285172861728717288172891729017291172921729317294172951729617297172981729917300173011730217303173041730517306173071730817309173101731117312173131731417315173161731717318173191732017321173221732317324173251732617327173281732917330173311733217333173341733517336173371733817339173401734117342173431734417345173461734717348173491735017351173521735317354173551735617357173581735917360173611736217363173641736517366173671736817369173701737117372173731737417375173761737717378173791738017381173821738317384173851738617387173881738917390173911739217393173941739517396173971739817399174001740117402174031740417405174061740717408174091741017411174121741317414174151741617417174181741917420174211742217423174241742517426174271742817429174301743117432174331743417435174361743717438174391744017441174421744317444174451744617447174481744917450174511745217453174541745517456174571745817459174601746117462174631746417465174661746717468174691747017471174721747317474174751747617477174781747917480174811748217483174841748517486174871748817489174901749117492174931749417495174961749717498174991750017501175021750317504175051750617507175081750917510175111751217513175141751517516175171751817519175201752117522175231752417525175261752717528175291753017531175321753317534175351753617537175381753917540175411754217543175441754517546175471754817549175501755117552175531755417555175561755717558175591756017561175621756317564175651756617567175681756917570175711757217573175741757517576175771757817579175801758117582175831758417585175861758717588175891759017591175921759317594175951759617597175981759917600176011760217603176041760517606176071760817609176101761117612176131761417615176161761717618176191762017621176221762317624176251762617627176281762917630176311763217633176341763517636176371763817639176401764117642176431764417645176461764717648176491765017651176521765317654176551765617657176581765917660176611766217663176641766517666176671766817669176701767117672176731767417675176761767717678176791768017681176821768317684176851768617687176881768917690176911769217693176941769517696176971769817699177001770117702177031770417705177061770717708177091771017711177121771317714177151771617717177181771917720177211772217723177241772517726177271772817729177301773117732177331773417735177361773717738177391774017741177421774317744177451774617747177481774917750177511775217753177541775517756177571775817759177601776117762177631776417765177661776717768177691777017771177721777317774177751777617777177781777917780177811778217783177841778517786177871778817789177901779117792177931779417795177961779717798177991780017801178021780317804178051780617807178081780917810178111781217813178141781517816178171781817819178201782117822178231782417825178261782717828178291783017831178321783317834178351783617837178381783917840178411784217843178441784517846178471784817849178501785117852178531785417855178561785717858178591786017861178621786317864178651786617867178681786917870178711787217873178741787517876178771787817879178801788117882178831788417885178861788717888178891789017891178921789317894178951789617897178981789917900179011790217903179041790517906179071790817909179101791117912179131791417915179161791717918179191792017921179221792317924179251792617927179281792917930179311793217933179341793517936179371793817939179401794117942179431794417945179461794717948179491795017951179521795317954179551795617957179581795917960179611796217963179641796517966179671796817969179701797117972179731797417975179761797717978179791798017981179821798317984179851798617987179881798917990179911799217993179941799517996179971799817999180001800118002180031800418005180061800718008180091801018011180121801318014180151801618017180181801918020180211802218023180241802518026180271802818029180301803118032180331803418035180361803718038180391804018041180421804318044180451804618047180481804918050180511805218053180541805518056180571805818059180601806118062180631806418065180661806718068180691807018071180721807318074180751807618077180781807918080180811808218083180841808518086180871808818089180901809118092180931809418095180961809718098180991810018101181021810318104181051810618107181081810918110181111811218113181141811518116181171811818119181201812118122181231812418125181261812718128181291813018131181321813318134181351813618137181381813918140181411814218143181441814518146181471814818149181501815118152181531815418155181561815718158181591816018161181621816318164181651816618167181681816918170181711817218173181741817518176181771817818179181801818118182181831818418185181861818718188181891819018191181921819318194181951819618197181981819918200182011820218203182041820518206182071820818209182101821118212182131821418215182161821718218182191822018221182221822318224182251822618227182281822918230182311823218233182341823518236182371823818239182401824118242182431824418245182461824718248182491825018251182521825318254182551825618257182581825918260182611826218263182641826518266182671826818269182701827118272182731827418275182761827718278182791828018281182821828318284182851828618287182881828918290182911829218293182941829518296182971829818299183001830118302183031830418305183061830718308183091831018311183121831318314183151831618317183181831918320183211832218323183241832518326183271832818329183301833118332183331833418335183361833718338183391834018341183421834318344183451834618347183481834918350183511835218353183541835518356183571835818359183601836118362183631836418365183661836718368183691837018371183721837318374183751837618377183781837918380183811838218383183841838518386183871838818389183901839118392183931839418395183961839718398183991840018401184021840318404184051840618407184081840918410184111841218413184141841518416184171841818419184201842118422184231842418425184261842718428184291843018431184321843318434184351843618437184381843918440184411844218443184441844518446184471844818449184501845118452184531845418455184561845718458184591846018461184621846318464184651846618467184681846918470184711847218473184741847518476184771847818479184801848118482184831848418485184861848718488184891849018491184921849318494184951849618497184981849918500185011850218503185041850518506185071850818509185101851118512185131851418515185161851718518185191852018521185221852318524185251852618527185281852918530185311853218533185341853518536185371853818539185401854118542185431854418545185461854718548185491855018551185521855318554185551855618557185581855918560185611856218563185641856518566185671856818569185701857118572185731857418575185761857718578185791858018581185821858318584185851858618587185881858918590185911859218593185941859518596185971859818599186001860118602186031860418605186061860718608186091861018611186121861318614186151861618617186181861918620186211862218623186241862518626186271862818629186301863118632186331863418635186361863718638186391864018641186421864318644186451864618647186481864918650186511865218653186541865518656186571865818659186601866118662186631866418665186661866718668186691867018671186721867318674186751867618677186781867918680186811868218683186841868518686186871868818689186901869118692186931869418695186961869718698186991870018701187021870318704187051870618707187081870918710187111871218713187141871518716187171871818719187201872118722187231872418725187261872718728187291873018731187321873318734187351873618737187381873918740187411874218743187441874518746187471874818749187501875118752187531875418755187561875718758187591876018761187621876318764187651876618767187681876918770187711877218773187741877518776187771877818779187801878118782187831878418785187861878718788187891879018791187921879318794187951879618797187981879918800188011880218803188041880518806188071880818809188101881118812188131881418815188161881718818188191882018821188221882318824188251882618827188281882918830188311883218833188341883518836188371883818839188401884118842188431884418845188461884718848188491885018851188521885318854188551885618857188581885918860188611886218863188641886518866188671886818869188701887118872188731887418875188761887718878188791888018881188821888318884188851888618887188881888918890188911889218893188941889518896188971889818899189001890118902189031890418905189061890718908189091891018911189121891318914189151891618917189181891918920189211892218923189241892518926189271892818929189301893118932189331893418935189361893718938189391894018941189421894318944189451894618947189481894918950189511895218953189541895518956189571895818959189601896118962189631896418965189661896718968189691897018971189721897318974189751897618977189781897918980189811898218983189841898518986189871898818989189901899118992189931899418995189961899718998189991900019001190021900319004190051900619007190081900919010190111901219013190141901519016190171901819019190201902119022190231902419025190261902719028190291903019031190321903319034190351903619037190381903919040190411904219043190441904519046190471904819049190501905119052190531905419055190561905719058190591906019061190621906319064190651906619067190681906919070190711907219073190741907519076190771907819079190801908119082190831908419085190861908719088190891909019091190921909319094190951909619097190981909919100191011910219103191041910519106191071910819109191101911119112191131911419115191161911719118191191912019121191221912319124191251912619127191281912919130191311913219133191341913519136191371913819139191401914119142191431914419145191461914719148191491915019151191521915319154191551915619157191581915919160191611916219163191641916519166191671916819169191701917119172191731917419175191761917719178191791918019181191821918319184191851918619187191881918919190191911919219193191941919519196191971919819199192001920119202192031920419205192061920719208192091921019211192121921319214192151921619217192181921919220192211922219223192241922519226192271922819229192301923119232192331923419235192361923719238192391924019241192421924319244192451924619247192481924919250192511925219253192541925519256192571925819259192601926119262192631926419265192661926719268192691927019271192721927319274192751927619277192781927919280192811928219283192841928519286192871928819289192901929119292192931929419295192961929719298192991930019301193021930319304193051930619307193081930919310193111931219313193141931519316193171931819319193201932119322193231932419325193261932719328193291933019331193321933319334193351933619337193381933919340193411934219343193441934519346193471934819349193501935119352193531935419355193561935719358193591936019361193621936319364193651936619367193681936919370193711937219373193741937519376193771937819379193801938119382193831938419385193861938719388193891939019391193921939319394193951939619397193981939919400194011940219403194041940519406194071940819409194101941119412194131941419415194161941719418194191942019421194221942319424194251942619427194281942919430194311943219433194341943519436194371943819439194401944119442194431944419445194461944719448194491945019451194521945319454194551945619457194581945919460194611946219463194641946519466194671946819469194701947119472194731947419475194761947719478194791948019481194821948319484194851948619487194881948919490194911949219493194941949519496194971949819499195001950119502195031950419505195061950719508195091951019511195121951319514195151951619517195181951919520195211952219523195241952519526195271952819529195301953119532195331953419535195361953719538195391954019541195421954319544195451954619547195481954919550195511955219553195541955519556195571955819559195601956119562195631956419565195661956719568195691957019571195721957319574195751957619577195781957919580195811958219583195841958519586195871958819589195901959119592195931959419595195961959719598195991960019601196021960319604196051960619607196081960919610196111961219613196141961519616196171961819619196201962119622196231962419625196261962719628196291963019631196321963319634196351963619637196381963919640196411964219643196441964519646196471964819649196501965119652196531965419655196561965719658196591966019661196621966319664196651966619667196681966919670196711967219673196741967519676196771967819679196801968119682196831968419685196861968719688196891969019691196921969319694196951969619697196981969919700197011970219703197041970519706197071970819709197101971119712197131971419715197161971719718197191972019721197221972319724197251972619727197281972919730197311973219733197341973519736197371973819739197401974119742197431974419745197461974719748197491975019751197521975319754197551975619757197581975919760197611976219763197641976519766197671976819769197701977119772197731977419775197761977719778197791978019781197821978319784197851978619787197881978919790197911979219793197941979519796197971979819799198001980119802198031980419805198061980719808198091981019811198121981319814198151981619817198181981919820198211982219823198241982519826198271982819829198301983119832198331983419835198361983719838198391984019841198421984319844198451984619847198481984919850198511985219853198541985519856198571985819859198601986119862198631986419865198661986719868198691987019871198721987319874198751987619877198781987919880198811988219883198841988519886198871988819889198901989119892198931989419895198961989719898198991990019901199021990319904199051990619907199081990919910199111991219913199141991519916199171991819919199201992119922199231992419925199261992719928199291993019931199321993319934199351993619937199381993919940199411994219943199441994519946199471994819949199501995119952199531995419955199561995719958199591996019961199621996319964199651996619967199681996919970199711997219973199741997519976199771997819979199801998119982199831998419985199861998719988199891999019991199921999319994199951999619997199981999920000200012000220003200042000520006200072000820009200102001120012200132001420015200162001720018200192002020021200222002320024200252002620027200282002920030200312003220033200342003520036200372003820039200402004120042200432004420045200462004720048200492005020051200522005320054200552005620057200582005920060200612006220063200642006520066200672006820069200702007120072200732007420075200762007720078200792008020081200822008320084200852008620087200882008920090200912009220093200942009520096200972009820099201002010120102201032010420105201062010720108201092011020111201122011320114201152011620117201182011920120201212012220123201242012520126201272012820129201302013120132201332013420135201362013720138201392014020141201422014320144201452014620147201482014920150201512015220153201542015520156201572015820159201602016120162201632016420165201662016720168201692017020171201722017320174201752017620177201782017920180201812018220183201842018520186201872018820189201902019120192201932019420195201962019720198201992020020201202022020320204202052020620207202082020920210202112021220213202142021520216202172021820219202202022120222202232022420225202262022720228202292023020231202322023320234202352023620237202382023920240202412024220243202442024520246202472024820249202502025120252202532025420255202562025720258202592026020261202622026320264202652026620267202682026920270202712027220273202742027520276202772027820279202802028120282202832028420285202862028720288202892029020291202922029320294202952029620297202982029920300203012030220303203042030520306203072030820309203102031120312203132031420315203162031720318203192032020321203222032320324203252032620327203282032920330203312033220333203342033520336203372033820339203402034120342203432034420345203462034720348203492035020351203522035320354203552035620357203582035920360203612036220363203642036520366203672036820369203702037120372203732037420375203762037720378203792038020381203822038320384203852038620387203882038920390203912039220393203942039520396203972039820399204002040120402204032040420405204062040720408204092041020411204122041320414204152041620417204182041920420204212042220423204242042520426204272042820429204302043120432204332043420435204362043720438204392044020441204422044320444204452044620447204482044920450204512045220453204542045520456204572045820459204602046120462204632046420465204662046720468204692047020471204722047320474204752047620477204782047920480204812048220483204842048520486204872048820489204902049120492204932049420495204962049720498204992050020501205022050320504205052050620507205082050920510205112051220513205142051520516205172051820519205202052120522205232052420525205262052720528205292053020531205322053320534205352053620537205382053920540205412054220543205442054520546205472054820549205502055120552205532055420555205562055720558205592056020561205622056320564205652056620567205682056920570205712057220573205742057520576205772057820579205802058120582205832058420585205862058720588205892059020591205922059320594205952059620597205982059920600206012060220603206042060520606206072060820609206102061120612206132061420615206162061720618206192062020621206222062320624206252062620627206282062920630206312063220633206342063520636206372063820639206402064120642206432064420645206462064720648206492065020651206522065320654206552065620657206582065920660206612066220663206642066520666206672066820669206702067120672206732067420675206762067720678206792068020681206822068320684206852068620687206882068920690206912069220693206942069520696206972069820699207002070120702207032070420705207062070720708207092071020711207122071320714207152071620717207182071920720207212072220723207242072520726207272072820729207302073120732207332073420735207362073720738207392074020741207422074320744207452074620747207482074920750207512075220753207542075520756207572075820759207602076120762207632076420765207662076720768207692077020771207722077320774207752077620777207782077920780207812078220783207842078520786207872078820789207902079120792207932079420795207962079720798207992080020801208022080320804208052080620807208082080920810208112081220813208142081520816208172081820819208202082120822208232082420825208262082720828208292083020831208322083320834208352083620837208382083920840208412084220843208442084520846208472084820849208502085120852208532085420855208562085720858208592086020861208622086320864208652086620867208682086920870208712087220873208742087520876208772087820879208802088120882208832088420885208862088720888208892089020891208922089320894208952089620897208982089920900209012090220903209042090520906209072090820909209102091120912209132091420915209162091720918209192092020921209222092320924209252092620927209282092920930209312093220933209342093520936209372093820939209402094120942209432094420945209462094720948209492095020951209522095320954209552095620957209582095920960209612096220963209642096520966209672096820969209702097120972209732097420975209762097720978209792098020981209822098320984209852098620987209882098920990209912099220993209942099520996209972099820999210002100121002210032100421005210062100721008210092101021011210122101321014210152101621017210182101921020210212102221023210242102521026210272102821029210302103121032210332103421035210362103721038210392104021041210422104321044210452104621047210482104921050210512105221053210542105521056210572105821059210602106121062210632106421065210662106721068210692107021071210722107321074210752107621077210782107921080210812108221083210842108521086210872108821089210902109121092210932109421095210962109721098210992110021101211022110321104211052110621107211082110921110211112111221113211142111521116211172111821119211202112121122211232112421125211262112721128211292113021131211322113321134211352113621137211382113921140211412114221143211442114521146211472114821149211502115121152211532115421155211562115721158211592116021161211622116321164211652116621167211682116921170211712117221173211742117521176211772117821179211802118121182211832118421185211862118721188211892119021191211922119321194211952119621197211982119921200212012120221203212042120521206212072120821209212102121121212212132121421215212162121721218212192122021221212222122321224212252122621227212282122921230212312123221233212342123521236212372123821239212402124121242212432124421245212462124721248212492125021251212522125321254212552125621257212582125921260212612126221263212642126521266212672126821269212702127121272212732127421275212762127721278212792128021281212822128321284212852128621287212882128921290212912129221293212942129521296212972129821299213002130121302213032130421305213062130721308213092131021311213122131321314213152131621317213182131921320213212132221323213242132521326213272132821329213302133121332213332133421335213362133721338213392134021341213422134321344213452134621347213482134921350213512135221353213542135521356213572135821359213602136121362213632136421365213662136721368213692137021371213722137321374213752137621377213782137921380213812138221383213842138521386213872138821389213902139121392213932139421395213962139721398213992140021401214022140321404214052140621407214082140921410214112141221413214142141521416214172141821419214202142121422214232142421425214262142721428214292143021431214322143321434214352143621437214382143921440214412144221443214442144521446214472144821449214502145121452214532145421455214562145721458214592146021461214622146321464214652146621467214682146921470214712147221473214742147521476214772147821479214802148121482214832148421485214862148721488214892149021491214922149321494214952149621497214982149921500215012150221503215042150521506215072150821509215102151121512215132151421515215162151721518215192152021521215222152321524215252152621527215282152921530215312153221533215342153521536215372153821539215402154121542215432154421545215462154721548215492155021551215522155321554215552155621557215582155921560215612156221563215642156521566215672156821569215702157121572215732157421575215762157721578215792158021581215822158321584215852158621587215882158921590215912159221593215942159521596215972159821599216002160121602216032160421605216062160721608216092161021611216122161321614216152161621617216182161921620216212162221623216242162521626216272162821629216302163121632216332163421635216362163721638216392164021641216422164321644216452164621647216482164921650216512165221653216542165521656216572165821659216602166121662216632166421665216662166721668216692167021671216722167321674216752167621677216782167921680216812168221683216842168521686216872168821689216902169121692216932169421695216962169721698216992170021701217022170321704217052170621707217082170921710217112171221713217142171521716217172171821719217202172121722217232172421725217262172721728217292173021731217322173321734217352173621737217382173921740217412174221743217442174521746217472174821749217502175121752217532175421755217562175721758217592176021761217622176321764217652176621767217682176921770217712177221773217742177521776217772177821779217802178121782217832178421785217862178721788217892179021791217922179321794217952179621797217982179921800218012180221803218042180521806218072180821809218102181121812218132181421815218162181721818218192182021821218222182321824218252182621827218282182921830218312183221833218342183521836218372183821839218402184121842218432184421845218462184721848218492185021851218522185321854218552185621857218582185921860218612186221863218642186521866218672186821869218702187121872218732187421875218762187721878218792188021881218822188321884218852188621887218882188921890218912189221893218942189521896218972189821899219002190121902219032190421905219062190721908219092191021911219122191321914219152191621917219182191921920219212192221923219242192521926219272192821929219302193121932219332193421935219362193721938219392194021941219422194321944219452194621947219482194921950219512195221953219542195521956219572195821959219602196121962219632196421965219662196721968219692197021971219722197321974219752197621977219782197921980219812198221983219842198521986219872198821989219902199121992219932199421995219962199721998219992200022001220022200322004220052200622007220082200922010220112201222013220142201522016220172201822019220202202122022220232202422025220262202722028220292203022031220322203322034220352203622037220382203922040220412204222043220442204522046220472204822049220502205122052220532205422055220562205722058220592206022061220622206322064220652206622067220682206922070220712207222073220742207522076220772207822079220802208122082220832208422085220862208722088220892209022091220922209322094220952209622097220982209922100221012210222103221042210522106221072210822109221102211122112221132211422115221162211722118221192212022121221222212322124221252212622127221282212922130221312213222133221342213522136221372213822139221402214122142221432214422145221462214722148221492215022151221522215322154221552215622157221582215922160221612216222163221642216522166221672216822169221702217122172221732217422175221762217722178221792218022181221822218322184221852218622187221882218922190221912219222193221942219522196221972219822199222002220122202222032220422205222062220722208222092221022211222122221322214222152221622217222182221922220222212222222223222242222522226222272222822229222302223122232222332223422235222362223722238222392224022241222422224322244222452224622247222482224922250222512225222253222542225522256222572225822259222602226122262222632226422265222662226722268222692227022271222722227322274222752227622277222782227922280222812228222283222842228522286222872228822289222902229122292222932229422295222962229722298222992230022301223022230322304223052230622307223082230922310223112231222313223142231522316223172231822319223202232122322223232232422325223262232722328223292233022331223322233322334223352233622337223382233922340223412234222343223442234522346223472234822349223502235122352223532235422355223562235722358223592236022361223622236322364223652236622367223682236922370223712237222373223742237522376223772237822379223802238122382223832238422385223862238722388223892239022391223922239322394223952239622397223982239922400224012240222403224042240522406224072240822409224102241122412224132241422415224162241722418224192242022421224222242322424224252242622427224282242922430224312243222433224342243522436224372243822439224402244122442224432244422445224462244722448224492245022451224522245322454224552245622457224582245922460224612246222463224642246522466224672246822469224702247122472224732247422475224762247722478224792248022481224822248322484224852248622487224882248922490224912249222493224942249522496224972249822499225002250122502225032250422505225062250722508225092251022511225122251322514225152251622517225182251922520225212252222523225242252522526225272252822529225302253122532225332253422535225362253722538225392254022541225422254322544225452254622547225482254922550225512255222553225542255522556225572255822559225602256122562225632256422565225662256722568225692257022571225722257322574225752257622577225782257922580225812258222583225842258522586225872258822589225902259122592225932259422595225962259722598225992260022601226022260322604226052260622607226082260922610226112261222613226142261522616226172261822619226202262122622226232262422625226262262722628226292263022631226322263322634226352263622637226382263922640226412264222643226442264522646226472264822649226502265122652226532265422655226562265722658226592266022661226622266322664226652266622667226682266922670226712267222673226742267522676226772267822679226802268122682226832268422685226862268722688226892269022691226922269322694226952269622697226982269922700227012270222703227042270522706227072270822709227102271122712227132271422715227162271722718227192272022721227222272322724227252272622727227282272922730227312273222733227342273522736227372273822739227402274122742227432274422745227462274722748227492275022751227522275322754227552275622757227582275922760227612276222763227642276522766227672276822769227702277122772227732277422775227762277722778227792278022781227822278322784227852278622787227882278922790227912279222793227942279522796227972279822799228002280122802228032280422805228062280722808228092281022811228122281322814228152281622817228182281922820228212282222823228242282522826228272282822829228302283122832228332283422835228362283722838228392284022841228422284322844228452284622847228482284922850228512285222853228542285522856228572285822859228602286122862228632286422865228662286722868228692287022871228722287322874228752287622877228782287922880228812288222883228842288522886228872288822889228902289122892228932289422895228962289722898228992290022901229022290322904229052290622907229082290922910229112291222913229142291522916229172291822919229202292122922229232292422925229262292722928229292293022931229322293322934229352293622937229382293922940229412294222943229442294522946229472294822949229502295122952229532295422955229562295722958229592296022961229622296322964229652296622967229682296922970229712297222973229742297522976229772297822979229802298122982229832298422985229862298722988229892299022991229922299322994229952299622997229982299923000230012300223003230042300523006230072300823009230102301123012230132301423015230162301723018230192302023021230222302323024230252302623027230282302923030230312303223033230342303523036230372303823039230402304123042230432304423045230462304723048230492305023051230522305323054230552305623057230582305923060230612306223063230642306523066230672306823069230702307123072230732307423075230762307723078230792308023081230822308323084230852308623087230882308923090230912309223093230942309523096230972309823099231002310123102231032310423105231062310723108231092311023111231122311323114231152311623117231182311923120231212312223123231242312523126231272312823129231302313123132231332313423135231362313723138231392314023141231422314323144231452314623147231482314923150231512315223153231542315523156231572315823159231602316123162231632316423165231662316723168231692317023171231722317323174231752317623177231782317923180231812318223183231842318523186231872318823189231902319123192231932319423195231962319723198231992320023201232022320323204232052320623207232082320923210232112321223213232142321523216232172321823219232202322123222232232322423225232262322723228232292323023231232322323323234232352323623237232382323923240232412324223243232442324523246232472324823249232502325123252232532325423255232562325723258232592326023261232622326323264232652326623267232682326923270232712327223273232742327523276232772327823279232802328123282232832328423285232862328723288232892329023291232922329323294232952329623297232982329923300233012330223303233042330523306233072330823309233102331123312233132331423315233162331723318233192332023321233222332323324233252332623327233282332923330233312333223333233342333523336233372333823339233402334123342233432334423345233462334723348233492335023351233522335323354233552335623357233582335923360233612336223363233642336523366233672336823369233702337123372233732337423375233762337723378233792338023381233822338323384233852338623387233882338923390233912339223393233942339523396233972339823399234002340123402234032340423405234062340723408234092341023411234122341323414234152341623417234182341923420234212342223423234242342523426234272342823429234302343123432234332343423435234362343723438234392344023441234422344323444234452344623447234482344923450234512345223453234542345523456234572345823459234602346123462234632346423465234662346723468234692347023471234722347323474234752347623477234782347923480234812348223483234842348523486234872348823489234902349123492234932349423495234962349723498234992350023501235022350323504235052350623507235082350923510235112351223513235142351523516235172351823519235202352123522235232352423525235262352723528235292353023531235322353323534235352353623537235382353923540235412354223543235442354523546235472354823549235502355123552235532355423555235562355723558235592356023561235622356323564235652356623567235682356923570235712357223573235742357523576235772357823579235802358123582235832358423585235862358723588235892359023591235922359323594235952359623597235982359923600236012360223603236042360523606236072360823609236102361123612236132361423615236162361723618236192362023621236222362323624236252362623627236282362923630236312363223633236342363523636236372363823639236402364123642236432364423645236462364723648236492365023651236522365323654236552365623657236582365923660236612366223663236642366523666236672366823669236702367123672236732367423675236762367723678236792368023681236822368323684236852368623687236882368923690236912369223693236942369523696236972369823699237002370123702237032370423705237062370723708237092371023711237122371323714237152371623717237182371923720237212372223723237242372523726237272372823729237302373123732237332373423735237362373723738237392374023741237422374323744237452374623747237482374923750237512375223753237542375523756237572375823759237602376123762237632376423765237662376723768237692377023771237722377323774237752377623777237782377923780237812378223783237842378523786237872378823789237902379123792237932379423795237962379723798237992380023801238022380323804238052380623807238082380923810238112381223813238142381523816238172381823819238202382123822238232382423825238262382723828238292383023831238322383323834238352383623837238382383923840238412384223843238442384523846238472384823849238502385123852238532385423855238562385723858238592386023861238622386323864238652386623867238682386923870238712387223873238742387523876238772387823879238802388123882238832388423885238862388723888238892389023891238922389323894238952389623897238982389923900239012390223903239042390523906239072390823909239102391123912239132391423915239162391723918239192392023921239222392323924239252392623927239282392923930239312393223933239342393523936239372393823939239402394123942239432394423945239462394723948239492395023951239522395323954239552395623957239582395923960239612396223963239642396523966239672396823969239702397123972239732397423975239762397723978239792398023981239822398323984239852398623987239882398923990239912399223993239942399523996239972399823999240002400124002240032400424005240062400724008240092401024011240122401324014240152401624017240182401924020240212402224023240242402524026240272402824029240302403124032240332403424035240362403724038240392404024041240422404324044240452404624047240482404924050240512405224053240542405524056240572405824059240602406124062240632406424065240662406724068240692407024071240722407324074240752407624077240782407924080240812408224083240842408524086240872408824089240902409124092240932409424095240962409724098240992410024101241022410324104241052410624107241082410924110241112411224113241142411524116241172411824119241202412124122241232412424125241262412724128241292413024131241322413324134241352413624137241382413924140241412414224143241442414524146241472414824149241502415124152241532415424155241562415724158241592416024161241622416324164241652416624167241682416924170241712417224173241742417524176241772417824179241802418124182241832418424185241862418724188241892419024191241922419324194241952419624197241982419924200242012420224203242042420524206242072420824209242102421124212242132421424215242162421724218242192422024221242222422324224242252422624227242282422924230242312423224233242342423524236242372423824239242402424124242242432424424245242462424724248242492425024251242522425324254242552425624257242582425924260242612426224263242642426524266242672426824269242702427124272242732427424275242762427724278242792428024281242822428324284242852428624287242882428924290242912429224293242942429524296242972429824299243002430124302243032430424305243062430724308243092431024311243122431324314243152431624317243182431924320243212432224323243242432524326243272432824329243302433124332243332433424335243362433724338243392434024341243422434324344243452434624347243482434924350243512435224353243542435524356243572435824359243602436124362243632436424365243662436724368243692437024371243722437324374243752437624377243782437924380243812438224383243842438524386243872438824389243902439124392243932439424395243962439724398243992440024401244022440324404244052440624407244082440924410244112441224413244142441524416244172441824419244202442124422244232442424425244262442724428244292443024431244322443324434244352443624437244382443924440244412444224443244442444524446244472444824449244502445124452244532445424455244562445724458244592446024461244622446324464244652446624467244682446924470244712447224473244742447524476244772447824479244802448124482244832448424485244862448724488244892449024491244922449324494244952449624497244982449924500245012450224503245042450524506245072450824509245102451124512245132451424515245162451724518245192452024521245222452324524245252452624527245282452924530245312453224533245342453524536245372453824539245402454124542245432454424545245462454724548245492455024551245522455324554245552455624557245582455924560245612456224563245642456524566245672456824569245702457124572245732457424575245762457724578245792458024581245822458324584245852458624587245882458924590245912459224593245942459524596245972459824599246002460124602246032460424605246062460724608246092461024611246122461324614246152461624617246182461924620246212462224623246242462524626246272462824629246302463124632246332463424635246362463724638246392464024641246422464324644246452464624647246482464924650246512465224653246542465524656246572465824659246602466124662246632466424665246662466724668246692467024671246722467324674246752467624677246782467924680246812468224683246842468524686246872468824689246902469124692246932469424695246962469724698246992470024701247022470324704247052470624707247082470924710247112471224713247142471524716247172471824719247202472124722247232472424725247262472724728247292473024731247322473324734247352473624737247382473924740247412474224743247442474524746247472474824749247502475124752247532475424755247562475724758247592476024761247622476324764247652476624767247682476924770247712477224773247742477524776247772477824779247802478124782247832478424785247862478724788247892479024791247922479324794247952479624797247982479924800248012480224803248042480524806248072480824809248102481124812248132481424815248162481724818248192482024821248222482324824248252482624827248282482924830248312483224833248342483524836248372483824839248402484124842248432484424845248462484724848248492485024851248522485324854248552485624857248582485924860248612486224863248642486524866248672486824869248702487124872248732487424875248762487724878248792488024881248822488324884248852488624887248882488924890248912489224893248942489524896248972489824899249002490124902249032490424905249062490724908249092491024911249122491324914249152491624917249182491924920249212492224923249242492524926249272492824929249302493124932249332493424935249362493724938249392494024941249422494324944249452494624947249482494924950249512495224953249542495524956249572495824959249602496124962249632496424965249662496724968249692497024971249722497324974249752497624977249782497924980249812498224983249842498524986249872498824989249902499124992249932499424995249962499724998249992500025001250022500325004250052500625007250082500925010250112501225013250142501525016250172501825019250202502125022250232502425025250262502725028250292503025031250322503325034250352503625037250382503925040250412504225043250442504525046250472504825049250502505125052250532505425055250562505725058250592506025061250622506325064250652506625067250682506925070250712507225073250742507525076250772507825079250802508125082250832508425085250862508725088250892509025091250922509325094250952509625097250982509925100251012510225103251042510525106251072510825109251102511125112251132511425115251162511725118251192512025121251222512325124251252512625127251282512925130251312513225133251342513525136251372513825139251402514125142251432514425145251462514725148251492515025151251522515325154251552515625157251582515925160251612516225163251642516525166251672516825169251702517125172251732517425175251762517725178251792518025181251822518325184251852518625187251882518925190251912519225193251942519525196251972519825199252002520125202252032520425205252062520725208252092521025211252122521325214252152521625217252182521925220252212522225223252242522525226252272522825229252302523125232252332523425235252362523725238252392524025241252422524325244252452524625247252482524925250252512525225253252542525525256252572525825259252602526125262252632526425265252662526725268252692527025271252722527325274252752527625277252782527925280252812528225283252842528525286252872528825289252902529125292252932529425295252962529725298252992530025301253022530325304253052530625307253082530925310253112531225313253142531525316253172531825319253202532125322253232532425325253262532725328253292533025331253322533325334253352533625337253382533925340253412534225343253442534525346253472534825349253502535125352253532535425355253562535725358253592536025361253622536325364253652536625367253682536925370253712537225373253742537525376253772537825379253802538125382253832538425385253862538725388253892539025391253922539325394253952539625397253982539925400254012540225403254042540525406254072540825409254102541125412254132541425415254162541725418254192542025421254222542325424254252542625427254282542925430254312543225433254342543525436254372543825439254402544125442254432544425445254462544725448254492545025451254522545325454254552545625457254582545925460254612546225463254642546525466254672546825469254702547125472254732547425475254762547725478254792548025481254822548325484254852548625487254882548925490254912549225493254942549525496254972549825499255002550125502255032550425505255062550725508255092551025511255122551325514255152551625517255182551925520255212552225523255242552525526255272552825529255302553125532255332553425535255362553725538255392554025541255422554325544255452554625547255482554925550255512555225553255542555525556255572555825559255602556125562255632556425565255662556725568255692557025571255722557325574255752557625577255782557925580255812558225583255842558525586255872558825589255902559125592255932559425595255962559725598255992560025601256022560325604256052560625607256082560925610256112561225613256142561525616256172561825619256202562125622256232562425625256262562725628256292563025631256322563325634256352563625637256382563925640256412564225643256442564525646256472564825649256502565125652256532565425655256562565725658256592566025661256622566325664256652566625667256682566925670256712567225673256742567525676256772567825679256802568125682256832568425685256862568725688256892569025691256922569325694256952569625697256982569925700257012570225703257042570525706257072570825709257102571125712257132571425715257162571725718257192572025721257222572325724257252572625727257282572925730257312573225733257342573525736257372573825739257402574125742257432574425745257462574725748257492575025751257522575325754257552575625757257582575925760257612576225763257642576525766257672576825769257702577125772257732577425775257762577725778257792578025781257822578325784257852578625787257882578925790257912579225793257942579525796257972579825799258002580125802258032580425805258062580725808258092581025811258122581325814258152581625817258182581925820258212582225823258242582525826258272582825829258302583125832258332583425835258362583725838258392584025841258422584325844258452584625847258482584925850258512585225853258542585525856258572585825859258602586125862258632586425865258662586725868258692587025871258722587325874258752587625877258782587925880258812588225883258842588525886258872588825889258902589125892258932589425895258962589725898258992590025901259022590325904259052590625907259082590925910259112591225913259142591525916259172591825919259202592125922259232592425925259262592725928259292593025931259322593325934259352593625937259382593925940259412594225943259442594525946259472594825949259502595125952259532595425955259562595725958259592596025961259622596325964259652596625967259682596925970259712597225973259742597525976259772597825979259802598125982259832598425985259862598725988259892599025991259922599325994259952599625997259982599926000260012600226003260042600526006260072600826009260102601126012260132601426015260162601726018260192602026021260222602326024260252602626027260282602926030260312603226033260342603526036260372603826039260402604126042260432604426045260462604726048260492605026051260522605326054260552605626057260582605926060260612606226063260642606526066260672606826069260702607126072260732607426075260762607726078260792608026081260822608326084260852608626087260882608926090260912609226093260942609526096260972609826099261002610126102261032610426105261062610726108261092611026111261122611326114261152611626117261182611926120261212612226123261242612526126261272612826129261302613126132261332613426135261362613726138261392614026141261422614326144261452614626147261482614926150261512615226153261542615526156261572615826159261602616126162261632616426165261662616726168261692617026171261722617326174261752617626177261782617926180261812618226183261842618526186261872618826189261902619126192261932619426195261962619726198261992620026201262022620326204262052620626207262082620926210262112621226213262142621526216262172621826219262202622126222262232622426225262262622726228262292623026231262322623326234262352623626237262382623926240262412624226243262442624526246262472624826249262502625126252262532625426255262562625726258262592626026261262622626326264262652626626267262682626926270262712627226273262742627526276262772627826279262802628126282262832628426285262862628726288262892629026291262922629326294262952629626297262982629926300263012630226303263042630526306263072630826309263102631126312263132631426315263162631726318263192632026321263222632326324263252632626327263282632926330263312633226333263342633526336263372633826339263402634126342263432634426345263462634726348263492635026351263522635326354263552635626357263582635926360263612636226363263642636526366263672636826369263702637126372263732637426375263762637726378263792638026381263822638326384263852638626387263882638926390263912639226393263942639526396263972639826399264002640126402264032640426405264062640726408264092641026411264122641326414264152641626417264182641926420264212642226423264242642526426264272642826429264302643126432264332643426435264362643726438264392644026441264422644326444264452644626447264482644926450264512645226453264542645526456264572645826459264602646126462264632646426465264662646726468264692647026471264722647326474264752647626477264782647926480264812648226483264842648526486264872648826489264902649126492264932649426495264962649726498264992650026501265022650326504265052650626507265082650926510265112651226513265142651526516265172651826519265202652126522265232652426525265262652726528265292653026531265322653326534265352653626537265382653926540265412654226543265442654526546265472654826549265502655126552265532655426555265562655726558265592656026561265622656326564265652656626567265682656926570265712657226573265742657526576265772657826579265802658126582265832658426585265862658726588265892659026591265922659326594265952659626597265982659926600266012660226603266042660526606266072660826609266102661126612266132661426615266162661726618266192662026621266222662326624266252662626627266282662926630266312663226633266342663526636266372663826639266402664126642266432664426645266462664726648266492665026651266522665326654266552665626657266582665926660266612666226663266642666526666266672666826669266702667126672266732667426675266762667726678266792668026681266822668326684266852668626687266882668926690266912669226693266942669526696266972669826699267002670126702267032670426705267062670726708267092671026711267122671326714267152671626717267182671926720267212672226723267242672526726267272672826729267302673126732267332673426735267362673726738267392674026741267422674326744267452674626747267482674926750267512675226753267542675526756267572675826759267602676126762267632676426765267662676726768267692677026771267722677326774267752677626777267782677926780267812678226783267842678526786267872678826789267902679126792267932679426795267962679726798267992680026801268022680326804268052680626807268082680926810268112681226813268142681526816268172681826819268202682126822268232682426825268262682726828268292683026831268322683326834268352683626837268382683926840268412684226843268442684526846268472684826849268502685126852268532685426855268562685726858268592686026861268622686326864268652686626867268682686926870268712687226873268742687526876268772687826879268802688126882268832688426885268862688726888268892689026891268922689326894268952689626897268982689926900269012690226903269042690526906269072690826909269102691126912269132691426915269162691726918269192692026921269222692326924269252692626927269282692926930269312693226933269342693526936269372693826939269402694126942269432694426945269462694726948269492695026951269522695326954269552695626957269582695926960269612696226963269642696526966269672696826969269702697126972269732697426975269762697726978269792698026981269822698326984269852698626987269882698926990269912699226993269942699526996269972699826999270002700127002270032700427005270062700727008270092701027011270122701327014270152701627017270182701927020270212702227023270242702527026270272702827029270302703127032270332703427035270362703727038270392704027041270422704327044270452704627047270482704927050270512705227053270542705527056270572705827059270602706127062270632706427065270662706727068270692707027071270722707327074270752707627077270782707927080270812708227083270842708527086270872708827089270902709127092270932709427095270962709727098270992710027101271022710327104271052710627107271082710927110271112711227113271142711527116271172711827119271202712127122271232712427125271262712727128271292713027131271322713327134271352713627137271382713927140271412714227143271442714527146271472714827149271502715127152271532715427155271562715727158271592716027161271622716327164271652716627167271682716927170271712717227173271742717527176271772717827179271802718127182271832718427185271862718727188271892719027191271922719327194271952719627197271982719927200272012720227203272042720527206272072720827209272102721127212272132721427215272162721727218272192722027221272222722327224272252722627227272282722927230272312723227233272342723527236272372723827239272402724127242272432724427245272462724727248272492725027251272522725327254272552725627257272582725927260272612726227263272642726527266272672726827269272702727127272272732727427275272762727727278272792728027281272822728327284272852728627287272882728927290272912729227293272942729527296272972729827299273002730127302273032730427305273062730727308273092731027311273122731327314273152731627317273182731927320273212732227323273242732527326273272732827329273302733127332273332733427335273362733727338273392734027341273422734327344273452734627347273482734927350273512735227353273542735527356273572735827359273602736127362273632736427365273662736727368273692737027371273722737327374273752737627377273782737927380273812738227383273842738527386273872738827389273902739127392273932739427395273962739727398273992740027401274022740327404274052740627407274082740927410274112741227413274142741527416274172741827419274202742127422274232742427425274262742727428274292743027431274322743327434274352743627437274382743927440274412744227443274442744527446274472744827449274502745127452274532745427455274562745727458274592746027461274622746327464274652746627467274682746927470274712747227473274742747527476274772747827479274802748127482274832748427485274862748727488274892749027491274922749327494274952749627497274982749927500275012750227503275042750527506275072750827509275102751127512275132751427515275162751727518275192752027521275222752327524275252752627527275282752927530275312753227533275342753527536275372753827539275402754127542275432754427545275462754727548275492755027551275522755327554275552755627557275582755927560275612756227563275642756527566275672756827569275702757127572275732757427575275762757727578275792758027581275822758327584275852758627587275882758927590275912759227593275942759527596275972759827599276002760127602276032760427605276062760727608276092761027611276122761327614276152761627617276182761927620276212762227623276242762527626276272762827629276302763127632276332763427635276362763727638276392764027641276422764327644276452764627647276482764927650276512765227653276542765527656276572765827659276602766127662276632766427665276662766727668276692767027671276722767327674276752767627677276782767927680276812768227683276842768527686276872768827689276902769127692276932769427695276962769727698276992770027701277022770327704277052770627707277082770927710277112771227713277142771527716277172771827719277202772127722277232772427725277262772727728277292773027731277322773327734277352773627737277382773927740277412774227743277442774527746277472774827749277502775127752277532775427755277562775727758277592776027761277622776327764277652776627767277682776927770277712777227773277742777527776277772777827779277802778127782277832778427785277862778727788277892779027791277922779327794277952779627797277982779927800278012780227803278042780527806278072780827809278102781127812278132781427815278162781727818278192782027821278222782327824278252782627827278282782927830278312783227833278342783527836278372783827839278402784127842278432784427845278462784727848278492785027851278522785327854278552785627857278582785927860278612786227863278642786527866278672786827869278702787127872278732787427875278762787727878278792788027881278822788327884278852788627887278882788927890278912789227893278942789527896278972789827899279002790127902279032790427905279062790727908279092791027911279122791327914279152791627917279182791927920279212792227923279242792527926279272792827929279302793127932279332793427935279362793727938279392794027941279422794327944279452794627947279482794927950279512795227953279542795527956279572795827959279602796127962279632796427965279662796727968279692797027971279722797327974279752797627977279782797927980279812798227983279842798527986279872798827989279902799127992279932799427995279962799727998279992800028001280022800328004280052800628007280082800928010280112801228013280142801528016280172801828019280202802128022280232802428025280262802728028280292803028031280322803328034280352803628037280382803928040280412804228043280442804528046280472804828049280502805128052280532805428055280562805728058280592806028061280622806328064280652806628067280682806928070280712807228073280742807528076280772807828079280802808128082280832808428085280862808728088280892809028091280922809328094280952809628097280982809928100281012810228103281042810528106281072810828109281102811128112281132811428115281162811728118281192812028121281222812328124281252812628127281282812928130281312813228133281342813528136281372813828139281402814128142281432814428145281462814728148281492815028151281522815328154281552815628157281582815928160281612816228163281642816528166281672816828169281702817128172281732817428175281762817728178281792818028181281822818328184281852818628187281882818928190281912819228193281942819528196281972819828199282002820128202282032820428205282062820728208282092821028211282122821328214282152821628217282182821928220282212822228223282242822528226282272822828229282302823128232282332823428235282362823728238282392824028241282422824328244282452824628247282482824928250282512825228253282542825528256282572825828259282602826128262282632826428265282662826728268282692827028271282722827328274282752827628277282782827928280282812828228283282842828528286282872828828289282902829128292282932829428295282962829728298282992830028301283022830328304283052830628307283082830928310283112831228313283142831528316283172831828319283202832128322283232832428325283262832728328283292833028331283322833328334283352833628337283382833928340283412834228343283442834528346283472834828349283502835128352283532835428355283562835728358283592836028361283622836328364283652836628367283682836928370283712837228373283742837528376283772837828379283802838128382283832838428385283862838728388283892839028391283922839328394283952839628397283982839928400284012840228403284042840528406284072840828409284102841128412284132841428415284162841728418284192842028421284222842328424284252842628427284282842928430284312843228433284342843528436284372843828439284402844128442284432844428445284462844728448284492845028451284522845328454284552845628457284582845928460284612846228463284642846528466284672846828469284702847128472284732847428475284762847728478284792848028481284822848328484284852848628487284882848928490284912849228493284942849528496284972849828499285002850128502285032850428505285062850728508285092851028511285122851328514285152851628517285182851928520285212852228523285242852528526285272852828529285302853128532285332853428535285362853728538285392854028541285422854328544285452854628547285482854928550285512855228553285542855528556285572855828559285602856128562285632856428565285662856728568285692857028571285722857328574285752857628577285782857928580285812858228583285842858528586285872858828589285902859128592285932859428595285962859728598285992860028601286022860328604286052860628607286082860928610286112861228613286142861528616286172861828619286202862128622286232862428625286262862728628286292863028631286322863328634286352863628637286382863928640286412864228643286442864528646286472864828649286502865128652286532865428655286562865728658286592866028661286622866328664286652866628667286682866928670286712867228673286742867528676286772867828679286802868128682286832868428685286862868728688286892869028691286922869328694286952869628697286982869928700287012870228703287042870528706287072870828709287102871128712287132871428715287162871728718287192872028721287222872328724287252872628727287282872928730287312873228733287342873528736287372873828739287402874128742287432874428745287462874728748287492875028751287522875328754287552875628757287582875928760287612876228763287642876528766287672876828769287702877128772287732877428775287762877728778287792878028781287822878328784287852878628787287882878928790287912879228793287942879528796287972879828799288002880128802288032880428805288062880728808288092881028811288122881328814288152881628817288182881928820288212882228823288242882528826288272882828829288302883128832288332883428835288362883728838288392884028841288422884328844288452884628847288482884928850288512885228853288542885528856288572885828859288602886128862288632886428865288662886728868288692887028871288722887328874288752887628877288782887928880288812888228883288842888528886288872888828889288902889128892288932889428895288962889728898288992890028901289022890328904289052890628907289082890928910289112891228913289142891528916289172891828919289202892128922289232892428925289262892728928289292893028931289322893328934289352893628937289382893928940289412894228943289442894528946289472894828949289502895128952289532895428955289562895728958289592896028961289622896328964289652896628967289682896928970289712897228973289742897528976289772897828979289802898128982289832898428985289862898728988289892899028991289922899328994289952899628997289982899929000290012900229003290042900529006290072900829009290102901129012290132901429015290162901729018290192902029021290222902329024290252902629027290282902929030290312903229033290342903529036290372903829039290402904129042290432904429045290462904729048290492905029051290522905329054290552905629057290582905929060290612906229063290642906529066290672906829069290702907129072290732907429075290762907729078290792908029081290822908329084290852908629087290882908929090290912909229093290942909529096290972909829099291002910129102291032910429105291062910729108291092911029111291122911329114291152911629117291182911929120291212912229123291242912529126291272912829129291302913129132291332913429135291362913729138291392914029141291422914329144291452914629147291482914929150291512915229153291542915529156291572915829159291602916129162291632916429165291662916729168291692917029171291722917329174291752917629177291782917929180291812918229183291842918529186291872918829189291902919129192291932919429195291962919729198291992920029201292022920329204292052920629207292082920929210292112921229213292142921529216292172921829219292202922129222292232922429225292262922729228292292923029231292322923329234292352923629237292382923929240292412924229243292442924529246292472924829249292502925129252292532925429255292562925729258292592926029261292622926329264292652926629267292682926929270292712927229273292742927529276292772927829279292802928129282292832928429285292862928729288292892929029291292922929329294292952929629297292982929929300293012930229303293042930529306293072930829309293102931129312293132931429315293162931729318293192932029321293222932329324293252932629327293282932929330293312933229333293342933529336293372933829339293402934129342293432934429345293462934729348293492935029351293522935329354293552935629357293582935929360293612936229363293642936529366293672936829369293702937129372293732937429375293762937729378293792938029381293822938329384293852938629387293882938929390293912939229393293942939529396293972939829399294002940129402294032940429405294062940729408294092941029411294122941329414294152941629417294182941929420294212942229423294242942529426294272942829429294302943129432294332943429435294362943729438294392944029441294422944329444294452944629447294482944929450294512945229453294542945529456294572945829459294602946129462294632946429465294662946729468294692947029471294722947329474294752947629477294782947929480294812948229483294842948529486294872948829489294902949129492294932949429495294962949729498294992950029501295022950329504295052950629507295082950929510295112951229513295142951529516295172951829519295202952129522295232952429525295262952729528295292953029531295322953329534295352953629537295382953929540295412954229543295442954529546295472954829549295502955129552295532955429555295562955729558295592956029561295622956329564295652956629567295682956929570295712957229573295742957529576295772957829579295802958129582295832958429585295862958729588295892959029591295922959329594295952959629597295982959929600296012960229603296042960529606296072960829609296102961129612296132961429615296162961729618296192962029621296222962329624296252962629627296282962929630296312963229633296342963529636296372963829639296402964129642296432964429645296462964729648296492965029651296522965329654296552965629657296582965929660296612966229663296642966529666296672966829669296702967129672296732967429675296762967729678296792968029681296822968329684296852968629687296882968929690296912969229693296942969529696296972969829699297002970129702297032970429705297062970729708297092971029711297122971329714297152971629717297182971929720297212972229723297242972529726297272972829729297302973129732297332973429735297362973729738297392974029741297422974329744297452974629747297482974929750297512975229753297542975529756297572975829759297602976129762297632976429765297662976729768297692977029771297722977329774297752977629777297782977929780297812978229783297842978529786297872978829789297902979129792297932979429795297962979729798297992980029801298022980329804298052980629807298082980929810298112981229813298142981529816298172981829819298202982129822298232982429825298262982729828298292983029831298322983329834298352983629837298382983929840298412984229843298442984529846298472984829849298502985129852298532985429855298562985729858298592986029861298622986329864298652986629867298682986929870298712987229873298742987529876298772987829879298802988129882298832988429885298862988729888298892989029891298922989329894298952989629897298982989929900299012990229903299042990529906299072990829909299102991129912299132991429915299162991729918299192992029921299222992329924299252992629927299282992929930299312993229933299342993529936299372993829939299402994129942299432994429945299462994729948299492995029951299522995329954299552995629957299582995929960299612996229963299642996529966299672996829969299702997129972299732997429975299762997729978299792998029981299822998329984299852998629987299882998929990299912999229993299942999529996299972999829999300003000130002300033000430005300063000730008300093001030011300123001330014300153001630017300183001930020300213002230023300243002530026300273002830029300303003130032300333003430035300363003730038300393004030041300423004330044300453004630047300483004930050300513005230053300543005530056300573005830059300603006130062300633006430065300663006730068300693007030071300723007330074300753007630077300783007930080300813008230083300843008530086300873008830089300903009130092300933009430095300963009730098300993010030101301023010330104301053010630107301083010930110301113011230113301143011530116301173011830119301203012130122301233012430125301263012730128301293013030131301323013330134301353013630137301383013930140301413014230143301443014530146301473014830149301503015130152301533015430155301563015730158301593016030161301623016330164301653016630167301683016930170301713017230173301743017530176301773017830179301803018130182301833018430185301863018730188301893019030191301923019330194301953019630197301983019930200302013020230203302043020530206302073020830209302103021130212302133021430215302163021730218302193022030221302223022330224302253022630227302283022930230302313023230233302343023530236302373023830239302403024130242302433024430245302463024730248302493025030251302523025330254302553025630257302583025930260302613026230263302643026530266302673026830269302703027130272302733027430275302763027730278302793028030281302823028330284302853028630287302883028930290302913029230293302943029530296302973029830299303003030130302303033030430305303063030730308303093031030311303123031330314303153031630317303183031930320303213032230323303243032530326303273032830329303303033130332303333033430335303363033730338303393034030341303423034330344303453034630347303483034930350303513035230353303543035530356303573035830359303603036130362303633036430365303663036730368303693037030371303723037330374303753037630377303783037930380303813038230383303843038530386303873038830389303903039130392303933039430395303963039730398303993040030401304023040330404304053040630407304083040930410304113041230413304143041530416304173041830419304203042130422304233042430425304263042730428304293043030431304323043330434304353043630437304383043930440304413044230443304443044530446304473044830449304503045130452304533045430455304563045730458304593046030461304623046330464304653046630467304683046930470304713047230473304743047530476304773047830479304803048130482304833048430485304863048730488304893049030491304923049330494304953049630497304983049930500305013050230503305043050530506305073050830509305103051130512305133051430515305163051730518305193052030521305223052330524305253052630527305283052930530305313053230533305343053530536305373053830539305403054130542305433054430545305463054730548305493055030551305523055330554305553055630557305583055930560305613056230563305643056530566305673056830569305703057130572305733057430575305763057730578305793058030581305823058330584305853058630587305883058930590305913059230593305943059530596305973059830599306003060130602306033060430605306063060730608306093061030611306123061330614306153061630617306183061930620306213062230623306243062530626306273062830629306303063130632306333063430635306363063730638306393064030641306423064330644306453064630647306483064930650306513065230653306543065530656306573065830659306603066130662306633066430665306663066730668306693067030671306723067330674306753067630677306783067930680306813068230683306843068530686306873068830689306903069130692306933069430695306963069730698306993070030701307023070330704307053070630707307083070930710307113071230713307143071530716307173071830719307203072130722307233072430725307263072730728307293073030731307323073330734307353073630737307383073930740307413074230743307443074530746307473074830749307503075130752307533075430755307563075730758307593076030761307623076330764307653076630767307683076930770307713077230773307743077530776307773077830779307803078130782307833078430785307863078730788307893079030791307923079330794307953079630797307983079930800308013080230803308043080530806308073080830809308103081130812308133081430815308163081730818308193082030821308223082330824308253082630827308283082930830308313083230833308343083530836308373083830839308403084130842308433084430845308463084730848308493085030851308523085330854308553085630857308583085930860308613086230863308643086530866308673086830869308703087130872308733087430875308763087730878308793088030881308823088330884308853088630887308883088930890308913089230893308943089530896308973089830899309003090130902309033090430905309063090730908309093091030911309123091330914309153091630917309183091930920309213092230923309243092530926309273092830929309303093130932309333093430935309363093730938309393094030941309423094330944309453094630947309483094930950309513095230953309543095530956309573095830959309603096130962309633096430965309663096730968309693097030971309723097330974309753097630977309783097930980309813098230983309843098530986309873098830989309903099130992309933099430995309963099730998309993100031001310023100331004310053100631007310083100931010310113101231013310143101531016310173101831019310203102131022310233102431025310263102731028310293103031031310323103331034310353103631037310383103931040310413104231043310443104531046310473104831049310503105131052310533105431055310563105731058310593106031061310623106331064310653106631067310683106931070310713107231073310743107531076310773107831079310803108131082310833108431085310863108731088310893109031091310923109331094310953109631097310983109931100311013110231103311043110531106311073110831109311103111131112311133111431115311163111731118311193112031121311223112331124311253112631127311283112931130311313113231133311343113531136311373113831139311403114131142311433114431145311463114731148311493115031151311523115331154311553115631157311583115931160311613116231163311643116531166311673116831169311703117131172311733117431175311763117731178311793118031181311823118331184311853118631187311883118931190311913119231193311943119531196311973119831199312003120131202312033120431205312063120731208312093121031211312123121331214312153121631217312183121931220312213122231223312243122531226312273122831229312303123131232312333123431235312363123731238312393124031241312423124331244312453124631247312483124931250312513125231253312543125531256312573125831259312603126131262312633126431265312663126731268312693127031271312723127331274312753127631277312783127931280312813128231283312843128531286312873128831289312903129131292312933129431295312963129731298312993130031301313023130331304313053130631307313083130931310313113131231313313143131531316313173131831319313203132131322313233132431325313263132731328313293133031331313323133331334313353133631337313383133931340313413134231343313443134531346313473134831349313503135131352313533135431355313563135731358313593136031361313623136331364313653136631367313683136931370313713137231373313743137531376313773137831379313803138131382313833138431385313863138731388313893139031391313923139331394313953139631397313983139931400314013140231403314043140531406314073140831409314103141131412314133141431415314163141731418314193142031421314223142331424314253142631427314283142931430314313143231433314343143531436314373143831439314403144131442314433144431445314463144731448314493145031451314523145331454314553145631457314583145931460314613146231463314643146531466314673146831469314703147131472314733147431475314763147731478314793148031481314823148331484314853148631487314883148931490314913149231493314943149531496314973149831499315003150131502315033150431505315063150731508315093151031511315123151331514315153151631517315183151931520315213152231523315243152531526315273152831529315303153131532315333153431535315363153731538315393154031541315423154331544315453154631547315483154931550315513155231553315543155531556315573155831559315603156131562315633156431565315663156731568315693157031571315723157331574315753157631577315783157931580315813158231583315843158531586315873158831589315903159131592315933159431595315963159731598315993160031601316023160331604316053160631607316083160931610316113161231613316143161531616316173161831619316203162131622316233162431625316263162731628316293163031631316323163331634316353163631637316383163931640316413164231643316443164531646316473164831649316503165131652316533165431655316563165731658316593166031661316623166331664316653166631667316683166931670316713167231673316743167531676316773167831679316803168131682316833168431685316863168731688316893169031691316923169331694316953169631697316983169931700317013170231703317043170531706317073170831709317103171131712317133171431715317163171731718317193172031721317223172331724317253172631727317283172931730317313173231733317343173531736317373173831739317403174131742317433174431745317463174731748317493175031751317523175331754317553175631757317583175931760317613176231763317643176531766317673176831769317703177131772317733177431775317763177731778317793178031781317823178331784317853178631787317883178931790317913179231793317943179531796317973179831799318003180131802318033180431805318063180731808318093181031811318123181331814318153181631817318183181931820318213182231823318243182531826318273182831829318303183131832318333183431835318363183731838318393184031841318423184331844318453184631847318483184931850318513185231853318543185531856318573185831859318603186131862318633186431865318663186731868318693187031871318723187331874318753187631877318783187931880318813188231883318843188531886318873188831889318903189131892318933189431895318963189731898318993190031901319023190331904319053190631907319083190931910319113191231913319143191531916319173191831919319203192131922319233192431925319263192731928319293193031931319323193331934319353193631937319383193931940319413194231943319443194531946319473194831949319503195131952319533195431955319563195731958319593196031961319623196331964319653196631967319683196931970319713197231973319743197531976319773197831979319803198131982319833198431985319863198731988319893199031991319923199331994319953199631997319983199932000320013200232003320043200532006320073200832009320103201132012320133201432015320163201732018320193202032021320223202332024320253202632027320283202932030320313203232033320343203532036320373203832039320403204132042320433204432045320463204732048320493205032051320523205332054320553205632057320583205932060320613206232063320643206532066320673206832069320703207132072320733207432075320763207732078320793208032081320823208332084320853208632087320883208932090320913209232093320943209532096320973209832099321003210132102321033210432105321063210732108321093211032111321123211332114321153211632117321183211932120321213212232123321243212532126321273212832129321303213132132321333213432135321363213732138321393214032141321423214332144321453214632147321483214932150321513215232153321543215532156321573215832159321603216132162321633216432165321663216732168321693217032171321723217332174321753217632177321783217932180321813218232183321843218532186321873218832189321903219132192321933219432195321963219732198321993220032201322023220332204322053220632207322083220932210322113221232213322143221532216322173221832219322203222132222322233222432225322263222732228322293223032231322323223332234322353223632237322383223932240322413224232243322443224532246322473224832249322503225132252322533225432255322563225732258322593226032261322623226332264322653226632267322683226932270322713227232273322743227532276322773227832279322803228132282322833228432285322863228732288322893229032291322923229332294322953229632297322983229932300323013230232303323043230532306323073230832309323103231132312323133231432315323163231732318323193232032321323223232332324323253232632327323283232932330323313233232333323343233532336323373233832339323403234132342323433234432345323463234732348323493235032351323523235332354323553235632357323583235932360323613236232363323643236532366323673236832369323703237132372323733237432375323763237732378323793238032381323823238332384323853238632387323883238932390323913239232393323943239532396323973239832399324003240132402324033240432405324063240732408324093241032411324123241332414324153241632417324183241932420324213242232423324243242532426324273242832429324303243132432324333243432435324363243732438324393244032441324423244332444324453244632447324483244932450324513245232453324543245532456324573245832459324603246132462324633246432465324663246732468324693247032471324723247332474324753247632477324783247932480324813248232483324843248532486324873248832489324903249132492324933249432495324963249732498324993250032501325023250332504325053250632507325083250932510325113251232513325143251532516325173251832519325203252132522325233252432525325263252732528325293253032531325323253332534325353253632537325383253932540325413254232543325443254532546325473254832549325503255132552325533255432555325563255732558325593256032561325623256332564325653256632567325683256932570325713257232573325743257532576325773257832579325803258132582325833258432585325863258732588325893259032591325923259332594325953259632597325983259932600326013260232603326043260532606326073260832609326103261132612326133261432615326163261732618326193262032621326223262332624326253262632627326283262932630326313263232633326343263532636326373263832639326403264132642326433264432645326463264732648326493265032651326523265332654326553265632657326583265932660326613266232663326643266532666326673266832669326703267132672326733267432675326763267732678326793268032681326823268332684326853268632687326883268932690326913269232693326943269532696326973269832699327003270132702327033270432705327063270732708327093271032711327123271332714327153271632717327183271932720327213272232723327243272532726327273272832729327303273132732327333273432735327363273732738327393274032741327423274332744327453274632747327483274932750327513275232753327543275532756327573275832759327603276132762327633276432765327663276732768327693277032771327723277332774327753277632777327783277932780327813278232783327843278532786327873278832789327903279132792327933279432795327963279732798327993280032801328023280332804328053280632807328083280932810328113281232813328143281532816328173281832819328203282132822328233282432825328263282732828328293283032831328323283332834328353283632837328383283932840328413284232843328443284532846328473284832849328503285132852328533285432855328563285732858328593286032861328623286332864328653286632867328683286932870328713287232873328743287532876328773287832879328803288132882328833288432885328863288732888328893289032891328923289332894328953289632897328983289932900329013290232903329043290532906329073290832909329103291132912329133291432915329163291732918329193292032921329223292332924329253292632927329283292932930329313293232933329343293532936329373293832939329403294132942329433294432945329463294732948329493295032951329523295332954329553295632957329583295932960329613296232963329643296532966329673296832969329703297132972329733297432975329763297732978329793298032981329823298332984329853298632987329883298932990329913299232993329943299532996329973299832999330003300133002330033300433005330063300733008330093301033011330123301333014330153301633017330183301933020330213302233023330243302533026330273302833029330303303133032330333303433035330363303733038330393304033041330423304333044330453304633047330483304933050330513305233053330543305533056330573305833059330603306133062330633306433065330663306733068330693307033071330723307333074330753307633077330783307933080330813308233083330843308533086330873308833089330903309133092330933309433095330963309733098330993310033101331023310333104331053310633107331083310933110331113311233113331143311533116331173311833119331203312133122331233312433125331263312733128331293313033131331323313333134331353313633137331383313933140331413314233143331443314533146331473314833149331503315133152331533315433155331563315733158331593316033161331623316333164331653316633167331683316933170331713317233173331743317533176331773317833179331803318133182331833318433185331863318733188331893319033191331923319333194331953319633197331983319933200332013320233203332043320533206332073320833209332103321133212332133321433215332163321733218332193322033221332223322333224332253322633227332283322933230332313323233233332343323533236332373323833239332403324133242332433324433245332463324733248332493325033251332523325333254332553325633257332583325933260332613326233263332643326533266332673326833269332703327133272332733327433275332763327733278332793328033281332823328333284332853328633287332883328933290332913329233293332943329533296332973329833299333003330133302333033330433305333063330733308333093331033311333123331333314333153331633317333183331933320333213332233323333243332533326333273332833329333303333133332333333333433335333363333733338333393334033341333423334333344333453334633347333483334933350333513335233353333543335533356333573335833359333603336133362333633336433365333663336733368333693337033371333723337333374333753337633377333783337933380333813338233383333843338533386333873338833389333903339133392333933339433395333963339733398333993340033401334023340333404334053340633407334083340933410334113341233413334143341533416334173341833419334203342133422334233342433425334263342733428334293343033431334323343333434334353343633437334383343933440334413344233443334443344533446334473344833449334503345133452334533345433455334563345733458334593346033461334623346333464334653346633467334683346933470334713347233473334743347533476334773347833479334803348133482334833348433485334863348733488334893349033491334923349333494334953349633497334983349933500335013350233503335043350533506335073350833509335103351133512335133351433515335163351733518335193352033521335223352333524335253352633527335283352933530335313353233533335343353533536335373353833539335403354133542335433354433545335463354733548335493355033551335523355333554335553355633557335583355933560335613356233563335643356533566335673356833569335703357133572335733357433575335763357733578335793358033581335823358333584335853358633587335883358933590335913359233593335943359533596335973359833599336003360133602336033360433605336063360733608336093361033611336123361333614336153361633617336183361933620336213362233623336243362533626336273362833629336303363133632336333363433635336363363733638336393364033641336423364333644336453364633647336483364933650336513365233653336543365533656336573365833659336603366133662336633366433665336663366733668336693367033671336723367333674336753367633677336783367933680336813368233683336843368533686336873368833689336903369133692336933369433695336963369733698336993370033701337023370333704337053370633707337083370933710337113371233713337143371533716337173371833719337203372133722337233372433725337263372733728337293373033731337323373333734337353373633737337383373933740337413374233743337443374533746337473374833749337503375133752337533375433755337563375733758337593376033761337623376333764337653376633767337683376933770337713377233773337743377533776337773377833779337803378133782337833378433785337863378733788337893379033791337923379333794337953379633797337983379933800338013380233803338043380533806338073380833809338103381133812338133381433815338163381733818338193382033821338223382333824338253382633827338283382933830338313383233833338343383533836338373383833839338403384133842338433384433845338463384733848338493385033851338523385333854338553385633857338583385933860338613386233863338643386533866338673386833869338703387133872338733387433875338763387733878338793388033881338823388333884338853388633887338883388933890338913389233893338943389533896338973389833899339003390133902339033390433905339063390733908339093391033911339123391333914339153391633917339183391933920339213392233923339243392533926339273392833929339303393133932339333393433935339363393733938339393394033941339423394333944339453394633947339483394933950339513395233953339543395533956339573395833959339603396133962339633396433965339663396733968339693397033971339723397333974339753397633977339783397933980339813398233983339843398533986339873398833989339903399133992339933399433995339963399733998339993400034001340023400334004340053400634007340083400934010340113401234013340143401534016340173401834019340203402134022340233402434025340263402734028340293403034031340323403334034340353403634037340383403934040340413404234043340443404534046340473404834049340503405134052340533405434055340563405734058340593406034061340623406334064340653406634067340683406934070340713407234073340743407534076340773407834079340803408134082340833408434085340863408734088340893409034091340923409334094340953409634097340983409934100341013410234103341043410534106341073410834109341103411134112341133411434115341163411734118341193412034121341223412334124341253412634127341283412934130341313413234133341343413534136341373413834139341403414134142341433414434145341463414734148341493415034151341523415334154341553415634157341583415934160341613416234163341643416534166341673416834169341703417134172341733417434175341763417734178341793418034181341823418334184341853418634187341883418934190341913419234193341943419534196341973419834199342003420134202342033420434205342063420734208342093421034211342123421334214342153421634217342183421934220342213422234223342243422534226342273422834229342303423134232342333423434235342363423734238342393424034241342423424334244342453424634247342483424934250342513425234253342543425534256342573425834259342603426134262342633426434265342663426734268342693427034271342723427334274342753427634277342783427934280342813428234283342843428534286342873428834289342903429134292342933429434295342963429734298342993430034301343023430334304343053430634307343083430934310343113431234313343143431534316343173431834319343203432134322343233432434325343263432734328343293433034331343323433334334343353433634337343383433934340343413434234343343443434534346343473434834349343503435134352343533435434355343563435734358343593436034361343623436334364343653436634367343683436934370343713437234373343743437534376343773437834379343803438134382343833438434385343863438734388343893439034391343923439334394343953439634397343983439934400344013440234403344043440534406344073440834409344103441134412344133441434415344163441734418344193442034421344223442334424344253442634427344283442934430344313443234433344343443534436344373443834439344403444134442344433444434445344463444734448344493445034451344523445334454344553445634457344583445934460344613446234463344643446534466344673446834469344703447134472344733447434475344763447734478344793448034481344823448334484344853448634487344883448934490344913449234493344943449534496344973449834499345003450134502345033450434505345063450734508345093451034511345123451334514345153451634517345183451934520345213452234523345243452534526345273452834529345303453134532345333453434535345363453734538345393454034541345423454334544345453454634547345483454934550345513455234553345543455534556345573455834559345603456134562345633456434565345663456734568345693457034571345723457334574345753457634577345783457934580345813458234583345843458534586345873458834589345903459134592345933459434595345963459734598345993460034601346023460334604346053460634607346083460934610346113461234613346143461534616346173461834619346203462134622346233462434625346263462734628346293463034631346323463334634346353463634637346383463934640346413464234643346443464534646346473464834649346503465134652346533465434655346563465734658346593466034661346623466334664346653466634667346683466934670346713467234673346743467534676346773467834679346803468134682346833468434685346863468734688346893469034691346923469334694346953469634697346983469934700347013470234703347043470534706347073470834709347103471134712347133471434715347163471734718347193472034721347223472334724347253472634727347283472934730347313473234733347343473534736347373473834739347403474134742347433474434745347463474734748347493475034751347523475334754347553475634757347583475934760347613476234763347643476534766347673476834769347703477134772347733477434775347763477734778347793478034781347823478334784347853478634787347883478934790347913479234793347943479534796347973479834799348003480134802348033480434805348063480734808348093481034811348123481334814348153481634817348183481934820348213482234823348243482534826348273482834829348303483134832348333483434835348363483734838348393484034841348423484334844348453484634847348483484934850348513485234853348543485534856348573485834859348603486134862348633486434865348663486734868348693487034871348723487334874348753487634877348783487934880348813488234883348843488534886348873488834889348903489134892348933489434895348963489734898348993490034901349023490334904349053490634907349083490934910349113491234913349143491534916349173491834919349203492134922349233492434925349263492734928349293493034931349323493334934349353493634937349383493934940349413494234943349443494534946349473494834949349503495134952349533495434955349563495734958349593496034961349623496334964349653496634967349683496934970349713497234973349743497534976349773497834979349803498134982349833498434985349863498734988349893499034991349923499334994349953499634997349983499935000350013500235003350043500535006350073500835009350103501135012350133501435015350163501735018350193502035021350223502335024350253502635027350283502935030350313503235033350343503535036350373503835039350403504135042350433504435045350463504735048350493505035051350523505335054350553505635057350583505935060350613506235063350643506535066350673506835069350703507135072350733507435075350763507735078350793508035081350823508335084350853508635087350883508935090350913509235093350943509535096350973509835099351003510135102351033510435105351063510735108351093511035111351123511335114351153511635117351183511935120351213512235123351243512535126351273512835129351303513135132351333513435135351363513735138351393514035141351423514335144351453514635147351483514935150351513515235153351543515535156351573515835159351603516135162351633516435165351663516735168351693517035171351723517335174351753517635177351783517935180351813518235183351843518535186351873518835189351903519135192351933519435195351963519735198351993520035201352023520335204352053520635207352083520935210352113521235213352143521535216352173521835219352203522135222352233522435225352263522735228352293523035231352323523335234352353523635237352383523935240352413524235243352443524535246352473524835249352503525135252352533525435255352563525735258352593526035261352623526335264352653526635267352683526935270352713527235273352743527535276352773527835279352803528135282352833528435285352863528735288352893529035291352923529335294352953529635297352983529935300353013530235303353043530535306353073530835309353103531135312353133531435315353163531735318353193532035321353223532335324353253532635327353283532935330353313533235333353343533535336353373533835339353403534135342353433534435345353463534735348353493535035351353523535335354353553535635357353583535935360353613536235363353643536535366353673536835369353703537135372353733537435375353763537735378353793538035381353823538335384353853538635387353883538935390353913539235393353943539535396353973539835399354003540135402354033540435405354063540735408354093541035411354123541335414354153541635417354183541935420354213542235423354243542535426354273542835429354303543135432354333543435435354363543735438354393544035441354423544335444354453544635447354483544935450354513545235453354543545535456354573545835459354603546135462354633546435465354663546735468354693547035471354723547335474354753547635477354783547935480354813548235483354843548535486354873548835489354903549135492354933549435495354963549735498354993550035501355023550335504355053550635507355083550935510355113551235513355143551535516355173551835519355203552135522355233552435525355263552735528355293553035531355323553335534355353553635537355383553935540355413554235543355443554535546355473554835549355503555135552355533555435555355563555735558355593556035561355623556335564355653556635567355683556935570355713557235573355743557535576355773557835579355803558135582355833558435585355863558735588355893559035591355923559335594355953559635597355983559935600356013560235603356043560535606356073560835609356103561135612356133561435615356163561735618356193562035621356223562335624356253562635627356283562935630356313563235633356343563535636356373563835639356403564135642356433564435645356463564735648356493565035651356523565335654356553565635657356583565935660356613566235663356643566535666356673566835669356703567135672356733567435675356763567735678356793568035681356823568335684356853568635687356883568935690356913569235693356943569535696356973569835699357003570135702357033570435705357063570735708357093571035711357123571335714357153571635717357183571935720357213572235723357243572535726357273572835729357303573135732357333573435735357363573735738357393574035741357423574335744357453574635747357483574935750357513575235753357543575535756357573575835759357603576135762357633576435765357663576735768357693577035771357723577335774357753577635777357783577935780357813578235783357843578535786357873578835789357903579135792357933579435795357963579735798357993580035801358023580335804358053580635807358083580935810358113581235813358143581535816358173581835819358203582135822358233582435825358263582735828358293583035831358323583335834358353583635837358383583935840358413584235843358443584535846358473584835849358503585135852358533585435855358563585735858358593586035861358623586335864358653586635867358683586935870358713587235873358743587535876358773587835879358803588135882358833588435885358863588735888358893589035891358923589335894358953589635897358983589935900359013590235903359043590535906359073590835909359103591135912359133591435915359163591735918359193592035921359223592335924359253592635927359283592935930359313593235933359343593535936359373593835939359403594135942359433594435945359463594735948359493595035951359523595335954359553595635957359583595935960359613596235963359643596535966359673596835969359703597135972359733597435975359763597735978359793598035981359823598335984359853598635987359883598935990359913599235993359943599535996359973599835999360003600136002360033600436005360063600736008360093601036011360123601336014360153601636017360183601936020360213602236023360243602536026360273602836029360303603136032360333603436035360363603736038360393604036041360423604336044360453604636047360483604936050360513605236053360543605536056360573605836059360603606136062360633606436065360663606736068360693607036071360723607336074360753607636077360783607936080360813608236083360843608536086360873608836089360903609136092360933609436095360963609736098360993610036101361023610336104361053610636107361083610936110361113611236113361143611536116361173611836119361203612136122361233612436125361263612736128361293613036131361323613336134361353613636137361383613936140361413614236143361443614536146361473614836149361503615136152361533615436155361563615736158361593616036161361623616336164361653616636167361683616936170361713617236173361743617536176361773617836179361803618136182361833618436185361863618736188361893619036191361923619336194361953619636197361983619936200362013620236203362043620536206362073620836209362103621136212362133621436215362163621736218362193622036221362223622336224362253622636227362283622936230362313623236233362343623536236362373623836239362403624136242362433624436245362463624736248362493625036251362523625336254362553625636257362583625936260362613626236263362643626536266362673626836269362703627136272362733627436275362763627736278362793628036281362823628336284362853628636287362883628936290362913629236293362943629536296362973629836299363003630136302363033630436305363063630736308363093631036311363123631336314363153631636317363183631936320363213632236323363243632536326363273632836329363303633136332363333633436335363363633736338363393634036341363423634336344363453634636347363483634936350363513635236353363543635536356363573635836359363603636136362363633636436365363663636736368363693637036371363723637336374363753637636377363783637936380363813638236383363843638536386363873638836389363903639136392363933639436395363963639736398363993640036401364023640336404364053640636407364083640936410364113641236413364143641536416364173641836419364203642136422364233642436425364263642736428364293643036431364323643336434364353643636437364383643936440364413644236443364443644536446364473644836449364503645136452364533645436455364563645736458364593646036461364623646336464364653646636467364683646936470364713647236473364743647536476364773647836479364803648136482364833648436485364863648736488364893649036491364923649336494364953649636497364983649936500365013650236503365043650536506365073650836509365103651136512365133651436515365163651736518365193652036521365223652336524365253652636527365283652936530365313653236533365343653536536365373653836539365403654136542365433654436545365463654736548365493655036551365523655336554365553655636557365583655936560365613656236563365643656536566365673656836569365703657136572365733657436575365763657736578365793658036581365823658336584365853658636587365883658936590365913659236593365943659536596365973659836599366003660136602366033660436605366063660736608366093661036611366123661336614366153661636617366183661936620366213662236623366243662536626366273662836629366303663136632366333663436635366363663736638366393664036641366423664336644366453664636647366483664936650366513665236653366543665536656366573665836659366603666136662366633666436665366663666736668366693667036671366723667336674366753667636677366783667936680366813668236683366843668536686366873668836689366903669136692366933669436695366963669736698366993670036701367023670336704367053670636707367083670936710367113671236713367143671536716367173671836719367203672136722367233672436725367263672736728367293673036731367323673336734367353673636737367383673936740367413674236743367443674536746367473674836749367503675136752367533675436755367563675736758367593676036761367623676336764367653676636767367683676936770367713677236773367743677536776367773677836779367803678136782367833678436785367863678736788367893679036791367923679336794367953679636797367983679936800368013680236803368043680536806368073680836809368103681136812368133681436815368163681736818368193682036821368223682336824368253682636827368283682936830368313683236833368343683536836368373683836839368403684136842368433684436845368463684736848368493685036851368523685336854368553685636857368583685936860368613686236863368643686536866368673686836869368703687136872368733687436875368763687736878368793688036881368823688336884368853688636887368883688936890368913689236893368943689536896368973689836899369003690136902369033690436905369063690736908369093691036911369123691336914369153691636917369183691936920369213692236923369243692536926369273692836929369303693136932369333693436935369363693736938369393694036941369423694336944369453694636947369483694936950369513695236953369543695536956369573695836959369603696136962369633696436965369663696736968369693697036971369723697336974369753697636977369783697936980369813698236983369843698536986369873698836989369903699136992369933699436995369963699736998369993700037001370023700337004370053700637007370083700937010370113701237013370143701537016370173701837019370203702137022370233702437025370263702737028370293703037031370323703337034370353703637037370383703937040370413704237043370443704537046370473704837049370503705137052370533705437055370563705737058370593706037061370623706337064370653706637067370683706937070370713707237073370743707537076370773707837079370803708137082370833708437085370863708737088370893709037091370923709337094370953709637097370983709937100371013710237103371043710537106371073710837109371103711137112371133711437115371163711737118371193712037121371223712337124371253712637127371283712937130371313713237133371343713537136371373713837139371403714137142371433714437145371463714737148371493715037151371523715337154371553715637157371583715937160371613716237163371643716537166371673716837169371703717137172371733717437175371763717737178371793718037181371823718337184371853718637187371883718937190371913719237193371943719537196371973719837199372003720137202372033720437205372063720737208372093721037211372123721337214372153721637217372183721937220372213722237223372243722537226372273722837229372303723137232372333723437235372363723737238372393724037241372423724337244372453724637247372483724937250372513725237253372543725537256372573725837259372603726137262372633726437265372663726737268372693727037271372723727337274372753727637277372783727937280372813728237283372843728537286372873728837289372903729137292372933729437295372963729737298372993730037301373023730337304373053730637307373083730937310373113731237313373143731537316373173731837319373203732137322373233732437325373263732737328373293733037331373323733337334373353733637337373383733937340373413734237343373443734537346373473734837349373503735137352373533735437355373563735737358373593736037361373623736337364373653736637367373683736937370373713737237373373743737537376373773737837379373803738137382373833738437385373863738737388373893739037391373923739337394373953739637397373983739937400374013740237403374043740537406374073740837409374103741137412374133741437415374163741737418374193742037421374223742337424374253742637427374283742937430374313743237433374343743537436374373743837439374403744137442374433744437445374463744737448374493745037451374523745337454374553745637457374583745937460374613746237463374643746537466374673746837469374703747137472374733747437475374763747737478374793748037481374823748337484374853748637487374883748937490374913749237493374943749537496374973749837499375003750137502375033750437505375063750737508375093751037511375123751337514375153751637517375183751937520375213752237523375243752537526375273752837529375303753137532375333753437535375363753737538375393754037541375423754337544375453754637547375483754937550375513755237553375543755537556375573755837559375603756137562375633756437565375663756737568375693757037571375723757337574375753757637577375783757937580375813758237583375843758537586375873758837589375903759137592375933759437595375963759737598375993760037601376023760337604376053760637607376083760937610376113761237613376143761537616376173761837619376203762137622376233762437625376263762737628376293763037631376323763337634376353763637637376383763937640376413764237643376443764537646376473764837649376503765137652376533765437655376563765737658376593766037661376623766337664376653766637667376683766937670376713767237673376743767537676376773767837679376803768137682376833768437685376863768737688376893769037691376923769337694376953769637697376983769937700377013770237703377043770537706377073770837709377103771137712377133771437715377163771737718377193772037721377223772337724377253772637727377283772937730377313773237733377343773537736377373773837739377403774137742377433774437745377463774737748377493775037751377523775337754377553775637757377583775937760377613776237763377643776537766377673776837769377703777137772377733777437775377763777737778377793778037781377823778337784377853778637787377883778937790377913779237793377943779537796377973779837799378003780137802378033780437805378063780737808378093781037811378123781337814378153781637817378183781937820378213782237823378243782537826378273782837829378303783137832378333783437835378363783737838378393784037841378423784337844378453784637847378483784937850378513785237853378543785537856378573785837859378603786137862378633786437865378663786737868378693787037871378723787337874378753787637877378783787937880378813788237883378843788537886378873788837889378903789137892378933789437895378963789737898378993790037901379023790337904379053790637907379083790937910379113791237913379143791537916379173791837919379203792137922379233792437925379263792737928379293793037931379323793337934379353793637937379383793937940379413794237943379443794537946379473794837949379503795137952379533795437955379563795737958379593796037961379623796337964379653796637967379683796937970379713797237973379743797537976379773797837979379803798137982379833798437985379863798737988379893799037991379923799337994379953799637997379983799938000380013800238003380043800538006380073800838009380103801138012380133801438015380163801738018380193802038021380223802338024380253802638027380283802938030380313803238033380343803538036380373803838039380403804138042380433804438045380463804738048380493805038051380523805338054380553805638057380583805938060380613806238063380643806538066380673806838069380703807138072380733807438075380763807738078380793808038081380823808338084380853808638087380883808938090380913809238093380943809538096380973809838099381003810138102381033810438105381063810738108381093811038111381123811338114381153811638117381183811938120381213812238123381243812538126381273812838129381303813138132381333813438135381363813738138381393814038141381423814338144381453814638147381483814938150381513815238153381543815538156381573815838159381603816138162381633816438165381663816738168381693817038171381723817338174381753817638177381783817938180381813818238183381843818538186381873818838189381903819138192381933819438195381963819738198381993820038201382023820338204382053820638207382083820938210382113821238213382143821538216382173821838219382203822138222382233822438225382263822738228382293823038231382323823338234382353823638237382383823938240382413824238243382443824538246382473824838249382503825138252382533825438255382563825738258382593826038261382623826338264382653826638267382683826938270382713827238273382743827538276382773827838279382803828138282382833828438285382863828738288382893829038291382923829338294382953829638297382983829938300383013830238303383043830538306383073830838309383103831138312383133831438315383163831738318383193832038321383223832338324383253832638327383283832938330383313833238333383343833538336383373833838339383403834138342383433834438345383463834738348383493835038351383523835338354383553835638357383583835938360383613836238363383643836538366383673836838369383703837138372383733837438375383763837738378383793838038381383823838338384383853838638387383883838938390383913839238393383943839538396383973839838399384003840138402384033840438405384063840738408384093841038411384123841338414384153841638417384183841938420384213842238423384243842538426384273842838429384303843138432384333843438435384363843738438384393844038441384423844338444384453844638447384483844938450384513845238453384543845538456384573845838459384603846138462384633846438465384663846738468384693847038471384723847338474384753847638477384783847938480384813848238483384843848538486384873848838489384903849138492384933849438495384963849738498384993850038501385023850338504385053850638507385083850938510385113851238513385143851538516385173851838519385203852138522385233852438525385263852738528385293853038531385323853338534385353853638537385383853938540385413854238543385443854538546385473854838549385503855138552385533855438555385563855738558385593856038561385623856338564385653856638567385683856938570385713857238573385743857538576385773857838579385803858138582385833858438585385863858738588385893859038591385923859338594385953859638597385983859938600386013860238603386043860538606386073860838609386103861138612386133861438615386163861738618386193862038621386223862338624386253862638627386283862938630386313863238633386343863538636386373863838639386403864138642386433864438645386463864738648386493865038651386523865338654386553865638657386583865938660386613866238663386643866538666386673866838669386703867138672386733867438675386763867738678386793868038681386823868338684386853868638687386883868938690386913869238693386943869538696386973869838699387003870138702387033870438705387063870738708387093871038711387123871338714387153871638717387183871938720387213872238723387243872538726387273872838729387303873138732387333873438735387363873738738387393874038741387423874338744387453874638747387483874938750387513875238753387543875538756387573875838759387603876138762387633876438765387663876738768387693877038771387723877338774387753877638777387783877938780387813878238783387843878538786387873878838789387903879138792387933879438795387963879738798387993880038801388023880338804388053880638807388083880938810388113881238813388143881538816388173881838819388203882138822388233882438825388263882738828388293883038831388323883338834388353883638837388383883938840388413884238843388443884538846388473884838849388503885138852388533885438855388563885738858388593886038861388623886338864388653886638867388683886938870388713887238873388743887538876388773887838879388803888138882388833888438885388863888738888388893889038891388923889338894388953889638897388983889938900389013890238903389043890538906389073890838909389103891138912389133891438915389163891738918389193892038921389223892338924389253892638927389283892938930389313893238933389343893538936389373893838939389403894138942389433894438945389463894738948389493895038951389523895338954389553895638957389583895938960389613896238963389643896538966389673896838969389703897138972389733897438975389763897738978389793898038981389823898338984389853898638987389883898938990389913899238993389943899538996389973899838999390003900139002390033900439005390063900739008390093901039011390123901339014390153901639017390183901939020390213902239023390243902539026390273902839029390303903139032390333903439035390363903739038390393904039041390423904339044390453904639047390483904939050390513905239053390543905539056390573905839059390603906139062390633906439065390663906739068390693907039071390723907339074390753907639077390783907939080390813908239083390843908539086390873908839089390903909139092390933909439095390963909739098390993910039101391023910339104391053910639107391083910939110391113911239113391143911539116391173911839119391203912139122391233912439125391263912739128391293913039131391323913339134391353913639137391383913939140391413914239143391443914539146391473914839149391503915139152391533915439155391563915739158391593916039161391623916339164391653916639167391683916939170391713917239173391743917539176391773917839179391803918139182391833918439185391863918739188391893919039191391923919339194391953919639197391983919939200392013920239203392043920539206392073920839209392103921139212392133921439215392163921739218392193922039221392223922339224392253922639227392283922939230392313923239233392343923539236392373923839239392403924139242392433924439245392463924739248392493925039251392523925339254392553925639257392583925939260392613926239263392643926539266392673926839269392703927139272392733927439275392763927739278392793928039281392823928339284392853928639287392883928939290392913929239293392943929539296392973929839299393003930139302393033930439305393063930739308393093931039311393123931339314393153931639317393183931939320393213932239323393243932539326393273932839329393303933139332393333933439335393363933739338393393934039341393423934339344393453934639347393483934939350393513935239353393543935539356393573935839359393603936139362393633936439365393663936739368393693937039371393723937339374393753937639377393783937939380393813938239383393843938539386393873938839389393903939139392393933939439395393963939739398393993940039401394023940339404394053940639407394083940939410394113941239413394143941539416394173941839419394203942139422394233942439425394263942739428394293943039431394323943339434394353943639437394383943939440394413944239443394443944539446394473944839449394503945139452394533945439455394563945739458394593946039461394623946339464394653946639467394683946939470394713947239473394743947539476394773947839479394803948139482394833948439485394863948739488394893949039491394923949339494394953949639497394983949939500395013950239503395043950539506395073950839509395103951139512395133951439515395163951739518395193952039521395223952339524395253952639527395283952939530395313953239533395343953539536395373953839539395403954139542395433954439545395463954739548395493955039551395523955339554395553955639557395583955939560395613956239563395643956539566395673956839569395703957139572395733957439575395763957739578395793958039581395823958339584395853958639587395883958939590395913959239593395943959539596395973959839599396003960139602396033960439605396063960739608396093961039611396123961339614396153961639617396183961939620396213962239623396243962539626396273962839629396303963139632396333963439635396363963739638396393964039641396423964339644396453964639647396483964939650396513965239653396543965539656396573965839659396603966139662396633966439665396663966739668396693967039671396723967339674396753967639677396783967939680396813968239683396843968539686396873968839689396903969139692396933969439695396963969739698396993970039701397023970339704397053970639707397083970939710397113971239713397143971539716397173971839719397203972139722397233972439725397263972739728397293973039731397323973339734397353973639737397383973939740397413974239743397443974539746397473974839749397503975139752397533975439755397563975739758397593976039761397623976339764397653976639767397683976939770397713977239773397743977539776397773977839779397803978139782397833978439785397863978739788397893979039791397923979339794397953979639797397983979939800398013980239803398043980539806398073980839809398103981139812398133981439815398163981739818398193982039821398223982339824398253982639827398283982939830398313983239833398343983539836398373983839839398403984139842398433984439845398463984739848398493985039851398523985339854398553985639857398583985939860398613986239863398643986539866398673986839869398703987139872398733987439875398763987739878398793988039881398823988339884398853988639887398883988939890398913989239893398943989539896398973989839899399003990139902399033990439905399063990739908399093991039911399123991339914399153991639917399183991939920399213992239923399243992539926399273992839929399303993139932399333993439935399363993739938399393994039941399423994339944399453994639947399483994939950399513995239953399543995539956399573995839959399603996139962399633996439965399663996739968399693997039971399723997339974399753997639977399783997939980399813998239983399843998539986399873998839989399903999139992399933999439995399963999739998399994000040001400024000340004400054000640007400084000940010400114001240013400144001540016400174001840019400204002140022400234002440025400264002740028400294003040031400324003340034400354003640037400384003940040400414004240043400444004540046400474004840049400504005140052400534005440055400564005740058400594006040061400624006340064400654006640067400684006940070400714007240073400744007540076400774007840079400804008140082400834008440085400864008740088400894009040091400924009340094400954009640097400984009940100401014010240103401044010540106401074010840109401104011140112401134011440115401164011740118401194012040121401224012340124401254012640127401284012940130401314013240133401344013540136401374013840139401404014140142401434014440145401464014740148401494015040151401524015340154401554015640157401584015940160401614016240163401644016540166401674016840169401704017140172401734017440175401764017740178401794018040181401824018340184401854018640187401884018940190401914019240193401944019540196401974019840199402004020140202402034020440205402064020740208402094021040211402124021340214402154021640217402184021940220402214022240223402244022540226402274022840229402304023140232402334023440235402364023740238402394024040241402424024340244402454024640247402484024940250402514025240253402544025540256402574025840259402604026140262402634026440265402664026740268402694027040271402724027340274402754027640277402784027940280402814028240283402844028540286402874028840289402904029140292402934029440295402964029740298402994030040301403024030340304403054030640307403084030940310403114031240313403144031540316403174031840319403204032140322403234032440325403264032740328403294033040331403324033340334403354033640337403384033940340403414034240343403444034540346403474034840349403504035140352403534035440355403564035740358403594036040361403624036340364403654036640367403684036940370403714037240373403744037540376403774037840379403804038140382403834038440385403864038740388403894039040391403924039340394403954039640397403984039940400404014040240403404044040540406404074040840409404104041140412404134041440415404164041740418404194042040421404224042340424404254042640427404284042940430404314043240433404344043540436404374043840439404404044140442404434044440445404464044740448404494045040451404524045340454404554045640457404584045940460404614046240463404644046540466404674046840469404704047140472404734047440475404764047740478404794048040481404824048340484404854048640487404884048940490404914049240493404944049540496404974049840499405004050140502405034050440505405064050740508405094051040511405124051340514405154051640517405184051940520405214052240523405244052540526405274052840529405304053140532405334053440535405364053740538405394054040541405424054340544405454054640547405484054940550405514055240553405544055540556405574055840559405604056140562405634056440565405664056740568405694057040571405724057340574405754057640577405784057940580405814058240583405844058540586405874058840589405904059140592405934059440595405964059740598405994060040601406024060340604406054060640607406084060940610406114061240613406144061540616406174061840619406204062140622406234062440625406264062740628406294063040631406324063340634406354063640637406384063940640406414064240643406444064540646406474064840649406504065140652406534065440655406564065740658406594066040661406624066340664406654066640667406684066940670406714067240673406744067540676406774067840679406804068140682406834068440685406864068740688406894069040691406924069340694406954069640697406984069940700407014070240703407044070540706407074070840709407104071140712407134071440715407164071740718407194072040721407224072340724407254072640727407284072940730407314073240733407344073540736407374073840739407404074140742407434074440745407464074740748407494075040751407524075340754407554075640757407584075940760407614076240763407644076540766407674076840769407704077140772407734077440775407764077740778407794078040781407824078340784407854078640787407884078940790407914079240793407944079540796407974079840799408004080140802408034080440805408064080740808408094081040811408124081340814408154081640817408184081940820408214082240823408244082540826408274082840829408304083140832408334083440835408364083740838408394084040841408424084340844408454084640847408484084940850408514085240853408544085540856408574085840859408604086140862408634086440865408664086740868408694087040871408724087340874408754087640877408784087940880408814088240883408844088540886408874088840889408904089140892408934089440895408964089740898408994090040901409024090340904409054090640907409084090940910409114091240913409144091540916409174091840919409204092140922409234092440925409264092740928409294093040931409324093340934409354093640937409384093940940409414094240943409444094540946409474094840949409504095140952409534095440955409564095740958409594096040961409624096340964409654096640967409684096940970409714097240973409744097540976409774097840979409804098140982409834098440985409864098740988409894099040991409924099340994409954099640997409984099941000410014100241003410044100541006410074100841009410104101141012410134101441015410164101741018410194102041021410224102341024410254102641027410284102941030410314103241033410344103541036410374103841039410404104141042410434104441045410464104741048410494105041051410524105341054410554105641057410584105941060410614106241063410644106541066410674106841069410704107141072410734107441075410764107741078410794108041081410824108341084410854108641087410884108941090410914109241093410944109541096410974109841099411004110141102411034110441105411064110741108411094111041111411124111341114411154111641117411184111941120411214112241123411244112541126411274112841129411304113141132411334113441135411364113741138411394114041141411424114341144411454114641147411484114941150411514115241153411544115541156411574115841159411604116141162411634116441165411664116741168411694117041171411724117341174411754117641177411784117941180411814118241183411844118541186411874118841189411904119141192411934119441195411964119741198411994120041201412024120341204412054120641207412084120941210412114121241213412144121541216412174121841219412204122141222412234122441225412264122741228412294123041231412324123341234412354123641237412384123941240412414124241243412444124541246412474124841249412504125141252412534125441255412564125741258412594126041261412624126341264412654126641267412684126941270412714127241273412744127541276412774127841279412804128141282412834128441285412864128741288412894129041291412924129341294412954129641297412984129941300413014130241303413044130541306413074130841309413104131141312413134131441315413164131741318413194132041321413224132341324413254132641327413284132941330413314133241333413344133541336413374133841339413404134141342413434134441345413464134741348413494135041351413524135341354413554135641357413584135941360413614136241363413644136541366413674136841369413704137141372413734137441375413764137741378413794138041381413824138341384413854138641387413884138941390413914139241393413944139541396413974139841399414004140141402414034140441405414064140741408414094141041411414124141341414414154141641417414184141941420414214142241423414244142541426414274142841429414304143141432414334143441435414364143741438414394144041441414424144341444414454144641447414484144941450414514145241453414544145541456414574145841459414604146141462414634146441465414664146741468414694147041471414724147341474414754147641477414784147941480414814148241483414844148541486414874148841489414904149141492414934149441495414964149741498414994150041501415024150341504415054150641507415084150941510415114151241513415144151541516415174151841519415204152141522415234152441525415264152741528415294153041531415324153341534415354153641537415384153941540415414154241543415444154541546415474154841549415504155141552415534155441555415564155741558415594156041561415624156341564415654156641567415684156941570415714157241573415744157541576415774157841579415804158141582415834158441585415864158741588415894159041591415924159341594415954159641597415984159941600416014160241603416044160541606416074160841609416104161141612416134161441615416164161741618416194162041621416224162341624416254162641627416284162941630416314163241633416344163541636416374163841639416404164141642416434164441645416464164741648416494165041651416524165341654416554165641657416584165941660416614166241663416644166541666416674166841669416704167141672416734167441675416764167741678416794168041681416824168341684416854168641687416884168941690416914169241693416944169541696416974169841699417004170141702417034170441705417064170741708417094171041711417124171341714417154171641717417184171941720417214172241723417244172541726417274172841729417304173141732417334173441735417364173741738417394174041741417424174341744417454174641747417484174941750417514175241753417544175541756417574175841759417604176141762417634176441765417664176741768417694177041771417724177341774417754177641777417784177941780417814178241783417844178541786417874178841789417904179141792417934179441795417964179741798417994180041801418024180341804418054180641807418084180941810418114181241813418144181541816418174181841819418204182141822418234182441825418264182741828418294183041831418324183341834418354183641837418384183941840418414184241843418444184541846418474184841849418504185141852418534185441855418564185741858418594186041861418624186341864418654186641867418684186941870418714187241873418744187541876418774187841879418804188141882418834188441885418864188741888418894189041891418924189341894418954189641897418984189941900419014190241903419044190541906419074190841909419104191141912419134191441915419164191741918419194192041921419224192341924419254192641927419284192941930419314193241933419344193541936419374193841939419404194141942419434194441945419464194741948419494195041951419524195341954419554195641957419584195941960419614196241963419644196541966419674196841969419704197141972419734197441975419764197741978419794198041981419824198341984419854198641987419884198941990419914199241993419944199541996419974199841999420004200142002420034200442005420064200742008420094201042011420124201342014420154201642017420184201942020420214202242023420244202542026420274202842029420304203142032420334203442035420364203742038420394204042041420424204342044420454204642047420484204942050420514205242053420544205542056420574205842059420604206142062420634206442065420664206742068420694207042071420724207342074420754207642077420784207942080420814208242083420844208542086420874208842089420904209142092420934209442095420964209742098420994210042101421024210342104421054210642107421084210942110421114211242113421144211542116421174211842119421204212142122421234212442125421264212742128421294213042131421324213342134421354213642137421384213942140421414214242143421444214542146421474214842149421504215142152421534215442155421564215742158421594216042161421624216342164421654216642167421684216942170421714217242173421744217542176421774217842179421804218142182421834218442185421864218742188421894219042191421924219342194421954219642197421984219942200422014220242203422044220542206422074220842209422104221142212422134221442215422164221742218422194222042221422224222342224422254222642227422284222942230422314223242233422344223542236422374223842239422404224142242422434224442245422464224742248422494225042251422524225342254422554225642257422584225942260422614226242263422644226542266422674226842269422704227142272422734227442275422764227742278422794228042281422824228342284422854228642287422884228942290422914229242293422944229542296422974229842299423004230142302423034230442305423064230742308423094231042311423124231342314423154231642317423184231942320423214232242323423244232542326423274232842329423304233142332423334233442335423364233742338423394234042341423424234342344423454234642347423484234942350423514235242353423544235542356423574235842359423604236142362423634236442365423664236742368423694237042371423724237342374423754237642377423784237942380423814238242383423844238542386423874238842389423904239142392423934239442395423964239742398423994240042401424024240342404424054240642407424084240942410424114241242413424144241542416424174241842419424204242142422424234242442425424264242742428424294243042431424324243342434424354243642437424384243942440424414244242443424444244542446424474244842449424504245142452424534245442455424564245742458424594246042461424624246342464424654246642467424684246942470424714247242473424744247542476424774247842479424804248142482424834248442485424864248742488424894249042491424924249342494424954249642497424984249942500425014250242503425044250542506425074250842509425104251142512425134251442515425164251742518425194252042521425224252342524425254252642527425284252942530425314253242533425344253542536425374253842539425404254142542425434254442545425464254742548425494255042551425524255342554425554255642557425584255942560425614256242563425644256542566425674256842569425704257142572425734257442575425764257742578425794258042581425824258342584425854258642587425884258942590425914259242593425944259542596425974259842599426004260142602426034260442605426064260742608426094261042611426124261342614426154261642617426184261942620426214262242623426244262542626426274262842629426304263142632426334263442635426364263742638426394264042641426424264342644426454264642647426484264942650426514265242653426544265542656426574265842659426604266142662426634266442665426664266742668426694267042671426724267342674426754267642677426784267942680426814268242683426844268542686426874268842689426904269142692426934269442695426964269742698426994270042701427024270342704427054270642707427084270942710427114271242713427144271542716427174271842719427204272142722427234272442725427264272742728427294273042731427324273342734427354273642737427384273942740427414274242743427444274542746427474274842749427504275142752427534275442755427564275742758427594276042761427624276342764427654276642767427684276942770427714277242773427744277542776427774277842779427804278142782427834278442785427864278742788427894279042791427924279342794427954279642797427984279942800428014280242803428044280542806428074280842809428104281142812428134281442815428164281742818428194282042821428224282342824428254282642827428284282942830428314283242833428344283542836428374283842839428404284142842428434284442845428464284742848428494285042851428524285342854428554285642857428584285942860428614286242863428644286542866428674286842869428704287142872428734287442875428764287742878428794288042881428824288342884428854288642887428884288942890428914289242893428944289542896428974289842899429004290142902429034290442905429064290742908429094291042911429124291342914429154291642917429184291942920429214292242923429244292542926429274292842929429304293142932429334293442935429364293742938429394294042941429424294342944429454294642947429484294942950429514295242953429544295542956429574295842959429604296142962429634296442965429664296742968429694297042971429724297342974429754297642977429784297942980429814298242983429844298542986429874298842989429904299142992429934299442995429964299742998429994300043001430024300343004430054300643007430084300943010430114301243013430144301543016430174301843019430204302143022430234302443025430264302743028430294303043031430324303343034430354303643037430384303943040430414304243043430444304543046430474304843049430504305143052430534305443055430564305743058430594306043061430624306343064430654306643067430684306943070430714307243073430744307543076430774307843079430804308143082430834308443085430864308743088430894309043091430924309343094430954309643097430984309943100431014310243103431044310543106431074310843109431104311143112431134311443115431164311743118431194312043121431224312343124431254312643127431284312943130431314313243133431344313543136431374313843139431404314143142431434314443145431464314743148431494315043151431524315343154431554315643157431584315943160431614316243163431644316543166431674316843169431704317143172431734317443175431764317743178431794318043181431824318343184431854318643187431884318943190431914319243193431944319543196431974319843199432004320143202432034320443205432064320743208432094321043211432124321343214432154321643217432184321943220432214322243223432244322543226432274322843229432304323143232432334323443235432364323743238432394324043241432424324343244432454324643247432484324943250432514325243253432544325543256432574325843259432604326143262432634326443265432664326743268432694327043271432724327343274432754327643277432784327943280432814328243283432844328543286432874328843289432904329143292432934329443295432964329743298432994330043301433024330343304433054330643307433084330943310433114331243313433144331543316433174331843319433204332143322433234332443325433264332743328433294333043331433324333343334433354333643337433384333943340433414334243343433444334543346433474334843349433504335143352433534335443355433564335743358433594336043361433624336343364433654336643367433684336943370433714337243373433744337543376433774337843379433804338143382433834338443385433864338743388433894339043391433924339343394433954339643397433984339943400434014340243403434044340543406434074340843409434104341143412434134341443415434164341743418434194342043421434224342343424434254342643427434284342943430434314343243433434344343543436434374343843439434404344143442434434344443445434464344743448434494345043451434524345343454434554345643457434584345943460434614346243463434644346543466434674346843469434704347143472434734347443475434764347743478434794348043481434824348343484434854348643487434884348943490434914349243493434944349543496434974349843499435004350143502435034350443505435064350743508435094351043511435124351343514435154351643517435184351943520435214352243523435244352543526435274352843529435304353143532435334353443535435364353743538435394354043541435424354343544435454354643547435484354943550435514355243553435544355543556435574355843559435604356143562435634356443565435664356743568435694357043571435724357343574435754357643577435784357943580435814358243583435844358543586435874358843589435904359143592435934359443595435964359743598435994360043601436024360343604436054360643607436084360943610436114361243613436144361543616436174361843619436204362143622436234362443625436264362743628436294363043631436324363343634436354363643637436384363943640436414364243643436444364543646436474364843649436504365143652436534365443655436564365743658436594366043661436624366343664436654366643667436684366943670436714367243673436744367543676436774367843679436804368143682436834368443685436864368743688436894369043691436924369343694436954369643697436984369943700437014370243703437044370543706437074370843709437104371143712437134371443715437164371743718437194372043721437224372343724437254372643727437284372943730437314373243733437344373543736437374373843739437404374143742437434374443745437464374743748437494375043751437524375343754437554375643757437584375943760437614376243763437644376543766437674376843769437704377143772437734377443775437764377743778437794378043781437824378343784437854378643787437884378943790437914379243793437944379543796437974379843799438004380143802438034380443805438064380743808438094381043811438124381343814438154381643817438184381943820438214382243823438244382543826438274382843829438304383143832438334383443835438364383743838438394384043841438424384343844438454384643847438484384943850438514385243853438544385543856438574385843859438604386143862438634386443865438664386743868438694387043871438724387343874438754387643877438784387943880438814388243883438844388543886438874388843889438904389143892438934389443895438964389743898438994390043901439024390343904439054390643907439084390943910439114391243913439144391543916439174391843919439204392143922439234392443925439264392743928439294393043931439324393343934439354393643937439384393943940439414394243943439444394543946439474394843949439504395143952439534395443955439564395743958439594396043961439624396343964439654396643967439684396943970439714397243973439744397543976439774397843979439804398143982439834398443985439864398743988439894399043991439924399343994439954399643997439984399944000440014400244003440044400544006440074400844009440104401144012440134401444015440164401744018440194402044021440224402344024440254402644027440284402944030440314403244033440344403544036440374403844039440404404144042440434404444045440464404744048440494405044051440524405344054440554405644057440584405944060440614406244063440644406544066440674406844069440704407144072440734407444075440764407744078440794408044081440824408344084440854408644087440884408944090440914409244093440944409544096440974409844099441004410144102441034410444105441064410744108441094411044111441124411344114441154411644117441184411944120441214412244123441244412544126441274412844129441304413144132441334413444135441364413744138441394414044141441424414344144441454414644147441484414944150441514415244153441544415544156441574415844159441604416144162441634416444165441664416744168441694417044171441724417344174441754417644177441784417944180441814418244183441844418544186441874418844189441904419144192441934419444195441964419744198441994420044201442024420344204442054420644207442084420944210442114421244213442144421544216442174421844219442204422144222442234422444225442264422744228442294423044231442324423344234442354423644237442384423944240442414424244243442444424544246442474424844249442504425144252442534425444255442564425744258442594426044261442624426344264442654426644267442684426944270442714427244273442744427544276442774427844279442804428144282442834428444285442864428744288442894429044291442924429344294442954429644297442984429944300443014430244303443044430544306443074430844309443104431144312443134431444315443164431744318443194432044321443224432344324443254432644327443284432944330443314433244333443344433544336443374433844339443404434144342443434434444345443464434744348443494435044351443524435344354443554435644357443584435944360443614436244363443644436544366443674436844369443704437144372443734437444375443764437744378443794438044381443824438344384443854438644387443884438944390443914439244393443944439544396443974439844399444004440144402444034440444405444064440744408444094441044411444124441344414444154441644417444184441944420444214442244423444244442544426444274442844429444304443144432444334443444435444364443744438444394444044441444424444344444444454444644447444484444944450444514445244453444544445544456444574445844459444604446144462444634446444465444664446744468444694447044471444724447344474444754447644477444784447944480444814448244483444844448544486444874448844489444904449144492444934449444495444964449744498444994450044501445024450344504445054450644507445084450944510445114451244513445144451544516445174451844519445204452144522445234452444525445264452744528445294453044531445324453344534445354453644537445384453944540445414454244543445444454544546445474454844549445504455144552445534455444555445564455744558445594456044561445624456344564445654456644567445684456944570445714457244573445744457544576445774457844579445804458144582445834458444585445864458744588445894459044591445924459344594445954459644597445984459944600446014460244603446044460544606446074460844609446104461144612446134461444615446164461744618446194462044621446224462344624446254462644627446284462944630446314463244633446344463544636446374463844639446404464144642446434464444645446464464744648446494465044651446524465344654446554465644657446584465944660446614466244663446644466544666446674466844669446704467144672446734467444675446764467744678446794468044681446824468344684446854468644687446884468944690446914469244693446944469544696446974469844699447004470144702447034470444705447064470744708447094471044711447124471344714447154471644717447184471944720447214472244723447244472544726447274472844729447304473144732447334473444735447364473744738447394474044741447424474344744447454474644747447484474944750447514475244753447544475544756447574475844759447604476144762447634476444765447664476744768447694477044771447724477344774447754477644777447784477944780447814478244783447844478544786447874478844789447904479144792447934479444795447964479744798447994480044801448024480344804448054480644807448084480944810448114481244813448144481544816448174481844819448204482144822448234482444825448264482744828448294483044831448324483344834448354483644837448384483944840448414484244843448444484544846448474484844849448504485144852448534485444855448564485744858448594486044861448624486344864448654486644867448684486944870448714487244873448744487544876448774487844879448804488144882448834488444885448864488744888448894489044891448924489344894448954489644897448984489944900449014490244903449044490544906449074490844909449104491144912449134491444915449164491744918449194492044921449224492344924449254492644927449284492944930449314493244933449344493544936449374493844939449404494144942449434494444945449464494744948449494495044951449524495344954449554495644957449584495944960449614496244963449644496544966449674496844969449704497144972449734497444975449764497744978449794498044981449824498344984449854498644987449884498944990449914499244993449944499544996449974499844999450004500145002450034500445005450064500745008450094501045011450124501345014450154501645017450184501945020450214502245023450244502545026450274502845029450304503145032450334503445035450364503745038450394504045041450424504345044450454504645047450484504945050450514505245053450544505545056450574505845059450604506145062450634506445065450664506745068450694507045071450724507345074450754507645077450784507945080450814508245083450844508545086450874508845089450904509145092450934509445095450964509745098450994510045101451024510345104451054510645107451084510945110451114511245113451144511545116451174511845119451204512145122451234512445125451264512745128451294513045131451324513345134451354513645137451384513945140451414514245143451444514545146451474514845149451504515145152451534515445155451564515745158451594516045161451624516345164451654516645167451684516945170451714517245173451744517545176451774517845179451804518145182451834518445185451864518745188451894519045191451924519345194451954519645197451984519945200452014520245203452044520545206452074520845209452104521145212452134521445215452164521745218452194522045221452224522345224452254522645227452284522945230452314523245233452344523545236452374523845239452404524145242452434524445245452464524745248452494525045251452524525345254452554525645257452584525945260452614526245263452644526545266452674526845269452704527145272452734527445275452764527745278452794528045281452824528345284452854528645287452884528945290452914529245293452944529545296452974529845299453004530145302453034530445305453064530745308453094531045311453124531345314453154531645317453184531945320453214532245323453244532545326453274532845329453304533145332453334533445335453364533745338453394534045341453424534345344453454534645347453484534945350453514535245353453544535545356453574535845359453604536145362453634536445365453664536745368453694537045371453724537345374453754537645377453784537945380453814538245383453844538545386453874538845389453904539145392453934539445395453964539745398453994540045401454024540345404454054540645407454084540945410454114541245413454144541545416454174541845419454204542145422454234542445425454264542745428454294543045431454324543345434454354543645437454384543945440454414544245443454444544545446454474544845449454504545145452454534545445455454564545745458454594546045461454624546345464454654546645467454684546945470454714547245473454744547545476454774547845479454804548145482454834548445485454864548745488454894549045491454924549345494454954549645497454984549945500455014550245503455044550545506455074550845509455104551145512455134551445515455164551745518455194552045521455224552345524455254552645527455284552945530455314553245533455344553545536455374553845539455404554145542455434554445545455464554745548455494555045551455524555345554455554555645557455584555945560455614556245563455644556545566455674556845569455704557145572455734557445575455764557745578455794558045581455824558345584455854558645587455884558945590455914559245593455944559545596455974559845599456004560145602456034560445605456064560745608456094561045611456124561345614456154561645617456184561945620456214562245623456244562545626456274562845629456304563145632456334563445635456364563745638456394564045641456424564345644456454564645647456484564945650456514565245653456544565545656456574565845659456604566145662456634566445665456664566745668456694567045671456724567345674456754567645677456784567945680456814568245683456844568545686456874568845689456904569145692456934569445695456964569745698456994570045701457024570345704457054570645707457084570945710457114571245713457144571545716457174571845719457204572145722457234572445725457264572745728457294573045731457324573345734457354573645737457384573945740457414574245743457444574545746457474574845749457504575145752457534575445755457564575745758457594576045761457624576345764457654576645767457684576945770457714577245773457744577545776457774577845779457804578145782457834578445785457864578745788457894579045791457924579345794457954579645797457984579945800458014580245803458044580545806458074580845809458104581145812458134581445815458164581745818458194582045821458224582345824458254582645827458284582945830458314583245833458344583545836458374583845839458404584145842458434584445845458464584745848458494585045851458524585345854458554585645857458584585945860458614586245863458644586545866458674586845869458704587145872458734587445875458764587745878458794588045881458824588345884458854588645887458884588945890458914589245893458944589545896458974589845899459004590145902459034590445905459064590745908459094591045911459124591345914459154591645917459184591945920459214592245923459244592545926459274592845929459304593145932459334593445935459364593745938459394594045941459424594345944459454594645947459484594945950459514595245953459544595545956459574595845959459604596145962459634596445965459664596745968459694597045971459724597345974459754597645977459784597945980459814598245983459844598545986459874598845989459904599145992459934599445995459964599745998459994600046001460024600346004460054600646007460084600946010460114601246013460144601546016460174601846019460204602146022460234602446025460264602746028460294603046031460324603346034460354603646037460384603946040460414604246043460444604546046460474604846049460504605146052460534605446055460564605746058460594606046061460624606346064460654606646067460684606946070460714607246073460744607546076460774607846079460804608146082460834608446085460864608746088460894609046091460924609346094460954609646097460984609946100461014610246103461044610546106461074610846109461104611146112461134611446115461164611746118461194612046121461224612346124461254612646127461284612946130461314613246133461344613546136461374613846139461404614146142461434614446145461464614746148461494615046151461524615346154461554615646157461584615946160461614616246163461644616546166461674616846169461704617146172461734617446175461764617746178461794618046181461824618346184461854618646187461884618946190461914619246193461944619546196461974619846199462004620146202462034620446205462064620746208462094621046211462124621346214462154621646217462184621946220462214622246223462244622546226462274622846229462304623146232462334623446235462364623746238462394624046241462424624346244462454624646247462484624946250462514625246253462544625546256462574625846259462604626146262462634626446265462664626746268462694627046271462724627346274462754627646277462784627946280462814628246283462844628546286462874628846289462904629146292462934629446295462964629746298462994630046301463024630346304463054630646307463084630946310463114631246313463144631546316463174631846319463204632146322463234632446325463264632746328463294633046331463324633346334463354633646337463384633946340463414634246343463444634546346463474634846349463504635146352463534635446355463564635746358463594636046361463624636346364463654636646367463684636946370463714637246373463744637546376463774637846379463804638146382463834638446385463864638746388463894639046391463924639346394463954639646397463984639946400464014640246403464044640546406464074640846409464104641146412464134641446415464164641746418464194642046421464224642346424464254642646427464284642946430464314643246433464344643546436464374643846439464404644146442464434644446445464464644746448464494645046451464524645346454464554645646457464584645946460464614646246463464644646546466464674646846469464704647146472464734647446475464764647746478464794648046481464824648346484464854648646487464884648946490464914649246493464944649546496464974649846499465004650146502465034650446505465064650746508465094651046511465124651346514465154651646517465184651946520465214652246523465244652546526465274652846529465304653146532465334653446535465364653746538465394654046541465424654346544465454654646547465484654946550465514655246553465544655546556465574655846559465604656146562465634656446565465664656746568465694657046571465724657346574465754657646577465784657946580465814658246583465844658546586465874658846589465904659146592465934659446595465964659746598465994660046601466024660346604466054660646607466084660946610466114661246613466144661546616466174661846619466204662146622466234662446625466264662746628466294663046631466324663346634466354663646637466384663946640466414664246643466444664546646466474664846649466504665146652466534665446655466564665746658466594666046661466624666346664466654666646667466684666946670466714667246673466744667546676466774667846679466804668146682466834668446685466864668746688466894669046691466924669346694466954669646697466984669946700467014670246703467044670546706467074670846709467104671146712467134671446715467164671746718467194672046721467224672346724467254672646727467284672946730467314673246733467344673546736467374673846739467404674146742467434674446745467464674746748467494675046751467524675346754467554675646757467584675946760467614676246763467644676546766467674676846769467704677146772467734677446775467764677746778467794678046781467824678346784467854678646787467884678946790467914679246793467944679546796467974679846799468004680146802468034680446805468064680746808468094681046811468124681346814468154681646817468184681946820468214682246823468244682546826468274682846829468304683146832468334683446835468364683746838468394684046841468424684346844468454684646847468484684946850468514685246853468544685546856468574685846859468604686146862468634686446865468664686746868468694687046871468724687346874468754687646877468784687946880468814688246883468844688546886468874688846889468904689146892468934689446895468964689746898468994690046901469024690346904469054690646907469084690946910469114691246913469144691546916469174691846919469204692146922469234692446925469264692746928469294693046931469324693346934469354693646937469384693946940469414694246943469444694546946469474694846949469504695146952469534695446955469564695746958469594696046961469624696346964469654696646967469684696946970469714697246973469744697546976469774697846979469804698146982469834698446985469864698746988469894699046991469924699346994469954699646997469984699947000470014700247003470044700547006470074700847009470104701147012470134701447015470164701747018470194702047021470224702347024470254702647027470284702947030470314703247033470344703547036470374703847039470404704147042470434704447045470464704747048470494705047051470524705347054470554705647057470584705947060470614706247063470644706547066470674706847069470704707147072470734707447075470764707747078470794708047081470824708347084470854708647087470884708947090470914709247093470944709547096470974709847099471004710147102471034710447105471064710747108471094711047111471124711347114471154711647117471184711947120471214712247123471244712547126471274712847129471304713147132471334713447135471364713747138471394714047141471424714347144471454714647147471484714947150471514715247153471544715547156471574715847159471604716147162471634716447165471664716747168471694717047171471724717347174471754717647177471784717947180471814718247183471844718547186471874718847189471904719147192471934719447195471964719747198471994720047201472024720347204472054720647207472084720947210472114721247213472144721547216472174721847219472204722147222472234722447225472264722747228472294723047231472324723347234472354723647237472384723947240472414724247243472444724547246472474724847249472504725147252472534725447255472564725747258472594726047261472624726347264472654726647267472684726947270472714727247273472744727547276472774727847279472804728147282472834728447285472864728747288472894729047291472924729347294472954729647297472984729947300473014730247303473044730547306473074730847309473104731147312473134731447315473164731747318473194732047321473224732347324473254732647327473284732947330473314733247333473344733547336473374733847339473404734147342473434734447345473464734747348473494735047351473524735347354473554735647357473584735947360473614736247363473644736547366473674736847369473704737147372473734737447375473764737747378473794738047381473824738347384473854738647387473884738947390473914739247393473944739547396473974739847399474004740147402474034740447405474064740747408474094741047411474124741347414474154741647417474184741947420474214742247423474244742547426474274742847429474304743147432474334743447435474364743747438474394744047441474424744347444474454744647447474484744947450474514745247453474544745547456474574745847459474604746147462474634746447465474664746747468474694747047471474724747347474474754747647477474784747947480474814748247483474844748547486474874748847489474904749147492474934749447495474964749747498474994750047501475024750347504475054750647507475084750947510475114751247513475144751547516475174751847519475204752147522475234752447525475264752747528475294753047531475324753347534475354753647537475384753947540475414754247543475444754547546475474754847549475504755147552475534755447555475564755747558475594756047561475624756347564475654756647567475684756947570475714757247573475744757547576475774757847579475804758147582475834758447585475864758747588475894759047591475924759347594475954759647597475984759947600476014760247603476044760547606476074760847609476104761147612476134761447615476164761747618476194762047621476224762347624476254762647627476284762947630476314763247633476344763547636476374763847639476404764147642476434764447645476464764747648476494765047651476524765347654476554765647657476584765947660476614766247663476644766547666476674766847669476704767147672476734767447675476764767747678476794768047681476824768347684476854768647687476884768947690476914769247693476944769547696476974769847699477004770147702477034770447705477064770747708477094771047711477124771347714477154771647717477184771947720477214772247723477244772547726477274772847729477304773147732477334773447735477364773747738477394774047741477424774347744477454774647747477484774947750477514775247753477544775547756477574775847759477604776147762477634776447765477664776747768477694777047771477724777347774477754777647777477784777947780477814778247783477844778547786477874778847789477904779147792477934779447795477964779747798477994780047801478024780347804478054780647807478084780947810478114781247813478144781547816478174781847819478204782147822478234782447825478264782747828478294783047831478324783347834478354783647837478384783947840478414784247843478444784547846478474784847849478504785147852478534785447855478564785747858478594786047861478624786347864478654786647867478684786947870478714787247873478744787547876478774787847879478804788147882478834788447885478864788747888478894789047891478924789347894478954789647897478984789947900479014790247903479044790547906479074790847909479104791147912479134791447915479164791747918479194792047921479224792347924479254792647927479284792947930479314793247933479344793547936479374793847939479404794147942479434794447945479464794747948479494795047951479524795347954479554795647957479584795947960479614796247963479644796547966479674796847969479704797147972479734797447975479764797747978479794798047981479824798347984479854798647987479884798947990479914799247993479944799547996479974799847999480004800148002480034800448005480064800748008480094801048011480124801348014480154801648017480184801948020480214802248023480244802548026480274802848029480304803148032480334803448035480364803748038480394804048041480424804348044480454804648047480484804948050480514805248053480544805548056480574805848059480604806148062480634806448065480664806748068480694807048071480724807348074480754807648077480784807948080480814808248083480844808548086480874808848089480904809148092480934809448095480964809748098480994810048101481024810348104481054810648107481084810948110481114811248113481144811548116481174811848119481204812148122481234812448125481264812748128481294813048131481324813348134481354813648137481384813948140481414814248143481444814548146481474814848149481504815148152481534815448155481564815748158481594816048161481624816348164481654816648167481684816948170481714817248173481744817548176481774817848179481804818148182481834818448185481864818748188481894819048191481924819348194481954819648197481984819948200482014820248203482044820548206482074820848209482104821148212482134821448215482164821748218482194822048221482224822348224482254822648227482284822948230482314823248233482344823548236482374823848239482404824148242482434824448245482464824748248482494825048251482524825348254482554825648257482584825948260482614826248263482644826548266482674826848269482704827148272482734827448275482764827748278482794828048281482824828348284482854828648287482884828948290482914829248293482944829548296482974829848299483004830148302483034830448305483064830748308483094831048311483124831348314483154831648317483184831948320483214832248323483244832548326483274832848329483304833148332483334833448335483364833748338483394834048341483424834348344483454834648347483484834948350483514835248353483544835548356483574835848359483604836148362483634836448365483664836748368483694837048371483724837348374483754837648377483784837948380483814838248383483844838548386483874838848389483904839148392483934839448395483964839748398483994840048401484024840348404484054840648407484084840948410484114841248413484144841548416484174841848419484204842148422484234842448425484264842748428484294843048431484324843348434484354843648437484384843948440484414844248443484444844548446484474844848449484504845148452484534845448455484564845748458484594846048461484624846348464484654846648467484684846948470484714847248473484744847548476484774847848479484804848148482484834848448485484864848748488484894849048491484924849348494484954849648497484984849948500485014850248503485044850548506485074850848509485104851148512485134851448515485164851748518485194852048521485224852348524485254852648527485284852948530485314853248533485344853548536485374853848539485404854148542485434854448545485464854748548485494855048551485524855348554485554855648557485584855948560485614856248563485644856548566485674856848569485704857148572485734857448575485764857748578485794858048581485824858348584485854858648587485884858948590485914859248593485944859548596485974859848599486004860148602486034860448605486064860748608486094861048611486124861348614486154861648617486184861948620486214862248623486244862548626486274862848629486304863148632486334863448635486364863748638486394864048641486424864348644486454864648647486484864948650486514865248653486544865548656486574865848659486604866148662486634866448665486664866748668486694867048671486724867348674486754867648677486784867948680486814868248683486844868548686486874868848689486904869148692486934869448695486964869748698486994870048701487024870348704487054870648707487084870948710487114871248713487144871548716487174871848719487204872148722487234872448725487264872748728487294873048731487324873348734487354873648737487384873948740487414874248743487444874548746487474874848749487504875148752487534875448755487564875748758487594876048761487624876348764487654876648767487684876948770487714877248773487744877548776487774877848779487804878148782487834878448785487864878748788487894879048791487924879348794487954879648797487984879948800488014880248803488044880548806488074880848809488104881148812488134881448815488164881748818488194882048821488224882348824488254882648827488284882948830488314883248833488344883548836488374883848839488404884148842488434884448845488464884748848488494885048851488524885348854488554885648857488584885948860488614886248863488644886548866488674886848869488704887148872488734887448875488764887748878488794888048881488824888348884488854888648887488884888948890488914889248893488944889548896488974889848899489004890148902489034890448905489064890748908489094891048911489124891348914489154891648917489184891948920489214892248923489244892548926489274892848929489304893148932489334893448935489364893748938489394894048941489424894348944489454894648947489484894948950489514895248953489544895548956489574895848959489604896148962489634896448965489664896748968489694897048971489724897348974489754897648977489784897948980489814898248983489844898548986489874898848989489904899148992489934899448995489964899748998489994900049001490024900349004490054900649007490084900949010490114901249013490144901549016490174901849019490204902149022490234902449025490264902749028490294903049031490324903349034490354903649037490384903949040490414904249043490444904549046490474904849049490504905149052490534905449055490564905749058490594906049061490624906349064490654906649067490684906949070490714907249073490744907549076490774907849079490804908149082490834908449085490864908749088490894909049091490924909349094490954909649097490984909949100491014910249103491044910549106491074910849109491104911149112491134911449115491164911749118491194912049121491224912349124491254912649127491284912949130491314913249133491344913549136491374913849139491404914149142491434914449145491464914749148491494915049151491524915349154491554915649157491584915949160491614916249163491644916549166491674916849169491704917149172491734917449175491764917749178491794918049181491824918349184491854918649187491884918949190491914919249193491944919549196491974919849199492004920149202492034920449205492064920749208492094921049211492124921349214492154921649217492184921949220492214922249223492244922549226492274922849229492304923149232492334923449235492364923749238492394924049241492424924349244492454924649247492484924949250492514925249253492544925549256492574925849259492604926149262492634926449265492664926749268492694927049271492724927349274492754927649277492784927949280492814928249283492844928549286492874928849289492904929149292492934929449295492964929749298492994930049301493024930349304493054930649307493084930949310493114931249313493144931549316493174931849319493204932149322493234932449325493264932749328493294933049331493324933349334493354933649337493384933949340493414934249343493444934549346493474934849349493504935149352493534935449355493564935749358493594936049361493624936349364493654936649367493684936949370493714937249373493744937549376493774937849379493804938149382493834938449385493864938749388493894939049391493924939349394493954939649397493984939949400494014940249403494044940549406494074940849409494104941149412494134941449415494164941749418494194942049421494224942349424494254942649427494284942949430494314943249433494344943549436494374943849439494404944149442494434944449445494464944749448494494945049451494524945349454494554945649457494584945949460494614946249463494644946549466494674946849469494704947149472494734947449475494764947749478494794948049481494824948349484494854948649487494884948949490494914949249493494944949549496494974949849499495004950149502495034950449505495064950749508495094951049511495124951349514495154951649517495184951949520495214952249523495244952549526495274952849529495304953149532495334953449535495364953749538495394954049541495424954349544495454954649547495484954949550495514955249553495544955549556495574955849559495604956149562495634956449565495664956749568495694957049571495724957349574495754957649577495784957949580495814958249583495844958549586495874958849589495904959149592495934959449595495964959749598495994960049601496024960349604496054960649607496084960949610496114961249613496144961549616496174961849619496204962149622496234962449625496264962749628496294963049631496324963349634496354963649637496384963949640496414964249643496444964549646496474964849649496504965149652496534965449655496564965749658496594966049661496624966349664496654966649667496684966949670496714967249673496744967549676496774967849679496804968149682496834968449685496864968749688496894969049691496924969349694496954969649697496984969949700497014970249703497044970549706497074970849709497104971149712497134971449715497164971749718497194972049721497224972349724497254972649727497284972949730497314973249733497344973549736497374973849739497404974149742497434974449745497464974749748497494975049751497524975349754497554975649757497584975949760497614976249763497644976549766497674976849769497704977149772497734977449775497764977749778497794978049781497824978349784497854978649787497884978949790497914979249793497944979549796497974979849799498004980149802498034980449805498064980749808498094981049811498124981349814498154981649817498184981949820498214982249823498244982549826498274982849829498304983149832498334983449835498364983749838498394984049841498424984349844498454984649847498484984949850498514985249853498544985549856498574985849859498604986149862498634986449865498664986749868498694987049871
  1. /*!
  2. * (C) Ionic http://ionicframework.com - MIT License
  3. */
  4. import { Readable } from 'stream';
  5. function hydrateFactory($stencilWindow, $stencilHydrateOpts, $stencilHydrateResults, $stencilAfterHydrate, $stencilHydrateResolve) {
  6. var globalThis = $stencilWindow;
  7. var self = $stencilWindow;
  8. var top = $stencilWindow;
  9. var parent = $stencilWindow;
  10. var addEventListener = $stencilWindow.addEventListener.bind($stencilWindow);
  11. var alert = $stencilWindow.alert.bind($stencilWindow);
  12. var blur = $stencilWindow.blur.bind($stencilWindow);
  13. var cancelAnimationFrame = $stencilWindow.cancelAnimationFrame.bind($stencilWindow);
  14. var cancelIdleCallback = $stencilWindow.cancelIdleCallback.bind($stencilWindow);
  15. var clearInterval = $stencilWindow.clearInterval.bind($stencilWindow);
  16. var clearTimeout = $stencilWindow.clearTimeout.bind($stencilWindow);
  17. var close = () => {};
  18. var confirm = $stencilWindow.confirm.bind($stencilWindow);
  19. var dispatchEvent = $stencilWindow.dispatchEvent.bind($stencilWindow);
  20. var focus = $stencilWindow.focus.bind($stencilWindow);
  21. var getComputedStyle = $stencilWindow.getComputedStyle.bind($stencilWindow);
  22. var matchMedia = $stencilWindow.matchMedia.bind($stencilWindow);
  23. var open = $stencilWindow.open.bind($stencilWindow);
  24. var prompt = $stencilWindow.prompt.bind($stencilWindow);
  25. var removeEventListener = $stencilWindow.removeEventListener.bind($stencilWindow);
  26. var requestAnimationFrame = $stencilWindow.requestAnimationFrame.bind($stencilWindow);
  27. var requestIdleCallback = $stencilWindow.requestIdleCallback.bind($stencilWindow);
  28. var setInterval = $stencilWindow.setInterval.bind($stencilWindow);
  29. var setTimeout = $stencilWindow.setTimeout.bind($stencilWindow);
  30. var CharacterData = $stencilWindow.CharacterData;
  31. var CSS = $stencilWindow.CSS;
  32. var CustomEvent = $stencilWindow.CustomEvent;
  33. var Document = $stencilWindow.Document;
  34. var DocumentFragment = $stencilWindow.DocumentFragment;
  35. var DocumentType = $stencilWindow.DocumentType;
  36. var DOMTokenList = $stencilWindow.DOMTokenList;
  37. var Element = $stencilWindow.Element;
  38. var Event = $stencilWindow.Event;
  39. var HTMLAnchorElement = $stencilWindow.HTMLAnchorElement;
  40. var HTMLBaseElement = $stencilWindow.HTMLBaseElement;
  41. var HTMLButtonElement = $stencilWindow.HTMLButtonElement;
  42. var HTMLCanvasElement = $stencilWindow.HTMLCanvasElement;
  43. var HTMLElement = $stencilWindow.HTMLElement;
  44. var HTMLFormElement = $stencilWindow.HTMLFormElement;
  45. var HTMLImageElement = $stencilWindow.HTMLImageElement;
  46. var HTMLInputElement = $stencilWindow.HTMLInputElement;
  47. var HTMLLinkElement = $stencilWindow.HTMLLinkElement;
  48. var HTMLMetaElement = $stencilWindow.HTMLMetaElement;
  49. var HTMLScriptElement = $stencilWindow.HTMLScriptElement;
  50. var HTMLStyleElement = $stencilWindow.HTMLStyleElement;
  51. var HTMLTemplateElement = $stencilWindow.HTMLTemplateElement;
  52. var HTMLTitleElement = $stencilWindow.HTMLTitleElement;
  53. var IntersectionObserver = $stencilWindow.IntersectionObserver;
  54. var KeyboardEvent = $stencilWindow.KeyboardEvent;
  55. var MouseEvent = $stencilWindow.MouseEvent;
  56. var Node = $stencilWindow.Node;
  57. var NodeList = $stencilWindow.NodeList;
  58. var URL = $stencilWindow.URL;
  59. var console = $stencilWindow.console;
  60. var customElements = $stencilWindow.customElements;
  61. var history = $stencilWindow.history;
  62. var localStorage = $stencilWindow.localStorage;
  63. var location = $stencilWindow.location;
  64. var navigator = $stencilWindow.navigator;
  65. var performance = $stencilWindow.performance;
  66. var sessionStorage = $stencilWindow.sessionStorage;
  67. var devicePixelRatio = $stencilWindow.devicePixelRatio;
  68. var innerHeight = $stencilWindow.innerHeight;
  69. var innerWidth = $stencilWindow.innerWidth;
  70. var origin = $stencilWindow.origin;
  71. var pageXOffset = $stencilWindow.pageXOffset;
  72. var pageYOffset = $stencilWindow.pageYOffset;
  73. var screen = $stencilWindow.screen;
  74. var screenLeft = $stencilWindow.screenLeft;
  75. var screenTop = $stencilWindow.screenTop;
  76. var screenX = $stencilWindow.screenX;
  77. var screenY = $stencilWindow.screenY;
  78. var scrollX = $stencilWindow.scrollX;
  79. var scrollY = $stencilWindow.scrollY;
  80. var exports = {};
  81. var fetch, FetchError, Headers, Request, Response;
  82. if (typeof $stencilWindow.fetch === 'function') {
  83. fetch = $stencilWindow.fetch;
  84. } else {
  85. fetch = $stencilWindow.fetch = function() { throw new Error('fetch() is not implemented'); };
  86. }
  87. if (typeof $stencilWindow.FetchError === 'function') {
  88. FetchError = $stencilWindow.FetchError;
  89. } else {
  90. FetchError = $stencilWindow.FetchError = class FetchError { constructor() { throw new Error('FetchError is not implemented'); } };
  91. }
  92. if (typeof $stencilWindow.Headers === 'function') {
  93. Headers = $stencilWindow.Headers;
  94. } else {
  95. Headers = $stencilWindow.Headers = class Headers { constructor() { throw new Error('Headers is not implemented'); } };
  96. }
  97. if (typeof $stencilWindow.Request === 'function') {
  98. Request = $stencilWindow.Request;
  99. } else {
  100. Request = $stencilWindow.Request = class Request { constructor() { throw new Error('Request is not implemented'); } };
  101. }
  102. if (typeof $stencilWindow.Response === 'function') {
  103. Response = $stencilWindow.Response;
  104. } else {
  105. Response = $stencilWindow.Response = class Response { constructor() { throw new Error('Response is not implemented'); } };
  106. }
  107. function hydrateAppClosure($stencilWindow) {
  108. const window = $stencilWindow;
  109. const document = $stencilWindow.document;
  110. /*hydrateAppClosure start*/
  111. const NAMESPACE = 'ionic';
  112. 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 };
  113. /*
  114. Stencil Hydrate Platform v4.20.0 | MIT Licensed | https://stenciljs.com
  115. */
  116. var __defProp = Object.defineProperty;
  117. var __export = (target, all) => {
  118. for (var name in all)
  119. __defProp(target, name, { get: all[name], enumerable: true });
  120. };
  121. // src/utils/constants.ts
  122. var EMPTY_OBJ = {};
  123. var SVG_NS = "http://www.w3.org/2000/svg";
  124. var HTML_NS = "http://www.w3.org/1999/xhtml";
  125. // src/utils/helpers.ts
  126. var isDef = (v) => v != null;
  127. var isComplexType = (o) => {
  128. o = typeof o;
  129. return o === "object" || o === "function";
  130. };
  131. // src/utils/query-nonce-meta-tag-content.ts
  132. function queryNonceMetaTagContent(doc2) {
  133. var _a, _b, _c;
  134. 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;
  135. }
  136. // src/utils/result.ts
  137. var result_exports = {};
  138. __export(result_exports, {
  139. err: () => err,
  140. map: () => map,
  141. ok: () => ok,
  142. unwrap: () => unwrap,
  143. unwrapErr: () => unwrapErr
  144. });
  145. var ok = (value) => ({
  146. isOk: true,
  147. isErr: false,
  148. value
  149. });
  150. var err = (value) => ({
  151. isOk: false,
  152. isErr: true,
  153. value
  154. });
  155. function map(result, fn) {
  156. if (result.isOk) {
  157. const val = fn(result.value);
  158. if (val instanceof Promise) {
  159. return val.then((newVal) => ok(newVal));
  160. } else {
  161. return ok(val);
  162. }
  163. }
  164. if (result.isErr) {
  165. const value = result.value;
  166. return err(value);
  167. }
  168. throw "should never get here";
  169. }
  170. var unwrap = (result) => {
  171. if (result.isOk) {
  172. return result.value;
  173. } else {
  174. throw result.value;
  175. }
  176. };
  177. var unwrapErr = (result) => {
  178. if (result.isErr) {
  179. return result.value;
  180. } else {
  181. throw result.value;
  182. }
  183. };
  184. var createTime = (fnName, tagName = "") => {
  185. {
  186. return () => {
  187. return;
  188. };
  189. }
  190. };
  191. var uniqueTime = (key, measureText) => {
  192. {
  193. return () => {
  194. return;
  195. };
  196. }
  197. };
  198. // src/runtime/runtime-constants.ts
  199. var CONTENT_REF_ID = "r";
  200. var ORG_LOCATION_ID = "o";
  201. var SLOT_NODE_ID = "s";
  202. var TEXT_NODE_ID = "t";
  203. var HYDRATE_ID = "s-id";
  204. var HYDRATED_STYLE_ID = "sty-id";
  205. var HYDRATE_CHILD_ID = "c-id";
  206. var SLOT_FB_CSS = "slot-fb{display:contents}slot-fb[hidden]{display:none}";
  207. var XLINK_NS = "http://www.w3.org/1999/xlink";
  208. var h = (nodeName, vnodeData, ...children) => {
  209. let child = null;
  210. let key = null;
  211. let slotName = null;
  212. let simple = false;
  213. let lastSimple = false;
  214. const vNodeChildren = [];
  215. const walk = (c) => {
  216. for (let i2 = 0; i2 < c.length; i2++) {
  217. child = c[i2];
  218. if (Array.isArray(child)) {
  219. walk(child);
  220. } else if (child != null && typeof child !== "boolean") {
  221. if (simple = typeof nodeName !== "function" && !isComplexType(child)) {
  222. child = String(child);
  223. }
  224. if (simple && lastSimple) {
  225. vNodeChildren[vNodeChildren.length - 1].$text$ += child;
  226. } else {
  227. vNodeChildren.push(simple ? newVNode(null, child) : child);
  228. }
  229. lastSimple = simple;
  230. }
  231. }
  232. };
  233. walk(children);
  234. if (vnodeData) {
  235. if (vnodeData.key) {
  236. key = vnodeData.key;
  237. }
  238. if (vnodeData.name) {
  239. slotName = vnodeData.name;
  240. }
  241. {
  242. const classData = vnodeData.className || vnodeData.class;
  243. if (classData) {
  244. vnodeData.class = typeof classData !== "object" ? classData : Object.keys(classData).filter((k) => classData[k]).join(" ");
  245. }
  246. }
  247. }
  248. if (typeof nodeName === "function") {
  249. return nodeName(
  250. vnodeData === null ? {} : vnodeData,
  251. vNodeChildren,
  252. vdomFnUtils
  253. );
  254. }
  255. const vnode = newVNode(nodeName, null);
  256. vnode.$attrs$ = vnodeData;
  257. if (vNodeChildren.length > 0) {
  258. vnode.$children$ = vNodeChildren;
  259. }
  260. {
  261. vnode.$key$ = key;
  262. }
  263. {
  264. vnode.$name$ = slotName;
  265. }
  266. return vnode;
  267. };
  268. var newVNode = (tag, text) => {
  269. const vnode = {
  270. $flags$: 0,
  271. $tag$: tag,
  272. $text$: text,
  273. $elm$: null,
  274. $children$: null
  275. };
  276. {
  277. vnode.$attrs$ = null;
  278. }
  279. {
  280. vnode.$key$ = null;
  281. }
  282. {
  283. vnode.$name$ = null;
  284. }
  285. return vnode;
  286. };
  287. var Host = {};
  288. var isHost = (node) => node && node.$tag$ === Host;
  289. var vdomFnUtils = {
  290. forEach: (children, cb) => children.map(convertToPublic).forEach(cb),
  291. map: (children, cb) => children.map(convertToPublic).map(cb).map(convertToPrivate)
  292. };
  293. var convertToPublic = (node) => ({
  294. vattrs: node.$attrs$,
  295. vchildren: node.$children$,
  296. vkey: node.$key$,
  297. vname: node.$name$,
  298. vtag: node.$tag$,
  299. vtext: node.$text$
  300. });
  301. var convertToPrivate = (node) => {
  302. if (typeof node.vtag === "function") {
  303. const vnodeData = { ...node.vattrs };
  304. if (node.vkey) {
  305. vnodeData.key = node.vkey;
  306. }
  307. if (node.vname) {
  308. vnodeData.name = node.vname;
  309. }
  310. return h(node.vtag, vnodeData, ...node.vchildren || []);
  311. }
  312. const vnode = newVNode(node.vtag, node.vtext);
  313. vnode.$attrs$ = node.vattrs;
  314. vnode.$children$ = node.vchildren;
  315. vnode.$key$ = node.vkey;
  316. vnode.$name$ = node.vname;
  317. return vnode;
  318. };
  319. // src/runtime/client-hydrate.ts
  320. var initializeClientHydrate = (hostElm, tagName, hostId, hostRef) => {
  321. const endHydrate = createTime("hydrateClient", tagName);
  322. const shadowRoot = hostElm.shadowRoot;
  323. const childRenderNodes = [];
  324. const slotNodes = [];
  325. const shadowRootNodes = shadowRoot ? [] : null;
  326. const vnode = hostRef.$vnode$ = newVNode(tagName, null);
  327. if (!plt.$orgLocNodes$) {
  328. initializeDocumentHydrate(doc$1.body, plt.$orgLocNodes$ = /* @__PURE__ */ new Map());
  329. }
  330. hostElm[HYDRATE_ID] = hostId;
  331. hostElm.removeAttribute(HYDRATE_ID);
  332. clientHydrate(vnode, childRenderNodes, slotNodes, shadowRootNodes, hostElm, hostElm, hostId);
  333. childRenderNodes.map((c) => {
  334. const orgLocationId = c.$hostId$ + "." + c.$nodeId$;
  335. const orgLocationNode = plt.$orgLocNodes$.get(orgLocationId);
  336. const node = c.$elm$;
  337. if (orgLocationNode && supportsShadow && orgLocationNode["s-en"] === "") {
  338. orgLocationNode.parentNode.insertBefore(node, orgLocationNode.nextSibling);
  339. }
  340. if (!shadowRoot) {
  341. node["s-hn"] = tagName;
  342. if (orgLocationNode) {
  343. node["s-ol"] = orgLocationNode;
  344. node["s-ol"]["s-nr"] = node;
  345. }
  346. }
  347. plt.$orgLocNodes$.delete(orgLocationId);
  348. });
  349. if (shadowRoot) {
  350. shadowRootNodes.map((shadowRootNode) => {
  351. if (shadowRootNode) {
  352. shadowRoot.appendChild(shadowRootNode);
  353. }
  354. });
  355. }
  356. endHydrate();
  357. };
  358. var clientHydrate = (parentVNode, childRenderNodes, slotNodes, shadowRootNodes, hostElm, node, hostId) => {
  359. let childNodeType;
  360. let childIdSplt;
  361. let childVNode;
  362. let i2;
  363. if (node.nodeType === 1 /* ElementNode */) {
  364. childNodeType = node.getAttribute(HYDRATE_CHILD_ID);
  365. if (childNodeType) {
  366. childIdSplt = childNodeType.split(".");
  367. if (childIdSplt[0] === hostId || childIdSplt[0] === "0") {
  368. childVNode = {
  369. $flags$: 0,
  370. $hostId$: childIdSplt[0],
  371. $nodeId$: childIdSplt[1],
  372. $depth$: childIdSplt[2],
  373. $index$: childIdSplt[3],
  374. $tag$: node.tagName.toLowerCase(),
  375. $elm$: node,
  376. $attrs$: null,
  377. $children$: null,
  378. $key$: null,
  379. $name$: null,
  380. $text$: null
  381. };
  382. childRenderNodes.push(childVNode);
  383. node.removeAttribute(HYDRATE_CHILD_ID);
  384. if (!parentVNode.$children$) {
  385. parentVNode.$children$ = [];
  386. }
  387. parentVNode.$children$[childVNode.$index$] = childVNode;
  388. parentVNode = childVNode;
  389. if (shadowRootNodes && childVNode.$depth$ === "0") {
  390. shadowRootNodes[childVNode.$index$] = childVNode.$elm$;
  391. }
  392. }
  393. }
  394. if (node.shadowRoot) {
  395. for (i2 = node.shadowRoot.childNodes.length - 1; i2 >= 0; i2--) {
  396. clientHydrate(
  397. parentVNode,
  398. childRenderNodes,
  399. slotNodes,
  400. shadowRootNodes,
  401. hostElm,
  402. node.shadowRoot.childNodes[i2],
  403. hostId
  404. );
  405. }
  406. }
  407. for (i2 = node.childNodes.length - 1; i2 >= 0; i2--) {
  408. clientHydrate(
  409. parentVNode,
  410. childRenderNodes,
  411. slotNodes,
  412. shadowRootNodes,
  413. hostElm,
  414. node.childNodes[i2],
  415. hostId
  416. );
  417. }
  418. } else if (node.nodeType === 8 /* CommentNode */) {
  419. childIdSplt = node.nodeValue.split(".");
  420. if (childIdSplt[1] === hostId || childIdSplt[1] === "0") {
  421. childNodeType = childIdSplt[0];
  422. childVNode = {
  423. $flags$: 0,
  424. $hostId$: childIdSplt[1],
  425. $nodeId$: childIdSplt[2],
  426. $depth$: childIdSplt[3],
  427. $index$: childIdSplt[4],
  428. $elm$: node,
  429. $attrs$: null,
  430. $children$: null,
  431. $key$: null,
  432. $name$: null,
  433. $tag$: null,
  434. $text$: null
  435. };
  436. if (childNodeType === TEXT_NODE_ID) {
  437. childVNode.$elm$ = node.nextSibling;
  438. if (childVNode.$elm$ && childVNode.$elm$.nodeType === 3 /* TextNode */) {
  439. childVNode.$text$ = childVNode.$elm$.textContent;
  440. childRenderNodes.push(childVNode);
  441. node.remove();
  442. if (!parentVNode.$children$) {
  443. parentVNode.$children$ = [];
  444. }
  445. parentVNode.$children$[childVNode.$index$] = childVNode;
  446. if (shadowRootNodes && childVNode.$depth$ === "0") {
  447. shadowRootNodes[childVNode.$index$] = childVNode.$elm$;
  448. }
  449. }
  450. } else if (childVNode.$hostId$ === hostId) {
  451. if (childNodeType === SLOT_NODE_ID) {
  452. childVNode.$tag$ = "slot";
  453. if (childIdSplt[5]) {
  454. node["s-sn"] = childVNode.$name$ = childIdSplt[5];
  455. } else {
  456. node["s-sn"] = "";
  457. }
  458. node["s-sr"] = true;
  459. if (shadowRootNodes) {
  460. childVNode.$elm$ = doc$1.createElement(childVNode.$tag$);
  461. if (childVNode.$name$) {
  462. childVNode.$elm$.setAttribute("name", childVNode.$name$);
  463. }
  464. node.parentNode.insertBefore(childVNode.$elm$, node);
  465. node.remove();
  466. if (childVNode.$depth$ === "0") {
  467. shadowRootNodes[childVNode.$index$] = childVNode.$elm$;
  468. }
  469. }
  470. slotNodes.push(childVNode);
  471. if (!parentVNode.$children$) {
  472. parentVNode.$children$ = [];
  473. }
  474. parentVNode.$children$[childVNode.$index$] = childVNode;
  475. } else if (childNodeType === CONTENT_REF_ID) {
  476. if (shadowRootNodes) {
  477. node.remove();
  478. } else {
  479. hostElm["s-cr"] = node;
  480. node["s-cn"] = true;
  481. }
  482. }
  483. }
  484. }
  485. } else if (parentVNode && parentVNode.$tag$ === "style") {
  486. const vnode = newVNode(null, node.textContent);
  487. vnode.$elm$ = node;
  488. vnode.$index$ = "0";
  489. parentVNode.$children$ = [vnode];
  490. }
  491. };
  492. var initializeDocumentHydrate = (node, orgLocNodes) => {
  493. if (node.nodeType === 1 /* ElementNode */) {
  494. let i2 = 0;
  495. if (node.shadowRoot) {
  496. for (; i2 < node.shadowRoot.childNodes.length; i2++) {
  497. initializeDocumentHydrate(node.shadowRoot.childNodes[i2], orgLocNodes);
  498. }
  499. }
  500. for (i2 = 0; i2 < node.childNodes.length; i2++) {
  501. initializeDocumentHydrate(node.childNodes[i2], orgLocNodes);
  502. }
  503. } else if (node.nodeType === 8 /* CommentNode */) {
  504. const childIdSplt = node.nodeValue.split(".");
  505. if (childIdSplt[0] === ORG_LOCATION_ID) {
  506. orgLocNodes.set(childIdSplt[1] + "." + childIdSplt[2], node);
  507. node.nodeValue = "";
  508. node["s-en"] = childIdSplt[3];
  509. }
  510. }
  511. };
  512. // src/runtime/mode.ts
  513. var computeMode = (elm) => modeResolutionChain.map((h2) => h2(elm)).find((m) => !!m);
  514. var getMode = (ref) => getHostRef(ref).$modeName$;
  515. var parsePropertyValue = (propValue, propType) => {
  516. if (propValue != null && !isComplexType(propValue)) {
  517. if (propType & 4 /* Boolean */) {
  518. return propValue === "false" ? false : propValue === "" || !!propValue;
  519. }
  520. if (propType & 2 /* Number */) {
  521. return parseFloat(propValue);
  522. }
  523. if (propType & 1 /* String */) {
  524. return String(propValue);
  525. }
  526. return propValue;
  527. }
  528. return propValue;
  529. };
  530. var getElement = (ref) => getHostRef(ref).$hostElement$ ;
  531. // src/runtime/event-emitter.ts
  532. var createEvent = (ref, name, flags) => {
  533. const elm = getElement(ref);
  534. return {
  535. emit: (detail) => {
  536. return emitEvent(elm, name, {
  537. bubbles: !!(flags & 4 /* Bubbles */),
  538. composed: !!(flags & 2 /* Composed */),
  539. cancelable: !!(flags & 1 /* Cancellable */),
  540. detail
  541. });
  542. }
  543. };
  544. };
  545. var emitEvent = (elm, name, opts) => {
  546. const ev = plt.ce(name, opts);
  547. elm.dispatchEvent(ev);
  548. return ev;
  549. };
  550. var rootAppliedStyles = /* @__PURE__ */ new WeakMap();
  551. var registerStyle = (scopeId2, cssText, allowCS) => {
  552. let style = styles.get(scopeId2);
  553. {
  554. style = cssText;
  555. }
  556. styles.set(scopeId2, style);
  557. };
  558. var addStyle = (styleContainerNode, cmpMeta, mode) => {
  559. var _a;
  560. const scopeId2 = getScopeId(cmpMeta, mode);
  561. const style = styles.get(scopeId2);
  562. styleContainerNode = styleContainerNode.nodeType === 11 /* DocumentFragment */ ? styleContainerNode : doc$1;
  563. if (style) {
  564. if (typeof style === "string") {
  565. styleContainerNode = styleContainerNode.head || styleContainerNode;
  566. let appliedStyles = rootAppliedStyles.get(styleContainerNode);
  567. let styleElm;
  568. if (!appliedStyles) {
  569. rootAppliedStyles.set(styleContainerNode, appliedStyles = /* @__PURE__ */ new Set());
  570. }
  571. if (!appliedStyles.has(scopeId2)) {
  572. if (styleContainerNode.host && (styleElm = styleContainerNode.querySelector(`[${HYDRATED_STYLE_ID}="${scopeId2}"]`))) {
  573. styleElm.innerHTML = style;
  574. } else {
  575. styleElm = doc$1.createElement("style");
  576. styleElm.innerHTML = style;
  577. const nonce = (_a = plt.$nonce$) != null ? _a : queryNonceMetaTagContent(doc$1);
  578. if (nonce != null) {
  579. styleElm.setAttribute("nonce", nonce);
  580. }
  581. if (cmpMeta.$flags$ & 2 /* scopedCssEncapsulation */) {
  582. styleElm.setAttribute(HYDRATED_STYLE_ID, scopeId2);
  583. }
  584. const injectStyle = (
  585. /**
  586. * we render a scoped component
  587. */
  588. !(cmpMeta.$flags$ & 1 /* shadowDomEncapsulation */) || /**
  589. * we are using shadow dom and render the style tag within the shadowRoot
  590. */
  591. cmpMeta.$flags$ & 1 /* shadowDomEncapsulation */ && styleContainerNode.nodeName !== "HEAD"
  592. );
  593. if (injectStyle) {
  594. styleContainerNode.insertBefore(styleElm, styleContainerNode.querySelector("link"));
  595. }
  596. }
  597. if (cmpMeta.$flags$ & 4 /* hasSlotRelocation */) {
  598. styleElm.innerHTML += SLOT_FB_CSS;
  599. }
  600. if (appliedStyles) {
  601. appliedStyles.add(scopeId2);
  602. }
  603. }
  604. }
  605. }
  606. return scopeId2;
  607. };
  608. var attachStyles = (hostRef) => {
  609. const cmpMeta = hostRef.$cmpMeta$;
  610. const elm = hostRef.$hostElement$;
  611. const flags = cmpMeta.$flags$;
  612. const endAttachStyles = createTime("attachStyles", cmpMeta.$tagName$);
  613. const scopeId2 = addStyle(
  614. elm.shadowRoot ? elm.shadowRoot : elm.getRootNode(),
  615. cmpMeta,
  616. hostRef.$modeName$
  617. );
  618. if (flags & 10 /* needsScopedEncapsulation */ && flags & 2 /* scopedCssEncapsulation */) {
  619. elm["s-sc"] = scopeId2;
  620. elm.classList.add(scopeId2 + "-h");
  621. if (flags & 2 /* scopedCssEncapsulation */) {
  622. elm.classList.add(scopeId2 + "-s");
  623. }
  624. }
  625. endAttachStyles();
  626. };
  627. var getScopeId = (cmp, mode) => "sc-" + (mode && cmp.$flags$ & 32 /* hasMode */ ? cmp.$tagName$ + "-" + mode : cmp.$tagName$);
  628. var setAccessor = (elm, memberName, oldValue, newValue, isSvg, flags) => {
  629. if (oldValue !== newValue) {
  630. let isProp = isMemberInElement(elm, memberName);
  631. let ln = memberName.toLowerCase();
  632. if (memberName === "class") {
  633. const classList = elm.classList;
  634. const oldClasses = parseClassList(oldValue);
  635. const newClasses = parseClassList(newValue);
  636. classList.remove(...oldClasses.filter((c) => c && !newClasses.includes(c)));
  637. classList.add(...newClasses.filter((c) => c && !oldClasses.includes(c)));
  638. } else if (memberName === "style") {
  639. {
  640. for (const prop in oldValue) {
  641. if (!newValue || newValue[prop] == null) {
  642. {
  643. elm.style[prop] = "";
  644. }
  645. }
  646. }
  647. }
  648. for (const prop in newValue) {
  649. if (!oldValue || newValue[prop] !== oldValue[prop]) {
  650. {
  651. elm.style[prop] = newValue[prop];
  652. }
  653. }
  654. }
  655. } else if (memberName === "key") ; else if (memberName === "ref") {
  656. if (newValue) {
  657. newValue(elm);
  658. }
  659. } else if ((!isProp ) && memberName[0] === "o" && memberName[1] === "n") {
  660. if (memberName[2] === "-") {
  661. memberName = memberName.slice(3);
  662. } else if (isMemberInElement(win$2, ln)) {
  663. memberName = ln.slice(2);
  664. } else {
  665. memberName = ln[2] + memberName.slice(3);
  666. }
  667. if (oldValue || newValue) {
  668. const capture = memberName.endsWith(CAPTURE_EVENT_SUFFIX);
  669. memberName = memberName.replace(CAPTURE_EVENT_REGEX, "");
  670. if (oldValue) {
  671. plt.rel(elm, memberName, oldValue, capture);
  672. }
  673. if (newValue) {
  674. plt.ael(elm, memberName, newValue, capture);
  675. }
  676. }
  677. } else {
  678. const isComplex = isComplexType(newValue);
  679. if ((isProp || isComplex && newValue !== null) && !isSvg) {
  680. try {
  681. if (!elm.tagName.includes("-")) {
  682. const n = newValue == null ? "" : newValue;
  683. if (memberName === "list") {
  684. isProp = false;
  685. } else if (oldValue == null || elm[memberName] != n) {
  686. elm[memberName] = n;
  687. }
  688. } else {
  689. elm[memberName] = newValue;
  690. }
  691. } catch (e) {
  692. }
  693. }
  694. let xlink = false;
  695. {
  696. if (ln !== (ln = ln.replace(/^xlink\:?/, ""))) {
  697. memberName = ln;
  698. xlink = true;
  699. }
  700. }
  701. if (newValue == null || newValue === false) {
  702. if (newValue !== false || elm.getAttribute(memberName) === "") {
  703. if (xlink) {
  704. elm.removeAttributeNS(XLINK_NS, memberName);
  705. } else {
  706. elm.removeAttribute(memberName);
  707. }
  708. }
  709. } else if ((!isProp || flags & 4 /* isHost */ || isSvg) && !isComplex) {
  710. newValue = newValue === true ? "" : newValue;
  711. if (xlink) {
  712. elm.setAttributeNS(XLINK_NS, memberName, newValue);
  713. } else {
  714. elm.setAttribute(memberName, newValue);
  715. }
  716. }
  717. }
  718. }
  719. };
  720. var parseClassListRegex = /\s/;
  721. var parseClassList = (value) => !value ? [] : value.split(parseClassListRegex);
  722. var CAPTURE_EVENT_SUFFIX = "Capture";
  723. var CAPTURE_EVENT_REGEX = new RegExp(CAPTURE_EVENT_SUFFIX + "$");
  724. // src/runtime/vdom/update-element.ts
  725. var updateElement = (oldVnode, newVnode, isSvgMode2) => {
  726. const elm = newVnode.$elm$.nodeType === 11 /* DocumentFragment */ && newVnode.$elm$.host ? newVnode.$elm$.host : newVnode.$elm$;
  727. const oldVnodeAttrs = oldVnode && oldVnode.$attrs$ || EMPTY_OBJ;
  728. const newVnodeAttrs = newVnode.$attrs$ || EMPTY_OBJ;
  729. {
  730. for (const memberName of sortedAttrNames(Object.keys(oldVnodeAttrs))) {
  731. if (!(memberName in newVnodeAttrs)) {
  732. setAccessor(elm, memberName, oldVnodeAttrs[memberName], void 0, isSvgMode2, newVnode.$flags$);
  733. }
  734. }
  735. }
  736. for (const memberName of sortedAttrNames(Object.keys(newVnodeAttrs))) {
  737. setAccessor(elm, memberName, oldVnodeAttrs[memberName], newVnodeAttrs[memberName], isSvgMode2, newVnode.$flags$);
  738. }
  739. };
  740. function sortedAttrNames(attrNames) {
  741. return attrNames.includes("ref") ? (
  742. // we need to sort these to ensure that `'ref'` is the last attr
  743. [...attrNames.filter((attr) => attr !== "ref"), "ref"]
  744. ) : (
  745. // no need to sort, return the original array
  746. attrNames
  747. );
  748. }
  749. // src/runtime/vdom/vdom-render.ts
  750. var scopeId;
  751. var contentRef;
  752. var hostTagName;
  753. var useNativeShadowDom = false;
  754. var checkSlotFallbackVisibility = false;
  755. var checkSlotRelocate = false;
  756. var isSvgMode = false;
  757. var createElm = (oldParentVNode, newParentVNode, childIndex, parentElm) => {
  758. var _a;
  759. const newVNode2 = newParentVNode.$children$[childIndex];
  760. let i2 = 0;
  761. let elm;
  762. let childNode;
  763. let oldVNode;
  764. if (!useNativeShadowDom) {
  765. checkSlotRelocate = true;
  766. if (newVNode2.$tag$ === "slot") {
  767. if (scopeId) {
  768. parentElm.classList.add(scopeId + "-s");
  769. }
  770. newVNode2.$flags$ |= newVNode2.$children$ ? (
  771. // slot element has fallback content
  772. // still create an element that "mocks" the slot element
  773. 2 /* isSlotFallback */
  774. ) : (
  775. // slot element does not have fallback content
  776. // create an html comment we'll use to always reference
  777. // where actual slot content should sit next to
  778. 1 /* isSlotReference */
  779. );
  780. }
  781. }
  782. if (newVNode2.$text$ !== null) {
  783. elm = newVNode2.$elm$ = doc$1.createTextNode(newVNode2.$text$);
  784. } else if (newVNode2.$flags$ & 1 /* isSlotReference */) {
  785. elm = newVNode2.$elm$ = slotReferenceDebugNode(newVNode2) ;
  786. } else {
  787. if (!isSvgMode) {
  788. isSvgMode = newVNode2.$tag$ === "svg";
  789. }
  790. elm = newVNode2.$elm$ = doc$1.createElementNS(
  791. isSvgMode ? SVG_NS : HTML_NS,
  792. !useNativeShadowDom && BUILD.slotRelocation && newVNode2.$flags$ & 2 /* isSlotFallback */ ? "slot-fb" : newVNode2.$tag$
  793. ) ;
  794. if (isSvgMode && newVNode2.$tag$ === "foreignObject") {
  795. isSvgMode = false;
  796. }
  797. {
  798. updateElement(null, newVNode2, isSvgMode);
  799. }
  800. const rootNode = elm.getRootNode();
  801. const isElementWithinShadowRoot = !rootNode.querySelector("body");
  802. if (!isElementWithinShadowRoot && BUILD.scoped && isDef(scopeId) && elm["s-si"] !== scopeId) {
  803. elm.classList.add(elm["s-si"] = scopeId);
  804. }
  805. {
  806. updateElementScopeIds(elm, parentElm);
  807. }
  808. if (newVNode2.$children$) {
  809. for (i2 = 0; i2 < newVNode2.$children$.length; ++i2) {
  810. childNode = createElm(oldParentVNode, newVNode2, i2, elm);
  811. if (childNode) {
  812. elm.appendChild(childNode);
  813. }
  814. }
  815. }
  816. {
  817. if (newVNode2.$tag$ === "svg") {
  818. isSvgMode = false;
  819. } else if (elm.tagName === "foreignObject") {
  820. isSvgMode = true;
  821. }
  822. }
  823. }
  824. elm["s-hn"] = hostTagName;
  825. {
  826. if (newVNode2.$flags$ & (2 /* isSlotFallback */ | 1 /* isSlotReference */)) {
  827. elm["s-sr"] = true;
  828. elm["s-cr"] = contentRef;
  829. elm["s-sn"] = newVNode2.$name$ || "";
  830. elm["s-rf"] = (_a = newVNode2.$attrs$) == null ? void 0 : _a.ref;
  831. oldVNode = oldParentVNode && oldParentVNode.$children$ && oldParentVNode.$children$[childIndex];
  832. if (oldVNode && oldVNode.$tag$ === newVNode2.$tag$ && oldParentVNode.$elm$) {
  833. {
  834. putBackInOriginalLocation(oldParentVNode.$elm$, false);
  835. }
  836. }
  837. }
  838. }
  839. return elm;
  840. };
  841. var putBackInOriginalLocation = (parentElm, recursive) => {
  842. plt.$flags$ |= 1 /* isTmpDisconnected */;
  843. const oldSlotChildNodes = Array.from(parentElm.childNodes);
  844. if (parentElm["s-sr"] && BUILD.experimentalSlotFixes) {
  845. let node = parentElm;
  846. while (node = node.nextSibling) {
  847. if (node && node["s-sn"] === parentElm["s-sn"] && node["s-sh"] === hostTagName) {
  848. oldSlotChildNodes.push(node);
  849. }
  850. }
  851. }
  852. for (let i2 = oldSlotChildNodes.length - 1; i2 >= 0; i2--) {
  853. const childNode = oldSlotChildNodes[i2];
  854. if (childNode["s-hn"] !== hostTagName && childNode["s-ol"]) {
  855. insertBefore(parentReferenceNode(childNode), childNode, referenceNode(childNode));
  856. childNode["s-ol"].remove();
  857. childNode["s-ol"] = void 0;
  858. childNode["s-sh"] = void 0;
  859. checkSlotRelocate = true;
  860. }
  861. if (recursive) {
  862. putBackInOriginalLocation(childNode, recursive);
  863. }
  864. }
  865. plt.$flags$ &= ~1 /* isTmpDisconnected */;
  866. };
  867. var addVnodes = (parentElm, before, parentVNode, vnodes, startIdx, endIdx) => {
  868. let containerElm = parentElm["s-cr"] && parentElm["s-cr"].parentNode || parentElm;
  869. let childNode;
  870. if (containerElm.shadowRoot && containerElm.tagName === hostTagName) {
  871. containerElm = containerElm.shadowRoot;
  872. }
  873. for (; startIdx <= endIdx; ++startIdx) {
  874. if (vnodes[startIdx]) {
  875. childNode = createElm(null, parentVNode, startIdx, parentElm);
  876. if (childNode) {
  877. vnodes[startIdx].$elm$ = childNode;
  878. insertBefore(containerElm, childNode, referenceNode(before) );
  879. }
  880. }
  881. }
  882. };
  883. var removeVnodes = (vnodes, startIdx, endIdx) => {
  884. for (let index = startIdx; index <= endIdx; ++index) {
  885. const vnode = vnodes[index];
  886. if (vnode) {
  887. const elm = vnode.$elm$;
  888. nullifyVNodeRefs(vnode);
  889. if (elm) {
  890. {
  891. checkSlotFallbackVisibility = true;
  892. if (elm["s-ol"]) {
  893. elm["s-ol"].remove();
  894. } else {
  895. putBackInOriginalLocation(elm, true);
  896. }
  897. }
  898. elm.remove();
  899. }
  900. }
  901. }
  902. };
  903. var updateChildren = (parentElm, oldCh, newVNode2, newCh, isInitialRender = false) => {
  904. let oldStartIdx = 0;
  905. let newStartIdx = 0;
  906. let idxInOld = 0;
  907. let i2 = 0;
  908. let oldEndIdx = oldCh.length - 1;
  909. let oldStartVnode = oldCh[0];
  910. let oldEndVnode = oldCh[oldEndIdx];
  911. let newEndIdx = newCh.length - 1;
  912. let newStartVnode = newCh[0];
  913. let newEndVnode = newCh[newEndIdx];
  914. let node;
  915. let elmToMove;
  916. while (oldStartIdx <= oldEndIdx && newStartIdx <= newEndIdx) {
  917. if (oldStartVnode == null) {
  918. oldStartVnode = oldCh[++oldStartIdx];
  919. } else if (oldEndVnode == null) {
  920. oldEndVnode = oldCh[--oldEndIdx];
  921. } else if (newStartVnode == null) {
  922. newStartVnode = newCh[++newStartIdx];
  923. } else if (newEndVnode == null) {
  924. newEndVnode = newCh[--newEndIdx];
  925. } else if (isSameVnode(oldStartVnode, newStartVnode, isInitialRender)) {
  926. patch(oldStartVnode, newStartVnode, isInitialRender);
  927. oldStartVnode = oldCh[++oldStartIdx];
  928. newStartVnode = newCh[++newStartIdx];
  929. } else if (isSameVnode(oldEndVnode, newEndVnode, isInitialRender)) {
  930. patch(oldEndVnode, newEndVnode, isInitialRender);
  931. oldEndVnode = oldCh[--oldEndIdx];
  932. newEndVnode = newCh[--newEndIdx];
  933. } else if (isSameVnode(oldStartVnode, newEndVnode, isInitialRender)) {
  934. if ((oldStartVnode.$tag$ === "slot" || newEndVnode.$tag$ === "slot")) {
  935. putBackInOriginalLocation(oldStartVnode.$elm$.parentNode, false);
  936. }
  937. patch(oldStartVnode, newEndVnode, isInitialRender);
  938. insertBefore(parentElm, oldStartVnode.$elm$, oldEndVnode.$elm$.nextSibling);
  939. oldStartVnode = oldCh[++oldStartIdx];
  940. newEndVnode = newCh[--newEndIdx];
  941. } else if (isSameVnode(oldEndVnode, newStartVnode, isInitialRender)) {
  942. if ((oldStartVnode.$tag$ === "slot" || newEndVnode.$tag$ === "slot")) {
  943. putBackInOriginalLocation(oldEndVnode.$elm$.parentNode, false);
  944. }
  945. patch(oldEndVnode, newStartVnode, isInitialRender);
  946. insertBefore(parentElm, oldEndVnode.$elm$, oldStartVnode.$elm$);
  947. oldEndVnode = oldCh[--oldEndIdx];
  948. newStartVnode = newCh[++newStartIdx];
  949. } else {
  950. idxInOld = -1;
  951. {
  952. for (i2 = oldStartIdx; i2 <= oldEndIdx; ++i2) {
  953. if (oldCh[i2] && oldCh[i2].$key$ !== null && oldCh[i2].$key$ === newStartVnode.$key$) {
  954. idxInOld = i2;
  955. break;
  956. }
  957. }
  958. }
  959. if (idxInOld >= 0) {
  960. elmToMove = oldCh[idxInOld];
  961. if (elmToMove.$tag$ !== newStartVnode.$tag$) {
  962. node = createElm(oldCh && oldCh[newStartIdx], newVNode2, idxInOld, parentElm);
  963. } else {
  964. patch(elmToMove, newStartVnode, isInitialRender);
  965. oldCh[idxInOld] = void 0;
  966. node = elmToMove.$elm$;
  967. }
  968. newStartVnode = newCh[++newStartIdx];
  969. } else {
  970. node = createElm(oldCh && oldCh[newStartIdx], newVNode2, newStartIdx, parentElm);
  971. newStartVnode = newCh[++newStartIdx];
  972. }
  973. if (node) {
  974. {
  975. insertBefore(parentReferenceNode(oldStartVnode.$elm$), node, referenceNode(oldStartVnode.$elm$));
  976. }
  977. }
  978. }
  979. }
  980. if (oldStartIdx > oldEndIdx) {
  981. addVnodes(
  982. parentElm,
  983. newCh[newEndIdx + 1] == null ? null : newCh[newEndIdx + 1].$elm$,
  984. newVNode2,
  985. newCh,
  986. newStartIdx,
  987. newEndIdx
  988. );
  989. } else if (newStartIdx > newEndIdx) {
  990. removeVnodes(oldCh, oldStartIdx, oldEndIdx);
  991. }
  992. };
  993. var isSameVnode = (leftVNode, rightVNode, isInitialRender = false) => {
  994. if (leftVNode.$tag$ === rightVNode.$tag$) {
  995. if (leftVNode.$tag$ === "slot") {
  996. if (
  997. // The component gets hydrated and no VDOM has been initialized.
  998. // Here the comparison can't happen as $name$ property is not set for `leftNode`.
  999. "$nodeId$" in leftVNode && isInitialRender && // `leftNode` is not from type HTMLComment which would cause many
  1000. // hydration comments to be removed
  1001. leftVNode.$elm$.nodeType !== 8
  1002. ) {
  1003. return false;
  1004. }
  1005. return leftVNode.$name$ === rightVNode.$name$;
  1006. }
  1007. if (!isInitialRender) {
  1008. return leftVNode.$key$ === rightVNode.$key$;
  1009. }
  1010. return true;
  1011. }
  1012. return false;
  1013. };
  1014. var referenceNode = (node) => {
  1015. return node && node["s-ol"] || node;
  1016. };
  1017. var parentReferenceNode = (node) => (node["s-ol"] ? node["s-ol"] : node).parentNode;
  1018. var patch = (oldVNode, newVNode2, isInitialRender = false) => {
  1019. const elm = newVNode2.$elm$ = oldVNode.$elm$;
  1020. const oldChildren = oldVNode.$children$;
  1021. const newChildren = newVNode2.$children$;
  1022. const tag = newVNode2.$tag$;
  1023. const text = newVNode2.$text$;
  1024. let defaultHolder;
  1025. if (text === null) {
  1026. {
  1027. isSvgMode = tag === "svg" ? true : tag === "foreignObject" ? false : isSvgMode;
  1028. }
  1029. {
  1030. if (tag === "slot" && !useNativeShadowDom) ; else {
  1031. updateElement(oldVNode, newVNode2, isSvgMode);
  1032. }
  1033. }
  1034. if (oldChildren !== null && newChildren !== null) {
  1035. updateChildren(elm, oldChildren, newVNode2, newChildren, isInitialRender);
  1036. } else if (newChildren !== null) {
  1037. if (oldVNode.$text$ !== null) {
  1038. elm.textContent = "";
  1039. }
  1040. addVnodes(elm, null, newVNode2, newChildren, 0, newChildren.length - 1);
  1041. } else if (
  1042. // don't do this on initial render as it can cause non-hydrated content to be removed
  1043. !isInitialRender && BUILD.updatable && oldChildren !== null
  1044. ) {
  1045. removeVnodes(oldChildren, 0, oldChildren.length - 1);
  1046. }
  1047. if (isSvgMode && tag === "svg") {
  1048. isSvgMode = false;
  1049. }
  1050. } else if ((defaultHolder = elm["s-cr"])) {
  1051. defaultHolder.parentNode.textContent = text;
  1052. } else if (oldVNode.$text$ !== text) {
  1053. elm.data = text;
  1054. }
  1055. };
  1056. var updateFallbackSlotVisibility = (elm) => {
  1057. const childNodes = elm.childNodes;
  1058. for (const childNode of childNodes) {
  1059. if (childNode.nodeType === 1 /* ElementNode */) {
  1060. if (childNode["s-sr"]) {
  1061. const slotName = childNode["s-sn"];
  1062. childNode.hidden = false;
  1063. for (const siblingNode of childNodes) {
  1064. if (siblingNode !== childNode) {
  1065. if (siblingNode["s-hn"] !== childNode["s-hn"] || slotName !== "") {
  1066. if (siblingNode.nodeType === 1 /* ElementNode */ && (slotName === siblingNode.getAttribute("slot") || slotName === siblingNode["s-sn"]) || siblingNode.nodeType === 3 /* TextNode */ && slotName === siblingNode["s-sn"]) {
  1067. childNode.hidden = true;
  1068. break;
  1069. }
  1070. } else {
  1071. if (siblingNode.nodeType === 1 /* ElementNode */ || siblingNode.nodeType === 3 /* TextNode */ && siblingNode.textContent.trim() !== "") {
  1072. childNode.hidden = true;
  1073. break;
  1074. }
  1075. }
  1076. }
  1077. }
  1078. }
  1079. updateFallbackSlotVisibility(childNode);
  1080. }
  1081. }
  1082. };
  1083. var relocateNodes = [];
  1084. var markSlotContentForRelocation = (elm) => {
  1085. let node;
  1086. let hostContentNodes;
  1087. let j;
  1088. for (const childNode of elm.childNodes) {
  1089. if (childNode["s-sr"] && (node = childNode["s-cr"]) && node.parentNode) {
  1090. hostContentNodes = node.parentNode.childNodes;
  1091. const slotName = childNode["s-sn"];
  1092. for (j = hostContentNodes.length - 1; j >= 0; j--) {
  1093. node = hostContentNodes[j];
  1094. if (!node["s-cn"] && !node["s-nr"] && node["s-hn"] !== childNode["s-hn"] && (!BUILD.experimentalSlotFixes )) {
  1095. if (isNodeLocatedInSlot(node, slotName)) {
  1096. let relocateNodeData = relocateNodes.find((r) => r.$nodeToRelocate$ === node);
  1097. checkSlotFallbackVisibility = true;
  1098. node["s-sn"] = node["s-sn"] || slotName;
  1099. if (relocateNodeData) {
  1100. relocateNodeData.$nodeToRelocate$["s-sh"] = childNode["s-hn"];
  1101. relocateNodeData.$slotRefNode$ = childNode;
  1102. } else {
  1103. node["s-sh"] = childNode["s-hn"];
  1104. relocateNodes.push({
  1105. $slotRefNode$: childNode,
  1106. $nodeToRelocate$: node
  1107. });
  1108. }
  1109. if (node["s-sr"]) {
  1110. relocateNodes.map((relocateNode) => {
  1111. if (isNodeLocatedInSlot(relocateNode.$nodeToRelocate$, node["s-sn"])) {
  1112. relocateNodeData = relocateNodes.find((r) => r.$nodeToRelocate$ === node);
  1113. if (relocateNodeData && !relocateNode.$slotRefNode$) {
  1114. relocateNode.$slotRefNode$ = relocateNodeData.$slotRefNode$;
  1115. }
  1116. }
  1117. });
  1118. }
  1119. } else if (!relocateNodes.some((r) => r.$nodeToRelocate$ === node)) {
  1120. relocateNodes.push({
  1121. $nodeToRelocate$: node
  1122. });
  1123. }
  1124. }
  1125. }
  1126. }
  1127. if (childNode.nodeType === 1 /* ElementNode */) {
  1128. markSlotContentForRelocation(childNode);
  1129. }
  1130. }
  1131. };
  1132. var isNodeLocatedInSlot = (nodeToRelocate, slotName) => {
  1133. if (nodeToRelocate.nodeType === 1 /* ElementNode */) {
  1134. if (nodeToRelocate.getAttribute("slot") === null && slotName === "") {
  1135. return true;
  1136. }
  1137. if (nodeToRelocate.getAttribute("slot") === slotName) {
  1138. return true;
  1139. }
  1140. return false;
  1141. }
  1142. if (nodeToRelocate["s-sn"] === slotName) {
  1143. return true;
  1144. }
  1145. return slotName === "";
  1146. };
  1147. var nullifyVNodeRefs = (vNode) => {
  1148. {
  1149. vNode.$attrs$ && vNode.$attrs$.ref && vNode.$attrs$.ref(null);
  1150. vNode.$children$ && vNode.$children$.map(nullifyVNodeRefs);
  1151. }
  1152. };
  1153. var insertBefore = (parent, newNode, reference) => {
  1154. const inserted = parent == null ? void 0 : parent.insertBefore(newNode, reference);
  1155. {
  1156. updateElementScopeIds(newNode, parent);
  1157. }
  1158. return inserted;
  1159. };
  1160. var findScopeIds = (element) => {
  1161. const scopeIds = [];
  1162. if (element) {
  1163. scopeIds.push(
  1164. ...element["s-scs"] || [],
  1165. element["s-si"],
  1166. element["s-sc"],
  1167. ...findScopeIds(element.parentElement)
  1168. );
  1169. }
  1170. return scopeIds;
  1171. };
  1172. var updateElementScopeIds = (element, parent, iterateChildNodes = false) => {
  1173. var _a;
  1174. if (element && parent && element.nodeType === 1 /* ElementNode */) {
  1175. const scopeIds = new Set(findScopeIds(parent).filter(Boolean));
  1176. if (scopeIds.size) {
  1177. (_a = element.classList) == null ? void 0 : _a.add(...element["s-scs"] = [...scopeIds]);
  1178. if (element["s-ol"] || iterateChildNodes) {
  1179. for (const childNode of Array.from(element.childNodes)) {
  1180. updateElementScopeIds(childNode, element, true);
  1181. }
  1182. }
  1183. }
  1184. }
  1185. };
  1186. var renderVdom = (hostRef, renderFnResults, isInitialLoad = false) => {
  1187. var _a, _b, _c, _d;
  1188. const hostElm = hostRef.$hostElement$;
  1189. const cmpMeta = hostRef.$cmpMeta$;
  1190. const oldVNode = hostRef.$vnode$ || newVNode(null, null);
  1191. const rootVnode = isHost(renderFnResults) ? renderFnResults : h(null, null, renderFnResults);
  1192. hostTagName = hostElm.tagName;
  1193. if (cmpMeta.$attrsToReflect$) {
  1194. rootVnode.$attrs$ = rootVnode.$attrs$ || {};
  1195. cmpMeta.$attrsToReflect$.map(
  1196. ([propName, attribute]) => rootVnode.$attrs$[attribute] = hostElm[propName]
  1197. );
  1198. }
  1199. if (isInitialLoad && rootVnode.$attrs$) {
  1200. for (const key of Object.keys(rootVnode.$attrs$)) {
  1201. if (hostElm.hasAttribute(key) && !["key", "ref", "style", "class"].includes(key)) {
  1202. rootVnode.$attrs$[key] = hostElm[key];
  1203. }
  1204. }
  1205. }
  1206. rootVnode.$tag$ = null;
  1207. rootVnode.$flags$ |= 4 /* isHost */;
  1208. hostRef.$vnode$ = rootVnode;
  1209. rootVnode.$elm$ = oldVNode.$elm$ = hostElm.shadowRoot || hostElm ;
  1210. {
  1211. scopeId = hostElm["s-sc"];
  1212. }
  1213. useNativeShadowDom = (cmpMeta.$flags$ & 1 /* shadowDomEncapsulation */) !== 0;
  1214. {
  1215. contentRef = hostElm["s-cr"];
  1216. checkSlotFallbackVisibility = false;
  1217. }
  1218. patch(oldVNode, rootVnode, isInitialLoad);
  1219. {
  1220. plt.$flags$ |= 1 /* isTmpDisconnected */;
  1221. if (checkSlotRelocate) {
  1222. markSlotContentForRelocation(rootVnode.$elm$);
  1223. for (const relocateData of relocateNodes) {
  1224. const nodeToRelocate = relocateData.$nodeToRelocate$;
  1225. if (!nodeToRelocate["s-ol"]) {
  1226. const orgLocationNode = originalLocationDebugNode(nodeToRelocate) ;
  1227. orgLocationNode["s-nr"] = nodeToRelocate;
  1228. insertBefore(nodeToRelocate.parentNode, nodeToRelocate["s-ol"] = orgLocationNode, nodeToRelocate);
  1229. }
  1230. }
  1231. for (const relocateData of relocateNodes) {
  1232. const nodeToRelocate = relocateData.$nodeToRelocate$;
  1233. const slotRefNode = relocateData.$slotRefNode$;
  1234. if (slotRefNode) {
  1235. const parentNodeRef = slotRefNode.parentNode;
  1236. let insertBeforeNode = slotRefNode.nextSibling;
  1237. {
  1238. let orgLocationNode = (_a = nodeToRelocate["s-ol"]) == null ? void 0 : _a.previousSibling;
  1239. while (orgLocationNode) {
  1240. let refNode = (_b = orgLocationNode["s-nr"]) != null ? _b : null;
  1241. if (refNode && refNode["s-sn"] === nodeToRelocate["s-sn"] && parentNodeRef === refNode.parentNode) {
  1242. refNode = refNode.nextSibling;
  1243. while (refNode === nodeToRelocate || (refNode == null ? void 0 : refNode["s-sr"])) {
  1244. refNode = refNode == null ? void 0 : refNode.nextSibling;
  1245. }
  1246. if (!refNode || !refNode["s-nr"]) {
  1247. insertBeforeNode = refNode;
  1248. break;
  1249. }
  1250. }
  1251. orgLocationNode = orgLocationNode.previousSibling;
  1252. }
  1253. }
  1254. if (!insertBeforeNode && parentNodeRef !== nodeToRelocate.parentNode || nodeToRelocate.nextSibling !== insertBeforeNode) {
  1255. if (nodeToRelocate !== insertBeforeNode) {
  1256. if (!nodeToRelocate["s-hn"] && nodeToRelocate["s-ol"]) {
  1257. nodeToRelocate["s-hn"] = nodeToRelocate["s-ol"].parentNode.nodeName;
  1258. }
  1259. insertBefore(parentNodeRef, nodeToRelocate, insertBeforeNode);
  1260. if (nodeToRelocate.nodeType === 1 /* ElementNode */) {
  1261. nodeToRelocate.hidden = (_c = nodeToRelocate["s-ih"]) != null ? _c : false;
  1262. }
  1263. }
  1264. }
  1265. nodeToRelocate && typeof slotRefNode["s-rf"] === "function" && slotRefNode["s-rf"](nodeToRelocate);
  1266. } else {
  1267. if (nodeToRelocate.nodeType === 1 /* ElementNode */) {
  1268. if (isInitialLoad) {
  1269. nodeToRelocate["s-ih"] = (_d = nodeToRelocate.hidden) != null ? _d : false;
  1270. }
  1271. nodeToRelocate.hidden = true;
  1272. }
  1273. }
  1274. }
  1275. }
  1276. if (checkSlotFallbackVisibility) {
  1277. updateFallbackSlotVisibility(rootVnode.$elm$);
  1278. }
  1279. plt.$flags$ &= ~1 /* isTmpDisconnected */;
  1280. relocateNodes.length = 0;
  1281. }
  1282. contentRef = void 0;
  1283. };
  1284. var slotReferenceDebugNode = (slotVNode) => doc$1.createComment(
  1285. `<slot${slotVNode.$name$ ? ' name="' + slotVNode.$name$ + '"' : ""}> (host=${hostTagName.toLowerCase()})`
  1286. );
  1287. var originalLocationDebugNode = (nodeToRelocate) => doc$1.createComment(
  1288. `org-location for ` + (nodeToRelocate.localName ? `<${nodeToRelocate.localName}> (host=${nodeToRelocate["s-hn"]})` : `[${nodeToRelocate.textContent}]`)
  1289. );
  1290. // src/runtime/update-component.ts
  1291. var attachToAncestor = (hostRef, ancestorComponent) => {
  1292. if (ancestorComponent && !hostRef.$onRenderResolve$ && ancestorComponent["s-p"]) {
  1293. ancestorComponent["s-p"].push(new Promise((r) => hostRef.$onRenderResolve$ = r));
  1294. }
  1295. };
  1296. var scheduleUpdate = (hostRef, isInitialLoad) => {
  1297. {
  1298. hostRef.$flags$ |= 16 /* isQueuedForUpdate */;
  1299. }
  1300. if (hostRef.$flags$ & 4 /* isWaitingForChildren */) {
  1301. hostRef.$flags$ |= 512 /* needsRerender */;
  1302. return;
  1303. }
  1304. attachToAncestor(hostRef, hostRef.$ancestorComponent$);
  1305. const dispatch = () => dispatchHooks(hostRef, isInitialLoad);
  1306. return writeTask(dispatch) ;
  1307. };
  1308. var dispatchHooks = (hostRef, isInitialLoad) => {
  1309. const elm = hostRef.$hostElement$;
  1310. const endSchedule = createTime("scheduleUpdate", hostRef.$cmpMeta$.$tagName$);
  1311. const instance = hostRef.$lazyInstance$ ;
  1312. if (!instance) {
  1313. throw new Error(
  1314. `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`
  1315. );
  1316. }
  1317. let maybePromise;
  1318. if (isInitialLoad) {
  1319. {
  1320. hostRef.$flags$ |= 256 /* isListenReady */;
  1321. if (hostRef.$queuedListeners$) {
  1322. hostRef.$queuedListeners$.map(([methodName, event]) => safeCall$1(instance, methodName, event));
  1323. hostRef.$queuedListeners$ = void 0;
  1324. }
  1325. }
  1326. {
  1327. maybePromise = safeCall$1(instance, "componentWillLoad");
  1328. }
  1329. }
  1330. {
  1331. maybePromise = enqueue(maybePromise, () => safeCall$1(instance, "componentWillRender"));
  1332. }
  1333. endSchedule();
  1334. return enqueue(maybePromise, () => updateComponent(hostRef, instance, isInitialLoad));
  1335. };
  1336. var enqueue = (maybePromise, fn) => isPromisey(maybePromise) ? maybePromise.then(fn).catch((err2) => {
  1337. console.error(err2);
  1338. fn();
  1339. }) : fn();
  1340. var isPromisey = (maybePromise) => maybePromise instanceof Promise || maybePromise && maybePromise.then && typeof maybePromise.then === "function";
  1341. var updateComponent = async (hostRef, instance, isInitialLoad) => {
  1342. var _a;
  1343. const elm = hostRef.$hostElement$;
  1344. const endUpdate = createTime("update", hostRef.$cmpMeta$.$tagName$);
  1345. const rc = elm["s-rc"];
  1346. if (isInitialLoad) {
  1347. attachStyles(hostRef);
  1348. }
  1349. const endRender = createTime("render", hostRef.$cmpMeta$.$tagName$);
  1350. {
  1351. await callRender(hostRef, instance, elm, isInitialLoad);
  1352. }
  1353. {
  1354. try {
  1355. serverSideConnected(elm);
  1356. if (isInitialLoad) {
  1357. if (hostRef.$cmpMeta$.$flags$ & 1 /* shadowDomEncapsulation */) {
  1358. elm["s-en"] = "";
  1359. } else if (hostRef.$cmpMeta$.$flags$ & 2 /* scopedCssEncapsulation */) {
  1360. elm["s-en"] = "c";
  1361. }
  1362. }
  1363. } catch (e) {
  1364. consoleError(e, elm);
  1365. }
  1366. }
  1367. if (rc) {
  1368. rc.map((cb) => cb());
  1369. elm["s-rc"] = void 0;
  1370. }
  1371. endRender();
  1372. endUpdate();
  1373. {
  1374. const childrenPromises = (_a = elm["s-p"]) != null ? _a : [];
  1375. const postUpdate = () => postUpdateComponent(hostRef);
  1376. if (childrenPromises.length === 0) {
  1377. postUpdate();
  1378. } else {
  1379. Promise.all(childrenPromises).then(postUpdate);
  1380. hostRef.$flags$ |= 4 /* isWaitingForChildren */;
  1381. childrenPromises.length = 0;
  1382. }
  1383. }
  1384. };
  1385. var callRender = (hostRef, instance, elm, isInitialLoad) => {
  1386. try {
  1387. instance = instance.render && instance.render();
  1388. {
  1389. hostRef.$flags$ &= ~16 /* isQueuedForUpdate */;
  1390. }
  1391. {
  1392. hostRef.$flags$ |= 2 /* hasRendered */;
  1393. }
  1394. {
  1395. {
  1396. {
  1397. return Promise.resolve(instance).then((value) => renderVdom(hostRef, value, isInitialLoad));
  1398. }
  1399. }
  1400. }
  1401. } catch (e) {
  1402. consoleError(e, hostRef.$hostElement$);
  1403. }
  1404. return null;
  1405. };
  1406. var postUpdateComponent = (hostRef) => {
  1407. const tagName = hostRef.$cmpMeta$.$tagName$;
  1408. const elm = hostRef.$hostElement$;
  1409. const endPostUpdate = createTime("postUpdate", tagName);
  1410. const instance = hostRef.$lazyInstance$ ;
  1411. const ancestorComponent = hostRef.$ancestorComponent$;
  1412. {
  1413. safeCall$1(instance, "componentDidRender");
  1414. }
  1415. if (!(hostRef.$flags$ & 64 /* hasLoadedComponent */)) {
  1416. hostRef.$flags$ |= 64 /* hasLoadedComponent */;
  1417. {
  1418. addHydratedFlag(elm);
  1419. }
  1420. {
  1421. safeCall$1(instance, "componentDidLoad");
  1422. }
  1423. endPostUpdate();
  1424. {
  1425. hostRef.$onReadyResolve$(elm);
  1426. if (!ancestorComponent) {
  1427. appDidLoad();
  1428. }
  1429. }
  1430. } else {
  1431. {
  1432. safeCall$1(instance, "componentDidUpdate");
  1433. }
  1434. endPostUpdate();
  1435. }
  1436. {
  1437. hostRef.$onInstanceResolve$(elm);
  1438. }
  1439. {
  1440. if (hostRef.$onRenderResolve$) {
  1441. hostRef.$onRenderResolve$();
  1442. hostRef.$onRenderResolve$ = void 0;
  1443. }
  1444. if (hostRef.$flags$ & 512 /* needsRerender */) {
  1445. nextTick(() => scheduleUpdate(hostRef, false));
  1446. }
  1447. hostRef.$flags$ &= ~(4 /* isWaitingForChildren */ | 512 /* needsRerender */);
  1448. }
  1449. };
  1450. var forceUpdate = (ref) => {
  1451. return false;
  1452. };
  1453. var appDidLoad = (who) => {
  1454. {
  1455. addHydratedFlag(doc$1.documentElement);
  1456. }
  1457. nextTick(() => emitEvent(win$2, "appload", { detail: { namespace: NAMESPACE } }));
  1458. };
  1459. var safeCall$1 = (instance, method, arg) => {
  1460. if (instance && instance[method]) {
  1461. try {
  1462. return instance[method](arg);
  1463. } catch (e) {
  1464. consoleError(e);
  1465. }
  1466. }
  1467. return void 0;
  1468. };
  1469. var addHydratedFlag = (elm) => {
  1470. var _a;
  1471. return elm.classList.add((_a = BUILD.hydratedSelectorName) != null ? _a : "hydrated") ;
  1472. };
  1473. var serverSideConnected = (elm) => {
  1474. const children = elm.children;
  1475. if (children != null) {
  1476. for (let i2 = 0, ii = children.length; i2 < ii; i2++) {
  1477. const childElm = children[i2];
  1478. if (typeof childElm.connectedCallback === "function") {
  1479. childElm.connectedCallback();
  1480. }
  1481. serverSideConnected(childElm);
  1482. }
  1483. }
  1484. };
  1485. // src/runtime/set-value.ts
  1486. var getValue = (ref, propName) => getHostRef(ref).$instanceValues$.get(propName);
  1487. var setValue = (ref, propName, newVal, cmpMeta) => {
  1488. const hostRef = getHostRef(ref);
  1489. if (!hostRef) {
  1490. throw new Error(
  1491. `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).`
  1492. );
  1493. }
  1494. const elm = hostRef.$hostElement$ ;
  1495. const oldVal = hostRef.$instanceValues$.get(propName);
  1496. const flags = hostRef.$flags$;
  1497. const instance = hostRef.$lazyInstance$ ;
  1498. newVal = parsePropertyValue(newVal, cmpMeta.$members$[propName][0]);
  1499. const areBothNaN = Number.isNaN(oldVal) && Number.isNaN(newVal);
  1500. const didValueChange = newVal !== oldVal && !areBothNaN;
  1501. if ((!(flags & 8 /* isConstructingInstance */) || oldVal === void 0) && didValueChange) {
  1502. hostRef.$instanceValues$.set(propName, newVal);
  1503. if (instance) {
  1504. if (cmpMeta.$watchers$ && flags & 128 /* isWatchReady */) {
  1505. const watchMethods = cmpMeta.$watchers$[propName];
  1506. if (watchMethods) {
  1507. watchMethods.map((watchMethodName) => {
  1508. try {
  1509. instance[watchMethodName](newVal, oldVal, propName);
  1510. } catch (e) {
  1511. consoleError(e, elm);
  1512. }
  1513. });
  1514. }
  1515. }
  1516. if ((flags & (2 /* hasRendered */ | 16 /* isQueuedForUpdate */)) === 2 /* hasRendered */) {
  1517. scheduleUpdate(hostRef, false);
  1518. }
  1519. }
  1520. }
  1521. };
  1522. // src/runtime/proxy-component.ts
  1523. var proxyComponent = (Cstr, cmpMeta, flags) => {
  1524. var _a, _b;
  1525. const prototype = Cstr.prototype;
  1526. if (cmpMeta.$members$ || (cmpMeta.$watchers$ || Cstr.watchers)) {
  1527. if (Cstr.watchers && !cmpMeta.$watchers$) {
  1528. cmpMeta.$watchers$ = Cstr.watchers;
  1529. }
  1530. const members = Object.entries((_a = cmpMeta.$members$) != null ? _a : {});
  1531. members.map(([memberName, [memberFlags]]) => {
  1532. if ((memberFlags & 31 /* Prop */ || (flags & 2 /* proxyState */) && memberFlags & 32 /* State */)) {
  1533. Object.defineProperty(prototype, memberName, {
  1534. get() {
  1535. return getValue(this, memberName);
  1536. },
  1537. set(newValue) {
  1538. setValue(this, memberName, newValue, cmpMeta);
  1539. },
  1540. configurable: true,
  1541. enumerable: true
  1542. });
  1543. } else if (flags & 1 /* isElementConstructor */ && memberFlags & 64 /* Method */) {
  1544. Object.defineProperty(prototype, memberName, {
  1545. value(...args) {
  1546. var _a2;
  1547. const ref = getHostRef(this);
  1548. return (_a2 = ref == null ? void 0 : ref.$onInstancePromise$) == null ? void 0 : _a2.then(() => {
  1549. var _a3;
  1550. return (_a3 = ref.$lazyInstance$) == null ? void 0 : _a3[memberName](...args);
  1551. });
  1552. }
  1553. });
  1554. }
  1555. });
  1556. if ((flags & 1 /* isElementConstructor */)) {
  1557. const attrNameToPropName = /* @__PURE__ */ new Map();
  1558. prototype.attributeChangedCallback = function(attrName, oldValue, newValue) {
  1559. plt.jmp(() => {
  1560. var _a2;
  1561. const propName = attrNameToPropName.get(attrName);
  1562. if (this.hasOwnProperty(propName)) {
  1563. newValue = this[propName];
  1564. delete this[propName];
  1565. } else if (prototype.hasOwnProperty(propName) && typeof this[propName] === "number" && // cast type to number to avoid TS compiler issues
  1566. this[propName] == newValue) {
  1567. return;
  1568. } else if (propName == null) {
  1569. const hostRef = getHostRef(this);
  1570. const flags2 = hostRef == null ? void 0 : hostRef.$flags$;
  1571. if (flags2 && !(flags2 & 8 /* isConstructingInstance */) && flags2 & 128 /* isWatchReady */ && newValue !== oldValue) {
  1572. const instance = hostRef.$lazyInstance$ ;
  1573. const entry = (_a2 = cmpMeta.$watchers$) == null ? void 0 : _a2[attrName];
  1574. entry == null ? void 0 : entry.forEach((callbackName) => {
  1575. if (instance[callbackName] != null) {
  1576. instance[callbackName].call(instance, newValue, oldValue, attrName);
  1577. }
  1578. });
  1579. }
  1580. return;
  1581. }
  1582. this[propName] = newValue === null && typeof this[propName] === "boolean" ? false : newValue;
  1583. });
  1584. };
  1585. Cstr.observedAttributes = Array.from(
  1586. /* @__PURE__ */ new Set([
  1587. ...Object.keys((_b = cmpMeta.$watchers$) != null ? _b : {}),
  1588. ...members.filter(([_, m]) => m[0] & 15 /* HasAttribute */).map(([propName, m]) => {
  1589. var _a2;
  1590. const attrName = m[1] || propName;
  1591. attrNameToPropName.set(attrName, propName);
  1592. if (m[0] & 512 /* ReflectAttr */) {
  1593. (_a2 = cmpMeta.$attrsToReflect$) == null ? void 0 : _a2.push([propName, attrName]);
  1594. }
  1595. return attrName;
  1596. })
  1597. ])
  1598. );
  1599. }
  1600. }
  1601. return Cstr;
  1602. };
  1603. // src/runtime/initialize-component.ts
  1604. var initializeComponent = async (elm, hostRef, cmpMeta, hmrVersionId) => {
  1605. let Cstr;
  1606. if ((hostRef.$flags$ & 32 /* hasInitializedComponent */) === 0) {
  1607. hostRef.$flags$ |= 32 /* hasInitializedComponent */;
  1608. const bundleId = cmpMeta.$lazyBundleId$;
  1609. if (bundleId) {
  1610. const CstrImport = loadModule(cmpMeta);
  1611. if (CstrImport && "then" in CstrImport) {
  1612. const endLoad = uniqueTime();
  1613. Cstr = await CstrImport;
  1614. endLoad();
  1615. } else {
  1616. Cstr = CstrImport;
  1617. }
  1618. if (!Cstr) {
  1619. throw new Error(`Constructor for "${cmpMeta.$tagName$}#${hostRef.$modeName$}" was not found`);
  1620. }
  1621. if (!Cstr.isProxied) {
  1622. {
  1623. cmpMeta.$watchers$ = Cstr.watchers;
  1624. }
  1625. proxyComponent(Cstr, cmpMeta, 2 /* proxyState */);
  1626. Cstr.isProxied = true;
  1627. }
  1628. const endNewInstance = createTime("createInstance", cmpMeta.$tagName$);
  1629. {
  1630. hostRef.$flags$ |= 8 /* isConstructingInstance */;
  1631. }
  1632. try {
  1633. new Cstr(hostRef);
  1634. } catch (e) {
  1635. consoleError(e);
  1636. }
  1637. {
  1638. hostRef.$flags$ &= ~8 /* isConstructingInstance */;
  1639. }
  1640. {
  1641. hostRef.$flags$ |= 128 /* isWatchReady */;
  1642. }
  1643. endNewInstance();
  1644. fireConnectedCallback(hostRef.$lazyInstance$);
  1645. } else {
  1646. Cstr = elm.constructor;
  1647. const cmpTag = elm.localName;
  1648. customElements.whenDefined(cmpTag).then(() => hostRef.$flags$ |= 128 /* isWatchReady */);
  1649. }
  1650. if (Cstr && Cstr.style) {
  1651. let style;
  1652. if (typeof Cstr.style === "string") {
  1653. style = Cstr.style;
  1654. } else if (typeof Cstr.style !== "string") {
  1655. hostRef.$modeName$ = computeMode(elm);
  1656. if (hostRef.$modeName$) {
  1657. style = Cstr.style[hostRef.$modeName$];
  1658. }
  1659. if (hostRef.$modeName$) {
  1660. elm.setAttribute("s-mode", hostRef.$modeName$);
  1661. }
  1662. }
  1663. const scopeId2 = getScopeId(cmpMeta, hostRef.$modeName$);
  1664. if (!styles.has(scopeId2)) {
  1665. const endRegisterStyles = createTime("registerStyles", cmpMeta.$tagName$);
  1666. registerStyle(scopeId2, style);
  1667. endRegisterStyles();
  1668. }
  1669. }
  1670. }
  1671. const ancestorComponent = hostRef.$ancestorComponent$;
  1672. const schedule = () => scheduleUpdate(hostRef, true);
  1673. if (ancestorComponent && ancestorComponent["s-rc"]) {
  1674. ancestorComponent["s-rc"].push(schedule);
  1675. } else {
  1676. schedule();
  1677. }
  1678. };
  1679. var fireConnectedCallback = (instance) => {
  1680. {
  1681. safeCall$1(instance, "connectedCallback");
  1682. }
  1683. };
  1684. // src/runtime/connected-callback.ts
  1685. var connectedCallback = (elm) => {
  1686. if ((plt.$flags$ & 1 /* isTmpDisconnected */) === 0) {
  1687. const hostRef = getHostRef(elm);
  1688. const cmpMeta = hostRef.$cmpMeta$;
  1689. const endConnected = createTime("connectedCallback", cmpMeta.$tagName$);
  1690. if (!(hostRef.$flags$ & 1 /* hasConnected */)) {
  1691. hostRef.$flags$ |= 1 /* hasConnected */;
  1692. let hostId;
  1693. {
  1694. hostId = elm.getAttribute(HYDRATE_ID);
  1695. if (hostId) {
  1696. if (cmpMeta.$flags$ & 1 /* shadowDomEncapsulation */) {
  1697. const scopeId2 = addStyle(elm.shadowRoot, cmpMeta, elm.getAttribute("s-mode")) ;
  1698. elm.classList.remove(scopeId2 + "-h", scopeId2 + "-s");
  1699. }
  1700. initializeClientHydrate(elm, cmpMeta.$tagName$, hostId, hostRef);
  1701. }
  1702. }
  1703. if (!hostId) {
  1704. {
  1705. setContentReference(elm);
  1706. }
  1707. }
  1708. {
  1709. let ancestorComponent = elm;
  1710. while (ancestorComponent = ancestorComponent.parentNode || ancestorComponent.host) {
  1711. if (ancestorComponent.nodeType === 1 /* ElementNode */ && ancestorComponent.hasAttribute("s-id") && ancestorComponent["s-p"] || ancestorComponent["s-p"]) {
  1712. attachToAncestor(hostRef, hostRef.$ancestorComponent$ = ancestorComponent);
  1713. break;
  1714. }
  1715. }
  1716. }
  1717. {
  1718. initializeComponent(elm, hostRef, cmpMeta);
  1719. }
  1720. } else {
  1721. addHostEventListeners(elm, hostRef, cmpMeta.$listeners$);
  1722. if (hostRef == null ? void 0 : hostRef.$lazyInstance$) {
  1723. fireConnectedCallback(hostRef.$lazyInstance$);
  1724. } else if (hostRef == null ? void 0 : hostRef.$onReadyPromise$) {
  1725. hostRef.$onReadyPromise$.then(() => fireConnectedCallback(hostRef.$lazyInstance$));
  1726. }
  1727. }
  1728. endConnected();
  1729. }
  1730. };
  1731. var setContentReference = (elm) => {
  1732. const contentRefElm = elm["s-cr"] = doc$1.createComment(
  1733. ""
  1734. );
  1735. contentRefElm["s-cn"] = true;
  1736. insertBefore(elm, contentRefElm, elm.firstChild);
  1737. };
  1738. var addHostEventListeners = (elm, hostRef, listeners, attachParentListeners) => {
  1739. if (listeners) {
  1740. listeners.map(([flags, name, method]) => {
  1741. const target = getHostListenerTarget(elm, flags) ;
  1742. const handler = hostListenerProxy(hostRef, method);
  1743. const opts = hostListenerOpts(flags);
  1744. plt.ael(target, name, handler, opts);
  1745. (hostRef.$rmListeners$ = hostRef.$rmListeners$ || []).push(() => plt.rel(target, name, handler, opts));
  1746. });
  1747. }
  1748. };
  1749. var hostListenerProxy = (hostRef, methodName) => (ev) => {
  1750. var _a;
  1751. try {
  1752. {
  1753. if (hostRef.$flags$ & 256 /* isListenReady */) {
  1754. (_a = hostRef.$lazyInstance$) == null ? void 0 : _a[methodName](ev);
  1755. } else {
  1756. (hostRef.$queuedListeners$ = hostRef.$queuedListeners$ || []).push([methodName, ev]);
  1757. }
  1758. }
  1759. } catch (e) {
  1760. consoleError(e);
  1761. }
  1762. };
  1763. var getHostListenerTarget = (elm, flags) => {
  1764. if (flags & 4 /* TargetDocument */) return doc$1;
  1765. if (flags & 8 /* TargetWindow */) return win$2;
  1766. if (flags & 16 /* TargetBody */) return doc$1.body;
  1767. return elm;
  1768. };
  1769. var hostListenerOpts = (flags) => (flags & 2 /* Capture */) !== 0;
  1770. // src/runtime/vdom/vdom-annotations.ts
  1771. var insertVdomAnnotations = (doc2, staticComponents) => {
  1772. if (doc2 != null) {
  1773. const docData = {
  1774. hostIds: 0,
  1775. rootLevelIds: 0,
  1776. staticComponents: new Set(staticComponents)
  1777. };
  1778. const orgLocationNodes = [];
  1779. parseVNodeAnnotations(doc2, doc2.body, docData, orgLocationNodes);
  1780. orgLocationNodes.forEach((orgLocationNode) => {
  1781. var _a;
  1782. if (orgLocationNode != null && orgLocationNode["s-nr"]) {
  1783. const nodeRef = orgLocationNode["s-nr"];
  1784. let hostId = nodeRef["s-host-id"];
  1785. let nodeId = nodeRef["s-node-id"];
  1786. let childId = `${hostId}.${nodeId}`;
  1787. if (hostId == null) {
  1788. hostId = 0;
  1789. docData.rootLevelIds++;
  1790. nodeId = docData.rootLevelIds;
  1791. childId = `${hostId}.${nodeId}`;
  1792. if (nodeRef.nodeType === 1 /* ElementNode */) {
  1793. nodeRef.setAttribute(HYDRATE_CHILD_ID, childId);
  1794. } else if (nodeRef.nodeType === 3 /* TextNode */) {
  1795. if (hostId === 0) {
  1796. const textContent = (_a = nodeRef.nodeValue) == null ? void 0 : _a.trim();
  1797. if (textContent === "") {
  1798. orgLocationNode.remove();
  1799. return;
  1800. }
  1801. }
  1802. const commentBeforeTextNode = doc2.createComment(childId);
  1803. commentBeforeTextNode.nodeValue = `${TEXT_NODE_ID}.${childId}`;
  1804. insertBefore(nodeRef.parentNode, commentBeforeTextNode, nodeRef);
  1805. }
  1806. }
  1807. let orgLocationNodeId = `${ORG_LOCATION_ID}.${childId}`;
  1808. const orgLocationParentNode = orgLocationNode.parentElement;
  1809. if (orgLocationParentNode) {
  1810. if (orgLocationParentNode["s-en"] === "") {
  1811. orgLocationNodeId += `.`;
  1812. } else if (orgLocationParentNode["s-en"] === "c") {
  1813. orgLocationNodeId += `.c`;
  1814. }
  1815. }
  1816. orgLocationNode.nodeValue = orgLocationNodeId;
  1817. }
  1818. });
  1819. }
  1820. };
  1821. var parseVNodeAnnotations = (doc2, node, docData, orgLocationNodes) => {
  1822. var _a;
  1823. if (node == null) {
  1824. return;
  1825. }
  1826. if (node["s-nr"] != null) {
  1827. orgLocationNodes.push(node);
  1828. }
  1829. if (node.nodeType === 1 /* ElementNode */) {
  1830. const childNodes = [...Array.from(node.childNodes), ...Array.from(((_a = node.shadowRoot) == null ? void 0 : _a.childNodes) || [])];
  1831. childNodes.forEach((childNode) => {
  1832. const hostRef = getHostRef(childNode);
  1833. if (hostRef != null && !docData.staticComponents.has(childNode.nodeName.toLowerCase())) {
  1834. const cmpData = {
  1835. nodeIds: 0
  1836. };
  1837. insertVNodeAnnotations(doc2, childNode, hostRef.$vnode$, docData, cmpData);
  1838. }
  1839. parseVNodeAnnotations(doc2, childNode, docData, orgLocationNodes);
  1840. });
  1841. }
  1842. };
  1843. var insertVNodeAnnotations = (doc2, hostElm, vnode, docData, cmpData) => {
  1844. if (vnode != null) {
  1845. const hostId = ++docData.hostIds;
  1846. hostElm.setAttribute(HYDRATE_ID, hostId);
  1847. if (hostElm["s-cr"] != null) {
  1848. hostElm["s-cr"].nodeValue = `${CONTENT_REF_ID}.${hostId}`;
  1849. }
  1850. if (vnode.$children$ != null) {
  1851. const depth = 0;
  1852. vnode.$children$.forEach((vnodeChild, index) => {
  1853. insertChildVNodeAnnotations(doc2, vnodeChild, cmpData, hostId, depth, index);
  1854. });
  1855. }
  1856. if (hostElm && vnode && vnode.$elm$ && !hostElm.hasAttribute(HYDRATE_CHILD_ID)) {
  1857. const parent = hostElm.parentElement;
  1858. if (parent && parent.childNodes) {
  1859. const parentChildNodes = Array.from(parent.childNodes);
  1860. const comment = parentChildNodes.find(
  1861. (node) => node.nodeType === 8 /* CommentNode */ && node["s-sr"]
  1862. );
  1863. if (comment) {
  1864. const index = parentChildNodes.indexOf(hostElm) - 1;
  1865. vnode.$elm$.setAttribute(
  1866. HYDRATE_CHILD_ID,
  1867. `${comment["s-host-id"]}.${comment["s-node-id"]}.0.${index}`
  1868. );
  1869. }
  1870. }
  1871. }
  1872. }
  1873. };
  1874. var insertChildVNodeAnnotations = (doc2, vnodeChild, cmpData, hostId, depth, index) => {
  1875. const childElm = vnodeChild.$elm$;
  1876. if (childElm == null) {
  1877. return;
  1878. }
  1879. const nodeId = cmpData.nodeIds++;
  1880. const childId = `${hostId}.${nodeId}.${depth}.${index}`;
  1881. childElm["s-host-id"] = hostId;
  1882. childElm["s-node-id"] = nodeId;
  1883. if (childElm.nodeType === 1 /* ElementNode */) {
  1884. childElm.setAttribute(HYDRATE_CHILD_ID, childId);
  1885. } else if (childElm.nodeType === 3 /* TextNode */) {
  1886. const parentNode = childElm.parentNode;
  1887. const nodeName = parentNode == null ? void 0 : parentNode.nodeName;
  1888. if (nodeName !== "STYLE" && nodeName !== "SCRIPT") {
  1889. const textNodeId = `${TEXT_NODE_ID}.${childId}`;
  1890. const commentBeforeTextNode = doc2.createComment(textNodeId);
  1891. insertBefore(parentNode, commentBeforeTextNode, childElm);
  1892. }
  1893. } else if (childElm.nodeType === 8 /* CommentNode */) {
  1894. if (childElm["s-sr"]) {
  1895. const slotName = childElm["s-sn"] || "";
  1896. const slotNodeId = `${SLOT_NODE_ID}.${childId}.${slotName}`;
  1897. childElm.nodeValue = slotNodeId;
  1898. }
  1899. }
  1900. if (vnodeChild.$children$ != null) {
  1901. const childDepth = depth + 1;
  1902. vnodeChild.$children$.forEach((vnode, index2) => {
  1903. insertChildVNodeAnnotations(doc2, vnode, cmpData, hostId, childDepth, index2);
  1904. });
  1905. }
  1906. };
  1907. // src/hydrate/platform/h-async.ts
  1908. var hAsync = (nodeName, vnodeData, ...children) => {
  1909. if (Array.isArray(children) && children.length > 0) {
  1910. const flatChildren = children.flat(Infinity);
  1911. if (flatChildren.some((child) => child instanceof Promise)) {
  1912. return Promise.all(flatChildren).then((resolvedChildren) => {
  1913. return h(nodeName, vnodeData, ...resolvedChildren);
  1914. }).catch((err2) => {
  1915. return h(nodeName, vnodeData);
  1916. });
  1917. }
  1918. return h(nodeName, vnodeData, ...flatChildren);
  1919. }
  1920. return h(nodeName, vnodeData);
  1921. };
  1922. function proxyHostElement(elm, cmpMeta) {
  1923. if (typeof elm.componentOnReady !== "function") {
  1924. elm.componentOnReady = componentOnReady$1;
  1925. }
  1926. if (typeof elm.forceUpdate !== "function") {
  1927. elm.forceUpdate = forceUpdate2;
  1928. }
  1929. if (!elm.shadowRoot && !!(cmpMeta.$flags$ & 1 /* shadowDomEncapsulation */)) {
  1930. {
  1931. elm.attachShadow({
  1932. mode: "open",
  1933. delegatesFocus: !!(cmpMeta.$flags$ & 16 /* shadowDelegatesFocus */)
  1934. });
  1935. }
  1936. }
  1937. if (cmpMeta.$members$ != null) {
  1938. const hostRef = getHostRef(elm);
  1939. const members = Object.entries(cmpMeta.$members$);
  1940. members.forEach(([memberName, m]) => {
  1941. var _a, _b;
  1942. const memberFlags = m[0];
  1943. if (memberFlags & 31 /* Prop */) {
  1944. const attributeName = m[1] || memberName;
  1945. let attrValue = elm.getAttribute(attributeName);
  1946. if ((attrValue == null ? void 0 : attrValue.startsWith("{")) && attrValue.endsWith("}") || (attrValue == null ? void 0 : attrValue.startsWith("[")) && attrValue.endsWith("]")) {
  1947. try {
  1948. attrValue = JSON.parse(attrValue);
  1949. } catch (e) {
  1950. }
  1951. }
  1952. if (attrValue != null) {
  1953. const parsedAttrValue = parsePropertyValue(attrValue, memberFlags);
  1954. (_a = hostRef == null ? void 0 : hostRef.$instanceValues$) == null ? void 0 : _a.set(memberName, parsedAttrValue);
  1955. }
  1956. const ownValue = elm[memberName];
  1957. if (ownValue !== void 0) {
  1958. (_b = hostRef == null ? void 0 : hostRef.$instanceValues$) == null ? void 0 : _b.set(memberName, ownValue);
  1959. delete elm[memberName];
  1960. }
  1961. Object.defineProperty(elm, memberName, {
  1962. get() {
  1963. return getValue(this, memberName);
  1964. },
  1965. set(newValue) {
  1966. setValue(this, memberName, newValue, cmpMeta);
  1967. },
  1968. configurable: true,
  1969. enumerable: true
  1970. });
  1971. } else if (memberFlags & 64 /* Method */) {
  1972. Object.defineProperty(elm, memberName, {
  1973. value(...args) {
  1974. var _a2;
  1975. const ref = getHostRef(this);
  1976. return (_a2 = ref == null ? void 0 : ref.$onInstancePromise$) == null ? void 0 : _a2.then(() => {
  1977. var _a3;
  1978. return (_a3 = ref == null ? void 0 : ref.$lazyInstance$) == null ? void 0 : _a3[memberName](...args);
  1979. }).catch(consoleError);
  1980. }
  1981. });
  1982. }
  1983. });
  1984. }
  1985. }
  1986. function componentOnReady$1() {
  1987. var _a;
  1988. return (_a = getHostRef(this)) == null ? void 0 : _a.$onReadyPromise$;
  1989. }
  1990. function forceUpdate2() {
  1991. }
  1992. // src/hydrate/platform/hydrate-app.ts
  1993. function hydrateApp(win2, opts, results, afterHydrate, resolve) {
  1994. const connectedElements = /* @__PURE__ */ new Set();
  1995. const createdElements = /* @__PURE__ */ new Set();
  1996. const waitingElements = /* @__PURE__ */ new Set();
  1997. const orgDocumentCreateElement = win2.document.createElement;
  1998. const orgDocumentCreateElementNS = win2.document.createElementNS;
  1999. const resolved2 = Promise.resolve();
  2000. let tmrId;
  2001. let ranCompleted = false;
  2002. function hydratedComplete() {
  2003. globalThis.clearTimeout(tmrId);
  2004. createdElements.clear();
  2005. connectedElements.clear();
  2006. if (!ranCompleted) {
  2007. ranCompleted = true;
  2008. try {
  2009. if (opts.clientHydrateAnnotations) {
  2010. insertVdomAnnotations(win2.document, opts.staticComponents);
  2011. }
  2012. win2.dispatchEvent(new win2.Event("DOMContentLoaded"));
  2013. win2.document.createElement = orgDocumentCreateElement;
  2014. win2.document.createElementNS = orgDocumentCreateElementNS;
  2015. } catch (e) {
  2016. renderCatchError(opts, results, e);
  2017. }
  2018. }
  2019. afterHydrate(win2, opts, results, resolve);
  2020. }
  2021. function hydratedError(err2) {
  2022. renderCatchError(opts, results, err2);
  2023. hydratedComplete();
  2024. }
  2025. function timeoutExceeded() {
  2026. hydratedError(`Hydrate exceeded timeout${waitingOnElementsMsg(waitingElements)}`);
  2027. }
  2028. try {
  2029. let patchedConnectedCallback2 = function() {
  2030. return connectElement2(this);
  2031. }, patchElement2 = function(elm) {
  2032. if (isValidComponent(elm, opts)) {
  2033. const hostRef = getHostRef(elm);
  2034. if (!hostRef) {
  2035. const Cstr = loadModule(
  2036. {
  2037. $tagName$: elm.nodeName.toLowerCase(),
  2038. $flags$: null
  2039. });
  2040. if (Cstr != null && Cstr.cmpMeta != null) {
  2041. createdElements.add(elm);
  2042. elm.connectedCallback = patchedConnectedCallback2;
  2043. registerHost(elm, Cstr.cmpMeta);
  2044. proxyHostElement(elm, Cstr.cmpMeta);
  2045. }
  2046. }
  2047. }
  2048. }, patchChild2 = function(elm) {
  2049. if (elm != null && elm.nodeType === 1) {
  2050. patchElement2(elm);
  2051. const children = elm.children;
  2052. for (let i2 = 0, ii = children.length; i2 < ii; i2++) {
  2053. patchChild2(children[i2]);
  2054. }
  2055. }
  2056. }, connectElement2 = function(elm) {
  2057. createdElements.delete(elm);
  2058. if (isValidComponent(elm, opts) && results.hydratedCount < opts.maxHydrateCount) {
  2059. if (!connectedElements.has(elm) && shouldHydrate(elm)) {
  2060. connectedElements.add(elm);
  2061. return hydrateComponent.call(elm, win2, results, elm.nodeName, elm, waitingElements);
  2062. }
  2063. }
  2064. return resolved2;
  2065. }, waitLoop2 = function() {
  2066. const toConnect = Array.from(createdElements).filter((elm) => elm.parentElement);
  2067. if (toConnect.length > 0) {
  2068. return Promise.all(toConnect.map(connectElement2)).then(waitLoop2);
  2069. }
  2070. return resolved2;
  2071. };
  2072. win2.document.createElement = function patchedCreateElement(tagName) {
  2073. const elm = orgDocumentCreateElement.call(win2.document, tagName);
  2074. patchElement2(elm);
  2075. return elm;
  2076. };
  2077. win2.document.createElementNS = function patchedCreateElement(namespaceURI, tagName) {
  2078. const elm = orgDocumentCreateElementNS.call(win2.document, namespaceURI, tagName);
  2079. patchElement2(elm);
  2080. return elm;
  2081. };
  2082. tmrId = globalThis.setTimeout(timeoutExceeded, opts.timeout);
  2083. plt.$resourcesUrl$ = new URL(opts.resourcesUrl || "./", doc$1.baseURI).href;
  2084. patchChild2(win2.document.body);
  2085. waitLoop2().then(hydratedComplete).catch(hydratedError);
  2086. } catch (e) {
  2087. hydratedError(e);
  2088. }
  2089. }
  2090. async function hydrateComponent(win2, results, tagName, elm, waitingElements) {
  2091. tagName = tagName.toLowerCase();
  2092. const Cstr = loadModule(
  2093. {
  2094. $tagName$: tagName,
  2095. $flags$: null
  2096. });
  2097. if (Cstr != null) {
  2098. const cmpMeta = Cstr.cmpMeta;
  2099. if (cmpMeta != null) {
  2100. waitingElements.add(elm);
  2101. const hostRef = getHostRef(this);
  2102. addHostEventListeners(this, hostRef, cmpMeta.$listeners$);
  2103. try {
  2104. connectedCallback(elm);
  2105. await elm.componentOnReady();
  2106. results.hydratedCount++;
  2107. const ref = getHostRef(elm);
  2108. const modeName = !ref.$modeName$ ? "$" : ref.$modeName$;
  2109. if (!results.components.some((c) => c.tag === tagName && c.mode === modeName)) {
  2110. results.components.push({
  2111. tag: tagName,
  2112. mode: modeName,
  2113. count: 0,
  2114. depth: -1
  2115. });
  2116. }
  2117. } catch (e) {
  2118. win2.console.error(e);
  2119. }
  2120. waitingElements.delete(elm);
  2121. }
  2122. }
  2123. }
  2124. function isValidComponent(elm, opts) {
  2125. if (elm != null && elm.nodeType === 1) {
  2126. const tagName = elm.nodeName;
  2127. if (typeof tagName === "string" && tagName.includes("-")) {
  2128. if (opts.excludeComponents.includes(tagName.toLowerCase())) {
  2129. return false;
  2130. }
  2131. return true;
  2132. }
  2133. }
  2134. return false;
  2135. }
  2136. function shouldHydrate(elm) {
  2137. if (elm.nodeType === 9) {
  2138. return true;
  2139. }
  2140. if (NO_HYDRATE_TAGS.has(elm.nodeName)) {
  2141. return false;
  2142. }
  2143. if (elm.hasAttribute("no-prerender")) {
  2144. return false;
  2145. }
  2146. const parentNode = elm.parentNode;
  2147. if (parentNode == null) {
  2148. return true;
  2149. }
  2150. return shouldHydrate(parentNode);
  2151. }
  2152. var NO_HYDRATE_TAGS = /* @__PURE__ */ new Set([
  2153. "CODE",
  2154. "HEAD",
  2155. "IFRAME",
  2156. "INPUT",
  2157. "OBJECT",
  2158. "OUTPUT",
  2159. "NOSCRIPT",
  2160. "PRE",
  2161. "SCRIPT",
  2162. "SELECT",
  2163. "STYLE",
  2164. "TEMPLATE",
  2165. "TEXTAREA"
  2166. ]);
  2167. function renderCatchError(opts, results, err2) {
  2168. const diagnostic = {
  2169. level: "error",
  2170. type: "build",
  2171. header: "Hydrate Error",
  2172. messageText: "",
  2173. relFilePath: void 0,
  2174. absFilePath: void 0,
  2175. lines: []
  2176. };
  2177. if (opts.url) {
  2178. try {
  2179. const u = new URL(opts.url);
  2180. if (u.pathname !== "/") {
  2181. diagnostic.header += ": " + u.pathname;
  2182. }
  2183. } catch (e) {
  2184. }
  2185. }
  2186. if (err2 != null) {
  2187. if (err2.stack != null) {
  2188. diagnostic.messageText = err2.stack.toString();
  2189. } else if (err2.message != null) {
  2190. diagnostic.messageText = err2.message.toString();
  2191. } else {
  2192. diagnostic.messageText = err2.toString();
  2193. }
  2194. }
  2195. results.diagnostics.push(diagnostic);
  2196. }
  2197. function printTag(elm) {
  2198. let tag = `<${elm.nodeName.toLowerCase()}`;
  2199. if (Array.isArray(elm.attributes)) {
  2200. for (let i2 = 0; i2 < elm.attributes.length; i2++) {
  2201. const attr = elm.attributes[i2];
  2202. tag += ` ${attr.name}`;
  2203. if (attr.value !== "") {
  2204. tag += `="${attr.value}"`;
  2205. }
  2206. }
  2207. }
  2208. tag += `>`;
  2209. return tag;
  2210. }
  2211. function waitingOnElementMsg(waitingElement) {
  2212. let msg = "";
  2213. if (waitingElement) {
  2214. const lines = [];
  2215. msg = " - waiting on:";
  2216. let elm = waitingElement;
  2217. while (elm && elm.nodeType !== 9 && elm.nodeName !== "BODY") {
  2218. lines.unshift(printTag(elm));
  2219. elm = elm.parentElement;
  2220. }
  2221. let indent = "";
  2222. for (const ln of lines) {
  2223. indent += " ";
  2224. msg += `
  2225. ${indent}${ln}`;
  2226. }
  2227. }
  2228. return msg;
  2229. }
  2230. function waitingOnElementsMsg(waitingElements) {
  2231. return Array.from(waitingElements).map(waitingOnElementMsg);
  2232. }
  2233. var cmpModules = /* @__PURE__ */ new Map();
  2234. var getModule = (tagName) => {
  2235. if (typeof tagName === "string") {
  2236. tagName = tagName.toLowerCase();
  2237. const cmpModule = cmpModules.get(tagName);
  2238. if (cmpModule != null) {
  2239. return cmpModule[tagName];
  2240. }
  2241. }
  2242. return null;
  2243. };
  2244. var loadModule = (cmpMeta, _hostRef, _hmrVersionId) => {
  2245. return getModule(cmpMeta.$tagName$);
  2246. };
  2247. var isMemberInElement = (elm, memberName) => {
  2248. if (elm != null) {
  2249. if (memberName in elm) {
  2250. return true;
  2251. }
  2252. const cstr = getModule(elm.nodeName);
  2253. if (cstr != null) {
  2254. const hostRef = cstr;
  2255. if (hostRef != null && hostRef.cmpMeta != null && hostRef.cmpMeta.$members$ != null) {
  2256. return memberName in hostRef.cmpMeta.$members$;
  2257. }
  2258. }
  2259. }
  2260. return false;
  2261. };
  2262. var registerComponents = (Cstrs) => {
  2263. for (const Cstr of Cstrs) {
  2264. const exportName = Cstr.cmpMeta.$tagName$;
  2265. cmpModules.set(exportName, {
  2266. [exportName]: Cstr
  2267. });
  2268. }
  2269. };
  2270. var win$2 = window;
  2271. var doc$1 = win$2.document;
  2272. var readTask = (cb) => {
  2273. nextTick(() => {
  2274. try {
  2275. cb();
  2276. } catch (e) {
  2277. consoleError(e);
  2278. }
  2279. });
  2280. };
  2281. var writeTask = (cb) => {
  2282. nextTick(() => {
  2283. try {
  2284. cb();
  2285. } catch (e) {
  2286. consoleError(e);
  2287. }
  2288. });
  2289. };
  2290. var resolved = /* @__PURE__ */ Promise.resolve();
  2291. var nextTick = (cb) => resolved.then(cb);
  2292. var defaultConsoleError = (e) => {
  2293. if (e != null) {
  2294. console.error(e.stack || e.message || e);
  2295. }
  2296. };
  2297. var consoleError = (e, el) => (defaultConsoleError)(e, el);
  2298. var plt = {
  2299. $flags$: 0,
  2300. $resourcesUrl$: "",
  2301. jmp: (h2) => h2(),
  2302. raf: (h2) => requestAnimationFrame(h2),
  2303. ael: (el, eventName, listener, opts) => el.addEventListener(eventName, listener, opts),
  2304. rel: (el, eventName, listener, opts) => el.removeEventListener(eventName, listener, opts),
  2305. ce: (eventName, opts) => new win$2.CustomEvent(eventName, opts)
  2306. };
  2307. var supportsShadow = BUILD.shadowDom;
  2308. var hostRefs = /* @__PURE__ */ new WeakMap();
  2309. var getHostRef = (ref) => hostRefs.get(ref);
  2310. var registerInstance = (lazyInstance, hostRef) => hostRefs.set(hostRef.$lazyInstance$ = lazyInstance, hostRef);
  2311. var registerHost = (elm, cmpMeta) => {
  2312. const hostRef = {
  2313. $flags$: 0,
  2314. $cmpMeta$: cmpMeta,
  2315. $hostElement$: elm,
  2316. $instanceValues$: /* @__PURE__ */ new Map(),
  2317. $renderCount$: 0
  2318. };
  2319. hostRef.$onInstancePromise$ = new Promise((r) => hostRef.$onInstanceResolve$ = r);
  2320. hostRef.$onReadyPromise$ = new Promise((r) => hostRef.$onReadyResolve$ = r);
  2321. elm["s-p"] = [];
  2322. elm["s-rc"] = [];
  2323. return hostRefs.set(elm, hostRef);
  2324. };
  2325. var Build = {
  2326. isDev: false,
  2327. isBrowser: false,
  2328. isServer: true,
  2329. isTesting: false
  2330. };
  2331. var styles = /* @__PURE__ */ new Map();
  2332. var modeResolutionChain = [];
  2333. // TODO(FW-2832): types
  2334. class Config {
  2335. constructor() {
  2336. this.m = new Map();
  2337. }
  2338. reset(configObj) {
  2339. this.m = new Map(Object.entries(configObj));
  2340. }
  2341. get(key, fallback) {
  2342. const value = this.m.get(key);
  2343. return value !== undefined ? value : fallback;
  2344. }
  2345. getBoolean(key, fallback = false) {
  2346. const val = this.m.get(key);
  2347. if (val === undefined) {
  2348. return fallback;
  2349. }
  2350. if (typeof val === 'string') {
  2351. return val === 'true';
  2352. }
  2353. return !!val;
  2354. }
  2355. getNumber(key, fallback) {
  2356. const val = parseFloat(this.m.get(key));
  2357. return isNaN(val) ? (fallback !== undefined ? fallback : NaN) : val;
  2358. }
  2359. set(key, value) {
  2360. this.m.set(key, value);
  2361. }
  2362. }
  2363. const config = /*@__PURE__*/ new Config();
  2364. var LogLevel;
  2365. (function (LogLevel) {
  2366. LogLevel["OFF"] = "OFF";
  2367. LogLevel["ERROR"] = "ERROR";
  2368. LogLevel["WARN"] = "WARN";
  2369. })(LogLevel || (LogLevel = {}));
  2370. /**
  2371. * Logs a warning to the console with an Ionic prefix
  2372. * to indicate the library that is warning the developer.
  2373. *
  2374. * @param message - The string message to be logged to the console.
  2375. */
  2376. const printIonWarning = (message, ...params) => {
  2377. const logLevel = config.get('logLevel', LogLevel.WARN);
  2378. if ([LogLevel.WARN].includes(logLevel)) {
  2379. return console.warn(`[Ionic Warning]: ${message}`, ...params);
  2380. }
  2381. };
  2382. /**
  2383. * Logs an error to the console with an Ionic prefix
  2384. * to indicate the library that is warning the developer.
  2385. *
  2386. * @param message - The string message to be logged to the console.
  2387. * @param params - Additional arguments to supply to the console.error.
  2388. */
  2389. const printIonError = (message, ...params) => {
  2390. const logLevel = config.get('logLevel', LogLevel.ERROR);
  2391. if ([LogLevel.ERROR, LogLevel.WARN].includes(logLevel)) {
  2392. return console.error(`[Ionic Error]: ${message}`, ...params);
  2393. }
  2394. };
  2395. /**
  2396. * Prints an error informing developers that an implementation requires an element to be used
  2397. * within a specific selector.
  2398. *
  2399. * @param el The web component element this is requiring the element.
  2400. * @param targetSelectors The selector or selectors that were not found.
  2401. */
  2402. const printRequiredElementError = (el, ...targetSelectors) => {
  2403. return console.error(`<${el.tagName.toLowerCase()}> must be used inside ${targetSelectors.join(' or ')}.`);
  2404. };
  2405. const transitionEndAsync = (el, expectedDuration = 0) => {
  2406. return new Promise((resolve) => {
  2407. transitionEnd(el, expectedDuration, resolve);
  2408. });
  2409. };
  2410. /**
  2411. * Allows developer to wait for a transition
  2412. * to finish and fallback to a timer if the
  2413. * transition is cancelled or otherwise
  2414. * never finishes. Also see transitionEndAsync
  2415. * which is an await-able version of this.
  2416. */
  2417. const transitionEnd = (el, expectedDuration = 0, callback) => {
  2418. let unRegTrans;
  2419. let animationTimeout;
  2420. const opts = { passive: true };
  2421. const ANIMATION_FALLBACK_TIMEOUT = 500;
  2422. const unregister = () => {
  2423. if (unRegTrans) {
  2424. unRegTrans();
  2425. }
  2426. };
  2427. const onTransitionEnd = (ev) => {
  2428. if (ev === undefined || el === ev.target) {
  2429. unregister();
  2430. callback(ev);
  2431. }
  2432. };
  2433. if (el) {
  2434. el.addEventListener('webkitTransitionEnd', onTransitionEnd, opts);
  2435. el.addEventListener('transitionend', onTransitionEnd, opts);
  2436. animationTimeout = setTimeout(onTransitionEnd, expectedDuration + ANIMATION_FALLBACK_TIMEOUT);
  2437. unRegTrans = () => {
  2438. if (animationTimeout !== undefined) {
  2439. clearTimeout(animationTimeout);
  2440. animationTimeout = undefined;
  2441. }
  2442. el.removeEventListener('webkitTransitionEnd', onTransitionEnd, opts);
  2443. el.removeEventListener('transitionend', onTransitionEnd, opts);
  2444. };
  2445. }
  2446. return unregister;
  2447. };
  2448. /**
  2449. * Waits for a component to be ready for
  2450. * both custom element and non-custom element builds.
  2451. * If non-custom element build, el.componentOnReady
  2452. * will be used.
  2453. * For custom element builds, we wait a frame
  2454. * so that the inner contents of the component
  2455. * have a chance to render.
  2456. *
  2457. * Use this utility rather than calling
  2458. * el.componentOnReady yourself.
  2459. */
  2460. const componentOnReady = (el, callback) => {
  2461. if (el.componentOnReady) {
  2462. // eslint-disable-next-line custom-rules/no-component-on-ready-method
  2463. el.componentOnReady().then((resolvedEl) => callback(resolvedEl));
  2464. }
  2465. else {
  2466. raf(() => callback(el));
  2467. }
  2468. };
  2469. /**
  2470. * This functions checks if a Stencil component is using
  2471. * the lazy loaded build of Stencil. Returns `true` if
  2472. * the component is lazy loaded. Returns `false` otherwise.
  2473. */
  2474. const hasLazyBuild = (stencilEl) => {
  2475. return stencilEl.componentOnReady !== undefined;
  2476. };
  2477. /**
  2478. * Elements inside of web components sometimes need to inherit global attributes
  2479. * set on the host. For example, the inner input in `ion-input` should inherit
  2480. * the `title` attribute that developers set directly on `ion-input`. This
  2481. * helper function should be called in componentWillLoad and assigned to a variable
  2482. * that is later used in the render function.
  2483. *
  2484. * This does not need to be reactive as changing attributes on the host element
  2485. * does not trigger a re-render.
  2486. */
  2487. const inheritAttributes$1 = (el, attributes = []) => {
  2488. const attributeObject = {};
  2489. attributes.forEach((attr) => {
  2490. if (el.hasAttribute(attr)) {
  2491. const value = el.getAttribute(attr);
  2492. if (value !== null) {
  2493. attributeObject[attr] = el.getAttribute(attr);
  2494. }
  2495. el.removeAttribute(attr);
  2496. }
  2497. });
  2498. return attributeObject;
  2499. };
  2500. /**
  2501. * List of available ARIA attributes + `role`.
  2502. * Removed deprecated attributes.
  2503. * https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Attributes
  2504. */
  2505. const ariaAttributes = [
  2506. 'role',
  2507. 'aria-activedescendant',
  2508. 'aria-atomic',
  2509. 'aria-autocomplete',
  2510. 'aria-braillelabel',
  2511. 'aria-brailleroledescription',
  2512. 'aria-busy',
  2513. 'aria-checked',
  2514. 'aria-colcount',
  2515. 'aria-colindex',
  2516. 'aria-colindextext',
  2517. 'aria-colspan',
  2518. 'aria-controls',
  2519. 'aria-current',
  2520. 'aria-describedby',
  2521. 'aria-description',
  2522. 'aria-details',
  2523. 'aria-disabled',
  2524. 'aria-errormessage',
  2525. 'aria-expanded',
  2526. 'aria-flowto',
  2527. 'aria-haspopup',
  2528. 'aria-hidden',
  2529. 'aria-invalid',
  2530. 'aria-keyshortcuts',
  2531. 'aria-label',
  2532. 'aria-labelledby',
  2533. 'aria-level',
  2534. 'aria-live',
  2535. 'aria-multiline',
  2536. 'aria-multiselectable',
  2537. 'aria-orientation',
  2538. 'aria-owns',
  2539. 'aria-placeholder',
  2540. 'aria-posinset',
  2541. 'aria-pressed',
  2542. 'aria-readonly',
  2543. 'aria-relevant',
  2544. 'aria-required',
  2545. 'aria-roledescription',
  2546. 'aria-rowcount',
  2547. 'aria-rowindex',
  2548. 'aria-rowindextext',
  2549. 'aria-rowspan',
  2550. 'aria-selected',
  2551. 'aria-setsize',
  2552. 'aria-sort',
  2553. 'aria-valuemax',
  2554. 'aria-valuemin',
  2555. 'aria-valuenow',
  2556. 'aria-valuetext',
  2557. ];
  2558. /**
  2559. * Returns an array of aria attributes that should be copied from
  2560. * the shadow host element to a target within the light DOM.
  2561. * @param el The element that the attributes should be copied from.
  2562. * @param ignoreList The list of aria-attributes to ignore reflecting and removing from the host.
  2563. * Use this in instances where we manually specify aria attributes on the `<Host>` element.
  2564. */
  2565. const inheritAriaAttributes = (el, ignoreList) => {
  2566. let attributesToInherit = ariaAttributes;
  2567. if (ignoreList && ignoreList.length > 0) {
  2568. attributesToInherit = attributesToInherit.filter((attr) => !ignoreList.includes(attr));
  2569. }
  2570. return inheritAttributes$1(el, attributesToInherit);
  2571. };
  2572. const addEventListener$1 = (el, eventName, callback, opts) => {
  2573. return el.addEventListener(eventName, callback, opts);
  2574. };
  2575. const removeEventListener = (el, eventName, callback, opts) => {
  2576. return el.removeEventListener(eventName, callback, opts);
  2577. };
  2578. /**
  2579. * Gets the root context of a shadow dom element
  2580. * On newer browsers this will be the shadowRoot,
  2581. * but for older browser this may just be the
  2582. * element itself.
  2583. *
  2584. * Useful for whenever you need to explicitly
  2585. * do "myElement.shadowRoot!.querySelector(...)".
  2586. */
  2587. const getElementRoot = (el, fallback = el) => {
  2588. return el.shadowRoot || fallback;
  2589. };
  2590. /**
  2591. * Patched version of requestAnimationFrame that avoids ngzone
  2592. * Use only when you know ngzone should not run
  2593. */
  2594. const raf = (h) => {
  2595. if (typeof __zone_symbol__requestAnimationFrame === 'function') {
  2596. return __zone_symbol__requestAnimationFrame(h);
  2597. }
  2598. if (typeof requestAnimationFrame === 'function') {
  2599. return requestAnimationFrame(h);
  2600. }
  2601. return setTimeout(h);
  2602. };
  2603. const hasShadowDom = (el) => {
  2604. return !!el.shadowRoot && !!el.attachShadow;
  2605. };
  2606. const focusVisibleElement = (el) => {
  2607. el.focus();
  2608. /**
  2609. * When programmatically focusing an element,
  2610. * the focus-visible utility will not run because
  2611. * it is expecting a keyboard event to have triggered this;
  2612. * however, there are times when we need to manually control
  2613. * this behavior so we call the `setFocus` method on ion-app
  2614. * which will let us explicitly set the elements to focus.
  2615. */
  2616. if (el.classList.contains('ion-focusable')) {
  2617. const app = el.closest('ion-app');
  2618. if (app) {
  2619. app.setFocus([el]);
  2620. }
  2621. }
  2622. };
  2623. /**
  2624. * This method is used to add a hidden input to a host element that contains
  2625. * a Shadow DOM. It does not add the input inside of the Shadow root which
  2626. * allows it to be picked up inside of forms. It should contain the same
  2627. * values as the host element.
  2628. *
  2629. * @param always Add a hidden input even if the container does not use Shadow
  2630. * @param container The element where the input will be added
  2631. * @param name The name of the input
  2632. * @param value The value of the input
  2633. * @param disabled If true, the input is disabled
  2634. */
  2635. const renderHiddenInput = (always, container, name, value, disabled) => {
  2636. if (always || hasShadowDom(container)) {
  2637. let input = container.querySelector('input.aux-input');
  2638. if (!input) {
  2639. input = container.ownerDocument.createElement('input');
  2640. input.type = 'hidden';
  2641. input.classList.add('aux-input');
  2642. container.appendChild(input);
  2643. }
  2644. input.disabled = disabled;
  2645. input.name = name;
  2646. input.value = value || '';
  2647. }
  2648. };
  2649. const clamp = (min, n, max) => {
  2650. return Math.max(min, Math.min(n, max));
  2651. };
  2652. const assert = (actual, reason) => {
  2653. if (!actual) {
  2654. const message = 'ASSERT: ' + reason;
  2655. printIonError(message);
  2656. debugger; // eslint-disable-line
  2657. throw new Error(message);
  2658. }
  2659. };
  2660. /**
  2661. * @hidden
  2662. * Given a side, return if it should be on the end
  2663. * based on the value of dir
  2664. * @param side the side
  2665. * @param isRTL whether the application dir is rtl
  2666. */
  2667. const isEndSide = (side) => {
  2668. const isRTL = document.dir === 'rtl';
  2669. switch (side) {
  2670. case 'start':
  2671. return isRTL;
  2672. case 'end':
  2673. return !isRTL;
  2674. default:
  2675. throw new Error(`"${side}" is not a valid value for [side]. Use "start" or "end" instead.`);
  2676. }
  2677. };
  2678. const debounceEvent = (event, wait) => {
  2679. const original = event._original || event;
  2680. return {
  2681. _original: event,
  2682. emit: debounce(original.emit.bind(original), wait),
  2683. };
  2684. };
  2685. const debounce = (func, wait = 0) => {
  2686. let timer;
  2687. return (...args) => {
  2688. clearTimeout(timer);
  2689. timer = setTimeout(func, wait, ...args);
  2690. };
  2691. };
  2692. /**
  2693. * Check whether the two string maps are shallow equal.
  2694. *
  2695. * undefined is treated as an empty map.
  2696. *
  2697. * @returns whether the keys are the same and the values are shallow equal.
  2698. */
  2699. const shallowEqualStringMap = (map1, map2) => {
  2700. map1 !== null && map1 !== void 0 ? map1 : (map1 = {});
  2701. map2 !== null && map2 !== void 0 ? map2 : (map2 = {});
  2702. if (map1 === map2) {
  2703. return true;
  2704. }
  2705. const keys1 = Object.keys(map1);
  2706. if (keys1.length !== Object.keys(map2).length) {
  2707. return false;
  2708. }
  2709. for (const k1 of keys1) {
  2710. if (!(k1 in map2)) {
  2711. return false;
  2712. }
  2713. if (map1[k1] !== map2[k1]) {
  2714. return false;
  2715. }
  2716. }
  2717. return true;
  2718. };
  2719. /**
  2720. * Checks input for usable number. Not NaN and not Infinite.
  2721. */
  2722. const isSafeNumber = (input) => {
  2723. return typeof input === 'number' && !isNaN(input) && isFinite(input);
  2724. };
  2725. /* Ionicons v7.2.2, ES Modules */
  2726. 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>";
  2727. 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>";
  2728. 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>";
  2729. 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>";
  2730. 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>";
  2731. 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>";
  2732. 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>";
  2733. 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>";
  2734. 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>";
  2735. 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>";
  2736. 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>";
  2737. 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>";
  2738. 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>";
  2739. 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>";
  2740. 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>";
  2741. 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>";
  2742. 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>";
  2743. 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>";
  2744. 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>";
  2745. 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>";
  2746. 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>";
  2747. 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>";
  2748. 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>";
  2749. 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>";
  2750. 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>";
  2751. const getPlatforms = (win) => setupPlatforms(win);
  2752. const isPlatform = (winOrPlatform, platform) => {
  2753. if (typeof winOrPlatform === 'string') {
  2754. platform = winOrPlatform;
  2755. winOrPlatform = undefined;
  2756. }
  2757. return getPlatforms(winOrPlatform).includes(platform);
  2758. };
  2759. const setupPlatforms = (win = window) => {
  2760. if (typeof win === 'undefined') {
  2761. return [];
  2762. }
  2763. win.Ionic = win.Ionic || {};
  2764. let platforms = win.Ionic.platforms;
  2765. if (platforms == null) {
  2766. platforms = win.Ionic.platforms = detectPlatforms(win);
  2767. platforms.forEach((p) => win.document.documentElement.classList.add(`plt-${p}`));
  2768. }
  2769. return platforms;
  2770. };
  2771. const detectPlatforms = (win) => {
  2772. const customPlatformMethods = config.get('platform');
  2773. return Object.keys(PLATFORMS_MAP).filter((p) => {
  2774. const customMethod = customPlatformMethods === null || customPlatformMethods === void 0 ? void 0 : customPlatformMethods[p];
  2775. return typeof customMethod === 'function' ? customMethod(win) : PLATFORMS_MAP[p](win);
  2776. });
  2777. };
  2778. const isMobileWeb = (win) => isMobile(win) && !isHybrid(win);
  2779. const isIpad = (win) => {
  2780. // iOS 12 and below
  2781. if (testUserAgent(win, /iPad/i)) {
  2782. return true;
  2783. }
  2784. // iOS 13+
  2785. if (testUserAgent(win, /Macintosh/i) && isMobile(win)) {
  2786. return true;
  2787. }
  2788. return false;
  2789. };
  2790. const isIphone = (win) => testUserAgent(win, /iPhone/i);
  2791. const isIOS = (win) => testUserAgent(win, /iPhone|iPod/i) || isIpad(win);
  2792. const isAndroid = (win) => testUserAgent(win, /android|sink/i);
  2793. const isAndroidTablet = (win) => {
  2794. return isAndroid(win) && !testUserAgent(win, /mobile/i);
  2795. };
  2796. const isPhablet = (win) => {
  2797. const width = win.innerWidth;
  2798. const height = win.innerHeight;
  2799. const smallest = Math.min(width, height);
  2800. const largest = Math.max(width, height);
  2801. return smallest > 390 && smallest < 520 && largest > 620 && largest < 800;
  2802. };
  2803. const isTablet = (win) => {
  2804. const width = win.innerWidth;
  2805. const height = win.innerHeight;
  2806. const smallest = Math.min(width, height);
  2807. const largest = Math.max(width, height);
  2808. return isIpad(win) || isAndroidTablet(win) || (smallest > 460 && smallest < 820 && largest > 780 && largest < 1400);
  2809. };
  2810. const isMobile = (win) => matchMedia$1(win, '(any-pointer:coarse)');
  2811. const isDesktop = (win) => !isMobile(win);
  2812. const isHybrid = (win) => isCordova(win) || isCapacitorNative(win);
  2813. const isCordova = (win) => !!(win['cordova'] || win['phonegap'] || win['PhoneGap']);
  2814. const isCapacitorNative = (win) => {
  2815. const capacitor = win['Capacitor'];
  2816. // TODO(ROU-11693): Remove when we no longer support Capacitor 2, which does not have isNativePlatform
  2817. return !!((capacitor === null || capacitor === void 0 ? void 0 : capacitor.isNative) || ((capacitor === null || capacitor === void 0 ? void 0 : capacitor.isNativePlatform) && !!capacitor.isNativePlatform()));
  2818. };
  2819. const isElectron = (win) => testUserAgent(win, /electron/i);
  2820. 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); };
  2821. const testUserAgent = (win, expr) => expr.test(win.navigator.userAgent);
  2822. const matchMedia$1 = (win, query) => { var _a; return (_a = win.matchMedia) === null || _a === void 0 ? void 0 : _a.call(win, query).matches; };
  2823. const PLATFORMS_MAP = {
  2824. ipad: isIpad,
  2825. iphone: isIphone,
  2826. ios: isIOS,
  2827. android: isAndroid,
  2828. phablet: isPhablet,
  2829. tablet: isTablet,
  2830. cordova: isCordova,
  2831. capacitor: isCapacitorNative,
  2832. electron: isElectron,
  2833. pwa: isPWA,
  2834. mobile: isMobile,
  2835. mobileweb: isMobileWeb,
  2836. desktop: isDesktop,
  2837. hybrid: isHybrid,
  2838. };
  2839. // TODO(FW-2832): types
  2840. let defaultMode;
  2841. const getIonMode$1 = (ref) => {
  2842. return (ref && getMode(ref)) || defaultMode;
  2843. };
  2844. 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}";
  2845. var IonAccordionIosStyle0 = accordionIosCss;
  2846. 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}}";
  2847. var IonAccordionMdStyle0 = accordionMdCss;
  2848. /**
  2849. * @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
  2850. *
  2851. * @slot header - Content is placed at the top and is used to
  2852. * expand or collapse the accordion item.
  2853. * @slot content - Content is placed below the header and is
  2854. * shown or hidden based on expanded state.
  2855. *
  2856. * @part header - The wrapper element for the header slot.
  2857. * @part content - The wrapper element for the content slot.
  2858. * @part expanded - The expanded element. Can be used in combination
  2859. * with the `header` and `content` parts (i.e. `::part(header expanded)`).
  2860. */
  2861. class Accordion {
  2862. constructor(hostRef) {
  2863. registerInstance(this, hostRef);
  2864. this.updateListener = () => this.updateState(false);
  2865. this.setItemDefaults = () => {
  2866. const ionItem = this.getSlottedHeaderIonItem();
  2867. if (!ionItem) {
  2868. return;
  2869. }
  2870. /**
  2871. * For a11y purposes, we make
  2872. * the ion-item a button so users
  2873. * can tab to it and use keyboard
  2874. * navigation to get around.
  2875. */
  2876. ionItem.button = true;
  2877. ionItem.detail = false;
  2878. /**
  2879. * By default, the lines in an
  2880. * item should be full here, but
  2881. * only do that if a user has
  2882. * not explicitly overridden them
  2883. */
  2884. if (ionItem.lines === undefined) {
  2885. ionItem.lines = 'full';
  2886. }
  2887. };
  2888. this.getSlottedHeaderIonItem = () => {
  2889. const { headerEl } = this;
  2890. if (!headerEl) {
  2891. return;
  2892. }
  2893. /**
  2894. * Get the first ion-item
  2895. * slotted in the header slot
  2896. */
  2897. const slot = headerEl.querySelector('slot');
  2898. if (!slot) {
  2899. return;
  2900. }
  2901. // This is not defined in unit tests
  2902. if (slot.assignedElements === undefined)
  2903. return;
  2904. return slot.assignedElements().find((el) => el.tagName === 'ION-ITEM');
  2905. };
  2906. this.setAria = (expanded = false) => {
  2907. const ionItem = this.getSlottedHeaderIonItem();
  2908. if (!ionItem) {
  2909. return;
  2910. }
  2911. /**
  2912. * Get the native <button> element inside of
  2913. * ion-item because that is what will be focused
  2914. */
  2915. const root = getElementRoot(ionItem);
  2916. const button = root.querySelector('button');
  2917. if (!button) {
  2918. return;
  2919. }
  2920. button.setAttribute('aria-expanded', `${expanded}`);
  2921. };
  2922. this.slotToggleIcon = () => {
  2923. const ionItem = this.getSlottedHeaderIonItem();
  2924. if (!ionItem) {
  2925. return;
  2926. }
  2927. const { toggleIconSlot, toggleIcon } = this;
  2928. /**
  2929. * Check if there already is a toggle icon.
  2930. * If so, do not add another one.
  2931. */
  2932. const existingToggleIcon = ionItem.querySelector('.ion-accordion-toggle-icon');
  2933. if (existingToggleIcon) {
  2934. return;
  2935. }
  2936. const iconEl = document.createElement('ion-icon');
  2937. iconEl.slot = toggleIconSlot;
  2938. iconEl.lazy = false;
  2939. iconEl.classList.add('ion-accordion-toggle-icon');
  2940. iconEl.icon = toggleIcon;
  2941. iconEl.setAttribute('aria-hidden', 'true');
  2942. ionItem.appendChild(iconEl);
  2943. };
  2944. this.expandAccordion = (initialUpdate = false) => {
  2945. const { contentEl, contentElWrapper } = this;
  2946. if (initialUpdate || contentEl === undefined || contentElWrapper === undefined) {
  2947. this.state = 4 /* AccordionState.Expanded */;
  2948. return;
  2949. }
  2950. if (this.state === 4 /* AccordionState.Expanded */) {
  2951. return;
  2952. }
  2953. if (this.currentRaf !== undefined) {
  2954. cancelAnimationFrame(this.currentRaf);
  2955. }
  2956. if (this.shouldAnimate()) {
  2957. raf(() => {
  2958. this.state = 8 /* AccordionState.Expanding */;
  2959. this.currentRaf = raf(async () => {
  2960. const contentHeight = contentElWrapper.offsetHeight;
  2961. const waitForTransition = transitionEndAsync(contentEl, 2000);
  2962. contentEl.style.setProperty('max-height', `${contentHeight}px`);
  2963. await waitForTransition;
  2964. this.state = 4 /* AccordionState.Expanded */;
  2965. contentEl.style.removeProperty('max-height');
  2966. });
  2967. });
  2968. }
  2969. else {
  2970. this.state = 4 /* AccordionState.Expanded */;
  2971. }
  2972. };
  2973. this.collapseAccordion = (initialUpdate = false) => {
  2974. const { contentEl } = this;
  2975. if (initialUpdate || contentEl === undefined) {
  2976. this.state = 1 /* AccordionState.Collapsed */;
  2977. return;
  2978. }
  2979. if (this.state === 1 /* AccordionState.Collapsed */) {
  2980. return;
  2981. }
  2982. if (this.currentRaf !== undefined) {
  2983. cancelAnimationFrame(this.currentRaf);
  2984. }
  2985. if (this.shouldAnimate()) {
  2986. this.currentRaf = raf(async () => {
  2987. const contentHeight = contentEl.offsetHeight;
  2988. contentEl.style.setProperty('max-height', `${contentHeight}px`);
  2989. raf(async () => {
  2990. const waitForTransition = transitionEndAsync(contentEl, 2000);
  2991. this.state = 2 /* AccordionState.Collapsing */;
  2992. await waitForTransition;
  2993. this.state = 1 /* AccordionState.Collapsed */;
  2994. contentEl.style.removeProperty('max-height');
  2995. });
  2996. });
  2997. }
  2998. else {
  2999. this.state = 1 /* AccordionState.Collapsed */;
  3000. }
  3001. };
  3002. /**
  3003. * Helper function to determine if
  3004. * something should animate.
  3005. * If prefers-reduced-motion is set
  3006. * then we should not animate, regardless
  3007. * of what is set in the config.
  3008. */
  3009. this.shouldAnimate = () => {
  3010. if (typeof window === 'undefined') {
  3011. return false;
  3012. }
  3013. const prefersReducedMotion = matchMedia('(prefers-reduced-motion: reduce)').matches;
  3014. if (prefersReducedMotion) {
  3015. return false;
  3016. }
  3017. const animated = config.get('animated', true);
  3018. if (!animated) {
  3019. return false;
  3020. }
  3021. if (this.accordionGroupEl && !this.accordionGroupEl.animated) {
  3022. return false;
  3023. }
  3024. return true;
  3025. };
  3026. this.updateState = async (initialUpdate = false) => {
  3027. const accordionGroup = this.accordionGroupEl;
  3028. const accordionValue = this.value;
  3029. if (!accordionGroup) {
  3030. return;
  3031. }
  3032. const value = accordionGroup.value;
  3033. const shouldExpand = Array.isArray(value) ? value.includes(accordionValue) : value === accordionValue;
  3034. if (shouldExpand) {
  3035. this.expandAccordion(initialUpdate);
  3036. this.isNext = this.isPrevious = false;
  3037. }
  3038. else {
  3039. this.collapseAccordion(initialUpdate);
  3040. /**
  3041. * When using popout or inset,
  3042. * the collapsed accordion items
  3043. * may need additional border radius
  3044. * applied. Check to see if the
  3045. * next or previous accordion is selected.
  3046. */
  3047. const nextAccordion = this.getNextSibling();
  3048. const nextAccordionValue = nextAccordion === null || nextAccordion === void 0 ? void 0 : nextAccordion.value;
  3049. if (nextAccordionValue !== undefined) {
  3050. this.isPrevious = Array.isArray(value) ? value.includes(nextAccordionValue) : value === nextAccordionValue;
  3051. }
  3052. const previousAccordion = this.getPreviousSibling();
  3053. const previousAccordionValue = previousAccordion === null || previousAccordion === void 0 ? void 0 : previousAccordion.value;
  3054. if (previousAccordionValue !== undefined) {
  3055. this.isNext = Array.isArray(value) ? value.includes(previousAccordionValue) : value === previousAccordionValue;
  3056. }
  3057. }
  3058. };
  3059. this.getNextSibling = () => {
  3060. if (!this.el) {
  3061. return;
  3062. }
  3063. const nextSibling = this.el.nextElementSibling;
  3064. if ((nextSibling === null || nextSibling === void 0 ? void 0 : nextSibling.tagName) !== 'ION-ACCORDION') {
  3065. return;
  3066. }
  3067. return nextSibling;
  3068. };
  3069. this.getPreviousSibling = () => {
  3070. if (!this.el) {
  3071. return;
  3072. }
  3073. const previousSibling = this.el.previousElementSibling;
  3074. if ((previousSibling === null || previousSibling === void 0 ? void 0 : previousSibling.tagName) !== 'ION-ACCORDION') {
  3075. return;
  3076. }
  3077. return previousSibling;
  3078. };
  3079. this.state = 1 /* AccordionState.Collapsed */;
  3080. this.isNext = false;
  3081. this.isPrevious = false;
  3082. this.value = `ion-accordion-${accordionIds++}`;
  3083. this.disabled = false;
  3084. this.readonly = false;
  3085. this.toggleIcon = chevronDown;
  3086. this.toggleIconSlot = 'end';
  3087. }
  3088. valueChanged() {
  3089. this.updateState();
  3090. }
  3091. connectedCallback() {
  3092. var _a;
  3093. const accordionGroupEl = (this.accordionGroupEl = (_a = this.el) === null || _a === void 0 ? void 0 : _a.closest('ion-accordion-group'));
  3094. if (accordionGroupEl) {
  3095. this.updateState(true);
  3096. addEventListener$1(accordionGroupEl, 'ionValueChange', this.updateListener);
  3097. }
  3098. }
  3099. disconnectedCallback() {
  3100. const accordionGroupEl = this.accordionGroupEl;
  3101. if (accordionGroupEl) {
  3102. removeEventListener(accordionGroupEl, 'ionValueChange', this.updateListener);
  3103. }
  3104. }
  3105. componentDidLoad() {
  3106. this.setItemDefaults();
  3107. this.slotToggleIcon();
  3108. /**
  3109. * We need to wait a tick because we
  3110. * just set ionItem.button = true and
  3111. * the button has not have been rendered yet.
  3112. */
  3113. raf(() => {
  3114. /**
  3115. * Set aria label on button inside of ion-item
  3116. * once the inner content has been rendered.
  3117. */
  3118. const expanded = this.state === 4 /* AccordionState.Expanded */ || this.state === 8 /* AccordionState.Expanding */;
  3119. this.setAria(expanded);
  3120. });
  3121. }
  3122. toggleExpanded() {
  3123. const { accordionGroupEl, disabled, readonly, value, state } = this;
  3124. if (disabled || readonly)
  3125. return;
  3126. if (accordionGroupEl) {
  3127. /**
  3128. * Because the accordion group may or may
  3129. * not allow multiple accordions open, we
  3130. * need to request the toggling of this
  3131. * accordion and the accordion group will
  3132. * make the decision on whether or not
  3133. * to allow it.
  3134. */
  3135. const expand = state === 1 /* AccordionState.Collapsed */ || state === 2 /* AccordionState.Collapsing */;
  3136. accordionGroupEl.requestAccordionToggle(value, expand);
  3137. }
  3138. }
  3139. render() {
  3140. const { disabled, readonly } = this;
  3141. const mode = getIonMode$1(this);
  3142. const expanded = this.state === 4 /* AccordionState.Expanded */ || this.state === 8 /* AccordionState.Expanding */;
  3143. const headerPart = expanded ? 'header expanded' : 'header';
  3144. const contentPart = expanded ? 'content expanded' : 'content';
  3145. this.setAria(expanded);
  3146. return (hAsync(Host, { key: '073e1d02c18dcbc20c68648426e87c14750c031d', class: {
  3147. [mode]: true,
  3148. 'accordion-expanding': this.state === 8 /* AccordionState.Expanding */,
  3149. 'accordion-expanded': this.state === 4 /* AccordionState.Expanded */,
  3150. 'accordion-collapsing': this.state === 2 /* AccordionState.Collapsing */,
  3151. 'accordion-collapsed': this.state === 1 /* AccordionState.Collapsed */,
  3152. 'accordion-next': this.isNext,
  3153. 'accordion-previous': this.isPrevious,
  3154. 'accordion-disabled': disabled,
  3155. 'accordion-readonly': readonly,
  3156. 'accordion-animated': this.shouldAnimate(),
  3157. } }, 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" })))));
  3158. }
  3159. static get delegatesFocus() { return true; }
  3160. get el() { return getElement(this); }
  3161. static get watchers() { return {
  3162. "value": ["valueChanged"]
  3163. }; }
  3164. static get style() { return {
  3165. ios: IonAccordionIosStyle0,
  3166. md: IonAccordionMdStyle0
  3167. }; }
  3168. static get cmpMeta() { return {
  3169. "$flags$": 57,
  3170. "$tagName$": "ion-accordion",
  3171. "$members$": {
  3172. "value": [1],
  3173. "disabled": [4],
  3174. "readonly": [4],
  3175. "toggleIcon": [1, "toggle-icon"],
  3176. "toggleIconSlot": [1, "toggle-icon-slot"],
  3177. "state": [32],
  3178. "isNext": [32],
  3179. "isPrevious": [32]
  3180. },
  3181. "$listeners$": undefined,
  3182. "$lazyBundleId$": "-",
  3183. "$attrsToReflect$": []
  3184. }; }
  3185. }
  3186. let accordionIds = 0;
  3187. 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}";
  3188. var IonAccordionGroupIosStyle0 = accordionGroupIosCss;
  3189. 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}";
  3190. var IonAccordionGroupMdStyle0 = accordionGroupMdCss;
  3191. /**
  3192. * @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
  3193. */
  3194. class AccordionGroup {
  3195. constructor(hostRef) {
  3196. registerInstance(this, hostRef);
  3197. this.ionChange = createEvent(this, "ionChange", 7);
  3198. this.ionValueChange = createEvent(this, "ionValueChange", 7);
  3199. this.animated = true;
  3200. this.multiple = undefined;
  3201. this.value = undefined;
  3202. this.disabled = false;
  3203. this.readonly = false;
  3204. this.expand = 'compact';
  3205. }
  3206. valueChanged() {
  3207. const { value, multiple } = this;
  3208. if (!multiple && Array.isArray(value)) {
  3209. /**
  3210. * We do some processing on the `value` array so
  3211. * that it looks more like an array when logged to
  3212. * the console.
  3213. * Example given ['a', 'b']
  3214. * Default toString() behavior: a,b
  3215. * Custom behavior: ['a', 'b']
  3216. */
  3217. 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".
  3218. Value Passed: [${value.map((v) => `'${v}'`).join(', ')}]
  3219. `, this.el);
  3220. }
  3221. /**
  3222. * Do not use `value` here as that will be
  3223. * not account for the adjustment we make above.
  3224. */
  3225. this.ionValueChange.emit({ value: this.value });
  3226. }
  3227. async disabledChanged() {
  3228. const { disabled } = this;
  3229. const accordions = await this.getAccordions();
  3230. for (const accordion of accordions) {
  3231. accordion.disabled = disabled;
  3232. }
  3233. }
  3234. async readonlyChanged() {
  3235. const { readonly } = this;
  3236. const accordions = await this.getAccordions();
  3237. for (const accordion of accordions) {
  3238. accordion.readonly = readonly;
  3239. }
  3240. }
  3241. async onKeydown(ev) {
  3242. const activeElement = document.activeElement;
  3243. if (!activeElement) {
  3244. return;
  3245. }
  3246. /**
  3247. * Make sure focus is in the header, not the body, of the accordion. This ensures
  3248. * that if there are any interactable elements in the body, their keyboard
  3249. * interaction doesn't get stolen by the accordion. Example: using up/down keys
  3250. * in ion-textarea.
  3251. */
  3252. const activeAccordionHeader = activeElement.closest('ion-accordion [slot="header"]');
  3253. if (!activeAccordionHeader) {
  3254. return;
  3255. }
  3256. const accordionEl = activeElement.tagName === 'ION-ACCORDION' ? activeElement : activeElement.closest('ion-accordion');
  3257. if (!accordionEl) {
  3258. return;
  3259. }
  3260. const closestGroup = accordionEl.closest('ion-accordion-group');
  3261. if (closestGroup !== this.el) {
  3262. return;
  3263. }
  3264. // If the active accordion is not in the current array of accordions, do not do anything
  3265. const accordions = await this.getAccordions();
  3266. const startingIndex = accordions.findIndex((a) => a === accordionEl);
  3267. if (startingIndex === -1) {
  3268. return;
  3269. }
  3270. let accordion;
  3271. if (ev.key === 'ArrowDown') {
  3272. accordion = this.findNextAccordion(accordions, startingIndex);
  3273. }
  3274. else if (ev.key === 'ArrowUp') {
  3275. accordion = this.findPreviousAccordion(accordions, startingIndex);
  3276. }
  3277. else if (ev.key === 'Home') {
  3278. accordion = accordions[0];
  3279. }
  3280. else if (ev.key === 'End') {
  3281. accordion = accordions[accordions.length - 1];
  3282. }
  3283. if (accordion !== undefined && accordion !== activeElement) {
  3284. accordion.focus();
  3285. }
  3286. }
  3287. async componentDidLoad() {
  3288. if (this.disabled) {
  3289. this.disabledChanged();
  3290. }
  3291. if (this.readonly) {
  3292. this.readonlyChanged();
  3293. }
  3294. /**
  3295. * When binding values in frameworks such as Angular
  3296. * it is possible for the value to be set after the Web Component
  3297. * initializes but before the value watcher is set up in Stencil.
  3298. * As a result, the watcher callback may not be fired.
  3299. * We work around this by manually calling the watcher
  3300. * callback when the component has loaded and the watcher
  3301. * is configured.
  3302. */
  3303. this.valueChanged();
  3304. }
  3305. /**
  3306. * Sets the value property and emits ionChange.
  3307. * This should only be called when the user interacts
  3308. * with the accordion and not for any update
  3309. * to the value property. The exception is when
  3310. * the app sets the value of a single-select
  3311. * accordion group to an array.
  3312. */
  3313. setValue(accordionValue) {
  3314. const value = (this.value = accordionValue);
  3315. this.ionChange.emit({ value });
  3316. }
  3317. /**
  3318. * This method is used to ensure that the value
  3319. * of ion-accordion-group is being set in a valid
  3320. * way. This method should only be called in
  3321. * response to a user generated action.
  3322. * @internal
  3323. */
  3324. async requestAccordionToggle(accordionValue, accordionExpand) {
  3325. const { multiple, value, readonly, disabled } = this;
  3326. if (readonly || disabled) {
  3327. return;
  3328. }
  3329. if (accordionExpand) {
  3330. /**
  3331. * If group accepts multiple values
  3332. * check to see if value is already in
  3333. * in values array. If not, add it
  3334. * to the array.
  3335. */
  3336. if (multiple) {
  3337. const groupValue = value !== null && value !== void 0 ? value : [];
  3338. const processedValue = Array.isArray(groupValue) ? groupValue : [groupValue];
  3339. const valueExists = processedValue.find((v) => v === accordionValue);
  3340. if (valueExists === undefined && accordionValue !== undefined) {
  3341. this.setValue([...processedValue, accordionValue]);
  3342. }
  3343. }
  3344. else {
  3345. this.setValue(accordionValue);
  3346. }
  3347. }
  3348. else {
  3349. /**
  3350. * If collapsing accordion, either filter the value
  3351. * out of the values array or unset the value.
  3352. */
  3353. if (multiple) {
  3354. const groupValue = value !== null && value !== void 0 ? value : [];
  3355. const processedValue = Array.isArray(groupValue) ? groupValue : [groupValue];
  3356. this.setValue(processedValue.filter((v) => v !== accordionValue));
  3357. }
  3358. else {
  3359. this.setValue(undefined);
  3360. }
  3361. }
  3362. }
  3363. findNextAccordion(accordions, startingIndex) {
  3364. const nextAccordion = accordions[startingIndex + 1];
  3365. if (nextAccordion === undefined) {
  3366. return accordions[0];
  3367. }
  3368. return nextAccordion;
  3369. }
  3370. findPreviousAccordion(accordions, startingIndex) {
  3371. const prevAccordion = accordions[startingIndex - 1];
  3372. if (prevAccordion === undefined) {
  3373. return accordions[accordions.length - 1];
  3374. }
  3375. return prevAccordion;
  3376. }
  3377. /**
  3378. * @internal
  3379. */
  3380. async getAccordions() {
  3381. return Array.from(this.el.querySelectorAll(':scope > ion-accordion'));
  3382. }
  3383. render() {
  3384. const { disabled, readonly, expand } = this;
  3385. const mode = getIonMode$1(this);
  3386. return (hAsync(Host, { key: 'd1a79a93179474fbba66fcf11a92f4871dacc975', class: {
  3387. [mode]: true,
  3388. 'accordion-group-disabled': disabled,
  3389. 'accordion-group-readonly': readonly,
  3390. [`accordion-group-expand-${expand}`]: true,
  3391. }, role: "presentation" }, hAsync("slot", { key: 'e6b8954b686d1fbb4fc92adb07fddc97a24b0a31' })));
  3392. }
  3393. get el() { return getElement(this); }
  3394. static get watchers() { return {
  3395. "value": ["valueChanged"],
  3396. "disabled": ["disabledChanged"],
  3397. "readonly": ["readonlyChanged"]
  3398. }; }
  3399. static get style() { return {
  3400. ios: IonAccordionGroupIosStyle0,
  3401. md: IonAccordionGroupMdStyle0
  3402. }; }
  3403. static get cmpMeta() { return {
  3404. "$flags$": 41,
  3405. "$tagName$": "ion-accordion-group",
  3406. "$members$": {
  3407. "animated": [4],
  3408. "multiple": [4],
  3409. "value": [1025],
  3410. "disabled": [4],
  3411. "readonly": [4],
  3412. "expand": [1],
  3413. "requestAccordionToggle": [64],
  3414. "getAccordions": [64]
  3415. },
  3416. "$listeners$": [[0, "keydown", "onKeydown"]],
  3417. "$lazyBundleId$": "-",
  3418. "$attrsToReflect$": []
  3419. }; }
  3420. }
  3421. const win$1 = typeof window !== 'undefined' ? window : undefined;
  3422. const doc = typeof document !== 'undefined' ? document : undefined;
  3423. const getCapacitor = () => {
  3424. if (win$1 !== undefined) {
  3425. return win$1.Capacitor;
  3426. }
  3427. return undefined;
  3428. };
  3429. var ImpactStyle;
  3430. (function (ImpactStyle) {
  3431. /**
  3432. * A collision between large, heavy user interface elements
  3433. *
  3434. * @since 1.0.0
  3435. */
  3436. ImpactStyle["Heavy"] = "HEAVY";
  3437. /**
  3438. * A collision between moderately sized user interface elements
  3439. *
  3440. * @since 1.0.0
  3441. */
  3442. ImpactStyle["Medium"] = "MEDIUM";
  3443. /**
  3444. * A collision between small, light user interface elements
  3445. *
  3446. * @since 1.0.0
  3447. */
  3448. ImpactStyle["Light"] = "LIGHT";
  3449. })(ImpactStyle || (ImpactStyle = {}));
  3450. var NotificationType;
  3451. (function (NotificationType) {
  3452. /**
  3453. * A notification feedback type indicating that a task has completed successfully
  3454. *
  3455. * @since 1.0.0
  3456. */
  3457. NotificationType["Success"] = "SUCCESS";
  3458. /**
  3459. * A notification feedback type indicating that a task has produced a warning
  3460. *
  3461. * @since 1.0.0
  3462. */
  3463. NotificationType["Warning"] = "WARNING";
  3464. /**
  3465. * A notification feedback type indicating that a task has failed
  3466. *
  3467. * @since 1.0.0
  3468. */
  3469. NotificationType["Error"] = "ERROR";
  3470. })(NotificationType || (NotificationType = {}));
  3471. const HapticEngine = {
  3472. getEngine() {
  3473. const capacitor = getCapacitor();
  3474. if (capacitor === null || capacitor === void 0 ? void 0 : capacitor.isPluginAvailable('Haptics')) {
  3475. // Capacitor
  3476. return capacitor.Plugins.Haptics;
  3477. }
  3478. return undefined;
  3479. },
  3480. available() {
  3481. const engine = this.getEngine();
  3482. if (!engine) {
  3483. return false;
  3484. }
  3485. const capacitor = getCapacitor();
  3486. /**
  3487. * Developers can manually import the
  3488. * Haptics plugin in their app which will cause
  3489. * getEngine to return the Haptics engine. However,
  3490. * the Haptics engine will throw an error if
  3491. * used in a web browser that does not support
  3492. * the Vibrate API. This check avoids that error
  3493. * if the browser does not support the Vibrate API.
  3494. */
  3495. if ((capacitor === null || capacitor === void 0 ? void 0 : capacitor.getPlatform()) === 'web') {
  3496. // eslint-disable-next-line @typescript-eslint/prefer-optional-chain
  3497. return typeof navigator !== 'undefined' && navigator.vibrate !== undefined;
  3498. }
  3499. return true;
  3500. },
  3501. impact(options) {
  3502. const engine = this.getEngine();
  3503. if (!engine) {
  3504. return;
  3505. }
  3506. engine.impact({ style: options.style });
  3507. },
  3508. notification(options) {
  3509. const engine = this.getEngine();
  3510. if (!engine) {
  3511. return;
  3512. }
  3513. engine.notification({ type: options.type });
  3514. },
  3515. selection() {
  3516. this.impact({ style: ImpactStyle.Light });
  3517. },
  3518. selectionStart() {
  3519. const engine = this.getEngine();
  3520. if (!engine) {
  3521. return;
  3522. }
  3523. engine.selectionStart();
  3524. },
  3525. selectionChanged() {
  3526. const engine = this.getEngine();
  3527. if (!engine) {
  3528. return;
  3529. }
  3530. engine.selectionChanged();
  3531. },
  3532. selectionEnd() {
  3533. const engine = this.getEngine();
  3534. if (!engine) {
  3535. return;
  3536. }
  3537. engine.selectionEnd();
  3538. },
  3539. };
  3540. /**
  3541. * Check to see if the Haptic Plugin is available
  3542. * @return Returns `true` or false if the plugin is available
  3543. */
  3544. const hapticAvailable = () => {
  3545. return HapticEngine.available();
  3546. };
  3547. /**
  3548. * Trigger a selection changed haptic event. Good for one-time events
  3549. * (not for gestures)
  3550. */
  3551. const hapticSelection = () => {
  3552. hapticAvailable() && HapticEngine.selection();
  3553. };
  3554. /**
  3555. * Tell the haptic engine that a gesture for a selection change is starting.
  3556. */
  3557. const hapticSelectionStart = () => {
  3558. hapticAvailable() && HapticEngine.selectionStart();
  3559. };
  3560. /**
  3561. * Tell the haptic engine that a selection changed during a gesture.
  3562. */
  3563. const hapticSelectionChanged = () => {
  3564. hapticAvailable() && HapticEngine.selectionChanged();
  3565. };
  3566. /**
  3567. * Tell the haptic engine we are done with a gesture. This needs to be
  3568. * called lest resources are not properly recycled.
  3569. */
  3570. const hapticSelectionEnd = () => {
  3571. hapticAvailable() && HapticEngine.selectionEnd();
  3572. };
  3573. /**
  3574. * Use this to indicate success/failure/warning to the user.
  3575. * options should be of the type `{ style: ImpactStyle.LIGHT }` (or `MEDIUM`/`HEAVY`)
  3576. */
  3577. const hapticImpact = (options) => {
  3578. hapticAvailable() && HapticEngine.impact(options);
  3579. };
  3580. class GestureController {
  3581. constructor() {
  3582. this.gestureId = 0;
  3583. this.requestedStart = new Map();
  3584. this.disabledGestures = new Map();
  3585. this.disabledScroll = new Set();
  3586. }
  3587. /**
  3588. * Creates a gesture delegate based on the GestureConfig passed
  3589. */
  3590. createGesture(config) {
  3591. var _a;
  3592. return new GestureDelegate(this, this.newID(), config.name, (_a = config.priority) !== null && _a !== void 0 ? _a : 0, !!config.disableScroll);
  3593. }
  3594. /**
  3595. * Creates a blocker that will block any other gesture events from firing. Set in the ion-gesture component.
  3596. */
  3597. createBlocker(opts = {}) {
  3598. return new BlockerDelegate(this, this.newID(), opts.disable, !!opts.disableScroll);
  3599. }
  3600. start(gestureName, id, priority) {
  3601. if (!this.canStart(gestureName)) {
  3602. this.requestedStart.delete(id);
  3603. return false;
  3604. }
  3605. this.requestedStart.set(id, priority);
  3606. return true;
  3607. }
  3608. capture(gestureName, id, priority) {
  3609. if (!this.start(gestureName, id, priority)) {
  3610. return false;
  3611. }
  3612. const requestedStart = this.requestedStart;
  3613. let maxPriority = -10000;
  3614. requestedStart.forEach((value) => {
  3615. maxPriority = Math.max(maxPriority, value);
  3616. });
  3617. if (maxPriority === priority) {
  3618. this.capturedId = id;
  3619. requestedStart.clear();
  3620. const event = new CustomEvent('ionGestureCaptured', { detail: { gestureName } });
  3621. document.dispatchEvent(event);
  3622. return true;
  3623. }
  3624. requestedStart.delete(id);
  3625. return false;
  3626. }
  3627. release(id) {
  3628. this.requestedStart.delete(id);
  3629. if (this.capturedId === id) {
  3630. this.capturedId = undefined;
  3631. }
  3632. }
  3633. disableGesture(gestureName, id) {
  3634. let set = this.disabledGestures.get(gestureName);
  3635. if (set === undefined) {
  3636. set = new Set();
  3637. this.disabledGestures.set(gestureName, set);
  3638. }
  3639. set.add(id);
  3640. }
  3641. enableGesture(gestureName, id) {
  3642. const set = this.disabledGestures.get(gestureName);
  3643. if (set !== undefined) {
  3644. set.delete(id);
  3645. }
  3646. }
  3647. disableScroll(id) {
  3648. this.disabledScroll.add(id);
  3649. if (this.disabledScroll.size === 1) {
  3650. document.body.classList.add(BACKDROP_NO_SCROLL);
  3651. }
  3652. }
  3653. enableScroll(id) {
  3654. this.disabledScroll.delete(id);
  3655. if (this.disabledScroll.size === 0) {
  3656. document.body.classList.remove(BACKDROP_NO_SCROLL);
  3657. }
  3658. }
  3659. canStart(gestureName) {
  3660. if (this.capturedId !== undefined) {
  3661. // a gesture already captured
  3662. return false;
  3663. }
  3664. if (this.isDisabled(gestureName)) {
  3665. return false;
  3666. }
  3667. return true;
  3668. }
  3669. isCaptured() {
  3670. return this.capturedId !== undefined;
  3671. }
  3672. isScrollDisabled() {
  3673. return this.disabledScroll.size > 0;
  3674. }
  3675. isDisabled(gestureName) {
  3676. const disabled = this.disabledGestures.get(gestureName);
  3677. if (disabled && disabled.size > 0) {
  3678. return true;
  3679. }
  3680. return false;
  3681. }
  3682. newID() {
  3683. this.gestureId++;
  3684. return this.gestureId;
  3685. }
  3686. }
  3687. class GestureDelegate {
  3688. constructor(ctrl, id, name, priority, disableScroll) {
  3689. this.id = id;
  3690. this.name = name;
  3691. this.disableScroll = disableScroll;
  3692. this.priority = priority * 1000000 + id;
  3693. this.ctrl = ctrl;
  3694. }
  3695. canStart() {
  3696. if (!this.ctrl) {
  3697. return false;
  3698. }
  3699. return this.ctrl.canStart(this.name);
  3700. }
  3701. start() {
  3702. if (!this.ctrl) {
  3703. return false;
  3704. }
  3705. return this.ctrl.start(this.name, this.id, this.priority);
  3706. }
  3707. capture() {
  3708. if (!this.ctrl) {
  3709. return false;
  3710. }
  3711. const captured = this.ctrl.capture(this.name, this.id, this.priority);
  3712. if (captured && this.disableScroll) {
  3713. this.ctrl.disableScroll(this.id);
  3714. }
  3715. return captured;
  3716. }
  3717. release() {
  3718. if (this.ctrl) {
  3719. this.ctrl.release(this.id);
  3720. if (this.disableScroll) {
  3721. this.ctrl.enableScroll(this.id);
  3722. }
  3723. }
  3724. }
  3725. destroy() {
  3726. this.release();
  3727. this.ctrl = undefined;
  3728. }
  3729. }
  3730. class BlockerDelegate {
  3731. constructor(ctrl, id, disable, disableScroll) {
  3732. this.id = id;
  3733. this.disable = disable;
  3734. this.disableScroll = disableScroll;
  3735. this.ctrl = ctrl;
  3736. }
  3737. block() {
  3738. if (!this.ctrl) {
  3739. return;
  3740. }
  3741. if (this.disable) {
  3742. for (const gesture of this.disable) {
  3743. this.ctrl.disableGesture(gesture, this.id);
  3744. }
  3745. }
  3746. if (this.disableScroll) {
  3747. this.ctrl.disableScroll(this.id);
  3748. }
  3749. }
  3750. unblock() {
  3751. if (!this.ctrl) {
  3752. return;
  3753. }
  3754. if (this.disable) {
  3755. for (const gesture of this.disable) {
  3756. this.ctrl.enableGesture(gesture, this.id);
  3757. }
  3758. }
  3759. if (this.disableScroll) {
  3760. this.ctrl.enableScroll(this.id);
  3761. }
  3762. }
  3763. destroy() {
  3764. this.unblock();
  3765. this.ctrl = undefined;
  3766. }
  3767. }
  3768. const BACKDROP_NO_SCROLL = 'backdrop-no-scroll';
  3769. const GESTURE_CONTROLLER = new GestureController();
  3770. const addEventListener = (el, // TODO(FW-2832): type
  3771. eventName, callback, opts) => {
  3772. // use event listener options when supported
  3773. // otherwise it's just a boolean for the "capture" arg
  3774. const listenerOpts = supportsPassive(el)
  3775. ? {
  3776. capture: !!opts.capture,
  3777. passive: !!opts.passive,
  3778. }
  3779. : !!opts.capture;
  3780. let add;
  3781. let remove;
  3782. if (el['__zone_symbol__addEventListener']) {
  3783. add = '__zone_symbol__addEventListener';
  3784. remove = '__zone_symbol__removeEventListener';
  3785. }
  3786. else {
  3787. add = 'addEventListener';
  3788. remove = 'removeEventListener';
  3789. }
  3790. el[add](eventName, callback, listenerOpts);
  3791. return () => {
  3792. el[remove](eventName, callback, listenerOpts);
  3793. };
  3794. };
  3795. const supportsPassive = (node) => {
  3796. if (_sPassive === undefined) {
  3797. try {
  3798. const opts = Object.defineProperty({}, 'passive', {
  3799. get: () => {
  3800. _sPassive = true;
  3801. },
  3802. });
  3803. node.addEventListener('optsTest', () => {
  3804. return;
  3805. }, opts);
  3806. }
  3807. catch (e) {
  3808. _sPassive = false;
  3809. }
  3810. }
  3811. return !!_sPassive;
  3812. };
  3813. let _sPassive;
  3814. const MOUSE_WAIT = 2000;
  3815. // TODO(FW-2832): types
  3816. const createPointerEvents = (el, pointerDown, pointerMove, pointerUp, options) => {
  3817. let rmTouchStart;
  3818. let rmTouchMove;
  3819. let rmTouchEnd;
  3820. let rmTouchCancel;
  3821. let rmMouseStart;
  3822. let rmMouseMove;
  3823. let rmMouseUp;
  3824. let lastTouchEvent = 0;
  3825. const handleTouchStart = (ev) => {
  3826. lastTouchEvent = Date.now() + MOUSE_WAIT;
  3827. if (!pointerDown(ev)) {
  3828. return;
  3829. }
  3830. if (!rmTouchMove && pointerMove) {
  3831. rmTouchMove = addEventListener(el, 'touchmove', pointerMove, options);
  3832. }
  3833. /**
  3834. * Events are dispatched on the element that is tapped and bubble up to
  3835. * the reference element in the gesture. In the event that the element this
  3836. * event was first dispatched on is removed from the DOM, the event will no
  3837. * longer bubble up to our reference element. This leaves the gesture in an
  3838. * unusable state. To account for this, the touchend and touchcancel listeners
  3839. * should be added to the event target so that they still fire even if the target
  3840. * is removed from the DOM.
  3841. */
  3842. if (!rmTouchEnd) {
  3843. rmTouchEnd = addEventListener(ev.target, 'touchend', handleTouchEnd, options);
  3844. }
  3845. if (!rmTouchCancel) {
  3846. rmTouchCancel = addEventListener(ev.target, 'touchcancel', handleTouchEnd, options);
  3847. }
  3848. };
  3849. const handleMouseDown = (ev) => {
  3850. if (lastTouchEvent > Date.now()) {
  3851. return;
  3852. }
  3853. if (!pointerDown(ev)) {
  3854. return;
  3855. }
  3856. if (!rmMouseMove && pointerMove) {
  3857. rmMouseMove = addEventListener(getDocument(el), 'mousemove', pointerMove, options);
  3858. }
  3859. if (!rmMouseUp) {
  3860. rmMouseUp = addEventListener(getDocument(el), 'mouseup', handleMouseUp, options);
  3861. }
  3862. };
  3863. const handleTouchEnd = (ev) => {
  3864. stopTouch();
  3865. if (pointerUp) {
  3866. pointerUp(ev);
  3867. }
  3868. };
  3869. const handleMouseUp = (ev) => {
  3870. stopMouse();
  3871. if (pointerUp) {
  3872. pointerUp(ev);
  3873. }
  3874. };
  3875. const stopTouch = () => {
  3876. if (rmTouchMove) {
  3877. rmTouchMove();
  3878. }
  3879. if (rmTouchEnd) {
  3880. rmTouchEnd();
  3881. }
  3882. if (rmTouchCancel) {
  3883. rmTouchCancel();
  3884. }
  3885. rmTouchMove = rmTouchEnd = rmTouchCancel = undefined;
  3886. };
  3887. const stopMouse = () => {
  3888. if (rmMouseMove) {
  3889. rmMouseMove();
  3890. }
  3891. if (rmMouseUp) {
  3892. rmMouseUp();
  3893. }
  3894. rmMouseMove = rmMouseUp = undefined;
  3895. };
  3896. const stop = () => {
  3897. stopTouch();
  3898. stopMouse();
  3899. };
  3900. const enable = (isEnabled = true) => {
  3901. if (!isEnabled) {
  3902. if (rmTouchStart) {
  3903. rmTouchStart();
  3904. }
  3905. if (rmMouseStart) {
  3906. rmMouseStart();
  3907. }
  3908. rmTouchStart = rmMouseStart = undefined;
  3909. stop();
  3910. }
  3911. else {
  3912. if (!rmTouchStart) {
  3913. rmTouchStart = addEventListener(el, 'touchstart', handleTouchStart, options);
  3914. }
  3915. if (!rmMouseStart) {
  3916. rmMouseStart = addEventListener(el, 'mousedown', handleMouseDown, options);
  3917. }
  3918. }
  3919. };
  3920. const destroy = () => {
  3921. enable(false);
  3922. pointerUp = pointerMove = pointerDown = undefined;
  3923. };
  3924. return {
  3925. enable,
  3926. stop,
  3927. destroy,
  3928. };
  3929. };
  3930. const getDocument = (node) => {
  3931. return node instanceof Document ? node : node.ownerDocument;
  3932. };
  3933. const createPanRecognizer = (direction, thresh, maxAngle) => {
  3934. const radians = maxAngle * (Math.PI / 180);
  3935. const isDirX = direction === 'x';
  3936. const maxCosine = Math.cos(radians);
  3937. const threshold = thresh * thresh;
  3938. let startX = 0;
  3939. let startY = 0;
  3940. let dirty = false;
  3941. let isPan = 0;
  3942. return {
  3943. start(x, y) {
  3944. startX = x;
  3945. startY = y;
  3946. isPan = 0;
  3947. dirty = true;
  3948. },
  3949. detect(x, y) {
  3950. if (!dirty) {
  3951. return false;
  3952. }
  3953. const deltaX = x - startX;
  3954. const deltaY = y - startY;
  3955. const distance = deltaX * deltaX + deltaY * deltaY;
  3956. if (distance < threshold) {
  3957. return false;
  3958. }
  3959. const hypotenuse = Math.sqrt(distance);
  3960. const cosine = (isDirX ? deltaX : deltaY) / hypotenuse;
  3961. if (cosine > maxCosine) {
  3962. isPan = 1;
  3963. }
  3964. else if (cosine < -maxCosine) {
  3965. isPan = -1;
  3966. }
  3967. else {
  3968. isPan = 0;
  3969. }
  3970. dirty = false;
  3971. return true;
  3972. },
  3973. isGesture() {
  3974. return isPan !== 0;
  3975. },
  3976. getDirection() {
  3977. return isPan;
  3978. },
  3979. };
  3980. };
  3981. // TODO(FW-2832): types
  3982. const createGesture = (config) => {
  3983. let hasCapturedPan = false;
  3984. let hasStartedPan = false;
  3985. let hasFiredStart = true;
  3986. let isMoveQueued = false;
  3987. const finalConfig = Object.assign({ disableScroll: false, direction: 'x', gesturePriority: 0, passive: true, maxAngle: 40, threshold: 10 }, config);
  3988. const canStart = finalConfig.canStart;
  3989. const onWillStart = finalConfig.onWillStart;
  3990. const onStart = finalConfig.onStart;
  3991. const onEnd = finalConfig.onEnd;
  3992. const notCaptured = finalConfig.notCaptured;
  3993. const onMove = finalConfig.onMove;
  3994. const threshold = finalConfig.threshold;
  3995. const passive = finalConfig.passive;
  3996. const blurOnStart = finalConfig.blurOnStart;
  3997. const detail = {
  3998. type: 'pan',
  3999. startX: 0,
  4000. startY: 0,
  4001. startTime: 0,
  4002. currentX: 0,
  4003. currentY: 0,
  4004. velocityX: 0,
  4005. velocityY: 0,
  4006. deltaX: 0,
  4007. deltaY: 0,
  4008. currentTime: 0,
  4009. event: undefined,
  4010. data: undefined,
  4011. };
  4012. const pan = createPanRecognizer(finalConfig.direction, finalConfig.threshold, finalConfig.maxAngle);
  4013. const gesture = GESTURE_CONTROLLER.createGesture({
  4014. name: config.gestureName,
  4015. priority: config.gesturePriority,
  4016. disableScroll: config.disableScroll,
  4017. });
  4018. const pointerDown = (ev) => {
  4019. const timeStamp = now(ev);
  4020. if (hasStartedPan || !hasFiredStart) {
  4021. return false;
  4022. }
  4023. updateDetail(ev, detail);
  4024. detail.startX = detail.currentX;
  4025. detail.startY = detail.currentY;
  4026. detail.startTime = detail.currentTime = timeStamp;
  4027. detail.velocityX = detail.velocityY = detail.deltaX = detail.deltaY = 0;
  4028. detail.event = ev;
  4029. // Check if gesture can start
  4030. if (canStart && canStart(detail) === false) {
  4031. return false;
  4032. }
  4033. // Release fallback
  4034. gesture.release();
  4035. // Start gesture
  4036. if (!gesture.start()) {
  4037. return false;
  4038. }
  4039. hasStartedPan = true;
  4040. if (threshold === 0) {
  4041. return tryToCapturePan();
  4042. }
  4043. pan.start(detail.startX, detail.startY);
  4044. return true;
  4045. };
  4046. const pointerMove = (ev) => {
  4047. // fast path, if gesture is currently captured
  4048. // do minimum job to get user-land even dispatched
  4049. if (hasCapturedPan) {
  4050. if (!isMoveQueued && hasFiredStart) {
  4051. isMoveQueued = true;
  4052. calcGestureData(detail, ev);
  4053. requestAnimationFrame(fireOnMove);
  4054. }
  4055. return;
  4056. }
  4057. // gesture is currently being detected
  4058. calcGestureData(detail, ev);
  4059. if (pan.detect(detail.currentX, detail.currentY)) {
  4060. if (!pan.isGesture() || !tryToCapturePan()) {
  4061. abortGesture();
  4062. }
  4063. }
  4064. };
  4065. const fireOnMove = () => {
  4066. // Since fireOnMove is called inside a RAF, onEnd() might be called,
  4067. // we must double check hasCapturedPan
  4068. if (!hasCapturedPan) {
  4069. return;
  4070. }
  4071. isMoveQueued = false;
  4072. if (onMove) {
  4073. onMove(detail);
  4074. }
  4075. };
  4076. const tryToCapturePan = () => {
  4077. if (!gesture.capture()) {
  4078. return false;
  4079. }
  4080. hasCapturedPan = true;
  4081. hasFiredStart = false;
  4082. // reset start position since the real user-land event starts here
  4083. // If the pan detector threshold is big, not resetting the start position
  4084. // will cause a jump in the animation equal to the detector threshold.
  4085. // the array of positions used to calculate the gesture velocity does not
  4086. // need to be cleaned, more points in the positions array always results in a
  4087. // more accurate value of the velocity.
  4088. detail.startX = detail.currentX;
  4089. detail.startY = detail.currentY;
  4090. detail.startTime = detail.currentTime;
  4091. if (onWillStart) {
  4092. onWillStart(detail).then(fireOnStart);
  4093. }
  4094. else {
  4095. fireOnStart();
  4096. }
  4097. return true;
  4098. };
  4099. const blurActiveElement = () => {
  4100. if (typeof document !== 'undefined') {
  4101. const activeElement = document.activeElement;
  4102. if (activeElement === null || activeElement === void 0 ? void 0 : activeElement.blur) {
  4103. activeElement.blur();
  4104. }
  4105. }
  4106. };
  4107. const fireOnStart = () => {
  4108. if (blurOnStart) {
  4109. blurActiveElement();
  4110. }
  4111. if (onStart) {
  4112. onStart(detail);
  4113. }
  4114. hasFiredStart = true;
  4115. };
  4116. const reset = () => {
  4117. hasCapturedPan = false;
  4118. hasStartedPan = false;
  4119. isMoveQueued = false;
  4120. hasFiredStart = true;
  4121. gesture.release();
  4122. };
  4123. // END *************************
  4124. const pointerUp = (ev) => {
  4125. const tmpHasCaptured = hasCapturedPan;
  4126. const tmpHasFiredStart = hasFiredStart;
  4127. reset();
  4128. if (!tmpHasFiredStart) {
  4129. return;
  4130. }
  4131. calcGestureData(detail, ev);
  4132. // Try to capture press
  4133. if (tmpHasCaptured) {
  4134. if (onEnd) {
  4135. onEnd(detail);
  4136. }
  4137. return;
  4138. }
  4139. // Not captured any event
  4140. if (notCaptured) {
  4141. notCaptured(detail);
  4142. }
  4143. };
  4144. const pointerEvents = createPointerEvents(finalConfig.el, pointerDown, pointerMove, pointerUp, {
  4145. capture: false,
  4146. passive,
  4147. });
  4148. const abortGesture = () => {
  4149. reset();
  4150. pointerEvents.stop();
  4151. if (notCaptured) {
  4152. notCaptured(detail);
  4153. }
  4154. };
  4155. return {
  4156. enable(enable = true) {
  4157. if (!enable) {
  4158. if (hasCapturedPan) {
  4159. pointerUp(undefined);
  4160. }
  4161. reset();
  4162. }
  4163. pointerEvents.enable(enable);
  4164. },
  4165. destroy() {
  4166. gesture.destroy();
  4167. pointerEvents.destroy();
  4168. },
  4169. };
  4170. };
  4171. const calcGestureData = (detail, ev) => {
  4172. if (!ev) {
  4173. return;
  4174. }
  4175. const prevX = detail.currentX;
  4176. const prevY = detail.currentY;
  4177. const prevT = detail.currentTime;
  4178. updateDetail(ev, detail);
  4179. const currentX = detail.currentX;
  4180. const currentY = detail.currentY;
  4181. const timestamp = (detail.currentTime = now(ev));
  4182. const timeDelta = timestamp - prevT;
  4183. if (timeDelta > 0 && timeDelta < 100) {
  4184. const velocityX = (currentX - prevX) / timeDelta;
  4185. const velocityY = (currentY - prevY) / timeDelta;
  4186. detail.velocityX = velocityX * 0.7 + detail.velocityX * 0.3;
  4187. detail.velocityY = velocityY * 0.7 + detail.velocityY * 0.3;
  4188. }
  4189. detail.deltaX = currentX - detail.startX;
  4190. detail.deltaY = currentY - detail.startY;
  4191. detail.event = ev;
  4192. };
  4193. const updateDetail = (ev, detail) => {
  4194. // get X coordinates for either a mouse click
  4195. // or a touch depending on the given event
  4196. let x = 0;
  4197. let y = 0;
  4198. if (ev) {
  4199. const changedTouches = ev.changedTouches;
  4200. if (changedTouches && changedTouches.length > 0) {
  4201. const touch = changedTouches[0];
  4202. x = touch.clientX;
  4203. y = touch.clientY;
  4204. }
  4205. else if (ev.pageX !== undefined) {
  4206. x = ev.pageX;
  4207. y = ev.pageY;
  4208. }
  4209. }
  4210. detail.currentX = x;
  4211. detail.currentY = y;
  4212. };
  4213. const now = (ev) => {
  4214. return ev.timeStamp || Date.now();
  4215. };
  4216. var index = /*#__PURE__*/Object.freeze({
  4217. __proto__: null,
  4218. createGesture: createGesture,
  4219. GESTURE_CONTROLLER: GESTURE_CONTROLLER
  4220. });
  4221. const createButtonActiveGesture = (el, isButton) => {
  4222. let currentTouchedButton;
  4223. let initialTouchedButton;
  4224. const activateButtonAtPoint = (x, y, hapticFeedbackFn) => {
  4225. if (typeof document === 'undefined') {
  4226. return;
  4227. }
  4228. const target = document.elementFromPoint(x, y);
  4229. if (!target || !isButton(target) || target.disabled) {
  4230. clearActiveButton();
  4231. return;
  4232. }
  4233. if (target !== currentTouchedButton) {
  4234. clearActiveButton();
  4235. setActiveButton(target, hapticFeedbackFn);
  4236. }
  4237. };
  4238. const setActiveButton = (button, hapticFeedbackFn) => {
  4239. currentTouchedButton = button;
  4240. if (!initialTouchedButton) {
  4241. initialTouchedButton = currentTouchedButton;
  4242. }
  4243. const buttonToModify = currentTouchedButton;
  4244. writeTask(() => buttonToModify.classList.add('ion-activated'));
  4245. hapticFeedbackFn();
  4246. };
  4247. const clearActiveButton = (dispatchClick = false) => {
  4248. if (!currentTouchedButton) {
  4249. return;
  4250. }
  4251. const buttonToModify = currentTouchedButton;
  4252. writeTask(() => buttonToModify.classList.remove('ion-activated'));
  4253. /**
  4254. * Clicking on one button, but releasing on another button
  4255. * does not dispatch a click event in browsers, so we
  4256. * need to do it manually here. Some browsers will
  4257. * dispatch a click if clicking on one button, dragging over
  4258. * another button, and releasing on the original button. In that
  4259. * case, we need to make sure we do not cause a double click there.
  4260. */
  4261. if (dispatchClick && initialTouchedButton !== currentTouchedButton) {
  4262. currentTouchedButton.click();
  4263. }
  4264. currentTouchedButton = undefined;
  4265. };
  4266. return createGesture({
  4267. el,
  4268. gestureName: 'buttonActiveDrag',
  4269. threshold: 0,
  4270. onStart: (ev) => activateButtonAtPoint(ev.currentX, ev.currentY, hapticSelectionStart),
  4271. onMove: (ev) => activateButtonAtPoint(ev.currentX, ev.currentY, hapticSelectionChanged),
  4272. onEnd: () => {
  4273. clearActiveButton(true);
  4274. hapticSelectionEnd();
  4275. initialTouchedButton = undefined;
  4276. },
  4277. });
  4278. };
  4279. /**
  4280. * Creates a lock controller.
  4281. *
  4282. * Claiming a lock means that nothing else can acquire the lock until it is released.
  4283. * This can momentarily prevent execution of code that needs to wait for the earlier code to finish.
  4284. * For example, this can be used to prevent multiple transitions from occurring at the same time.
  4285. */
  4286. const createLockController = () => {
  4287. let waitPromise;
  4288. /**
  4289. * When lock() is called, the lock is claimed.
  4290. * Once a lock has been claimed, it cannot be claimed again until it is released.
  4291. * When this function gets resolved, the lock is released, allowing it to be claimed again.
  4292. *
  4293. * @example ```tsx
  4294. * const unlock = await this.lockController.lock();
  4295. * // do other stuff
  4296. * unlock();
  4297. * ```
  4298. */
  4299. const lock = async () => {
  4300. const p = waitPromise;
  4301. let resolve;
  4302. waitPromise = new Promise((r) => (resolve = r));
  4303. if (p !== undefined) {
  4304. await p;
  4305. }
  4306. return resolve;
  4307. };
  4308. return {
  4309. lock,
  4310. };
  4311. };
  4312. /**
  4313. * This query string selects elements that
  4314. * are eligible to receive focus. We select
  4315. * interactive elements that meet the following
  4316. * criteria:
  4317. * 1. Element does not have a negative tabindex
  4318. * 2. Element does not have `hidden`
  4319. * 3. Element does not have `disabled` for non-Ionic components.
  4320. * 4. Element does not have `disabled` or `disabled="true"` for Ionic components.
  4321. * Note: We need this distinction because `disabled="false"` is
  4322. * valid usage for the disabled property on ion-button.
  4323. */
  4324. 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])';
  4325. /**
  4326. * Focuses the first descendant in a context
  4327. * that can receive focus. If none exists,
  4328. * a fallback element will be focused.
  4329. * This fallback is typically an ancestor
  4330. * container such as a menu or overlay so focus does not
  4331. * leave the container we are trying to trap focus in.
  4332. *
  4333. * If no fallback is specified then we focus the container itself.
  4334. */
  4335. const focusFirstDescendant = (ref, fallbackElement) => {
  4336. const firstInput = ref.querySelector(focusableQueryString);
  4337. focusElementInContext(firstInput, fallbackElement !== null && fallbackElement !== void 0 ? fallbackElement : ref);
  4338. };
  4339. /**
  4340. * Focuses the last descendant in a context
  4341. * that can receive focus. If none exists,
  4342. * a fallback element will be focused.
  4343. * This fallback is typically an ancestor
  4344. * container such as a menu or overlay so focus does not
  4345. * leave the container we are trying to trap focus in.
  4346. *
  4347. * If no fallback is specified then we focus the container itself.
  4348. */
  4349. const focusLastDescendant = (ref, fallbackElement) => {
  4350. const inputs = Array.from(ref.querySelectorAll(focusableQueryString));
  4351. const lastInput = inputs.length > 0 ? inputs[inputs.length - 1] : null;
  4352. focusElementInContext(lastInput, fallbackElement !== null && fallbackElement !== void 0 ? fallbackElement : ref);
  4353. };
  4354. /**
  4355. * Focuses a particular element in a context. If the element
  4356. * doesn't have anything focusable associated with it then
  4357. * a fallback element will be focused.
  4358. *
  4359. * This fallback is typically an ancestor
  4360. * container such as a menu or overlay so focus does not
  4361. * leave the container we are trying to trap focus in.
  4362. * This should be used instead of the focus() method
  4363. * on most elements because the focusable element
  4364. * may not be the host element.
  4365. *
  4366. * For example, if an ion-button should be focused
  4367. * then we should actually focus the native <button>
  4368. * element inside of ion-button's shadow root, not
  4369. * the host element itself.
  4370. */
  4371. const focusElementInContext = (hostToFocus, fallbackElement) => {
  4372. let elementToFocus = hostToFocus;
  4373. const shadowRoot = hostToFocus === null || hostToFocus === void 0 ? void 0 : hostToFocus.shadowRoot;
  4374. if (shadowRoot) {
  4375. // If there are no inner focusable elements, just focus the host element.
  4376. elementToFocus = shadowRoot.querySelector(focusableQueryString) || hostToFocus;
  4377. }
  4378. if (elementToFocus) {
  4379. const radioGroup = elementToFocus.closest('ion-radio-group');
  4380. if (radioGroup) {
  4381. radioGroup.setFocus();
  4382. }
  4383. else {
  4384. focusVisibleElement(elementToFocus);
  4385. }
  4386. }
  4387. else {
  4388. // Focus fallback element instead of letting focus escape
  4389. fallbackElement.focus();
  4390. }
  4391. };
  4392. /**
  4393. * CloseWatcher is a newer API that lets
  4394. * use detect the hardware back button event
  4395. * in a web browser: https://caniuse.com/?search=closewatcher
  4396. * However, not every browser supports it yet.
  4397. *
  4398. * This needs to be a function so that we can
  4399. * check the config once it has been set.
  4400. * Otherwise, this code would be evaluated the
  4401. * moment this file is evaluated which could be
  4402. * before the config is set.
  4403. */
  4404. const shouldUseCloseWatcher = () => config.get('experimentalCloseWatcher', false) && win$1 !== undefined && 'CloseWatcher' in win$1;
  4405. const OVERLAY_BACK_BUTTON_PRIORITY = 100;
  4406. const MENU_BACK_BUTTON_PRIORITY = 99; // 1 less than overlay priority since menu is displayed behind overlays
  4407. // TODO(FW-2832): types
  4408. const attachComponent = async (delegate, container, component, cssClasses, componentProps, inline) => {
  4409. var _a;
  4410. if (delegate) {
  4411. return delegate.attachViewToDom(container, component, componentProps, cssClasses);
  4412. }
  4413. if (!inline && typeof component !== 'string' && !(component instanceof HTMLElement)) {
  4414. throw new Error('framework delegate is missing');
  4415. }
  4416. const el = typeof component === 'string' ? (_a = container.ownerDocument) === null || _a === void 0 ? void 0 : _a.createElement(component) : component;
  4417. if (cssClasses) {
  4418. cssClasses.forEach((c) => el.classList.add(c));
  4419. }
  4420. if (componentProps) {
  4421. Object.assign(el, componentProps);
  4422. }
  4423. container.appendChild(el);
  4424. await new Promise((resolve) => componentOnReady(el, resolve));
  4425. return el;
  4426. };
  4427. const detachComponent = (delegate, element) => {
  4428. if (element) {
  4429. if (delegate) {
  4430. const container = element.parentElement;
  4431. return delegate.removeViewFromDom(container, element);
  4432. }
  4433. element.remove();
  4434. }
  4435. return Promise.resolve();
  4436. };
  4437. const CoreDelegate = () => {
  4438. let BaseComponent;
  4439. let Reference;
  4440. const attachViewToDom = async (parentElement, userComponent, userComponentProps = {}, cssClasses = []) => {
  4441. var _a, _b;
  4442. BaseComponent = parentElement;
  4443. let ChildComponent;
  4444. /**
  4445. * If passing in a component via the `component` props
  4446. * we need to append it inside of our overlay component.
  4447. */
  4448. if (userComponent) {
  4449. /**
  4450. * If passing in the tag name, create
  4451. * the element otherwise just get a reference
  4452. * to the component.
  4453. */
  4454. const el = typeof userComponent === 'string' ? (_a = BaseComponent.ownerDocument) === null || _a === void 0 ? void 0 : _a.createElement(userComponent) : userComponent;
  4455. /**
  4456. * Add any css classes passed in
  4457. * via the cssClasses prop on the overlay.
  4458. */
  4459. cssClasses.forEach((c) => el.classList.add(c));
  4460. /**
  4461. * Add any props passed in
  4462. * via the componentProps prop on the overlay.
  4463. */
  4464. Object.assign(el, userComponentProps);
  4465. /**
  4466. * Finally, append the component
  4467. * inside of the overlay component.
  4468. */
  4469. BaseComponent.appendChild(el);
  4470. ChildComponent = el;
  4471. await new Promise((resolve) => componentOnReady(el, resolve));
  4472. }
  4473. else if (BaseComponent.children.length > 0 &&
  4474. (BaseComponent.tagName === 'ION-MODAL' || BaseComponent.tagName === 'ION-POPOVER')) {
  4475. /**
  4476. * The delegate host wrapper el is only needed for modals and popovers
  4477. * because they allow the dev to provide custom content to the overlay.
  4478. */
  4479. const root = (ChildComponent = BaseComponent.children[0]);
  4480. if (!root.classList.contains('ion-delegate-host')) {
  4481. /**
  4482. * If the root element is not a delegate host, it means
  4483. * that the overlay has not been presented yet and we need
  4484. * to create the containing element with the specified classes.
  4485. */
  4486. const el = (_b = BaseComponent.ownerDocument) === null || _b === void 0 ? void 0 : _b.createElement('div');
  4487. // Add a class to track if the root element was created by the delegate.
  4488. el.classList.add('ion-delegate-host');
  4489. cssClasses.forEach((c) => el.classList.add(c));
  4490. // Move each child from the original template to the new parent element.
  4491. el.append(...BaseComponent.children);
  4492. // Append the new parent element to the original parent element.
  4493. BaseComponent.appendChild(el);
  4494. /**
  4495. * Update the ChildComponent to be the
  4496. * newly created div in the event that one
  4497. * does not already exist.
  4498. */
  4499. ChildComponent = el;
  4500. }
  4501. }
  4502. /**
  4503. * Get the root of the app and
  4504. * add the overlay there.
  4505. */
  4506. const app = document.querySelector('ion-app') || document.body;
  4507. /**
  4508. * Create a placeholder comment so that
  4509. * we can return this component to where
  4510. * it was previously.
  4511. */
  4512. Reference = document.createComment('ionic teleport');
  4513. BaseComponent.parentNode.insertBefore(Reference, BaseComponent);
  4514. app.appendChild(BaseComponent);
  4515. /**
  4516. * We return the child component rather than the overlay
  4517. * reference itself since modal and popover will
  4518. * use this to wait for any Ionic components in the child view
  4519. * to be ready (i.e. componentOnReady) when using the
  4520. * lazy loaded component bundle.
  4521. *
  4522. * However, we fall back to returning BaseComponent
  4523. * in the event that a modal or popover is presented
  4524. * with no child content.
  4525. */
  4526. return ChildComponent !== null && ChildComponent !== void 0 ? ChildComponent : BaseComponent;
  4527. };
  4528. const removeViewFromDom = () => {
  4529. /**
  4530. * Return component to where it was previously in the DOM.
  4531. */
  4532. if (BaseComponent && Reference) {
  4533. Reference.parentNode.insertBefore(BaseComponent, Reference);
  4534. Reference.remove();
  4535. }
  4536. return Promise.resolve();
  4537. };
  4538. return { attachViewToDom, removeViewFromDom };
  4539. };
  4540. let lastOverlayIndex = 0;
  4541. let lastId = 0;
  4542. const activeAnimations = new WeakMap();
  4543. const createController = (tagName) => {
  4544. return {
  4545. create(options) {
  4546. return createOverlay(tagName, options);
  4547. },
  4548. dismiss(data, role, id) {
  4549. return dismissOverlay(document, data, role, tagName, id);
  4550. },
  4551. async getTop() {
  4552. return getPresentedOverlay(document, tagName);
  4553. },
  4554. };
  4555. };
  4556. const alertController = /*@__PURE__*/ createController('ion-alert');
  4557. const actionSheetController = /*@__PURE__*/ createController('ion-action-sheet');
  4558. const modalController = /*@__PURE__*/ createController('ion-modal');
  4559. const popoverController = /*@__PURE__*/ createController('ion-popover');
  4560. /**
  4561. * Prepares the overlay element to be presented.
  4562. */
  4563. const prepareOverlay = (el) => {
  4564. if (typeof document !== 'undefined') {
  4565. /**
  4566. * Adds a single instance of event listeners for application behaviors:
  4567. *
  4568. * - Escape Key behavior to dismiss an overlay
  4569. * - Trapping focus within an overlay
  4570. * - Back button behavior to dismiss an overlay
  4571. *
  4572. * This only occurs when the first overlay is created.
  4573. */
  4574. connectListeners(document);
  4575. }
  4576. const overlayIndex = lastOverlayIndex++;
  4577. /**
  4578. * overlayIndex is used in the overlay components to set a zIndex.
  4579. * This ensures that the most recently presented overlay will be
  4580. * on top.
  4581. */
  4582. el.overlayIndex = overlayIndex;
  4583. };
  4584. /**
  4585. * Assigns an incrementing id to an overlay element, that does not
  4586. * already have an id assigned to it.
  4587. *
  4588. * Used to track unique instances of an overlay element.
  4589. */
  4590. const setOverlayId = (el) => {
  4591. if (!el.hasAttribute('id')) {
  4592. el.id = `ion-overlay-${++lastId}`;
  4593. }
  4594. return el.id;
  4595. };
  4596. const createOverlay = (tagName, opts) => {
  4597. // eslint-disable-next-line @typescript-eslint/prefer-optional-chain
  4598. if (typeof window !== 'undefined' && typeof window.customElements !== 'undefined') {
  4599. return window.customElements.whenDefined(tagName).then(() => {
  4600. const element = document.createElement(tagName);
  4601. element.classList.add('overlay-hidden');
  4602. /**
  4603. * Convert the passed in overlay options into props
  4604. * that get passed down into the new overlay.
  4605. */
  4606. Object.assign(element, Object.assign(Object.assign({}, opts), { hasController: true }));
  4607. // append the overlay element to the document body
  4608. getAppRoot(document).appendChild(element);
  4609. return new Promise((resolve) => componentOnReady(element, resolve));
  4610. });
  4611. }
  4612. return Promise.resolve();
  4613. };
  4614. const isOverlayHidden = (overlay) => overlay.classList.contains('overlay-hidden');
  4615. /**
  4616. * Focuses a particular element in an overlay. If the element
  4617. * doesn't have anything focusable associated with it then
  4618. * the overlay itself will be focused.
  4619. * This should be used instead of the focus() method
  4620. * on most elements because the focusable element
  4621. * may not be the host element.
  4622. *
  4623. * For example, if an ion-button should be focused
  4624. * then we should actually focus the native <button>
  4625. * element inside of ion-button's shadow root, not
  4626. * the host element itself.
  4627. */
  4628. const focusElementInOverlay = (hostToFocus, overlay) => {
  4629. let elementToFocus = hostToFocus;
  4630. const shadowRoot = hostToFocus === null || hostToFocus === void 0 ? void 0 : hostToFocus.shadowRoot;
  4631. if (shadowRoot) {
  4632. // If there are no inner focusable elements, just focus the host element.
  4633. elementToFocus = shadowRoot.querySelector(focusableQueryString) || hostToFocus;
  4634. }
  4635. if (elementToFocus) {
  4636. focusVisibleElement(elementToFocus);
  4637. }
  4638. else {
  4639. // Focus overlay instead of letting focus escape
  4640. overlay.focus();
  4641. }
  4642. };
  4643. /**
  4644. * Traps keyboard focus inside of overlay components.
  4645. * Based on https://w3c.github.io/aria-practices/examples/dialog-modal/alertdialog.html
  4646. * This includes the following components: Action Sheet, Alert, Loading, Modal,
  4647. * Picker, and Popover.
  4648. * Should NOT include: Toast
  4649. */
  4650. const trapKeyboardFocus = (ev, doc) => {
  4651. const lastOverlay = getPresentedOverlay(doc, 'ion-alert,ion-action-sheet,ion-loading,ion-modal,ion-picker-legacy,ion-popover');
  4652. const target = ev.target;
  4653. /**
  4654. * If no active overlay, ignore this event.
  4655. *
  4656. * If this component uses the shadow dom,
  4657. * this global listener is pointless
  4658. * since it will not catch the focus
  4659. * traps as they are inside the shadow root.
  4660. * We need to add a listener to the shadow root
  4661. * itself to ensure the focus trap works.
  4662. */
  4663. if (!lastOverlay || !target) {
  4664. return;
  4665. }
  4666. /**
  4667. * If the ion-disable-focus-trap class
  4668. * is present on an overlay, then this component
  4669. * instance has opted out of focus trapping.
  4670. * An example of this is when the sheet modal
  4671. * has a backdrop that is disabled. The content
  4672. * behind the sheet should be focusable until
  4673. * the backdrop is enabled.
  4674. */
  4675. if (lastOverlay.classList.contains(FOCUS_TRAP_DISABLE_CLASS)) {
  4676. return;
  4677. }
  4678. const trapScopedFocus = () => {
  4679. /**
  4680. * If we are focusing the overlay, clear
  4681. * the last focused element so that hitting
  4682. * tab activates the first focusable element
  4683. * in the overlay wrapper.
  4684. */
  4685. if (lastOverlay === target) {
  4686. lastOverlay.lastFocus = undefined;
  4687. /**
  4688. * Toasts can be presented from an overlay.
  4689. * However, focus should still be returned to
  4690. * the overlay when clicking a toast. Normally,
  4691. * focus would be returned to the last focusable
  4692. * descendant in the overlay which may not always be
  4693. * the button that the toast was presented from. In this case,
  4694. * the focus may be returned to an unexpected element.
  4695. * To account for this, we make sure to return focus to the
  4696. * last focused element in the overlay if focus is
  4697. * moved to the toast.
  4698. */
  4699. }
  4700. else if (target.tagName === 'ION-TOAST') {
  4701. focusElementInOverlay(lastOverlay.lastFocus, lastOverlay);
  4702. /**
  4703. * Otherwise, we must be focusing an element
  4704. * inside of the overlay. The two possible options
  4705. * here are an input/button/etc or the ion-focus-trap
  4706. * element. The focus trap element is used to prevent
  4707. * the keyboard focus from leaving the overlay when
  4708. * using Tab or screen assistants.
  4709. */
  4710. }
  4711. else {
  4712. /**
  4713. * We do not want to focus the traps, so get the overlay
  4714. * wrapper element as the traps live outside of the wrapper.
  4715. */
  4716. const overlayRoot = getElementRoot(lastOverlay);
  4717. if (!overlayRoot.contains(target)) {
  4718. return;
  4719. }
  4720. const overlayWrapper = overlayRoot.querySelector('.ion-overlay-wrapper');
  4721. if (!overlayWrapper) {
  4722. return;
  4723. }
  4724. /**
  4725. * If the target is inside the wrapper, let the browser
  4726. * focus as normal and keep a log of the last focused element.
  4727. * Additionally, if the backdrop was tapped we should not
  4728. * move focus back inside the wrapper as that could cause
  4729. * an interactive elements focus state to activate.
  4730. */
  4731. if (overlayWrapper.contains(target) || target === overlayRoot.querySelector('ion-backdrop')) {
  4732. lastOverlay.lastFocus = target;
  4733. }
  4734. else {
  4735. /**
  4736. * Otherwise, we must have focused one of the focus traps.
  4737. * We need to wrap the focus to either the first element
  4738. * or the last element.
  4739. */
  4740. /**
  4741. * Once we call `focusFirstDescendant` and focus the first
  4742. * descendant, another focus event will fire which will
  4743. * cause `lastOverlay.lastFocus` to be updated before
  4744. * we can run the code after that. We will cache the value
  4745. * here to avoid that.
  4746. */
  4747. const lastFocus = lastOverlay.lastFocus;
  4748. // Focus the first element in the overlay wrapper
  4749. focusFirstDescendant(overlayWrapper, lastOverlay);
  4750. /**
  4751. * If the cached last focused element is the
  4752. * same as the active element, then we need
  4753. * to wrap focus to the last descendant. This happens
  4754. * when the first descendant is focused, and the user
  4755. * presses Shift + Tab. The previous line will focus
  4756. * the same descendant again (the first one), causing
  4757. * last focus to equal the active element.
  4758. */
  4759. if (lastFocus === doc.activeElement) {
  4760. focusLastDescendant(overlayWrapper, lastOverlay);
  4761. }
  4762. lastOverlay.lastFocus = doc.activeElement;
  4763. }
  4764. }
  4765. };
  4766. const trapShadowFocus = () => {
  4767. /**
  4768. * If the target is inside the wrapper, let the browser
  4769. * focus as normal and keep a log of the last focused element.
  4770. */
  4771. if (lastOverlay.contains(target)) {
  4772. lastOverlay.lastFocus = target;
  4773. /**
  4774. * Toasts can be presented from an overlay.
  4775. * However, focus should still be returned to
  4776. * the overlay when clicking a toast. Normally,
  4777. * focus would be returned to the last focusable
  4778. * descendant in the overlay which may not always be
  4779. * the button that the toast was presented from. In this case,
  4780. * the focus may be returned to an unexpected element.
  4781. * To account for this, we make sure to return focus to the
  4782. * last focused element in the overlay if focus is
  4783. * moved to the toast.
  4784. */
  4785. }
  4786. else if (target.tagName === 'ION-TOAST') {
  4787. focusElementInOverlay(lastOverlay.lastFocus, lastOverlay);
  4788. }
  4789. else {
  4790. /**
  4791. * Otherwise, we are about to have focus
  4792. * go out of the overlay. We need to wrap
  4793. * the focus to either the first element
  4794. * or the last element.
  4795. */
  4796. /**
  4797. * Once we call `focusFirstDescendant` and focus the first
  4798. * descendant, another focus event will fire which will
  4799. * cause `lastOverlay.lastFocus` to be updated before
  4800. * we can run the code after that. We will cache the value
  4801. * here to avoid that.
  4802. */
  4803. const lastFocus = lastOverlay.lastFocus;
  4804. // Focus the first element in the overlay wrapper
  4805. focusFirstDescendant(lastOverlay);
  4806. /**
  4807. * If the cached last focused element is the
  4808. * same as the active element, then we need
  4809. * to wrap focus to the last descendant. This happens
  4810. * when the first descendant is focused, and the user
  4811. * presses Shift + Tab. The previous line will focus
  4812. * the same descendant again (the first one), causing
  4813. * last focus to equal the active element.
  4814. */
  4815. if (lastFocus === doc.activeElement) {
  4816. focusLastDescendant(lastOverlay);
  4817. }
  4818. lastOverlay.lastFocus = doc.activeElement;
  4819. }
  4820. };
  4821. if (lastOverlay.shadowRoot) {
  4822. trapShadowFocus();
  4823. }
  4824. else {
  4825. trapScopedFocus();
  4826. }
  4827. };
  4828. const connectListeners = (doc) => {
  4829. if (lastOverlayIndex === 0) {
  4830. lastOverlayIndex = 1;
  4831. doc.addEventListener('focus', (ev) => {
  4832. trapKeyboardFocus(ev, doc);
  4833. }, true);
  4834. // handle back-button click
  4835. doc.addEventListener('ionBackButton', (ev) => {
  4836. const lastOverlay = getPresentedOverlay(doc);
  4837. if (lastOverlay === null || lastOverlay === void 0 ? void 0 : lastOverlay.backdropDismiss) {
  4838. ev.detail.register(OVERLAY_BACK_BUTTON_PRIORITY, () => {
  4839. /**
  4840. * Do not return this promise otherwise
  4841. * the hardware back button utility will
  4842. * be blocked until the overlay dismisses.
  4843. * This is important for a modal with canDismiss.
  4844. * If the application presents a confirmation alert
  4845. * in the "canDismiss" callback, then it will be impossible
  4846. * to use the hardware back button to dismiss the alert
  4847. * dialog because the hardware back button utility
  4848. * is blocked on waiting for the modal to dismiss.
  4849. */
  4850. lastOverlay.dismiss(undefined, BACKDROP);
  4851. });
  4852. }
  4853. });
  4854. /**
  4855. * Handle ESC to close overlay.
  4856. * CloseWatcher also handles pressing the Esc
  4857. * key, so if a browser supports CloseWatcher then
  4858. * this behavior will be handled via the ionBackButton
  4859. * event.
  4860. */
  4861. if (!shouldUseCloseWatcher()) {
  4862. doc.addEventListener('keydown', (ev) => {
  4863. if (ev.key === 'Escape') {
  4864. const lastOverlay = getPresentedOverlay(doc);
  4865. if (lastOverlay === null || lastOverlay === void 0 ? void 0 : lastOverlay.backdropDismiss) {
  4866. lastOverlay.dismiss(undefined, BACKDROP);
  4867. }
  4868. }
  4869. });
  4870. }
  4871. }
  4872. };
  4873. const dismissOverlay = (doc, data, role, overlayTag, id) => {
  4874. const overlay = getPresentedOverlay(doc, overlayTag, id);
  4875. if (!overlay) {
  4876. return Promise.reject('overlay does not exist');
  4877. }
  4878. return overlay.dismiss(data, role);
  4879. };
  4880. /**
  4881. * Returns a list of all overlays in the DOM even if they are not presented.
  4882. */
  4883. const getOverlays = (doc, selector) => {
  4884. if (selector === undefined) {
  4885. selector = 'ion-alert,ion-action-sheet,ion-loading,ion-modal,ion-picker-legacy,ion-popover,ion-toast';
  4886. }
  4887. return Array.from(doc.querySelectorAll(selector)).filter((c) => c.overlayIndex > 0);
  4888. };
  4889. /**
  4890. * Returns a list of all presented overlays.
  4891. * Inline overlays can exist in the DOM but not be presented,
  4892. * so there are times when we want to exclude those.
  4893. * @param doc The document to find the element within.
  4894. * @param overlayTag The selector for the overlay, defaults to Ionic overlay components.
  4895. */
  4896. const getPresentedOverlays = (doc, overlayTag) => {
  4897. return getOverlays(doc, overlayTag).filter((o) => !isOverlayHidden(o));
  4898. };
  4899. /**
  4900. * Returns a presented overlay element.
  4901. * @param doc The document to find the element within.
  4902. * @param overlayTag The selector for the overlay, defaults to Ionic overlay components.
  4903. * @param id The unique identifier for the overlay instance.
  4904. * @returns The overlay element or `undefined` if no overlay element is found.
  4905. */
  4906. const getPresentedOverlay = (doc, overlayTag, id) => {
  4907. const overlays = getPresentedOverlays(doc, overlayTag);
  4908. return id === undefined ? overlays[overlays.length - 1] : overlays.find((o) => o.id === id);
  4909. };
  4910. /**
  4911. * When an overlay is presented, the main
  4912. * focus is the overlay not the page content.
  4913. * We need to remove the page content from the
  4914. * accessibility tree otherwise when
  4915. * users use "read screen from top" gestures with
  4916. * TalkBack and VoiceOver, the screen reader will begin
  4917. * to read the content underneath the overlay.
  4918. *
  4919. * We need a container where all page components
  4920. * exist that is separate from where the overlays
  4921. * are added in the DOM. For most apps, this element
  4922. * is the top most ion-router-outlet. In the event
  4923. * that devs are not using a router,
  4924. * they will need to add the "ion-view-container-root"
  4925. * id to the element that contains all of their views.
  4926. *
  4927. * TODO: If Framework supports having multiple top
  4928. * level router outlets we would need to update this.
  4929. * Example: One outlet for side menu and one outlet
  4930. * for main content.
  4931. */
  4932. const setRootAriaHidden = (hidden = false) => {
  4933. const root = getAppRoot(document);
  4934. const viewContainer = root.querySelector('ion-router-outlet, ion-nav, #ion-view-container-root');
  4935. if (!viewContainer) {
  4936. return;
  4937. }
  4938. if (hidden) {
  4939. viewContainer.setAttribute('aria-hidden', 'true');
  4940. }
  4941. else {
  4942. viewContainer.removeAttribute('aria-hidden');
  4943. }
  4944. };
  4945. const present = async (overlay, name, iosEnterAnimation, mdEnterAnimation, opts) => {
  4946. var _a, _b;
  4947. if (overlay.presented) {
  4948. return;
  4949. }
  4950. /**
  4951. * Due to accessibility guidelines, toasts do not have
  4952. * focus traps.
  4953. *
  4954. * All other overlays should have focus traps to prevent
  4955. * the keyboard focus from leaving the overlay.
  4956. */
  4957. if (overlay.el.tagName !== 'ION-TOAST') {
  4958. setRootAriaHidden(true);
  4959. document.body.classList.add(BACKDROP_NO_SCROLL);
  4960. }
  4961. hideUnderlyingOverlaysFromScreenReaders(overlay.el);
  4962. hideAnimatingOverlayFromScreenReaders(overlay.el);
  4963. overlay.presented = true;
  4964. overlay.willPresent.emit();
  4965. (_a = overlay.willPresentShorthand) === null || _a === void 0 ? void 0 : _a.emit();
  4966. const mode = getIonMode$1(overlay);
  4967. // get the user's animation fn if one was provided
  4968. const animationBuilder = overlay.enterAnimation
  4969. ? overlay.enterAnimation
  4970. : config.get(name, mode === 'ios' ? iosEnterAnimation : mdEnterAnimation);
  4971. const completed = await overlayAnimation(overlay, animationBuilder, overlay.el, opts);
  4972. if (completed) {
  4973. overlay.didPresent.emit();
  4974. (_b = overlay.didPresentShorthand) === null || _b === void 0 ? void 0 : _b.emit();
  4975. }
  4976. /**
  4977. * When an overlay that steals focus
  4978. * is dismissed, focus should be returned
  4979. * to the element that was focused
  4980. * prior to the overlay opening. Toast
  4981. * does not steal focus and is excluded
  4982. * from returning focus as a result.
  4983. */
  4984. if (overlay.el.tagName !== 'ION-TOAST') {
  4985. restoreElementFocus(overlay.el);
  4986. }
  4987. /**
  4988. * If the focused element is already
  4989. * inside the overlay component then
  4990. * focus should not be moved from that
  4991. * to the overlay container.
  4992. */
  4993. if (overlay.keyboardClose && (document.activeElement === null || !overlay.el.contains(document.activeElement))) {
  4994. overlay.el.focus();
  4995. }
  4996. /**
  4997. * If this overlay was previously dismissed without being
  4998. * the topmost one (such as by manually calling dismiss()),
  4999. * it would still have aria-hidden on being presented again.
  5000. * Removing it here ensures the overlay is visible to screen
  5001. * readers.
  5002. *
  5003. * If this overlay was being presented, then it was hidden
  5004. * from screen readers during the animation. Now that the
  5005. * animation is complete, we can reveal the overlay to
  5006. * screen readers.
  5007. */
  5008. overlay.el.removeAttribute('aria-hidden');
  5009. };
  5010. /**
  5011. * When an overlay component is dismissed,
  5012. * focus should be returned to the element
  5013. * that presented the overlay. Otherwise
  5014. * focus will be set on the body which
  5015. * means that people using screen readers
  5016. * or tabbing will need to re-navigate
  5017. * to where they were before they
  5018. * opened the overlay.
  5019. */
  5020. const restoreElementFocus = async (overlayEl) => {
  5021. let previousElement = document.activeElement;
  5022. if (!previousElement) {
  5023. return;
  5024. }
  5025. const shadowRoot = previousElement === null || previousElement === void 0 ? void 0 : previousElement.shadowRoot;
  5026. if (shadowRoot) {
  5027. // If there are no inner focusable elements, just focus the host element.
  5028. previousElement = shadowRoot.querySelector(focusableQueryString) || previousElement;
  5029. }
  5030. await overlayEl.onDidDismiss();
  5031. /**
  5032. * After onDidDismiss, the overlay loses focus
  5033. * because it is removed from the document
  5034. *
  5035. * > An element will also lose focus [...]
  5036. * > if the element is removed from the document)
  5037. *
  5038. * https://developer.mozilla.org/en-US/docs/Web/API/Element/blur_event
  5039. *
  5040. * Additionally, `document.activeElement` returns:
  5041. *
  5042. * > The Element which currently has focus,
  5043. * > `<body>` or null if there is
  5044. * > no focused element.
  5045. *
  5046. * https://developer.mozilla.org/en-US/docs/Web/API/Document/activeElement#value
  5047. *
  5048. * However, if the user has already focused
  5049. * an element sometime between onWillDismiss
  5050. * and onDidDismiss (for example, focusing a
  5051. * text box after tapping a button in an
  5052. * action sheet) then don't restore focus to
  5053. * previous element
  5054. */
  5055. if (document.activeElement === null || document.activeElement === document.body) {
  5056. previousElement.focus();
  5057. }
  5058. };
  5059. const dismiss = async (overlay, data, role, name, iosLeaveAnimation, mdLeaveAnimation, opts) => {
  5060. var _a, _b;
  5061. if (!overlay.presented) {
  5062. return false;
  5063. }
  5064. const presentedOverlays = doc !== undefined ? getPresentedOverlays(doc) : [];
  5065. /**
  5066. * For accessibility, toasts lack focus traps and don't receive
  5067. * `aria-hidden` on the root element when presented.
  5068. *
  5069. * All other overlays use focus traps to keep keyboard focus
  5070. * within the overlay, setting `aria-hidden` on the root element
  5071. * to enhance accessibility.
  5072. *
  5073. * Therefore, we must remove `aria-hidden` from the root element
  5074. * when the last non-toast overlay is dismissed.
  5075. */
  5076. const overlaysNotToast = presentedOverlays.filter((o) => o.tagName !== 'ION-TOAST');
  5077. const lastOverlayNotToast = overlaysNotToast.length === 1 && overlaysNotToast[0].id === overlay.el.id;
  5078. /**
  5079. * If this is the last visible overlay that is not a toast
  5080. * then we want to re-add the root to the accessibility tree.
  5081. */
  5082. if (lastOverlayNotToast) {
  5083. setRootAriaHidden(false);
  5084. document.body.classList.remove(BACKDROP_NO_SCROLL);
  5085. }
  5086. overlay.presented = false;
  5087. try {
  5088. /**
  5089. * There is no need to show the overlay to screen readers during
  5090. * the dismiss animation. This is because the overlay will be removed
  5091. * from the DOM after the animation is complete.
  5092. */
  5093. hideAnimatingOverlayFromScreenReaders(overlay.el);
  5094. // Overlay contents should not be clickable during dismiss
  5095. overlay.el.style.setProperty('pointer-events', 'none');
  5096. overlay.willDismiss.emit({ data, role });
  5097. (_a = overlay.willDismissShorthand) === null || _a === void 0 ? void 0 : _a.emit({ data, role });
  5098. const mode = getIonMode$1(overlay);
  5099. const animationBuilder = overlay.leaveAnimation
  5100. ? overlay.leaveAnimation
  5101. : config.get(name, mode === 'ios' ? iosLeaveAnimation : mdLeaveAnimation);
  5102. // If dismissed via gesture, no need to play leaving animation again
  5103. if (role !== GESTURE) {
  5104. await overlayAnimation(overlay, animationBuilder, overlay.el, opts);
  5105. }
  5106. overlay.didDismiss.emit({ data, role });
  5107. (_b = overlay.didDismissShorthand) === null || _b === void 0 ? void 0 : _b.emit({ data, role });
  5108. // Get a reference to all animations currently assigned to this overlay
  5109. // Then tear them down to return the overlay to its initial visual state
  5110. const animations = activeAnimations.get(overlay) || [];
  5111. animations.forEach((ani) => ani.destroy());
  5112. activeAnimations.delete(overlay);
  5113. /**
  5114. * Make overlay hidden again in case it is being reused.
  5115. * We can safely remove pointer-events: none as
  5116. * overlay-hidden will set display: none.
  5117. */
  5118. overlay.el.classList.add('overlay-hidden');
  5119. overlay.el.style.removeProperty('pointer-events');
  5120. /**
  5121. * Clear any focus trapping references
  5122. * when the overlay is dismissed.
  5123. */
  5124. if (overlay.el.lastFocus !== undefined) {
  5125. overlay.el.lastFocus = undefined;
  5126. }
  5127. }
  5128. catch (err) {
  5129. printIonError(`[${overlay.el.tagName.toLowerCase()}] - `, err);
  5130. }
  5131. overlay.el.remove();
  5132. revealOverlaysToScreenReaders();
  5133. return true;
  5134. };
  5135. const getAppRoot = (doc) => {
  5136. return doc.querySelector('ion-app') || doc.body;
  5137. };
  5138. const overlayAnimation = async (overlay, animationBuilder, baseEl, opts) => {
  5139. // Make overlay visible in case it's hidden
  5140. baseEl.classList.remove('overlay-hidden');
  5141. const aniRoot = overlay.el;
  5142. const animation = animationBuilder(aniRoot, opts);
  5143. if (!overlay.animated || !config.getBoolean('animated', true)) {
  5144. animation.duration(0);
  5145. }
  5146. if (overlay.keyboardClose) {
  5147. animation.beforeAddWrite(() => {
  5148. const activeElement = baseEl.ownerDocument.activeElement;
  5149. if (activeElement === null || activeElement === void 0 ? void 0 : activeElement.matches('input,ion-input, ion-textarea')) {
  5150. activeElement.blur();
  5151. }
  5152. });
  5153. }
  5154. const activeAni = activeAnimations.get(overlay) || [];
  5155. activeAnimations.set(overlay, [...activeAni, animation]);
  5156. await animation.play();
  5157. return true;
  5158. };
  5159. const eventMethod = (element, eventName) => {
  5160. let resolve;
  5161. const promise = new Promise((r) => (resolve = r));
  5162. onceEvent(element, eventName, (event) => {
  5163. resolve(event.detail);
  5164. });
  5165. return promise;
  5166. };
  5167. const onceEvent = (element, eventName, callback) => {
  5168. const handler = (ev) => {
  5169. removeEventListener(element, eventName, handler);
  5170. callback(ev);
  5171. };
  5172. addEventListener$1(element, eventName, handler);
  5173. };
  5174. const isCancel = (role) => {
  5175. return role === 'cancel' || role === BACKDROP;
  5176. };
  5177. const defaultGate = (h) => h();
  5178. /**
  5179. * Calls a developer provided method while avoiding
  5180. * Angular Zones. Since the handler is provided by
  5181. * the developer, we should throw any errors
  5182. * received so that developer-provided bug
  5183. * tracking software can log it.
  5184. */
  5185. const safeCall = (handler, arg) => {
  5186. if (typeof handler === 'function') {
  5187. const jmp = config.get('_zoneGate', defaultGate);
  5188. return jmp(() => {
  5189. try {
  5190. return handler(arg);
  5191. }
  5192. catch (e) {
  5193. throw e;
  5194. }
  5195. });
  5196. }
  5197. return undefined;
  5198. };
  5199. const BACKDROP = 'backdrop';
  5200. const GESTURE = 'gesture';
  5201. const OVERLAY_GESTURE_PRIORITY = 39;
  5202. /**
  5203. * Creates a delegate controller.
  5204. *
  5205. * Requires that the component has the following properties:
  5206. * - `el: HTMLElement`
  5207. * - `hasController: boolean`
  5208. * - `delegate?: FrameworkDelegate`
  5209. *
  5210. * @param ref The component class instance.
  5211. */
  5212. const createDelegateController = (ref) => {
  5213. let inline = false;
  5214. let workingDelegate;
  5215. const coreDelegate = CoreDelegate();
  5216. /**
  5217. * Determines whether or not an overlay is being used
  5218. * inline or via a controller/JS and returns the correct delegate.
  5219. * By default, subsequent calls to getDelegate will use
  5220. * a cached version of the delegate.
  5221. * This is useful for calling dismiss after present,
  5222. * so that the correct delegate is given.
  5223. * @param force `true` to force the non-cached version of the delegate.
  5224. * @returns The delegate to use and whether or not the overlay is inline.
  5225. */
  5226. const getDelegate = (force = false) => {
  5227. if (workingDelegate && !force) {
  5228. return {
  5229. delegate: workingDelegate,
  5230. inline,
  5231. };
  5232. }
  5233. const { el, hasController, delegate } = ref;
  5234. /**
  5235. * If using overlay inline
  5236. * we potentially need to use the coreDelegate
  5237. * so that this works in vanilla JS apps.
  5238. * If a developer has presented this component
  5239. * via a controller, then we can assume
  5240. * the component is already in the
  5241. * correct place.
  5242. */
  5243. const parentEl = el.parentNode;
  5244. inline = parentEl !== null && !hasController;
  5245. workingDelegate = inline ? delegate || coreDelegate : delegate;
  5246. return { inline, delegate: workingDelegate };
  5247. };
  5248. /**
  5249. * Attaches a component in the DOM. Teleports the component
  5250. * to the root of the app.
  5251. * @param component The component to optionally construct and append to the element.
  5252. */
  5253. const attachViewToDom = async (component) => {
  5254. const { delegate } = getDelegate(true);
  5255. if (delegate) {
  5256. return await delegate.attachViewToDom(ref.el, component);
  5257. }
  5258. const { hasController } = ref;
  5259. if (hasController && component !== undefined) {
  5260. throw new Error('framework delegate is missing');
  5261. }
  5262. return null;
  5263. };
  5264. /**
  5265. * Moves a component back to its original location in the DOM.
  5266. */
  5267. const removeViewFromDom = () => {
  5268. const { delegate } = getDelegate();
  5269. if (delegate && ref.el !== undefined) {
  5270. delegate.removeViewFromDom(ref.el.parentElement, ref.el);
  5271. }
  5272. };
  5273. return {
  5274. attachViewToDom,
  5275. removeViewFromDom,
  5276. };
  5277. };
  5278. /**
  5279. * Constructs a trigger interaction for an overlay.
  5280. * Presents an overlay when the trigger is clicked.
  5281. *
  5282. * Usage:
  5283. * ```ts
  5284. * triggerController = createTriggerController();
  5285. * triggerController.addClickListener(el, trigger);
  5286. * ```
  5287. */
  5288. const createTriggerController = () => {
  5289. let destroyTriggerInteraction;
  5290. /**
  5291. * Removes the click listener from the trigger element.
  5292. */
  5293. const removeClickListener = () => {
  5294. if (destroyTriggerInteraction) {
  5295. destroyTriggerInteraction();
  5296. destroyTriggerInteraction = undefined;
  5297. }
  5298. };
  5299. /**
  5300. * Adds a click listener to the trigger element.
  5301. * Presents the overlay when the trigger is clicked.
  5302. * @param el The overlay element.
  5303. * @param trigger The ID of the element to add a click listener to.
  5304. */
  5305. const addClickListener = (el, trigger) => {
  5306. removeClickListener();
  5307. const triggerEl = trigger !== undefined ? document.getElementById(trigger) : null;
  5308. if (!triggerEl) {
  5309. 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);
  5310. return;
  5311. }
  5312. const configureTriggerInteraction = (targetEl, overlayEl) => {
  5313. const openOverlay = () => {
  5314. overlayEl.present();
  5315. };
  5316. targetEl.addEventListener('click', openOverlay);
  5317. return () => {
  5318. targetEl.removeEventListener('click', openOverlay);
  5319. };
  5320. };
  5321. destroyTriggerInteraction = configureTriggerInteraction(triggerEl, el);
  5322. };
  5323. return {
  5324. addClickListener,
  5325. removeClickListener,
  5326. };
  5327. };
  5328. /**
  5329. * The overlay that is being animated also needs to hide from screen
  5330. * readers during its animation. This ensures that assistive technologies
  5331. * like TalkBack do not announce or interact with the content until the
  5332. * animation is complete, avoiding confusion for users.
  5333. *
  5334. * When the overlay is presented on an Android device, TalkBack's focus rings
  5335. * may appear in the wrong position due to the transition (specifically
  5336. * `transform` styles). This occurs because the focus rings are initially
  5337. * displayed at the starting position of the elements before the transition
  5338. * begins. This workaround ensures the focus rings do not appear in the
  5339. * incorrect location.
  5340. *
  5341. * If this solution is applied to iOS devices, then it leads to a bug where
  5342. * the overlays cannot be accessed by screen readers. This is due to
  5343. * VoiceOver not being able to update the accessibility tree when the
  5344. * `aria-hidden` is removed.
  5345. *
  5346. * @param overlay - The overlay that is being animated.
  5347. */
  5348. const hideAnimatingOverlayFromScreenReaders = (overlay) => {
  5349. if (doc === undefined)
  5350. return;
  5351. if (isPlatform('android')) {
  5352. /**
  5353. * Once the animation is complete, this attribute will be removed.
  5354. * This is done at the end of the `present` method.
  5355. */
  5356. overlay.setAttribute('aria-hidden', 'true');
  5357. }
  5358. };
  5359. /**
  5360. * Ensure that underlying overlays have aria-hidden if necessary so that screen readers
  5361. * cannot move focus to these elements. Note that we cannot rely on focus/focusin/focusout
  5362. * events here because those events do not fire when the screen readers moves to a non-focusable
  5363. * element such as text.
  5364. * Without this logic screen readers would be able to move focus outside of the top focus-trapped overlay.
  5365. *
  5366. * @param newTopMostOverlay - The overlay that is being presented. Since the overlay has not been
  5367. * fully presented yet at the time this function is called it will not be included in the getPresentedOverlays result.
  5368. */
  5369. const hideUnderlyingOverlaysFromScreenReaders = (newTopMostOverlay) => {
  5370. var _a;
  5371. if (doc === undefined)
  5372. return;
  5373. const overlays = getPresentedOverlays(doc);
  5374. for (let i = overlays.length - 1; i >= 0; i--) {
  5375. const presentedOverlay = overlays[i];
  5376. const nextPresentedOverlay = (_a = overlays[i + 1]) !== null && _a !== void 0 ? _a : newTopMostOverlay;
  5377. /**
  5378. * If next overlay has aria-hidden then all remaining overlays will have it too.
  5379. * Or, if the next overlay is a Toast that does not have aria-hidden then current overlay
  5380. * should not have aria-hidden either so focus can remain in the current overlay.
  5381. */
  5382. if (nextPresentedOverlay.hasAttribute('aria-hidden') || nextPresentedOverlay.tagName !== 'ION-TOAST') {
  5383. presentedOverlay.setAttribute('aria-hidden', 'true');
  5384. }
  5385. }
  5386. };
  5387. /**
  5388. * When dismissing an overlay we need to reveal the new top-most overlay to screen readers.
  5389. * If the top-most overlay is a Toast we potentially need to reveal more overlays since
  5390. * focus is never automatically moved to the Toast.
  5391. */
  5392. const revealOverlaysToScreenReaders = () => {
  5393. if (doc === undefined)
  5394. return;
  5395. const overlays = getPresentedOverlays(doc);
  5396. for (let i = overlays.length - 1; i >= 0; i--) {
  5397. const currentOverlay = overlays[i];
  5398. /**
  5399. * If the current we are looking at is a Toast then we can remove aria-hidden.
  5400. * However, we potentially need to keep looking at the overlay stack because there
  5401. * could be more Toasts underneath. Additionally, we need to unhide the closest non-Toast
  5402. * overlay too so focus can move there since focus is never automatically moved to the Toast.
  5403. */
  5404. currentOverlay.removeAttribute('aria-hidden');
  5405. /**
  5406. * If we found a non-Toast element then we can just remove aria-hidden and stop searching entirely
  5407. * since this overlay should always receive focus. As a result, all underlying overlays should still
  5408. * be hidden from screen readers.
  5409. */
  5410. if (currentOverlay.tagName !== 'ION-TOAST') {
  5411. break;
  5412. }
  5413. }
  5414. };
  5415. const FOCUS_TRAP_DISABLE_CLASS = 'ion-disable-focus-trap';
  5416. const hostContext = (selector, el) => {
  5417. return el.closest(selector) !== null;
  5418. };
  5419. /**
  5420. * Create the mode and color classes for the component based on the classes passed in
  5421. */
  5422. const createColorClasses$1 = (color, cssClassMap) => {
  5423. return typeof color === 'string' && color.length > 0
  5424. ? Object.assign({ 'ion-color': true, [`ion-color-${color}`]: true }, cssClassMap) : cssClassMap;
  5425. };
  5426. const getClassList = (classes) => {
  5427. if (classes !== undefined) {
  5428. const array = Array.isArray(classes) ? classes : classes.split(' ');
  5429. return array
  5430. .filter((c) => c != null)
  5431. .map((c) => c.trim())
  5432. .filter((c) => c !== '');
  5433. }
  5434. return [];
  5435. };
  5436. const getClassMap = (classes) => {
  5437. const map = {};
  5438. getClassList(classes).forEach((c) => (map[c] = true));
  5439. return map;
  5440. };
  5441. const SCHEME = /^[a-z][a-z0-9+\-.]*:/;
  5442. const openURL = async (url, ev, direction, animation) => {
  5443. if (url != null && url[0] !== '#' && !SCHEME.test(url)) {
  5444. const router = document.querySelector('ion-router');
  5445. if (router) {
  5446. if (ev != null) {
  5447. ev.preventDefault();
  5448. }
  5449. return router.push(url, direction, animation);
  5450. }
  5451. }
  5452. return false;
  5453. };
  5454. let animationPrefix;
  5455. const getAnimationPrefix = (el) => {
  5456. if (animationPrefix === undefined) {
  5457. const supportsUnprefixed = el.style.animationName !== undefined;
  5458. const supportsWebkitPrefix = el.style.webkitAnimationName !== undefined;
  5459. animationPrefix = !supportsUnprefixed && supportsWebkitPrefix ? '-webkit-' : '';
  5460. }
  5461. return animationPrefix;
  5462. };
  5463. const setStyleProperty = (element, propertyName, value) => {
  5464. const prefix = propertyName.startsWith('animation') ? getAnimationPrefix(element) : '';
  5465. element.style.setProperty(prefix + propertyName, value);
  5466. };
  5467. const addClassToArray = (classes = [], className) => {
  5468. if (className !== undefined) {
  5469. const classNameToAppend = Array.isArray(className) ? className : [className];
  5470. return [...classes, ...classNameToAppend];
  5471. }
  5472. return classes;
  5473. };
  5474. const createAnimation = (animationId) => {
  5475. let _delay;
  5476. let _duration;
  5477. let _easing;
  5478. let _iterations;
  5479. let _fill;
  5480. let _direction;
  5481. let _keyframes = [];
  5482. let beforeAddClasses = [];
  5483. let beforeRemoveClasses = [];
  5484. let initialized = false;
  5485. let parentAnimation;
  5486. let beforeStylesValue = {};
  5487. let afterAddClasses = [];
  5488. let afterRemoveClasses = [];
  5489. let afterStylesValue = {};
  5490. let numAnimationsRunning = 0;
  5491. let shouldForceLinearEasing = false;
  5492. let shouldForceSyncPlayback = false;
  5493. let forceDirectionValue;
  5494. let forceDurationValue;
  5495. let forceDelayValue;
  5496. let willComplete = true;
  5497. let finished = false;
  5498. let shouldCalculateNumAnimations = true;
  5499. let ani;
  5500. let paused = false;
  5501. const id = animationId;
  5502. const onFinishCallbacks = [];
  5503. const onFinishOneTimeCallbacks = [];
  5504. const onStopOneTimeCallbacks = [];
  5505. const elements = [];
  5506. const childAnimations = [];
  5507. const stylesheets = [];
  5508. const _beforeAddReadFunctions = [];
  5509. const _beforeAddWriteFunctions = [];
  5510. const _afterAddReadFunctions = [];
  5511. const _afterAddWriteFunctions = [];
  5512. const webAnimations = [];
  5513. const supportsAnimationEffect = typeof AnimationEffect === 'function' ||
  5514. (win$1 !== undefined && typeof win$1.AnimationEffect === 'function');
  5515. /**
  5516. * This is a feature detection for Web Animations.
  5517. *
  5518. * Certain environments such as emulated browser environments for testing,
  5519. * do not support Web Animations. As a result, we need to check for support
  5520. * and provide a fallback to test certain functionality related to Web Animations.
  5521. */
  5522. const supportsWebAnimations = typeof Element === 'function' &&
  5523. typeof Element.prototype.animate === 'function' &&
  5524. supportsAnimationEffect;
  5525. const getWebAnimations = () => {
  5526. return webAnimations;
  5527. };
  5528. const destroy = (clearStyleSheets) => {
  5529. childAnimations.forEach((childAnimation) => {
  5530. childAnimation.destroy(clearStyleSheets);
  5531. });
  5532. cleanUp(clearStyleSheets);
  5533. elements.length = 0;
  5534. childAnimations.length = 0;
  5535. _keyframes.length = 0;
  5536. clearOnFinish();
  5537. initialized = false;
  5538. shouldCalculateNumAnimations = true;
  5539. return ani;
  5540. };
  5541. /**
  5542. * Cancels any Web Animations, removes
  5543. * any animation properties from the
  5544. * animation's elements, and removes the
  5545. * animation's stylesheets from the DOM.
  5546. */
  5547. const cleanUp = (clearStyleSheets) => {
  5548. cleanUpElements();
  5549. if (clearStyleSheets) {
  5550. cleanUpStyleSheets();
  5551. }
  5552. };
  5553. const resetFlags = () => {
  5554. shouldForceLinearEasing = false;
  5555. shouldForceSyncPlayback = false;
  5556. shouldCalculateNumAnimations = true;
  5557. forceDirectionValue = undefined;
  5558. forceDurationValue = undefined;
  5559. forceDelayValue = undefined;
  5560. numAnimationsRunning = 0;
  5561. finished = false;
  5562. willComplete = true;
  5563. paused = false;
  5564. };
  5565. const isRunning = () => {
  5566. return numAnimationsRunning !== 0 && !paused;
  5567. };
  5568. /**
  5569. * @internal
  5570. * Remove a callback from a chosen callback array
  5571. * @param callbackToRemove: A reference to the callback that should be removed
  5572. * @param callbackObjects: An array of callbacks that callbackToRemove should be removed from.
  5573. */
  5574. const clearCallback = (callbackToRemove, callbackObjects) => {
  5575. const index = callbackObjects.findIndex((callbackObject) => callbackObject.c === callbackToRemove);
  5576. if (index > -1) {
  5577. callbackObjects.splice(index, 1);
  5578. }
  5579. };
  5580. /**
  5581. * @internal
  5582. * Add a callback to be fired when an animation is stopped/cancelled.
  5583. * @param callback: A reference to the callback that should be fired
  5584. * @param opts: Any options associated with this particular callback
  5585. */
  5586. const onStop = (callback, opts) => {
  5587. onStopOneTimeCallbacks.push({ c: callback, o: opts });
  5588. return ani;
  5589. };
  5590. const onFinish = (callback, opts) => {
  5591. const callbacks = (opts === null || opts === void 0 ? void 0 : opts.oneTimeCallback) ? onFinishOneTimeCallbacks : onFinishCallbacks;
  5592. callbacks.push({ c: callback, o: opts });
  5593. return ani;
  5594. };
  5595. const clearOnFinish = () => {
  5596. onFinishCallbacks.length = 0;
  5597. onFinishOneTimeCallbacks.length = 0;
  5598. return ani;
  5599. };
  5600. /**
  5601. * Cancels any Web Animations and removes
  5602. * any animation properties from the
  5603. * the animation's elements.
  5604. */
  5605. const cleanUpElements = () => {
  5606. if (supportsWebAnimations) {
  5607. webAnimations.forEach((animation) => {
  5608. animation.cancel();
  5609. });
  5610. webAnimations.length = 0;
  5611. }
  5612. };
  5613. /**
  5614. * Removes the animation's stylesheets
  5615. * from the DOM.
  5616. */
  5617. const cleanUpStyleSheets = () => {
  5618. stylesheets.forEach((stylesheet) => {
  5619. /**
  5620. * When sharing stylesheets, it's possible
  5621. * for another animation to have already
  5622. * cleaned up a particular stylesheet
  5623. */
  5624. if (stylesheet === null || stylesheet === void 0 ? void 0 : stylesheet.parentNode) {
  5625. stylesheet.parentNode.removeChild(stylesheet);
  5626. }
  5627. });
  5628. stylesheets.length = 0;
  5629. };
  5630. const beforeAddRead = (readFn) => {
  5631. _beforeAddReadFunctions.push(readFn);
  5632. return ani;
  5633. };
  5634. const beforeAddWrite = (writeFn) => {
  5635. _beforeAddWriteFunctions.push(writeFn);
  5636. return ani;
  5637. };
  5638. const afterAddRead = (readFn) => {
  5639. _afterAddReadFunctions.push(readFn);
  5640. return ani;
  5641. };
  5642. const afterAddWrite = (writeFn) => {
  5643. _afterAddWriteFunctions.push(writeFn);
  5644. return ani;
  5645. };
  5646. const beforeAddClass = (className) => {
  5647. beforeAddClasses = addClassToArray(beforeAddClasses, className);
  5648. return ani;
  5649. };
  5650. const beforeRemoveClass = (className) => {
  5651. beforeRemoveClasses = addClassToArray(beforeRemoveClasses, className);
  5652. return ani;
  5653. };
  5654. /**
  5655. * Set CSS inline styles to the animation's
  5656. * elements before the animation begins.
  5657. */
  5658. const beforeStyles = (styles = {}) => {
  5659. beforeStylesValue = styles;
  5660. return ani;
  5661. };
  5662. /**
  5663. * Clear CSS inline styles from the animation's
  5664. * elements before the animation begins.
  5665. */
  5666. const beforeClearStyles = (propertyNames = []) => {
  5667. for (const property of propertyNames) {
  5668. beforeStylesValue[property] = '';
  5669. }
  5670. return ani;
  5671. };
  5672. const afterAddClass = (className) => {
  5673. afterAddClasses = addClassToArray(afterAddClasses, className);
  5674. return ani;
  5675. };
  5676. const afterRemoveClass = (className) => {
  5677. afterRemoveClasses = addClassToArray(afterRemoveClasses, className);
  5678. return ani;
  5679. };
  5680. const afterStyles = (styles = {}) => {
  5681. afterStylesValue = styles;
  5682. return ani;
  5683. };
  5684. const afterClearStyles = (propertyNames = []) => {
  5685. for (const property of propertyNames) {
  5686. afterStylesValue[property] = '';
  5687. }
  5688. return ani;
  5689. };
  5690. const getFill = () => {
  5691. if (_fill !== undefined) {
  5692. return _fill;
  5693. }
  5694. if (parentAnimation) {
  5695. return parentAnimation.getFill();
  5696. }
  5697. return 'both';
  5698. };
  5699. const getDirection = () => {
  5700. if (forceDirectionValue !== undefined) {
  5701. return forceDirectionValue;
  5702. }
  5703. if (_direction !== undefined) {
  5704. return _direction;
  5705. }
  5706. if (parentAnimation) {
  5707. return parentAnimation.getDirection();
  5708. }
  5709. return 'normal';
  5710. };
  5711. const getEasing = () => {
  5712. if (shouldForceLinearEasing) {
  5713. return 'linear';
  5714. }
  5715. if (_easing !== undefined) {
  5716. return _easing;
  5717. }
  5718. if (parentAnimation) {
  5719. return parentAnimation.getEasing();
  5720. }
  5721. return 'linear';
  5722. };
  5723. const getDuration = () => {
  5724. if (shouldForceSyncPlayback) {
  5725. return 0;
  5726. }
  5727. if (forceDurationValue !== undefined) {
  5728. return forceDurationValue;
  5729. }
  5730. if (_duration !== undefined) {
  5731. return _duration;
  5732. }
  5733. if (parentAnimation) {
  5734. return parentAnimation.getDuration();
  5735. }
  5736. return 0;
  5737. };
  5738. const getIterations = () => {
  5739. if (_iterations !== undefined) {
  5740. return _iterations;
  5741. }
  5742. if (parentAnimation) {
  5743. return parentAnimation.getIterations();
  5744. }
  5745. return 1;
  5746. };
  5747. const getDelay = () => {
  5748. if (forceDelayValue !== undefined) {
  5749. return forceDelayValue;
  5750. }
  5751. if (_delay !== undefined) {
  5752. return _delay;
  5753. }
  5754. if (parentAnimation) {
  5755. return parentAnimation.getDelay();
  5756. }
  5757. return 0;
  5758. };
  5759. const getKeyframes = () => {
  5760. return _keyframes;
  5761. };
  5762. const direction = (animationDirection) => {
  5763. _direction = animationDirection;
  5764. update(true);
  5765. return ani;
  5766. };
  5767. const fill = (animationFill) => {
  5768. _fill = animationFill;
  5769. update(true);
  5770. return ani;
  5771. };
  5772. const delay = (animationDelay) => {
  5773. _delay = animationDelay;
  5774. update(true);
  5775. return ani;
  5776. };
  5777. const easing = (animationEasing) => {
  5778. _easing = animationEasing;
  5779. update(true);
  5780. return ani;
  5781. };
  5782. const duration = (animationDuration) => {
  5783. /**
  5784. * CSS Animation Durations of 0ms work fine on Chrome
  5785. * but do not run on Safari, so force it to 1ms to
  5786. * get it to run on both platforms.
  5787. */
  5788. if (!supportsWebAnimations && animationDuration === 0) {
  5789. animationDuration = 1;
  5790. }
  5791. _duration = animationDuration;
  5792. update(true);
  5793. return ani;
  5794. };
  5795. const iterations = (animationIterations) => {
  5796. _iterations = animationIterations;
  5797. update(true);
  5798. return ani;
  5799. };
  5800. const parent = (animation) => {
  5801. parentAnimation = animation;
  5802. return ani;
  5803. };
  5804. const addElement = (el) => {
  5805. if (el != null) {
  5806. if (el.nodeType === 1) {
  5807. elements.push(el);
  5808. }
  5809. else if (el.length >= 0) {
  5810. for (let i = 0; i < el.length; i++) {
  5811. elements.push(el[i]);
  5812. }
  5813. }
  5814. else {
  5815. printIonError('createAnimation - Invalid addElement value.');
  5816. }
  5817. }
  5818. return ani;
  5819. };
  5820. const addAnimation = (animationToAdd) => {
  5821. if (animationToAdd != null) {
  5822. if (Array.isArray(animationToAdd)) {
  5823. for (const animation of animationToAdd) {
  5824. animation.parent(ani);
  5825. childAnimations.push(animation);
  5826. }
  5827. }
  5828. else {
  5829. animationToAdd.parent(ani);
  5830. childAnimations.push(animationToAdd);
  5831. }
  5832. }
  5833. return ani;
  5834. };
  5835. const keyframes = (keyframeValues) => {
  5836. const different = _keyframes !== keyframeValues;
  5837. _keyframes = keyframeValues;
  5838. if (different) {
  5839. updateKeyframes(_keyframes);
  5840. }
  5841. return ani;
  5842. };
  5843. const updateKeyframes = (keyframeValues) => {
  5844. if (supportsWebAnimations) {
  5845. getWebAnimations().forEach((animation) => {
  5846. /**
  5847. * animation.effect's type is AnimationEffect.
  5848. * However, in this case we have a more specific
  5849. * type of AnimationEffect called KeyframeEffect which
  5850. * inherits from AnimationEffect. As a result,
  5851. * we cast animation.effect to KeyframeEffect.
  5852. */
  5853. const keyframeEffect = animation.effect;
  5854. /**
  5855. * setKeyframes is not supported in all browser
  5856. * versions that Ionic supports, so we need to
  5857. * check for support before using it.
  5858. */
  5859. // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
  5860. if (keyframeEffect.setKeyframes) {
  5861. keyframeEffect.setKeyframes(keyframeValues);
  5862. }
  5863. else {
  5864. const newEffect = new KeyframeEffect(keyframeEffect.target, keyframeValues, keyframeEffect.getTiming());
  5865. animation.effect = newEffect;
  5866. }
  5867. });
  5868. }
  5869. };
  5870. /**
  5871. * Run all "before" animation hooks.
  5872. */
  5873. const beforeAnimation = () => {
  5874. // Runs all before read callbacks
  5875. _beforeAddReadFunctions.forEach((callback) => callback());
  5876. // Runs all before write callbacks
  5877. _beforeAddWriteFunctions.forEach((callback) => callback());
  5878. // Updates styles and classes before animation runs
  5879. const addClasses = beforeAddClasses;
  5880. const removeClasses = beforeRemoveClasses;
  5881. const styles = beforeStylesValue;
  5882. elements.forEach((el) => {
  5883. const elementClassList = el.classList;
  5884. addClasses.forEach((c) => elementClassList.add(c));
  5885. removeClasses.forEach((c) => elementClassList.remove(c));
  5886. for (const property in styles) {
  5887. // eslint-disable-next-line no-prototype-builtins
  5888. if (styles.hasOwnProperty(property)) {
  5889. setStyleProperty(el, property, styles[property]);
  5890. }
  5891. }
  5892. });
  5893. };
  5894. /**
  5895. * Run all "after" animation hooks.
  5896. */
  5897. const afterAnimation = () => {
  5898. // Runs all after read callbacks
  5899. _afterAddReadFunctions.forEach((callback) => callback());
  5900. // Runs all after write callbacks
  5901. _afterAddWriteFunctions.forEach((callback) => callback());
  5902. // Updates styles and classes before animation ends
  5903. const currentStep = willComplete ? 1 : 0;
  5904. const addClasses = afterAddClasses;
  5905. const removeClasses = afterRemoveClasses;
  5906. const styles = afterStylesValue;
  5907. elements.forEach((el) => {
  5908. const elementClassList = el.classList;
  5909. addClasses.forEach((c) => elementClassList.add(c));
  5910. removeClasses.forEach((c) => elementClassList.remove(c));
  5911. for (const property in styles) {
  5912. // eslint-disable-next-line no-prototype-builtins
  5913. if (styles.hasOwnProperty(property)) {
  5914. setStyleProperty(el, property, styles[property]);
  5915. }
  5916. }
  5917. });
  5918. /**
  5919. * Clean up any value coercion before
  5920. * the user callbacks fire otherwise
  5921. * they may get stale values. For example,
  5922. * if someone calls progressStart(0) the
  5923. * animation may still be reversed.
  5924. */
  5925. forceDurationValue = undefined;
  5926. forceDirectionValue = undefined;
  5927. forceDelayValue = undefined;
  5928. onFinishCallbacks.forEach((onFinishCallback) => {
  5929. return onFinishCallback.c(currentStep, ani);
  5930. });
  5931. onFinishOneTimeCallbacks.forEach((onFinishCallback) => {
  5932. return onFinishCallback.c(currentStep, ani);
  5933. });
  5934. onFinishOneTimeCallbacks.length = 0;
  5935. shouldCalculateNumAnimations = true;
  5936. if (willComplete) {
  5937. finished = true;
  5938. }
  5939. willComplete = true;
  5940. };
  5941. const animationFinish = () => {
  5942. if (numAnimationsRunning === 0) {
  5943. return;
  5944. }
  5945. numAnimationsRunning--;
  5946. if (numAnimationsRunning === 0) {
  5947. afterAnimation();
  5948. if (parentAnimation) {
  5949. parentAnimation.animationFinish();
  5950. }
  5951. }
  5952. };
  5953. const initializeWebAnimation = () => {
  5954. elements.forEach((element) => {
  5955. const animation = element.animate(_keyframes, {
  5956. id,
  5957. delay: getDelay(),
  5958. duration: getDuration(),
  5959. easing: getEasing(),
  5960. iterations: getIterations(),
  5961. fill: getFill(),
  5962. direction: getDirection(),
  5963. });
  5964. animation.pause();
  5965. webAnimations.push(animation);
  5966. });
  5967. if (webAnimations.length > 0) {
  5968. webAnimations[0].onfinish = () => {
  5969. animationFinish();
  5970. };
  5971. }
  5972. };
  5973. const initializeAnimation = () => {
  5974. beforeAnimation();
  5975. if (_keyframes.length > 0) {
  5976. if (supportsWebAnimations) {
  5977. initializeWebAnimation();
  5978. }
  5979. }
  5980. initialized = true;
  5981. };
  5982. const setAnimationStep = (step) => {
  5983. step = Math.min(Math.max(step, 0), 0.9999);
  5984. if (supportsWebAnimations) {
  5985. webAnimations.forEach((animation) => {
  5986. // When creating the animation the delay is guaranteed to be set to a number.
  5987. animation.currentTime = animation.effect.getComputedTiming().delay + getDuration() * step;
  5988. animation.pause();
  5989. });
  5990. }
  5991. };
  5992. const updateWebAnimation = (step) => {
  5993. webAnimations.forEach((animation) => {
  5994. animation.effect.updateTiming({
  5995. delay: getDelay(),
  5996. duration: getDuration(),
  5997. easing: getEasing(),
  5998. iterations: getIterations(),
  5999. fill: getFill(),
  6000. direction: getDirection(),
  6001. });
  6002. });
  6003. if (step !== undefined) {
  6004. setAnimationStep(step);
  6005. }
  6006. };
  6007. const update = (deep = false, toggleAnimationName = true, step) => {
  6008. if (deep) {
  6009. childAnimations.forEach((animation) => {
  6010. animation.update(deep, toggleAnimationName, step);
  6011. });
  6012. }
  6013. if (supportsWebAnimations) {
  6014. updateWebAnimation(step);
  6015. }
  6016. return ani;
  6017. };
  6018. const progressStart = (forceLinearEasing = false, step) => {
  6019. childAnimations.forEach((animation) => {
  6020. animation.progressStart(forceLinearEasing, step);
  6021. });
  6022. pauseAnimation();
  6023. shouldForceLinearEasing = forceLinearEasing;
  6024. if (!initialized) {
  6025. initializeAnimation();
  6026. }
  6027. update(false, true, step);
  6028. return ani;
  6029. };
  6030. const progressStep = (step) => {
  6031. childAnimations.forEach((animation) => {
  6032. animation.progressStep(step);
  6033. });
  6034. setAnimationStep(step);
  6035. return ani;
  6036. };
  6037. const progressEnd = (playTo, step, dur) => {
  6038. shouldForceLinearEasing = false;
  6039. childAnimations.forEach((animation) => {
  6040. animation.progressEnd(playTo, step, dur);
  6041. });
  6042. if (dur !== undefined) {
  6043. forceDurationValue = dur;
  6044. }
  6045. finished = false;
  6046. willComplete = true;
  6047. if (playTo === 0) {
  6048. forceDirectionValue = getDirection() === 'reverse' ? 'normal' : 'reverse';
  6049. if (forceDirectionValue === 'reverse') {
  6050. willComplete = false;
  6051. }
  6052. if (supportsWebAnimations) {
  6053. update();
  6054. setAnimationStep(1 - step);
  6055. }
  6056. else {
  6057. forceDelayValue = (1 - step) * getDuration() * -1;
  6058. update(false, false);
  6059. }
  6060. }
  6061. else if (playTo === 1) {
  6062. if (supportsWebAnimations) {
  6063. update();
  6064. setAnimationStep(step);
  6065. }
  6066. else {
  6067. forceDelayValue = step * getDuration() * -1;
  6068. update(false, false);
  6069. }
  6070. }
  6071. if (playTo !== undefined && !parentAnimation) {
  6072. play();
  6073. }
  6074. return ani;
  6075. };
  6076. const pauseAnimation = () => {
  6077. if (initialized) {
  6078. if (supportsWebAnimations) {
  6079. webAnimations.forEach((animation) => {
  6080. animation.pause();
  6081. });
  6082. }
  6083. else {
  6084. elements.forEach((element) => {
  6085. setStyleProperty(element, 'animation-play-state', 'paused');
  6086. });
  6087. }
  6088. paused = true;
  6089. }
  6090. };
  6091. const pause = () => {
  6092. childAnimations.forEach((animation) => {
  6093. animation.pause();
  6094. });
  6095. pauseAnimation();
  6096. return ani;
  6097. };
  6098. const playCSSAnimations = () => {
  6099. animationFinish();
  6100. };
  6101. const playWebAnimations = () => {
  6102. webAnimations.forEach((animation) => {
  6103. animation.play();
  6104. });
  6105. if (_keyframes.length === 0 || elements.length === 0) {
  6106. animationFinish();
  6107. }
  6108. };
  6109. const resetAnimation = () => {
  6110. if (supportsWebAnimations) {
  6111. setAnimationStep(0);
  6112. updateWebAnimation();
  6113. }
  6114. };
  6115. const play = (opts) => {
  6116. return new Promise((resolve) => {
  6117. if (opts === null || opts === void 0 ? void 0 : opts.sync) {
  6118. shouldForceSyncPlayback = true;
  6119. onFinish(() => (shouldForceSyncPlayback = false), { oneTimeCallback: true });
  6120. }
  6121. if (!initialized) {
  6122. initializeAnimation();
  6123. }
  6124. if (finished) {
  6125. resetAnimation();
  6126. finished = false;
  6127. }
  6128. if (shouldCalculateNumAnimations) {
  6129. numAnimationsRunning = childAnimations.length + 1;
  6130. shouldCalculateNumAnimations = false;
  6131. }
  6132. /**
  6133. * When one of these callbacks fires we
  6134. * need to clear the other's callback otherwise
  6135. * you can potentially get these callbacks
  6136. * firing multiple times if the play method
  6137. * is subsequently called.
  6138. * Example:
  6139. * animation.play() (onStop and onFinish callbacks are registered)
  6140. * animation.stop() (onStop callback is fired, onFinish is not)
  6141. * animation.play() (onStop and onFinish callbacks are registered)
  6142. * Total onStop callbacks: 1
  6143. * Total onFinish callbacks: 2
  6144. */
  6145. const onStopCallback = () => {
  6146. clearCallback(onFinishCallback, onFinishOneTimeCallbacks);
  6147. resolve();
  6148. };
  6149. const onFinishCallback = () => {
  6150. clearCallback(onStopCallback, onStopOneTimeCallbacks);
  6151. resolve();
  6152. };
  6153. /**
  6154. * The play method resolves when an animation
  6155. * run either finishes or is cancelled.
  6156. */
  6157. onFinish(onFinishCallback, { oneTimeCallback: true });
  6158. onStop(onStopCallback, { oneTimeCallback: true });
  6159. childAnimations.forEach((animation) => {
  6160. animation.play();
  6161. });
  6162. if (supportsWebAnimations) {
  6163. playWebAnimations();
  6164. }
  6165. else {
  6166. playCSSAnimations();
  6167. }
  6168. paused = false;
  6169. });
  6170. };
  6171. /**
  6172. * Stops an animation and resets it state to the
  6173. * beginning. This does not fire any onFinish
  6174. * callbacks because the animation did not finish.
  6175. * However, since the animation was not destroyed
  6176. * (i.e. the animation could run again) we do not
  6177. * clear the onFinish callbacks.
  6178. */
  6179. const stop = () => {
  6180. childAnimations.forEach((animation) => {
  6181. animation.stop();
  6182. });
  6183. if (initialized) {
  6184. cleanUpElements();
  6185. initialized = false;
  6186. }
  6187. resetFlags();
  6188. onStopOneTimeCallbacks.forEach((onStopCallback) => onStopCallback.c(0, ani));
  6189. onStopOneTimeCallbacks.length = 0;
  6190. };
  6191. const from = (property, value) => {
  6192. const firstFrame = _keyframes[0];
  6193. if (firstFrame !== undefined && (firstFrame.offset === undefined || firstFrame.offset === 0)) {
  6194. firstFrame[property] = value;
  6195. }
  6196. else {
  6197. _keyframes = [{ offset: 0, [property]: value }, ..._keyframes];
  6198. }
  6199. return ani;
  6200. };
  6201. const to = (property, value) => {
  6202. const lastFrame = _keyframes[_keyframes.length - 1];
  6203. if (lastFrame !== undefined && (lastFrame.offset === undefined || lastFrame.offset === 1)) {
  6204. lastFrame[property] = value;
  6205. }
  6206. else {
  6207. _keyframes = [..._keyframes, { offset: 1, [property]: value }];
  6208. }
  6209. return ani;
  6210. };
  6211. const fromTo = (property, fromValue, toValue) => {
  6212. return from(property, fromValue).to(property, toValue);
  6213. };
  6214. return (ani = {
  6215. parentAnimation,
  6216. elements,
  6217. childAnimations,
  6218. id,
  6219. animationFinish,
  6220. from,
  6221. to,
  6222. fromTo,
  6223. parent,
  6224. play,
  6225. pause,
  6226. stop,
  6227. destroy,
  6228. keyframes,
  6229. addAnimation,
  6230. addElement,
  6231. update,
  6232. fill,
  6233. direction,
  6234. iterations,
  6235. duration,
  6236. easing,
  6237. delay,
  6238. getWebAnimations,
  6239. getKeyframes,
  6240. getFill,
  6241. getDirection,
  6242. getDelay,
  6243. getIterations,
  6244. getEasing,
  6245. getDuration,
  6246. afterAddRead,
  6247. afterAddWrite,
  6248. afterClearStyles,
  6249. afterStyles,
  6250. afterRemoveClass,
  6251. afterAddClass,
  6252. beforeAddRead,
  6253. beforeAddWrite,
  6254. beforeClearStyles,
  6255. beforeStyles,
  6256. beforeRemoveClass,
  6257. beforeAddClass,
  6258. onFinish,
  6259. isRunning,
  6260. progressStart,
  6261. progressStep,
  6262. progressEnd,
  6263. });
  6264. };
  6265. /**
  6266. * iOS Action Sheet Enter Animation
  6267. */
  6268. const iosEnterAnimation$6 = (baseEl) => {
  6269. const baseAnimation = createAnimation();
  6270. const backdropAnimation = createAnimation();
  6271. const wrapperAnimation = createAnimation();
  6272. backdropAnimation
  6273. .addElement(baseEl.querySelector('ion-backdrop'))
  6274. .fromTo('opacity', 0.01, 'var(--backdrop-opacity)')
  6275. .beforeStyles({
  6276. 'pointer-events': 'none',
  6277. })
  6278. .afterClearStyles(['pointer-events']);
  6279. wrapperAnimation
  6280. .addElement(baseEl.querySelector('.action-sheet-wrapper'))
  6281. .fromTo('transform', 'translateY(100%)', 'translateY(0%)');
  6282. return baseAnimation
  6283. .addElement(baseEl)
  6284. .easing('cubic-bezier(.36,.66,.04,1)')
  6285. .duration(400)
  6286. .addAnimation([backdropAnimation, wrapperAnimation]);
  6287. };
  6288. /**
  6289. * iOS Action Sheet Leave Animation
  6290. */
  6291. const iosLeaveAnimation$6 = (baseEl) => {
  6292. const baseAnimation = createAnimation();
  6293. const backdropAnimation = createAnimation();
  6294. const wrapperAnimation = createAnimation();
  6295. backdropAnimation.addElement(baseEl.querySelector('ion-backdrop')).fromTo('opacity', 'var(--backdrop-opacity)', 0);
  6296. wrapperAnimation
  6297. .addElement(baseEl.querySelector('.action-sheet-wrapper'))
  6298. .fromTo('transform', 'translateY(0%)', 'translateY(100%)');
  6299. return baseAnimation
  6300. .addElement(baseEl)
  6301. .easing('cubic-bezier(.36,.66,.04,1)')
  6302. .duration(450)
  6303. .addAnimation([backdropAnimation, wrapperAnimation]);
  6304. };
  6305. /**
  6306. * MD Action Sheet Enter Animation
  6307. */
  6308. const mdEnterAnimation$5 = (baseEl) => {
  6309. const baseAnimation = createAnimation();
  6310. const backdropAnimation = createAnimation();
  6311. const wrapperAnimation = createAnimation();
  6312. backdropAnimation
  6313. .addElement(baseEl.querySelector('ion-backdrop'))
  6314. .fromTo('opacity', 0.01, 'var(--backdrop-opacity)')
  6315. .beforeStyles({
  6316. 'pointer-events': 'none',
  6317. })
  6318. .afterClearStyles(['pointer-events']);
  6319. wrapperAnimation
  6320. .addElement(baseEl.querySelector('.action-sheet-wrapper'))
  6321. .fromTo('transform', 'translateY(100%)', 'translateY(0%)');
  6322. return baseAnimation
  6323. .addElement(baseEl)
  6324. .easing('cubic-bezier(.36,.66,.04,1)')
  6325. .duration(400)
  6326. .addAnimation([backdropAnimation, wrapperAnimation]);
  6327. };
  6328. /**
  6329. * MD Action Sheet Leave Animation
  6330. */
  6331. const mdLeaveAnimation$5 = (baseEl) => {
  6332. const baseAnimation = createAnimation();
  6333. const backdropAnimation = createAnimation();
  6334. const wrapperAnimation = createAnimation();
  6335. backdropAnimation.addElement(baseEl.querySelector('ion-backdrop')).fromTo('opacity', 'var(--backdrop-opacity)', 0);
  6336. wrapperAnimation
  6337. .addElement(baseEl.querySelector('.action-sheet-wrapper'))
  6338. .fromTo('transform', 'translateY(0%)', 'translateY(100%)');
  6339. return baseAnimation
  6340. .addElement(baseEl)
  6341. .easing('cubic-bezier(.36,.66,.04,1)')
  6342. .duration(450)
  6343. .addAnimation([backdropAnimation, wrapperAnimation]);
  6344. };
  6345. 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)}}";
  6346. var IonActionSheetIosStyle0 = actionSheetIosCss;
  6347. 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}";
  6348. var IonActionSheetMdStyle0 = actionSheetMdCss;
  6349. /**
  6350. * @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
  6351. */
  6352. class ActionSheet {
  6353. constructor(hostRef) {
  6354. registerInstance(this, hostRef);
  6355. this.didPresent = createEvent(this, "ionActionSheetDidPresent", 7);
  6356. this.willPresent = createEvent(this, "ionActionSheetWillPresent", 7);
  6357. this.willDismiss = createEvent(this, "ionActionSheetWillDismiss", 7);
  6358. this.didDismiss = createEvent(this, "ionActionSheetDidDismiss", 7);
  6359. this.didPresentShorthand = createEvent(this, "didPresent", 7);
  6360. this.willPresentShorthand = createEvent(this, "willPresent", 7);
  6361. this.willDismissShorthand = createEvent(this, "willDismiss", 7);
  6362. this.didDismissShorthand = createEvent(this, "didDismiss", 7);
  6363. this.delegateController = createDelegateController(this);
  6364. this.lockController = createLockController();
  6365. this.triggerController = createTriggerController();
  6366. this.presented = false;
  6367. this.onBackdropTap = () => {
  6368. this.dismiss(undefined, BACKDROP);
  6369. };
  6370. this.dispatchCancelHandler = (ev) => {
  6371. const role = ev.detail.role;
  6372. if (isCancel(role)) {
  6373. const cancelButton = this.getButtons().find((b) => b.role === 'cancel');
  6374. this.callButtonHandler(cancelButton);
  6375. }
  6376. };
  6377. this.overlayIndex = undefined;
  6378. this.delegate = undefined;
  6379. this.hasController = false;
  6380. this.keyboardClose = true;
  6381. this.enterAnimation = undefined;
  6382. this.leaveAnimation = undefined;
  6383. this.buttons = [];
  6384. this.cssClass = undefined;
  6385. this.backdropDismiss = true;
  6386. this.header = undefined;
  6387. this.subHeader = undefined;
  6388. this.translucent = false;
  6389. this.animated = true;
  6390. this.htmlAttributes = undefined;
  6391. this.isOpen = false;
  6392. this.trigger = undefined;
  6393. }
  6394. onIsOpenChange(newValue, oldValue) {
  6395. if (newValue === true && oldValue === false) {
  6396. this.present();
  6397. }
  6398. else if (newValue === false && oldValue === true) {
  6399. this.dismiss();
  6400. }
  6401. }
  6402. triggerChanged() {
  6403. const { trigger, el, triggerController } = this;
  6404. if (trigger) {
  6405. triggerController.addClickListener(el, trigger);
  6406. }
  6407. }
  6408. /**
  6409. * Present the action sheet overlay after it has been created.
  6410. */
  6411. async present() {
  6412. const unlock = await this.lockController.lock();
  6413. await this.delegateController.attachViewToDom();
  6414. await present(this, 'actionSheetEnter', iosEnterAnimation$6, mdEnterAnimation$5);
  6415. unlock();
  6416. }
  6417. /**
  6418. * Dismiss the action sheet overlay after it has been presented.
  6419. *
  6420. * @param data Any data to emit in the dismiss events.
  6421. * @param role The role of the element that is dismissing the action sheet.
  6422. * This can be useful in a button handler for determining which button was
  6423. * clicked to dismiss the action sheet.
  6424. * Some examples include: ``"cancel"`, `"destructive"`, "selected"`, and `"backdrop"`.
  6425. *
  6426. * This is a no-op if the overlay has not been presented yet. If you want
  6427. * to remove an overlay from the DOM that was never presented, use the
  6428. * [remove](https://developer.mozilla.org/en-US/docs/Web/API/Element/remove) method.
  6429. */
  6430. async dismiss(data, role) {
  6431. const unlock = await this.lockController.lock();
  6432. const dismissed = await dismiss(this, data, role, 'actionSheetLeave', iosLeaveAnimation$6, mdLeaveAnimation$5);
  6433. if (dismissed) {
  6434. this.delegateController.removeViewFromDom();
  6435. }
  6436. unlock();
  6437. return dismissed;
  6438. }
  6439. /**
  6440. * Returns a promise that resolves when the action sheet did dismiss.
  6441. */
  6442. onDidDismiss() {
  6443. return eventMethod(this.el, 'ionActionSheetDidDismiss');
  6444. }
  6445. /**
  6446. * Returns a promise that resolves when the action sheet will dismiss.
  6447. *
  6448. */
  6449. onWillDismiss() {
  6450. return eventMethod(this.el, 'ionActionSheetWillDismiss');
  6451. }
  6452. async buttonClick(button) {
  6453. const role = button.role;
  6454. if (isCancel(role)) {
  6455. return this.dismiss(button.data, role);
  6456. }
  6457. const shouldDismiss = await this.callButtonHandler(button);
  6458. if (shouldDismiss) {
  6459. return this.dismiss(button.data, button.role);
  6460. }
  6461. return Promise.resolve();
  6462. }
  6463. async callButtonHandler(button) {
  6464. if (button) {
  6465. // a handler has been provided, execute it
  6466. // pass the handler the values from the inputs
  6467. const rtn = await safeCall(button.handler);
  6468. if (rtn === false) {
  6469. // if the return value of the handler is false then do not dismiss
  6470. return false;
  6471. }
  6472. }
  6473. return true;
  6474. }
  6475. getButtons() {
  6476. return this.buttons.map((b) => {
  6477. return typeof b === 'string' ? { text: b } : b;
  6478. });
  6479. }
  6480. connectedCallback() {
  6481. prepareOverlay(this.el);
  6482. this.triggerChanged();
  6483. }
  6484. disconnectedCallback() {
  6485. if (this.gesture) {
  6486. this.gesture.destroy();
  6487. this.gesture = undefined;
  6488. }
  6489. this.triggerController.removeClickListener();
  6490. }
  6491. componentWillLoad() {
  6492. var _a;
  6493. if (!((_a = this.htmlAttributes) === null || _a === void 0 ? void 0 : _a.id)) {
  6494. setOverlayId(this.el);
  6495. }
  6496. }
  6497. componentDidLoad() {
  6498. /**
  6499. * Only create gesture if:
  6500. * 1. A gesture does not already exist
  6501. * 2. App is running in iOS mode
  6502. * 3. A wrapper ref exists
  6503. * 4. A group ref exists
  6504. */
  6505. const { groupEl, wrapperEl } = this;
  6506. if (!this.gesture && getIonMode$1(this) === 'ios' && wrapperEl && groupEl) {
  6507. readTask(() => {
  6508. const isScrollable = groupEl.scrollHeight > groupEl.clientHeight;
  6509. if (!isScrollable) {
  6510. this.gesture = createButtonActiveGesture(wrapperEl, (refEl) => refEl.classList.contains('action-sheet-button'));
  6511. this.gesture.enable(true);
  6512. }
  6513. });
  6514. }
  6515. /**
  6516. * If action sheet was rendered with isOpen="true"
  6517. * then we should open action sheet immediately.
  6518. */
  6519. if (this.isOpen === true) {
  6520. raf(() => this.present());
  6521. }
  6522. /**
  6523. * When binding values in frameworks such as Angular
  6524. * it is possible for the value to be set after the Web Component
  6525. * initializes but before the value watcher is set up in Stencil.
  6526. * As a result, the watcher callback may not be fired.
  6527. * We work around this by manually calling the watcher
  6528. * callback when the component has loaded and the watcher
  6529. * is configured.
  6530. */
  6531. this.triggerChanged();
  6532. }
  6533. render() {
  6534. const { header, htmlAttributes, overlayIndex } = this;
  6535. const mode = getIonMode$1(this);
  6536. const allButtons = this.getButtons();
  6537. const cancelButton = allButtons.find((b) => b.role === 'cancel');
  6538. const buttons = allButtons.filter((b) => b.role !== 'cancel');
  6539. const headerID = `action-sheet-${overlayIndex}-header`;
  6540. return (hAsync(Host, Object.assign({ key: '7bbd202ca9e19727e7514abbe073687d982f80c3', role: "dialog", "aria-modal": "true", "aria-labelledby": header !== undefined ? headerID : null, tabindex: "-1" }, htmlAttributes, { style: {
  6541. zIndex: `${20000 + this.overlayIndex}`,
  6542. }, 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: {
  6543. 'action-sheet-title': true,
  6544. 'action-sheet-has-sub-title': this.subHeader !== undefined,
  6545. } }, 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" })));
  6546. }
  6547. get el() { return getElement(this); }
  6548. static get watchers() { return {
  6549. "isOpen": ["onIsOpenChange"],
  6550. "trigger": ["triggerChanged"]
  6551. }; }
  6552. static get style() { return {
  6553. ios: IonActionSheetIosStyle0,
  6554. md: IonActionSheetMdStyle0
  6555. }; }
  6556. static get cmpMeta() { return {
  6557. "$flags$": 34,
  6558. "$tagName$": "ion-action-sheet",
  6559. "$members$": {
  6560. "overlayIndex": [2, "overlay-index"],
  6561. "delegate": [16],
  6562. "hasController": [4, "has-controller"],
  6563. "keyboardClose": [4, "keyboard-close"],
  6564. "enterAnimation": [16],
  6565. "leaveAnimation": [16],
  6566. "buttons": [16],
  6567. "cssClass": [1, "css-class"],
  6568. "backdropDismiss": [4, "backdrop-dismiss"],
  6569. "header": [1],
  6570. "subHeader": [1, "sub-header"],
  6571. "translucent": [4],
  6572. "animated": [4],
  6573. "htmlAttributes": [16],
  6574. "isOpen": [4, "is-open"],
  6575. "trigger": [1],
  6576. "present": [64],
  6577. "dismiss": [64],
  6578. "onDidDismiss": [64],
  6579. "onWillDismiss": [64]
  6580. },
  6581. "$listeners$": undefined,
  6582. "$lazyBundleId$": "-",
  6583. "$attrsToReflect$": []
  6584. }; }
  6585. }
  6586. const buttonClass$3 = (button) => {
  6587. 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));
  6588. };
  6589. const ENABLE_HTML_CONTENT_DEFAULT = false;
  6590. /**
  6591. * Does a simple sanitization of all elements
  6592. * in an untrusted string
  6593. */
  6594. const sanitizeDOMString = (untrustedString) => {
  6595. try {
  6596. if (untrustedString instanceof IonicSafeString) {
  6597. return untrustedString.value;
  6598. }
  6599. if (!isSanitizerEnabled() || typeof untrustedString !== 'string' || untrustedString === '') {
  6600. return untrustedString;
  6601. }
  6602. /**
  6603. * onload is fired when appending to a document
  6604. * fragment in Chrome. If a string
  6605. * contains onload then we should not
  6606. * attempt to add this to the fragment.
  6607. */
  6608. if (untrustedString.includes('onload=')) {
  6609. return '';
  6610. }
  6611. /**
  6612. * Create a document fragment
  6613. * separate from the main DOM,
  6614. * create a div to do our work in
  6615. */
  6616. const documentFragment = document.createDocumentFragment();
  6617. const workingDiv = document.createElement('div');
  6618. documentFragment.appendChild(workingDiv);
  6619. workingDiv.innerHTML = untrustedString;
  6620. /**
  6621. * Remove any elements
  6622. * that are blocked
  6623. */
  6624. blockedTags.forEach((blockedTag) => {
  6625. const getElementsToRemove = documentFragment.querySelectorAll(blockedTag);
  6626. for (let elementIndex = getElementsToRemove.length - 1; elementIndex >= 0; elementIndex--) {
  6627. const element = getElementsToRemove[elementIndex];
  6628. if (element.parentNode) {
  6629. element.parentNode.removeChild(element);
  6630. }
  6631. else {
  6632. documentFragment.removeChild(element);
  6633. }
  6634. /**
  6635. * We still need to sanitize
  6636. * the children of this element
  6637. * as they are left behind
  6638. */
  6639. const childElements = getElementChildren(element);
  6640. /* eslint-disable-next-line */
  6641. for (let childIndex = 0; childIndex < childElements.length; childIndex++) {
  6642. sanitizeElement(childElements[childIndex]);
  6643. }
  6644. }
  6645. });
  6646. /**
  6647. * Go through remaining elements and remove
  6648. * non-allowed attribs
  6649. */
  6650. // IE does not support .children on document fragments, only .childNodes
  6651. const dfChildren = getElementChildren(documentFragment);
  6652. /* eslint-disable-next-line */
  6653. for (let childIndex = 0; childIndex < dfChildren.length; childIndex++) {
  6654. sanitizeElement(dfChildren[childIndex]);
  6655. }
  6656. // Append document fragment to div
  6657. const fragmentDiv = document.createElement('div');
  6658. fragmentDiv.appendChild(documentFragment);
  6659. // First child is always the div we did our work in
  6660. const getInnerDiv = fragmentDiv.querySelector('div');
  6661. return getInnerDiv !== null ? getInnerDiv.innerHTML : fragmentDiv.innerHTML;
  6662. }
  6663. catch (err) {
  6664. printIonError('sanitizeDOMString', err);
  6665. return '';
  6666. }
  6667. };
  6668. /**
  6669. * Clean up current element based on allowed attributes
  6670. * and then recursively dig down into any child elements to
  6671. * clean those up as well
  6672. */
  6673. // TODO(FW-2832): type (using Element triggers other type errors as well)
  6674. const sanitizeElement = (element) => {
  6675. // IE uses childNodes, so ignore nodes that are not elements
  6676. if (element.nodeType && element.nodeType !== 1) {
  6677. return;
  6678. }
  6679. /**
  6680. * If attributes is not a NamedNodeMap
  6681. * then we should remove the element entirely.
  6682. * This helps avoid DOM Clobbering attacks where
  6683. * attributes is overridden.
  6684. */
  6685. if (typeof NamedNodeMap !== 'undefined' && !(element.attributes instanceof NamedNodeMap)) {
  6686. element.remove();
  6687. return;
  6688. }
  6689. for (let i = element.attributes.length - 1; i >= 0; i--) {
  6690. const attribute = element.attributes.item(i);
  6691. const attributeName = attribute.name;
  6692. // remove non-allowed attribs
  6693. if (!allowedAttributes.includes(attributeName.toLowerCase())) {
  6694. element.removeAttribute(attributeName);
  6695. continue;
  6696. }
  6697. // clean up any allowed attribs
  6698. // that attempt to do any JS funny-business
  6699. const attributeValue = attribute.value;
  6700. /**
  6701. * We also need to check the property value
  6702. * as javascript: can allow special characters
  6703. * such as &Tab; and still be valid (i.e. java&Tab;script)
  6704. */
  6705. const propertyValue = element[attributeName];
  6706. /* eslint-disable */
  6707. if ((attributeValue != null && attributeValue.toLowerCase().includes('javascript:')) ||
  6708. (propertyValue != null && propertyValue.toLowerCase().includes('javascript:'))) {
  6709. element.removeAttribute(attributeName);
  6710. }
  6711. /* eslint-enable */
  6712. }
  6713. /**
  6714. * Sanitize any nested children
  6715. */
  6716. const childElements = getElementChildren(element);
  6717. /* eslint-disable-next-line */
  6718. for (let i = 0; i < childElements.length; i++) {
  6719. sanitizeElement(childElements[i]);
  6720. }
  6721. };
  6722. /**
  6723. * IE doesn't always support .children
  6724. * so we revert to .childNodes instead
  6725. */
  6726. // TODO(FW-2832): type
  6727. const getElementChildren = (el) => {
  6728. return el.children != null ? el.children : el.childNodes;
  6729. };
  6730. const isSanitizerEnabled = () => {
  6731. var _a;
  6732. const win = window;
  6733. const config = (_a = win === null || win === void 0 ? void 0 : win.Ionic) === null || _a === void 0 ? void 0 : _a.config;
  6734. if (config) {
  6735. if (config.get) {
  6736. return config.get('sanitizerEnabled', true);
  6737. }
  6738. else {
  6739. return config.sanitizerEnabled === true || config.sanitizerEnabled === undefined;
  6740. }
  6741. }
  6742. return true;
  6743. };
  6744. const allowedAttributes = ['class', 'id', 'href', 'src', 'name', 'slot'];
  6745. const blockedTags = ['script', 'style', 'iframe', 'meta', 'link', 'object', 'embed'];
  6746. class IonicSafeString {
  6747. constructor(value) {
  6748. this.value = value;
  6749. }
  6750. }
  6751. /**
  6752. * iOS Alert Enter Animation
  6753. */
  6754. const iosEnterAnimation$5 = (baseEl) => {
  6755. const baseAnimation = createAnimation();
  6756. const backdropAnimation = createAnimation();
  6757. const wrapperAnimation = createAnimation();
  6758. backdropAnimation
  6759. .addElement(baseEl.querySelector('ion-backdrop'))
  6760. .fromTo('opacity', 0.01, 'var(--backdrop-opacity)')
  6761. .beforeStyles({
  6762. 'pointer-events': 'none',
  6763. })
  6764. .afterClearStyles(['pointer-events']);
  6765. wrapperAnimation.addElement(baseEl.querySelector('.alert-wrapper')).keyframes([
  6766. { offset: 0, opacity: '0.01', transform: 'scale(1.1)' },
  6767. { offset: 1, opacity: '1', transform: 'scale(1)' },
  6768. ]);
  6769. return baseAnimation
  6770. .addElement(baseEl)
  6771. .easing('ease-in-out')
  6772. .duration(200)
  6773. .addAnimation([backdropAnimation, wrapperAnimation]);
  6774. };
  6775. /**
  6776. * iOS Alert Leave Animation
  6777. */
  6778. const iosLeaveAnimation$5 = (baseEl) => {
  6779. const baseAnimation = createAnimation();
  6780. const backdropAnimation = createAnimation();
  6781. const wrapperAnimation = createAnimation();
  6782. backdropAnimation.addElement(baseEl.querySelector('ion-backdrop')).fromTo('opacity', 'var(--backdrop-opacity)', 0);
  6783. wrapperAnimation.addElement(baseEl.querySelector('.alert-wrapper')).keyframes([
  6784. { offset: 0, opacity: 0.99, transform: 'scale(1)' },
  6785. { offset: 1, opacity: 0, transform: 'scale(0.9)' },
  6786. ]);
  6787. return baseAnimation
  6788. .addElement(baseEl)
  6789. .easing('ease-in-out')
  6790. .duration(200)
  6791. .addAnimation([backdropAnimation, wrapperAnimation]);
  6792. };
  6793. /**
  6794. * Md Alert Enter Animation
  6795. */
  6796. const mdEnterAnimation$4 = (baseEl) => {
  6797. const baseAnimation = createAnimation();
  6798. const backdropAnimation = createAnimation();
  6799. const wrapperAnimation = createAnimation();
  6800. backdropAnimation
  6801. .addElement(baseEl.querySelector('ion-backdrop'))
  6802. .fromTo('opacity', 0.01, 'var(--backdrop-opacity)')
  6803. .beforeStyles({
  6804. 'pointer-events': 'none',
  6805. })
  6806. .afterClearStyles(['pointer-events']);
  6807. wrapperAnimation.addElement(baseEl.querySelector('.alert-wrapper')).keyframes([
  6808. { offset: 0, opacity: '0.01', transform: 'scale(0.9)' },
  6809. { offset: 1, opacity: '1', transform: 'scale(1)' },
  6810. ]);
  6811. return baseAnimation
  6812. .addElement(baseEl)
  6813. .easing('ease-in-out')
  6814. .duration(150)
  6815. .addAnimation([backdropAnimation, wrapperAnimation]);
  6816. };
  6817. /**
  6818. * Md Alert Leave Animation
  6819. */
  6820. const mdLeaveAnimation$4 = (baseEl) => {
  6821. const baseAnimation = createAnimation();
  6822. const backdropAnimation = createAnimation();
  6823. const wrapperAnimation = createAnimation();
  6824. backdropAnimation.addElement(baseEl.querySelector('ion-backdrop')).fromTo('opacity', 'var(--backdrop-opacity)', 0);
  6825. wrapperAnimation.addElement(baseEl.querySelector('.alert-wrapper')).fromTo('opacity', 0.99, 0);
  6826. return baseAnimation
  6827. .addElement(baseEl)
  6828. .easing('ease-in-out')
  6829. .duration(150)
  6830. .addAnimation([backdropAnimation, wrapperAnimation]);
  6831. };
  6832. 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)}";
  6833. var IonAlertIosStyle0 = alertIosCss;
  6834. 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)}}";
  6835. var IonAlertMdStyle0 = alertMdCss;
  6836. // TODO(FW-2832): types
  6837. /**
  6838. * @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
  6839. */
  6840. class Alert {
  6841. constructor(hostRef) {
  6842. registerInstance(this, hostRef);
  6843. this.didPresent = createEvent(this, "ionAlertDidPresent", 7);
  6844. this.willPresent = createEvent(this, "ionAlertWillPresent", 7);
  6845. this.willDismiss = createEvent(this, "ionAlertWillDismiss", 7);
  6846. this.didDismiss = createEvent(this, "ionAlertDidDismiss", 7);
  6847. this.didPresentShorthand = createEvent(this, "didPresent", 7);
  6848. this.willPresentShorthand = createEvent(this, "willPresent", 7);
  6849. this.willDismissShorthand = createEvent(this, "willDismiss", 7);
  6850. this.didDismissShorthand = createEvent(this, "didDismiss", 7);
  6851. this.delegateController = createDelegateController(this);
  6852. this.lockController = createLockController();
  6853. this.triggerController = createTriggerController();
  6854. this.customHTMLEnabled = config.get('innerHTMLTemplatesEnabled', ENABLE_HTML_CONTENT_DEFAULT);
  6855. this.processedInputs = [];
  6856. this.processedButtons = [];
  6857. this.presented = false;
  6858. this.onBackdropTap = () => {
  6859. this.dismiss(undefined, BACKDROP);
  6860. };
  6861. this.dispatchCancelHandler = (ev) => {
  6862. const role = ev.detail.role;
  6863. if (isCancel(role)) {
  6864. const cancelButton = this.processedButtons.find((b) => b.role === 'cancel');
  6865. this.callButtonHandler(cancelButton);
  6866. }
  6867. };
  6868. this.overlayIndex = undefined;
  6869. this.delegate = undefined;
  6870. this.hasController = false;
  6871. this.keyboardClose = true;
  6872. this.enterAnimation = undefined;
  6873. this.leaveAnimation = undefined;
  6874. this.cssClass = undefined;
  6875. this.header = undefined;
  6876. this.subHeader = undefined;
  6877. this.message = undefined;
  6878. this.buttons = [];
  6879. this.inputs = [];
  6880. this.backdropDismiss = true;
  6881. this.translucent = false;
  6882. this.animated = true;
  6883. this.htmlAttributes = undefined;
  6884. this.isOpen = false;
  6885. this.trigger = undefined;
  6886. }
  6887. onIsOpenChange(newValue, oldValue) {
  6888. if (newValue === true && oldValue === false) {
  6889. this.present();
  6890. }
  6891. else if (newValue === false && oldValue === true) {
  6892. this.dismiss();
  6893. }
  6894. }
  6895. triggerChanged() {
  6896. const { trigger, el, triggerController } = this;
  6897. if (trigger) {
  6898. triggerController.addClickListener(el, trigger);
  6899. }
  6900. }
  6901. onKeydown(ev) {
  6902. var _a;
  6903. const inputTypes = new Set(this.processedInputs.map((i) => i.type));
  6904. /**
  6905. * Based on keyboard navigation requirements, the
  6906. * checkbox should not respond to the enter keydown event.
  6907. */
  6908. if (inputTypes.has('checkbox') && ev.key === 'Enter') {
  6909. ev.preventDefault();
  6910. return;
  6911. }
  6912. /**
  6913. * 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.
  6914. */
  6915. if (ev.target.classList.contains('alert-wrapper')) {
  6916. if (ev.key === 'Tab' && ev.shiftKey) {
  6917. ev.preventDefault();
  6918. const lastChildBtn = (_a = this.wrapperEl) === null || _a === void 0 ? void 0 : _a.querySelector('.alert-button:last-child');
  6919. lastChildBtn.focus();
  6920. return;
  6921. }
  6922. }
  6923. // The only inputs we want to navigate between using arrow keys are the radios
  6924. // ignore the keydown event if it is not on a radio button
  6925. if (!inputTypes.has('radio') ||
  6926. (ev.target && !this.el.contains(ev.target)) ||
  6927. ev.target.classList.contains('alert-button')) {
  6928. return;
  6929. }
  6930. // Get all radios inside of the radio group and then
  6931. // filter out disabled radios since we need to skip those
  6932. const query = this.el.querySelectorAll('.alert-radio');
  6933. const radios = Array.from(query).filter((radio) => !radio.disabled);
  6934. // The focused radio is the one that shares the same id as
  6935. // the event target
  6936. const index = radios.findIndex((radio) => radio.id === ev.target.id);
  6937. // We need to know what the next radio element should
  6938. // be in order to change the focus
  6939. let nextEl;
  6940. // If hitting arrow down or arrow right, move to the next radio
  6941. // If we're on the last radio, move to the first radio
  6942. if (['ArrowDown', 'ArrowRight'].includes(ev.key)) {
  6943. nextEl = index === radios.length - 1 ? radios[0] : radios[index + 1];
  6944. }
  6945. // If hitting arrow up or arrow left, move to the previous radio
  6946. // If we're on the first radio, move to the last radio
  6947. if (['ArrowUp', 'ArrowLeft'].includes(ev.key)) {
  6948. nextEl = index === 0 ? radios[radios.length - 1] : radios[index - 1];
  6949. }
  6950. if (nextEl && radios.includes(nextEl)) {
  6951. const nextProcessed = this.processedInputs.find((input) => input.id === (nextEl === null || nextEl === void 0 ? void 0 : nextEl.id));
  6952. if (nextProcessed) {
  6953. this.rbClick(nextProcessed);
  6954. nextEl.focus();
  6955. }
  6956. }
  6957. }
  6958. buttonsChanged() {
  6959. const buttons = this.buttons;
  6960. this.processedButtons = buttons.map((btn) => {
  6961. return typeof btn === 'string' ? { text: btn, role: btn.toLowerCase() === 'cancel' ? 'cancel' : undefined } : btn;
  6962. });
  6963. }
  6964. inputsChanged() {
  6965. const inputs = this.inputs;
  6966. // Get the first input that is not disabled and the checked one
  6967. // If an enabled checked input exists, set it to be the focusable input
  6968. // otherwise we default to focus the first input
  6969. // This will only be used when the input is type radio
  6970. const first = inputs.find((input) => !input.disabled);
  6971. const checked = inputs.find((input) => input.checked && !input.disabled);
  6972. const focusable = checked || first;
  6973. // An alert can be created with several different inputs. Radios,
  6974. // checkboxes and inputs are all accepted, but they cannot be mixed.
  6975. const inputTypes = new Set(inputs.map((i) => i.type));
  6976. if (inputTypes.has('checkbox') && inputTypes.has('radio')) {
  6977. printIonWarning(`[ion-alert] - Alert cannot mix input types: ${Array.from(inputTypes.values()).join('/')}. Please see alert docs for more info.`);
  6978. }
  6979. this.inputType = inputTypes.values().next().value;
  6980. this.processedInputs = inputs.map((i, index) => {
  6981. var _a;
  6982. return ({
  6983. type: i.type || 'text',
  6984. name: i.name || `${index}`,
  6985. placeholder: i.placeholder || '',
  6986. value: i.value,
  6987. label: i.label,
  6988. checked: !!i.checked,
  6989. disabled: !!i.disabled,
  6990. id: i.id || `alert-input-${this.overlayIndex}-${index}`,
  6991. handler: i.handler,
  6992. min: i.min,
  6993. max: i.max,
  6994. cssClass: (_a = i.cssClass) !== null && _a !== void 0 ? _a : '',
  6995. attributes: i.attributes || {},
  6996. tabindex: i.type === 'radio' && i !== focusable ? -1 : 0,
  6997. });
  6998. });
  6999. }
  7000. connectedCallback() {
  7001. prepareOverlay(this.el);
  7002. this.triggerChanged();
  7003. }
  7004. componentWillLoad() {
  7005. var _a;
  7006. if (!((_a = this.htmlAttributes) === null || _a === void 0 ? void 0 : _a.id)) {
  7007. setOverlayId(this.el);
  7008. }
  7009. this.inputsChanged();
  7010. this.buttonsChanged();
  7011. }
  7012. disconnectedCallback() {
  7013. this.triggerController.removeClickListener();
  7014. if (this.gesture) {
  7015. this.gesture.destroy();
  7016. this.gesture = undefined;
  7017. }
  7018. }
  7019. componentDidLoad() {
  7020. /**
  7021. * Only create gesture if:
  7022. * 1. A gesture does not already exist
  7023. * 2. App is running in iOS mode
  7024. * 3. A wrapper ref exists
  7025. */
  7026. if (!this.gesture && getIonMode$1(this) === 'ios' && this.wrapperEl) {
  7027. this.gesture = createButtonActiveGesture(this.wrapperEl, (refEl) => refEl.classList.contains('alert-button'));
  7028. this.gesture.enable(true);
  7029. }
  7030. /**
  7031. * If alert was rendered with isOpen="true"
  7032. * then we should open alert immediately.
  7033. */
  7034. if (this.isOpen === true) {
  7035. raf(() => this.present());
  7036. }
  7037. /**
  7038. * When binding values in frameworks such as Angular
  7039. * it is possible for the value to be set after the Web Component
  7040. * initializes but before the value watcher is set up in Stencil.
  7041. * As a result, the watcher callback may not be fired.
  7042. * We work around this by manually calling the watcher
  7043. * callback when the component has loaded and the watcher
  7044. * is configured.
  7045. */
  7046. this.triggerChanged();
  7047. }
  7048. /**
  7049. * Present the alert overlay after it has been created.
  7050. */
  7051. async present() {
  7052. const unlock = await this.lockController.lock();
  7053. await this.delegateController.attachViewToDom();
  7054. await present(this, 'alertEnter', iosEnterAnimation$5, mdEnterAnimation$4).then(() => {
  7055. var _a, _b;
  7056. /**
  7057. * Check if alert has only one button and no inputs.
  7058. * If so, then focus on the button. Otherwise, focus the alert wrapper.
  7059. * This will map to the default native alert behavior.
  7060. */
  7061. if (this.buttons.length === 1 && this.inputs.length === 0) {
  7062. const queryBtn = (_a = this.wrapperEl) === null || _a === void 0 ? void 0 : _a.querySelector('.alert-button');
  7063. queryBtn.focus();
  7064. }
  7065. else {
  7066. (_b = this.wrapperEl) === null || _b === void 0 ? void 0 : _b.focus();
  7067. }
  7068. });
  7069. unlock();
  7070. }
  7071. /**
  7072. * Dismiss the alert overlay after it has been presented.
  7073. *
  7074. * @param data Any data to emit in the dismiss events.
  7075. * @param role The role of the element that is dismissing the alert.
  7076. * This can be useful in a button handler for determining which button was
  7077. * clicked to dismiss the alert.
  7078. * Some examples include: ``"cancel"`, `"destructive"`, "selected"`, and `"backdrop"`.
  7079. *
  7080. * This is a no-op if the overlay has not been presented yet. If you want
  7081. * to remove an overlay from the DOM that was never presented, use the
  7082. * [remove](https://developer.mozilla.org/en-US/docs/Web/API/Element/remove) method.
  7083. */
  7084. async dismiss(data, role) {
  7085. const unlock = await this.lockController.lock();
  7086. const dismissed = await dismiss(this, data, role, 'alertLeave', iosLeaveAnimation$5, mdLeaveAnimation$4);
  7087. if (dismissed) {
  7088. this.delegateController.removeViewFromDom();
  7089. }
  7090. unlock();
  7091. return dismissed;
  7092. }
  7093. /**
  7094. * Returns a promise that resolves when the alert did dismiss.
  7095. */
  7096. onDidDismiss() {
  7097. return eventMethod(this.el, 'ionAlertDidDismiss');
  7098. }
  7099. /**
  7100. * Returns a promise that resolves when the alert will dismiss.
  7101. */
  7102. onWillDismiss() {
  7103. return eventMethod(this.el, 'ionAlertWillDismiss');
  7104. }
  7105. rbClick(selectedInput) {
  7106. for (const input of this.processedInputs) {
  7107. input.checked = input === selectedInput;
  7108. input.tabindex = input === selectedInput ? 0 : -1;
  7109. }
  7110. this.activeId = selectedInput.id;
  7111. safeCall(selectedInput.handler, selectedInput);
  7112. }
  7113. cbClick(selectedInput) {
  7114. selectedInput.checked = !selectedInput.checked;
  7115. safeCall(selectedInput.handler, selectedInput);
  7116. }
  7117. async buttonClick(button) {
  7118. const role = button.role;
  7119. const values = this.getValues();
  7120. if (isCancel(role)) {
  7121. return this.dismiss({ values }, role);
  7122. }
  7123. const returnData = await this.callButtonHandler(button, values);
  7124. if (returnData !== false) {
  7125. return this.dismiss(Object.assign({ values }, returnData), button.role);
  7126. }
  7127. return false;
  7128. }
  7129. async callButtonHandler(button, data) {
  7130. if (button === null || button === void 0 ? void 0 : button.handler) {
  7131. // a handler has been provided, execute it
  7132. // pass the handler the values from the inputs
  7133. const returnData = await safeCall(button.handler, data);
  7134. if (returnData === false) {
  7135. // if the return value of the handler is false then do not dismiss
  7136. return false;
  7137. }
  7138. if (typeof returnData === 'object') {
  7139. return returnData;
  7140. }
  7141. }
  7142. return {};
  7143. }
  7144. getValues() {
  7145. if (this.processedInputs.length === 0) {
  7146. // this is an alert without any options/inputs at all
  7147. return undefined;
  7148. }
  7149. if (this.inputType === 'radio') {
  7150. // this is an alert with radio buttons (single value select)
  7151. // return the one value which is checked, otherwise undefined
  7152. const checkedInput = this.processedInputs.find((i) => !!i.checked);
  7153. return checkedInput ? checkedInput.value : undefined;
  7154. }
  7155. if (this.inputType === 'checkbox') {
  7156. // this is an alert with checkboxes (multiple value select)
  7157. // return an array of all the checked values
  7158. return this.processedInputs.filter((i) => i.checked).map((i) => i.value);
  7159. }
  7160. // this is an alert with text inputs
  7161. // return an object of all the values with the input name as the key
  7162. const values = {};
  7163. this.processedInputs.forEach((i) => {
  7164. values[i.name] = i.value || '';
  7165. });
  7166. return values;
  7167. }
  7168. renderAlertInputs() {
  7169. switch (this.inputType) {
  7170. case 'checkbox':
  7171. return this.renderCheckbox();
  7172. case 'radio':
  7173. return this.renderRadio();
  7174. default:
  7175. return this.renderInput();
  7176. }
  7177. }
  7178. renderCheckbox() {
  7179. const inputs = this.processedInputs;
  7180. const mode = getIonMode$1(this);
  7181. if (inputs.length === 0) {
  7182. return null;
  7183. }
  7184. 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))))));
  7185. }
  7186. renderRadio() {
  7187. const inputs = this.processedInputs;
  7188. if (inputs.length === 0) {
  7189. return null;
  7190. }
  7191. 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)))))));
  7192. }
  7193. renderInput() {
  7194. const inputs = this.processedInputs;
  7195. if (inputs.length === 0) {
  7196. return null;
  7197. }
  7198. return (hAsync("div", { class: "alert-input-group" }, inputs.map((i) => {
  7199. var _a, _b, _c, _d;
  7200. if (i.type === 'textarea') {
  7201. 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) => {
  7202. var _a;
  7203. i.value = e.target.value;
  7204. if ((_a = i.attributes) === null || _a === void 0 ? void 0 : _a.onInput) {
  7205. i.attributes.onInput(e);
  7206. }
  7207. } }))));
  7208. }
  7209. else {
  7210. 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) => {
  7211. var _a;
  7212. i.value = e.target.value;
  7213. if ((_a = i.attributes) === null || _a === void 0 ? void 0 : _a.onInput) {
  7214. i.attributes.onInput(e);
  7215. }
  7216. } }))));
  7217. }
  7218. })));
  7219. }
  7220. renderAlertButtons() {
  7221. const buttons = this.processedButtons;
  7222. const mode = getIonMode$1(this);
  7223. const alertButtonGroupClass = {
  7224. 'alert-button-group': true,
  7225. 'alert-button-group-vertical': buttons.length > 2,
  7226. };
  7227. 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))))));
  7228. }
  7229. renderAlertMessage(msgId) {
  7230. const { customHTMLEnabled, message } = this;
  7231. if (customHTMLEnabled) {
  7232. return hAsync("div", { id: msgId, class: "alert-message", innerHTML: sanitizeDOMString(message) });
  7233. }
  7234. return (hAsync("div", { id: msgId, class: "alert-message" }, message));
  7235. }
  7236. render() {
  7237. const { overlayIndex, header, subHeader, message, htmlAttributes } = this;
  7238. const mode = getIonMode$1(this);
  7239. const hdrId = `alert-${overlayIndex}-hdr`;
  7240. const msgId = `alert-${overlayIndex}-msg`;
  7241. const subHdrId = `alert-${overlayIndex}-sub-hdr`;
  7242. const role = this.inputs.length > 0 || this.buttons.length > 0 ? 'alertdialog' : 'alert';
  7243. /**
  7244. * Use both the header and subHeader ids if they are defined.
  7245. * If only the header is defined, use the header id.
  7246. * If only the subHeader is defined, use the subHeader id.
  7247. * If neither are defined, do not set aria-labelledby.
  7248. */
  7249. const ariaLabelledBy = header && subHeader ? `${hdrId} ${subHdrId}` : header ? hdrId : subHeader ? subHdrId : null;
  7250. return (hAsync(Host, { key: 'f8ee04fe6a97a2585b302c8e1a9eea3b122e3479', tabindex: "-1", style: {
  7251. zIndex: `${20000 + overlayIndex}`,
  7252. }, 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" })));
  7253. }
  7254. get el() { return getElement(this); }
  7255. static get watchers() { return {
  7256. "isOpen": ["onIsOpenChange"],
  7257. "trigger": ["triggerChanged"],
  7258. "buttons": ["buttonsChanged"],
  7259. "inputs": ["inputsChanged"]
  7260. }; }
  7261. static get style() { return {
  7262. ios: IonAlertIosStyle0,
  7263. md: IonAlertMdStyle0
  7264. }; }
  7265. static get cmpMeta() { return {
  7266. "$flags$": 34,
  7267. "$tagName$": "ion-alert",
  7268. "$members$": {
  7269. "overlayIndex": [2, "overlay-index"],
  7270. "delegate": [16],
  7271. "hasController": [4, "has-controller"],
  7272. "keyboardClose": [4, "keyboard-close"],
  7273. "enterAnimation": [16],
  7274. "leaveAnimation": [16],
  7275. "cssClass": [1, "css-class"],
  7276. "header": [1],
  7277. "subHeader": [1, "sub-header"],
  7278. "message": [1],
  7279. "buttons": [16],
  7280. "inputs": [1040],
  7281. "backdropDismiss": [4, "backdrop-dismiss"],
  7282. "translucent": [4],
  7283. "animated": [4],
  7284. "htmlAttributes": [16],
  7285. "isOpen": [4, "is-open"],
  7286. "trigger": [1],
  7287. "present": [64],
  7288. "dismiss": [64],
  7289. "onDidDismiss": [64],
  7290. "onWillDismiss": [64]
  7291. },
  7292. "$listeners$": [[4, "keydown", "onKeydown"]],
  7293. "$lazyBundleId$": "-",
  7294. "$attrsToReflect$": []
  7295. }; }
  7296. }
  7297. const inputClass = (input) => {
  7298. var _a, _b, _c;
  7299. 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() : ''));
  7300. };
  7301. const buttonClass$2 = (button) => {
  7302. return Object.assign({ 'alert-button': true, 'ion-focusable': true, 'ion-activatable': true, [`alert-button-role-${button.role}`]: button.role !== undefined }, getClassMap(button.cssClass));
  7303. };
  7304. 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}";
  7305. var IonAppStyle0 = appCss;
  7306. class App {
  7307. constructor(hostRef) {
  7308. registerInstance(this, hostRef);
  7309. }
  7310. componentDidLoad() {
  7311. }
  7312. /**
  7313. * Used to set focus on an element that uses `ion-focusable`.
  7314. * Do not use this if focusing the element as a result of a keyboard
  7315. * event as the focus utility should handle this for us. This method
  7316. * should be used when we want to programmatically focus an element as
  7317. * a result of another user action. (Ex: We focus the first element
  7318. * inside of a popover when the user presents it, but the popover is not always
  7319. * presented as a result of keyboard action.)
  7320. */
  7321. async setFocus(elements) {
  7322. if (this.focusVisible) {
  7323. this.focusVisible.setFocus(elements);
  7324. }
  7325. }
  7326. render() {
  7327. const mode = getIonMode$1(this);
  7328. return (hAsync(Host, { key: '03aa892f986330078d112b1e8b010df98fa7e39e', class: {
  7329. [mode]: true,
  7330. 'ion-page': true,
  7331. 'force-statusbar-padding': config.getBoolean('_forceStatusbarPadding'),
  7332. } }));
  7333. }
  7334. get el() { return getElement(this); }
  7335. static get style() { return IonAppStyle0; }
  7336. static get cmpMeta() { return {
  7337. "$flags$": 0,
  7338. "$tagName$": "ion-app",
  7339. "$members$": {
  7340. "setFocus": [64]
  7341. },
  7342. "$listeners$": undefined,
  7343. "$lazyBundleId$": "-",
  7344. "$attrsToReflect$": []
  7345. }; }
  7346. }
  7347. 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}";
  7348. var IonAvatarIosStyle0 = avatarIosCss;
  7349. 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}";
  7350. var IonAvatarMdStyle0 = avatarMdCss;
  7351. class Avatar {
  7352. constructor(hostRef) {
  7353. registerInstance(this, hostRef);
  7354. }
  7355. render() {
  7356. return (hAsync(Host, { key: '998217066084f966bf5d356fed85bcbd451f675a', class: getIonMode$1(this) }, hAsync("slot", { key: '1a6f7c9d4dc6a875f86b5b3cda6d59cb39587f22' })));
  7357. }
  7358. static get style() { return {
  7359. ios: IonAvatarIosStyle0,
  7360. md: IonAvatarMdStyle0
  7361. }; }
  7362. static get cmpMeta() { return {
  7363. "$flags$": 41,
  7364. "$tagName$": "ion-avatar",
  7365. "$members$": undefined,
  7366. "$listeners$": undefined,
  7367. "$lazyBundleId$": "-",
  7368. "$attrsToReflect$": []
  7369. }; }
  7370. }
  7371. 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}}";
  7372. var IonBackButtonIosStyle0 = backButtonIosCss;
  7373. 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)}";
  7374. var IonBackButtonMdStyle0 = backButtonMdCss;
  7375. /**
  7376. * @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
  7377. *
  7378. * @part native - The native HTML button element that wraps all child elements.
  7379. * @part icon - The back button icon (uses ion-icon).
  7380. * @part text - The back button text.
  7381. */
  7382. class BackButton {
  7383. constructor(hostRef) {
  7384. registerInstance(this, hostRef);
  7385. this.inheritedAttributes = {};
  7386. this.onClick = async (ev) => {
  7387. const nav = this.el.closest('ion-nav');
  7388. ev.preventDefault();
  7389. if (nav && (await nav.canGoBack())) {
  7390. return nav.pop({ animationBuilder: this.routerAnimation, skipIfBusy: true });
  7391. }
  7392. return openURL(this.defaultHref, ev, 'back', this.routerAnimation);
  7393. };
  7394. this.color = undefined;
  7395. this.defaultHref = undefined;
  7396. this.disabled = false;
  7397. this.icon = undefined;
  7398. this.text = undefined;
  7399. this.type = 'button';
  7400. this.routerAnimation = undefined;
  7401. }
  7402. componentWillLoad() {
  7403. this.inheritedAttributes = inheritAriaAttributes(this.el);
  7404. if (this.defaultHref === undefined) {
  7405. this.defaultHref = config.get('backButtonDefaultHref');
  7406. }
  7407. }
  7408. get backButtonIcon() {
  7409. const icon = this.icon;
  7410. if (icon != null) {
  7411. // icon is set on the component or by the config
  7412. return icon;
  7413. }
  7414. if (getIonMode$1(this) === 'ios') {
  7415. // default ios back button icon
  7416. return config.get('backButtonIcon', chevronBack);
  7417. }
  7418. // default md back button icon
  7419. return config.get('backButtonIcon', arrowBackSharp);
  7420. }
  7421. get backButtonText() {
  7422. const defaultBackButtonText = getIonMode$1(this) === 'ios' ? 'Back' : null;
  7423. return this.text != null ? this.text : config.get('backButtonText', defaultBackButtonText);
  7424. }
  7425. get hasIconOnly() {
  7426. return this.backButtonIcon && !this.backButtonText;
  7427. }
  7428. get rippleType() {
  7429. // If the button only has an icon we use the unbounded
  7430. // "circular" ripple effect
  7431. if (this.hasIconOnly) {
  7432. return 'unbounded';
  7433. }
  7434. return 'bounded';
  7435. }
  7436. render() {
  7437. const { color, defaultHref, disabled, type, hasIconOnly, backButtonIcon, backButtonText, icon, inheritedAttributes, } = this;
  7438. const showBackButton = defaultHref !== undefined;
  7439. const mode = getIonMode$1(this);
  7440. const ariaLabel = inheritedAttributes['aria-label'] || backButtonText || 'back';
  7441. return (hAsync(Host, { key: '5466624a10f1ab56f5469e6dc07080303880f2fe', onClick: this.onClick, class: createColorClasses$1(color, {
  7442. [mode]: true,
  7443. button: true, // ion-buttons target .button
  7444. 'back-button-disabled': disabled,
  7445. 'back-button-has-icon-only': hasIconOnly,
  7446. 'in-toolbar': hostContext('ion-toolbar', this.el),
  7447. 'in-toolbar-color': hostContext('ion-toolbar[color]', this.el),
  7448. 'ion-activatable': true,
  7449. 'ion-focusable': true,
  7450. 'show-back-button': showBackButton,
  7451. }) }, 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 }))));
  7452. }
  7453. get el() { return getElement(this); }
  7454. static get style() { return {
  7455. ios: IonBackButtonIosStyle0,
  7456. md: IonBackButtonMdStyle0
  7457. }; }
  7458. static get cmpMeta() { return {
  7459. "$flags$": 41,
  7460. "$tagName$": "ion-back-button",
  7461. "$members$": {
  7462. "color": [513],
  7463. "defaultHref": [1025, "default-href"],
  7464. "disabled": [516],
  7465. "icon": [1],
  7466. "text": [1],
  7467. "type": [1],
  7468. "routerAnimation": [16]
  7469. },
  7470. "$listeners$": undefined,
  7471. "$lazyBundleId$": "-",
  7472. "$attrsToReflect$": [["color", "color"], ["disabled", "disabled"]]
  7473. }; }
  7474. }
  7475. 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)}";
  7476. var IonBackdropIosStyle0 = backdropIosCss;
  7477. 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)}";
  7478. var IonBackdropMdStyle0 = backdropMdCss;
  7479. class Backdrop {
  7480. constructor(hostRef) {
  7481. registerInstance(this, hostRef);
  7482. this.ionBackdropTap = createEvent(this, "ionBackdropTap", 7);
  7483. this.visible = true;
  7484. this.tappable = true;
  7485. this.stopPropagation = true;
  7486. }
  7487. onMouseDown(ev) {
  7488. this.emitTap(ev);
  7489. }
  7490. emitTap(ev) {
  7491. if (this.stopPropagation) {
  7492. ev.preventDefault();
  7493. ev.stopPropagation();
  7494. }
  7495. if (this.tappable) {
  7496. this.ionBackdropTap.emit();
  7497. }
  7498. }
  7499. render() {
  7500. const mode = getIonMode$1(this);
  7501. return (hAsync(Host, { key: '7abaf2c310aa399607451b14063265e8a5846938', "aria-hidden": "true", class: {
  7502. [mode]: true,
  7503. 'backdrop-hide': !this.visible,
  7504. 'backdrop-no-tappable': !this.tappable,
  7505. } }));
  7506. }
  7507. static get style() { return {
  7508. ios: IonBackdropIosStyle0,
  7509. md: IonBackdropMdStyle0
  7510. }; }
  7511. static get cmpMeta() { return {
  7512. "$flags$": 41,
  7513. "$tagName$": "ion-backdrop",
  7514. "$members$": {
  7515. "visible": [4],
  7516. "tappable": [4],
  7517. "stopPropagation": [4, "stop-propagation"]
  7518. },
  7519. "$listeners$": [[2, "click", "onMouseDown"]],
  7520. "$lazyBundleId$": "-",
  7521. "$attrsToReflect$": []
  7522. }; }
  7523. }
  7524. 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)}";
  7525. var IonBadgeIosStyle0 = badgeIosCss;
  7526. 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}";
  7527. var IonBadgeMdStyle0 = badgeMdCss;
  7528. /**
  7529. * @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
  7530. */
  7531. class Badge {
  7532. constructor(hostRef) {
  7533. registerInstance(this, hostRef);
  7534. this.color = undefined;
  7535. }
  7536. render() {
  7537. const mode = getIonMode$1(this);
  7538. return (hAsync(Host, { key: '1a2d39c5deec771a2f2196447627b62a7d4c8389', class: createColorClasses$1(this.color, {
  7539. [mode]: true,
  7540. }) }, hAsync("slot", { key: 'fc1b6587f1ed24715748eb6785e7fb7a57cdd5cd' })));
  7541. }
  7542. static get style() { return {
  7543. ios: IonBadgeIosStyle0,
  7544. md: IonBadgeMdStyle0
  7545. }; }
  7546. static get cmpMeta() { return {
  7547. "$flags$": 41,
  7548. "$tagName$": "ion-badge",
  7549. "$members$": {
  7550. "color": [513]
  7551. },
  7552. "$listeners$": undefined,
  7553. "$lazyBundleId$": "-",
  7554. "$attrsToReflect$": [["color", "color"]]
  7555. }; }
  7556. }
  7557. 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)}";
  7558. var IonBreadcrumbIosStyle0 = breadcrumbIosCss;
  7559. 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))}";
  7560. var IonBreadcrumbMdStyle0 = breadcrumbMdCss;
  7561. /**
  7562. * @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
  7563. *
  7564. * @part native - The native HTML anchor or div element that wraps all child elements.
  7565. * @part separator - The separator element between each breadcrumb.
  7566. * @part collapsed-indicator - The indicator element that shows the breadcrumbs are collapsed.
  7567. */
  7568. class Breadcrumb {
  7569. constructor(hostRef) {
  7570. registerInstance(this, hostRef);
  7571. this.ionFocus = createEvent(this, "ionFocus", 7);
  7572. this.ionBlur = createEvent(this, "ionBlur", 7);
  7573. this.collapsedClick = createEvent(this, "collapsedClick", 7);
  7574. this.inheritedAttributes = {};
  7575. this.onFocus = () => {
  7576. this.ionFocus.emit();
  7577. };
  7578. this.onBlur = () => {
  7579. this.ionBlur.emit();
  7580. };
  7581. this.collapsedIndicatorClick = () => {
  7582. this.collapsedClick.emit({ ionShadowTarget: this.collapsedRef });
  7583. };
  7584. this.collapsed = false;
  7585. this.last = undefined;
  7586. this.showCollapsedIndicator = undefined;
  7587. this.color = undefined;
  7588. this.active = false;
  7589. this.disabled = false;
  7590. this.download = undefined;
  7591. this.href = undefined;
  7592. this.rel = undefined;
  7593. this.separator = undefined;
  7594. this.target = undefined;
  7595. this.routerDirection = 'forward';
  7596. this.routerAnimation = undefined;
  7597. }
  7598. componentWillLoad() {
  7599. this.inheritedAttributes = inheritAriaAttributes(this.el);
  7600. }
  7601. isClickable() {
  7602. return this.href !== undefined;
  7603. }
  7604. render() {
  7605. const { color, active, collapsed, disabled, download, el, inheritedAttributes, last, routerAnimation, routerDirection, separator, showCollapsedIndicator, target, } = this;
  7606. const clickable = this.isClickable();
  7607. const TagType = this.href === undefined ? 'span' : 'a';
  7608. // Links can still be tabbed to when set to disabled if they have an href
  7609. // in order to truly disable them we can keep it as an anchor but remove the href
  7610. const href = disabled ? undefined : this.href;
  7611. const mode = getIonMode$1(this);
  7612. const attrs = TagType === 'span'
  7613. ? {}
  7614. : {
  7615. download,
  7616. href,
  7617. target,
  7618. };
  7619. // If the breadcrumb is collapsed, check if it contains the collapsed indicator
  7620. // to show the separator as long as it isn't also the last breadcrumb
  7621. // otherwise if not collapsed use the value in separator
  7622. const showSeparator = last ? false : collapsed ? (showCollapsedIndicator && !last ? true : false) : separator;
  7623. return (hAsync(Host, { key: '32ca61c83721dff52b5e97171ed449dce3584a55', onClick: (ev) => openURL(href, ev, routerDirection, routerAnimation), "aria-disabled": disabled ? 'true' : null, class: createColorClasses$1(color, {
  7624. [mode]: true,
  7625. 'breadcrumb-active': active,
  7626. 'breadcrumb-collapsed': collapsed,
  7627. 'breadcrumb-disabled': disabled,
  7628. 'in-breadcrumbs-color': hostContext('ion-breadcrumbs[color]', el),
  7629. 'in-toolbar': hostContext('ion-toolbar', this.el),
  7630. 'in-toolbar-color': hostContext('ion-toolbar[color]', this.el),
  7631. 'ion-activatable': clickable,
  7632. 'ion-focusable': clickable,
  7633. }) }, 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: {
  7634. 'breadcrumbs-collapsed-indicator': true,
  7635. } }, hAsync("ion-icon", { key: 'a849e1142a86f06f207cf11662fa2a560ab7fc6a', "aria-hidden": "true", icon: ellipsisHorizontal, lazy: false }))), showSeparator && (
  7636. /**
  7637. * Separators should not be announced by narrators.
  7638. * We add aria-hidden on the span so that this applies
  7639. * to any custom separators too.
  7640. */
  7641. 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, "/")))))));
  7642. }
  7643. get el() { return getElement(this); }
  7644. static get style() { return {
  7645. ios: IonBreadcrumbIosStyle0,
  7646. md: IonBreadcrumbMdStyle0
  7647. }; }
  7648. static get cmpMeta() { return {
  7649. "$flags$": 41,
  7650. "$tagName$": "ion-breadcrumb",
  7651. "$members$": {
  7652. "collapsed": [4],
  7653. "last": [4],
  7654. "showCollapsedIndicator": [4, "show-collapsed-indicator"],
  7655. "color": [1],
  7656. "active": [4],
  7657. "disabled": [4],
  7658. "download": [1],
  7659. "href": [1],
  7660. "rel": [1],
  7661. "separator": [4],
  7662. "target": [1],
  7663. "routerDirection": [1, "router-direction"],
  7664. "routerAnimation": [16]
  7665. },
  7666. "$listeners$": undefined,
  7667. "$lazyBundleId$": "-",
  7668. "$attrsToReflect$": []
  7669. }; }
  7670. }
  7671. 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}";
  7672. var IonBreadcrumbsIosStyle0 = breadcrumbsIosCss;
  7673. 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}";
  7674. var IonBreadcrumbsMdStyle0 = breadcrumbsMdCss;
  7675. /**
  7676. * @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
  7677. *
  7678. */
  7679. class Breadcrumbs {
  7680. constructor(hostRef) {
  7681. registerInstance(this, hostRef);
  7682. this.ionCollapsedClick = createEvent(this, "ionCollapsedClick", 7);
  7683. this.breadcrumbsInit = () => {
  7684. this.setBreadcrumbSeparator();
  7685. this.setMaxItems();
  7686. };
  7687. this.resetActiveBreadcrumb = () => {
  7688. const breadcrumbs = this.getBreadcrumbs();
  7689. // Only reset the active breadcrumb if we were the ones to change it
  7690. // otherwise use the one set on the component
  7691. const activeBreadcrumb = breadcrumbs.find((breadcrumb) => breadcrumb.active);
  7692. if (activeBreadcrumb && this.activeChanged) {
  7693. activeBreadcrumb.active = false;
  7694. }
  7695. };
  7696. this.setMaxItems = () => {
  7697. const { itemsAfterCollapse, itemsBeforeCollapse, maxItems } = this;
  7698. const breadcrumbs = this.getBreadcrumbs();
  7699. for (const breadcrumb of breadcrumbs) {
  7700. breadcrumb.showCollapsedIndicator = false;
  7701. breadcrumb.collapsed = false;
  7702. }
  7703. // If the number of breadcrumbs exceeds the maximum number of items
  7704. // that should show and the items before / after collapse do not
  7705. // exceed the maximum items then we need to collapse the breadcrumbs
  7706. const shouldCollapse = maxItems !== undefined && breadcrumbs.length > maxItems && itemsBeforeCollapse + itemsAfterCollapse <= maxItems;
  7707. if (shouldCollapse) {
  7708. // Show the collapsed indicator in the first breadcrumb that collapses
  7709. breadcrumbs.forEach((breadcrumb, index) => {
  7710. if (index === itemsBeforeCollapse) {
  7711. breadcrumb.showCollapsedIndicator = true;
  7712. }
  7713. // Collapse all breadcrumbs that have an index greater than or equal to
  7714. // the number before collapse and an index less than the total number
  7715. // of breadcrumbs minus the items that should show after the collapse
  7716. if (index >= itemsBeforeCollapse && index < breadcrumbs.length - itemsAfterCollapse) {
  7717. breadcrumb.collapsed = true;
  7718. }
  7719. });
  7720. }
  7721. };
  7722. this.setBreadcrumbSeparator = () => {
  7723. const { itemsAfterCollapse, itemsBeforeCollapse, maxItems } = this;
  7724. const breadcrumbs = this.getBreadcrumbs();
  7725. // Check if an active breadcrumb exists already
  7726. const active = breadcrumbs.find((breadcrumb) => breadcrumb.active);
  7727. // Set the separator on all but the last breadcrumb
  7728. for (const breadcrumb of breadcrumbs) {
  7729. // The only time the last breadcrumb changes is when
  7730. // itemsAfterCollapse is set to 0, in this case the
  7731. // last breadcrumb will be the collapsed indicator
  7732. const last = maxItems !== undefined && itemsAfterCollapse === 0
  7733. ? breadcrumb === breadcrumbs[itemsBeforeCollapse]
  7734. : breadcrumb === breadcrumbs[breadcrumbs.length - 1];
  7735. breadcrumb.last = last;
  7736. // If the breadcrumb has defined whether or not to show the
  7737. // separator then use that value, otherwise check if it's the
  7738. // last breadcrumb
  7739. const separator = breadcrumb.separator !== undefined ? breadcrumb.separator : last ? undefined : true;
  7740. breadcrumb.separator = separator;
  7741. // If there is not an active breadcrumb already
  7742. // set the last one to active
  7743. if (!active && last) {
  7744. breadcrumb.active = true;
  7745. this.activeChanged = true;
  7746. }
  7747. }
  7748. };
  7749. this.getBreadcrumbs = () => {
  7750. return Array.from(this.el.querySelectorAll('ion-breadcrumb'));
  7751. };
  7752. this.slotChanged = () => {
  7753. this.resetActiveBreadcrumb();
  7754. this.breadcrumbsInit();
  7755. };
  7756. this.collapsed = undefined;
  7757. this.activeChanged = undefined;
  7758. this.color = undefined;
  7759. this.maxItems = undefined;
  7760. this.itemsBeforeCollapse = 1;
  7761. this.itemsAfterCollapse = 1;
  7762. }
  7763. onCollapsedClick(ev) {
  7764. const breadcrumbs = this.getBreadcrumbs();
  7765. const collapsedBreadcrumbs = breadcrumbs.filter((breadcrumb) => breadcrumb.collapsed);
  7766. this.ionCollapsedClick.emit(Object.assign(Object.assign({}, ev.detail), { collapsedBreadcrumbs }));
  7767. }
  7768. maxItemsChanged() {
  7769. this.resetActiveBreadcrumb();
  7770. this.breadcrumbsInit();
  7771. }
  7772. componentWillLoad() {
  7773. this.breadcrumbsInit();
  7774. }
  7775. render() {
  7776. const { color, collapsed } = this;
  7777. const mode = getIonMode$1(this);
  7778. return (hAsync(Host, { key: 'fe64e9cdf597ede2db140bf5fa05a0359d82db57', class: createColorClasses$1(color, {
  7779. [mode]: true,
  7780. 'in-toolbar': hostContext('ion-toolbar', this.el),
  7781. 'in-toolbar-color': hostContext('ion-toolbar[color]', this.el),
  7782. 'breadcrumbs-collapsed': collapsed,
  7783. }) }, hAsync("slot", { key: 'a2c99b579e339055c50a613d5c6b61032f5ddffe', onSlotchange: this.slotChanged })));
  7784. }
  7785. get el() { return getElement(this); }
  7786. static get watchers() { return {
  7787. "maxItems": ["maxItemsChanged"],
  7788. "itemsBeforeCollapse": ["maxItemsChanged"],
  7789. "itemsAfterCollapse": ["maxItemsChanged"]
  7790. }; }
  7791. static get style() { return {
  7792. ios: IonBreadcrumbsIosStyle0,
  7793. md: IonBreadcrumbsMdStyle0
  7794. }; }
  7795. static get cmpMeta() { return {
  7796. "$flags$": 41,
  7797. "$tagName$": "ion-breadcrumbs",
  7798. "$members$": {
  7799. "color": [513],
  7800. "maxItems": [2, "max-items"],
  7801. "itemsBeforeCollapse": [2, "items-before-collapse"],
  7802. "itemsAfterCollapse": [2, "items-after-collapse"],
  7803. "collapsed": [32],
  7804. "activeChanged": [32]
  7805. },
  7806. "$listeners$": [[0, "collapsedClick", "onCollapsedClick"]],
  7807. "$lazyBundleId$": "-",
  7808. "$attrsToReflect$": [["color", "color"]]
  7809. }; }
  7810. }
  7811. 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))}";
  7812. var IonButtonIosStyle0 = buttonIosCss;
  7813. 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))}";
  7814. var IonButtonMdStyle0 = buttonMdCss;
  7815. /**
  7816. * @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
  7817. *
  7818. * @slot - Content is placed between the named slots if provided without a slot.
  7819. * @slot icon-only - Should be used on an icon in a button that has no text.
  7820. * @slot start - Content is placed to the left of the button text in LTR, and to the right in RTL.
  7821. * @slot end - Content is placed to the right of the button text in LTR, and to the left in RTL.
  7822. *
  7823. * @part native - The native HTML button or anchor element that wraps all child elements.
  7824. */
  7825. class Button {
  7826. constructor(hostRef) {
  7827. registerInstance(this, hostRef);
  7828. this.ionFocus = createEvent(this, "ionFocus", 7);
  7829. this.ionBlur = createEvent(this, "ionBlur", 7);
  7830. this.inItem = false;
  7831. this.inListHeader = false;
  7832. this.inToolbar = false;
  7833. this.formButtonEl = null;
  7834. this.formEl = null;
  7835. this.inheritedAttributes = {};
  7836. this.handleClick = (ev) => {
  7837. const { el } = this;
  7838. if (this.type === 'button') {
  7839. openURL(this.href, ev, this.routerDirection, this.routerAnimation);
  7840. }
  7841. else if (hasShadowDom(el)) {
  7842. this.submitForm(ev);
  7843. }
  7844. };
  7845. this.onFocus = () => {
  7846. this.ionFocus.emit();
  7847. };
  7848. this.onBlur = () => {
  7849. this.ionBlur.emit();
  7850. };
  7851. this.slotChanged = () => {
  7852. /**
  7853. * Ensures that the 'has-icon-only' class is properly added
  7854. * or removed from `ion-button` when manipulating the
  7855. * `icon-only` slot.
  7856. *
  7857. * Without this, the 'has-icon-only' class is only checked
  7858. * or added when `ion-button` component first renders.
  7859. */
  7860. this.isCircle = this.hasIconOnly;
  7861. };
  7862. this.isCircle = false;
  7863. this.color = undefined;
  7864. this.buttonType = 'button';
  7865. this.disabled = false;
  7866. this.expand = undefined;
  7867. this.fill = undefined;
  7868. this.routerDirection = 'forward';
  7869. this.routerAnimation = undefined;
  7870. this.download = undefined;
  7871. this.href = undefined;
  7872. this.rel = undefined;
  7873. this.shape = undefined;
  7874. this.size = undefined;
  7875. this.strong = false;
  7876. this.target = undefined;
  7877. this.type = 'button';
  7878. this.form = undefined;
  7879. }
  7880. disabledChanged() {
  7881. const { disabled } = this;
  7882. if (this.formButtonEl) {
  7883. this.formButtonEl.disabled = disabled;
  7884. }
  7885. }
  7886. /**
  7887. * This is responsible for rendering a hidden native
  7888. * button element inside the associated form. This allows
  7889. * users to submit a form by pressing "Enter" when a text
  7890. * field inside of the form is focused. The native button
  7891. * rendered inside of `ion-button` is in the Shadow DOM
  7892. * and therefore does not participate in form submission
  7893. * which is why the following code is necessary.
  7894. */
  7895. renderHiddenButton() {
  7896. const formEl = (this.formEl = this.findForm());
  7897. if (formEl) {
  7898. const { formButtonEl } = this;
  7899. /**
  7900. * If the form already has a rendered form button
  7901. * then do not append a new one again.
  7902. */
  7903. if (formButtonEl !== null && formEl.contains(formButtonEl)) {
  7904. return;
  7905. }
  7906. // Create a hidden native button inside of the form
  7907. const newFormButtonEl = (this.formButtonEl = document.createElement('button'));
  7908. newFormButtonEl.type = this.type;
  7909. newFormButtonEl.style.display = 'none';
  7910. // Only submit if the button is not disabled.
  7911. newFormButtonEl.disabled = this.disabled;
  7912. formEl.appendChild(newFormButtonEl);
  7913. }
  7914. }
  7915. componentWillLoad() {
  7916. this.inToolbar = !!this.el.closest('ion-buttons');
  7917. this.inListHeader = !!this.el.closest('ion-list-header');
  7918. this.inItem = !!this.el.closest('ion-item') || !!this.el.closest('ion-item-divider');
  7919. this.inheritedAttributes = inheritAriaAttributes(this.el);
  7920. }
  7921. get hasIconOnly() {
  7922. return !!this.el.querySelector('[slot="icon-only"]');
  7923. }
  7924. get rippleType() {
  7925. const hasClearFill = this.fill === undefined || this.fill === 'clear';
  7926. // If the button is in a toolbar, has a clear fill (which is the default)
  7927. // and only has an icon we use the unbounded "circular" ripple effect
  7928. if (hasClearFill && this.hasIconOnly && this.inToolbar) {
  7929. return 'unbounded';
  7930. }
  7931. return 'bounded';
  7932. }
  7933. /**
  7934. * Finds the form element based on the provided `form` selector
  7935. * or element reference provided.
  7936. */
  7937. findForm() {
  7938. const { form } = this;
  7939. if (form instanceof HTMLFormElement) {
  7940. return form;
  7941. }
  7942. if (typeof form === 'string') {
  7943. // Check if the string provided is a form id.
  7944. const el = document.getElementById(form);
  7945. if (el) {
  7946. if (el instanceof HTMLFormElement) {
  7947. return el;
  7948. }
  7949. else {
  7950. /**
  7951. * The developer specified a string for the form attribute, but the
  7952. * element with that id is not a form element.
  7953. */
  7954. printIonWarning(`[ion-button] - Form with selector: "#${form}" could not be found. Verify that the id is attached to a <form> element.`, this.el);
  7955. return null;
  7956. }
  7957. }
  7958. else {
  7959. /**
  7960. * The developer specified a string for the form attribute, but the
  7961. * element with that id could not be found in the DOM.
  7962. */
  7963. 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);
  7964. return null;
  7965. }
  7966. }
  7967. if (form !== undefined) {
  7968. /**
  7969. * The developer specified a HTMLElement for the form attribute,
  7970. * but the element is not a HTMLFormElement.
  7971. * This will also catch if the developer tries to pass in null
  7972. * as the form attribute.
  7973. */
  7974. printIonWarning(`[ion-button] - The provided "form" element is invalid. Verify that the form is a HTMLFormElement and rendered in the DOM.`, this.el);
  7975. return null;
  7976. }
  7977. /**
  7978. * If the form element is not set, the button may be inside
  7979. * of a form element. Query the closest form element to the button.
  7980. */
  7981. return this.el.closest('form');
  7982. }
  7983. submitForm(ev) {
  7984. // this button wants to specifically submit a form
  7985. // climb up the dom to see if we're in a <form>
  7986. // and if so, then use JS to submit it
  7987. if (this.formEl && this.formButtonEl) {
  7988. ev.preventDefault();
  7989. this.formButtonEl.click();
  7990. }
  7991. }
  7992. render() {
  7993. const mode = getIonMode$1(this);
  7994. const { buttonType, type, disabled, rel, target, size, href, color, expand, hasIconOnly, shape, strong, inheritedAttributes, } = this;
  7995. const finalSize = size === undefined && this.inItem ? 'small' : size;
  7996. const TagType = href === undefined ? 'button' : 'a';
  7997. const attrs = TagType === 'button'
  7998. ? { type }
  7999. : {
  8000. download: this.download,
  8001. href,
  8002. rel,
  8003. target,
  8004. };
  8005. let fill = this.fill;
  8006. /**
  8007. * We check both undefined and null to
  8008. * work around https://github.com/ionic-team/stencil/issues/3586.
  8009. */
  8010. if (fill == null) {
  8011. fill = this.inToolbar || this.inListHeader ? 'clear' : 'solid';
  8012. }
  8013. /**
  8014. * We call renderHiddenButton in the render function to account
  8015. * for any properties being set async. For example, changing the
  8016. * "type" prop from "button" to "submit" after the component has
  8017. * loaded would warrant the hidden button being added to the
  8018. * associated form.
  8019. */
  8020. {
  8021. type !== 'button' && this.renderHiddenButton();
  8022. }
  8023. return (hAsync(Host, { key: 'e213b0bb76b3f90f883b1a0ea463bb86c2df69c3', onClick: this.handleClick, "aria-disabled": disabled ? 'true' : null, class: createColorClasses$1(color, {
  8024. [mode]: true,
  8025. [buttonType]: true,
  8026. [`${buttonType}-${expand}`]: expand !== undefined,
  8027. [`${buttonType}-${finalSize}`]: finalSize !== undefined,
  8028. [`${buttonType}-${shape}`]: shape !== undefined,
  8029. [`${buttonType}-${fill}`]: true,
  8030. [`${buttonType}-strong`]: strong,
  8031. 'in-toolbar': hostContext('ion-toolbar', this.el),
  8032. 'in-toolbar-color': hostContext('ion-toolbar[color]', this.el),
  8033. 'in-buttons': hostContext('ion-buttons', this.el),
  8034. 'button-has-icon-only': hasIconOnly,
  8035. 'button-disabled': disabled,
  8036. 'ion-activatable': true,
  8037. 'ion-focusable': true,
  8038. }) }, 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 }))));
  8039. }
  8040. get el() { return getElement(this); }
  8041. static get watchers() { return {
  8042. "disabled": ["disabledChanged"]
  8043. }; }
  8044. static get style() { return {
  8045. ios: IonButtonIosStyle0,
  8046. md: IonButtonMdStyle0
  8047. }; }
  8048. static get cmpMeta() { return {
  8049. "$flags$": 41,
  8050. "$tagName$": "ion-button",
  8051. "$members$": {
  8052. "color": [513],
  8053. "buttonType": [1025, "button-type"],
  8054. "disabled": [516],
  8055. "expand": [513],
  8056. "fill": [1537],
  8057. "routerDirection": [1, "router-direction"],
  8058. "routerAnimation": [16],
  8059. "download": [1],
  8060. "href": [1],
  8061. "rel": [1],
  8062. "shape": [513],
  8063. "size": [513],
  8064. "strong": [4],
  8065. "target": [1],
  8066. "type": [1],
  8067. "form": [1],
  8068. "isCircle": [32]
  8069. },
  8070. "$listeners$": undefined,
  8071. "$lazyBundleId$": "-",
  8072. "$attrsToReflect$": [["color", "color"], ["disabled", "disabled"], ["expand", "expand"], ["fill", "fill"], ["shape", "shape"], ["size", "size"]]
  8073. }; }
  8074. }
  8075. 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}";
  8076. var IonButtonsIosStyle0 = buttonsIosCss;
  8077. 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}";
  8078. var IonButtonsMdStyle0 = buttonsMdCss;
  8079. class Buttons {
  8080. constructor(hostRef) {
  8081. registerInstance(this, hostRef);
  8082. this.collapse = false;
  8083. }
  8084. render() {
  8085. const mode = getIonMode$1(this);
  8086. return (hAsync(Host, { key: '58c1fc5eb867d0731c63549b1ccb3ec3bbbe6e1b', class: {
  8087. [mode]: true,
  8088. ['buttons-collapse']: this.collapse,
  8089. } }, hAsync("slot", { key: '0c8f95b9840c8fa0c4e50be84c5159620a3eb5c8' })));
  8090. }
  8091. static get style() { return {
  8092. ios: IonButtonsIosStyle0,
  8093. md: IonButtonsMdStyle0
  8094. }; }
  8095. static get cmpMeta() { return {
  8096. "$flags$": 38,
  8097. "$tagName$": "ion-buttons",
  8098. "$members$": {
  8099. "collapse": [4]
  8100. },
  8101. "$listeners$": undefined,
  8102. "$lazyBundleId$": "-",
  8103. "$attrsToReflect$": []
  8104. }; }
  8105. }
  8106. 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)}";
  8107. var IonCardIosStyle0 = cardIosCss;
  8108. 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)}";
  8109. var IonCardMdStyle0 = cardMdCss;
  8110. /**
  8111. * @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
  8112. *
  8113. * @part native - The native HTML button, anchor, or div element that wraps all child elements.
  8114. */
  8115. class Card {
  8116. constructor(hostRef) {
  8117. registerInstance(this, hostRef);
  8118. this.inheritedAriaAttributes = {};
  8119. this.color = undefined;
  8120. this.button = false;
  8121. this.type = 'button';
  8122. this.disabled = false;
  8123. this.download = undefined;
  8124. this.href = undefined;
  8125. this.rel = undefined;
  8126. this.routerDirection = 'forward';
  8127. this.routerAnimation = undefined;
  8128. this.target = undefined;
  8129. }
  8130. componentWillLoad() {
  8131. this.inheritedAriaAttributes = inheritAttributes$1(this.el, ['aria-label']);
  8132. }
  8133. isClickable() {
  8134. return this.href !== undefined || this.button;
  8135. }
  8136. renderCard(mode) {
  8137. const clickable = this.isClickable();
  8138. if (!clickable) {
  8139. return [hAsync("slot", null)];
  8140. }
  8141. const { href, routerAnimation, routerDirection, inheritedAriaAttributes } = this;
  8142. const TagType = clickable ? (href === undefined ? 'button' : 'a') : 'div';
  8143. const attrs = TagType === 'button'
  8144. ? { type: this.type }
  8145. : {
  8146. download: this.download,
  8147. href: this.href,
  8148. rel: this.rel,
  8149. target: this.target,
  8150. };
  8151. 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)));
  8152. }
  8153. render() {
  8154. const mode = getIonMode$1(this);
  8155. return (hAsync(Host, { key: '85e9b30bd81e79a0c7ac75cb3664bdcf9e4afc4d', class: createColorClasses$1(this.color, {
  8156. [mode]: true,
  8157. 'card-disabled': this.disabled,
  8158. 'ion-activatable': this.isClickable(),
  8159. }) }, this.renderCard(mode)));
  8160. }
  8161. get el() { return getElement(this); }
  8162. static get style() { return {
  8163. ios: IonCardIosStyle0,
  8164. md: IonCardMdStyle0
  8165. }; }
  8166. static get cmpMeta() { return {
  8167. "$flags$": 41,
  8168. "$tagName$": "ion-card",
  8169. "$members$": {
  8170. "color": [513],
  8171. "button": [4],
  8172. "type": [1],
  8173. "disabled": [4],
  8174. "download": [1],
  8175. "href": [1],
  8176. "rel": [1],
  8177. "routerDirection": [1, "router-direction"],
  8178. "routerAnimation": [16],
  8179. "target": [1]
  8180. },
  8181. "$listeners$": undefined,
  8182. "$lazyBundleId$": "-",
  8183. "$attrsToReflect$": [["color", "color"]]
  8184. }; }
  8185. }
  8186. 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}";
  8187. var IonCardContentIosStyle0 = cardContentIosCss;
  8188. 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}";
  8189. var IonCardContentMdStyle0 = cardContentMdCss;
  8190. /**
  8191. * @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
  8192. */
  8193. class CardContent {
  8194. constructor(hostRef) {
  8195. registerInstance(this, hostRef);
  8196. }
  8197. render() {
  8198. const mode = getIonMode$1(this);
  8199. return (hAsync(Host, { key: 'd98e4d1fc6ad3237549f9bc17e4c67ec5059b1b3', class: {
  8200. [mode]: true,
  8201. // Used internally for styling
  8202. [`card-content-${mode}`]: true,
  8203. } }));
  8204. }
  8205. static get style() { return {
  8206. ios: IonCardContentIosStyle0,
  8207. md: IonCardContentMdStyle0
  8208. }; }
  8209. static get cmpMeta() { return {
  8210. "$flags$": 32,
  8211. "$tagName$": "ion-card-content",
  8212. "$members$": undefined,
  8213. "$listeners$": undefined,
  8214. "$lazyBundleId$": "-",
  8215. "$attrsToReflect$": []
  8216. }; }
  8217. }
  8218. 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)}}";
  8219. var IonCardHeaderIosStyle0 = cardHeaderIosCss;
  8220. 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}";
  8221. var IonCardHeaderMdStyle0 = cardHeaderMdCss;
  8222. /**
  8223. * @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
  8224. */
  8225. class CardHeader {
  8226. constructor(hostRef) {
  8227. registerInstance(this, hostRef);
  8228. this.color = undefined;
  8229. this.translucent = false;
  8230. }
  8231. render() {
  8232. const mode = getIonMode$1(this);
  8233. return (hAsync(Host, { key: '64246b81931203a64d553c788cd736f41e23f37b', class: createColorClasses$1(this.color, {
  8234. 'card-header-translucent': this.translucent,
  8235. 'ion-inherit-color': true,
  8236. [mode]: true,
  8237. }) }, hAsync("slot", { key: 'af2da2dfe266889afeb57fac25c6a730558dbba4' })));
  8238. }
  8239. static get style() { return {
  8240. ios: IonCardHeaderIosStyle0,
  8241. md: IonCardHeaderMdStyle0
  8242. }; }
  8243. static get cmpMeta() { return {
  8244. "$flags$": 41,
  8245. "$tagName$": "ion-card-header",
  8246. "$members$": {
  8247. "color": [513],
  8248. "translucent": [4]
  8249. },
  8250. "$listeners$": undefined,
  8251. "$lazyBundleId$": "-",
  8252. "$attrsToReflect$": [["color", "color"]]
  8253. }; }
  8254. }
  8255. 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}";
  8256. var IonCardSubtitleIosStyle0 = cardSubtitleIosCss;
  8257. 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}";
  8258. var IonCardSubtitleMdStyle0 = cardSubtitleMdCss;
  8259. /**
  8260. * @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
  8261. */
  8262. class CardSubtitle {
  8263. constructor(hostRef) {
  8264. registerInstance(this, hostRef);
  8265. this.color = undefined;
  8266. }
  8267. render() {
  8268. const mode = getIonMode$1(this);
  8269. return (hAsync(Host, { key: '84d820a19d9074f9c8bc61ccba1ca40062a60b73', role: "heading", "aria-level": "3", class: createColorClasses$1(this.color, {
  8270. 'ion-inherit-color': true,
  8271. [mode]: true,
  8272. }) }, hAsync("slot", { key: 'e4d07d395a1f4469a90847636083101b32b776a1' })));
  8273. }
  8274. static get style() { return {
  8275. ios: IonCardSubtitleIosStyle0,
  8276. md: IonCardSubtitleMdStyle0
  8277. }; }
  8278. static get cmpMeta() { return {
  8279. "$flags$": 41,
  8280. "$tagName$": "ion-card-subtitle",
  8281. "$members$": {
  8282. "color": [513]
  8283. },
  8284. "$listeners$": undefined,
  8285. "$lazyBundleId$": "-",
  8286. "$attrsToReflect$": [["color", "color"]]
  8287. }; }
  8288. }
  8289. 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}";
  8290. var IonCardTitleIosStyle0 = cardTitleIosCss;
  8291. 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}";
  8292. var IonCardTitleMdStyle0 = cardTitleMdCss;
  8293. /**
  8294. * @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
  8295. */
  8296. class CardTitle {
  8297. constructor(hostRef) {
  8298. registerInstance(this, hostRef);
  8299. this.color = undefined;
  8300. }
  8301. render() {
  8302. const mode = getIonMode$1(this);
  8303. return (hAsync(Host, { key: 'fca001a86396e83718d5211cd71912fdf40dea2f', role: "heading", "aria-level": "2", class: createColorClasses$1(this.color, {
  8304. 'ion-inherit-color': true,
  8305. [mode]: true,
  8306. }) }, hAsync("slot", { key: '2ba416aed488b2ff462fa75fb3b70373a6dd7da6' })));
  8307. }
  8308. static get style() { return {
  8309. ios: IonCardTitleIosStyle0,
  8310. md: IonCardTitleMdStyle0
  8311. }; }
  8312. static get cmpMeta() { return {
  8313. "$flags$": 41,
  8314. "$tagName$": "ion-card-title",
  8315. "$members$": {
  8316. "color": [513]
  8317. },
  8318. "$listeners$": undefined,
  8319. "$lazyBundleId$": "-",
  8320. "$attrsToReflect$": [["color", "color"]]
  8321. }; }
  8322. }
  8323. 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}";
  8324. var IonCheckboxIosStyle0 = checkboxIosCss;
  8325. 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}";
  8326. var IonCheckboxMdStyle0 = checkboxMdCss;
  8327. /**
  8328. * @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
  8329. *
  8330. * @slot - The label text to associate with the checkbox. Use the "labelPlacement" property to control where the label is placed relative to the checkbox.
  8331. *
  8332. * @part container - The container for the checkbox mark.
  8333. * @part label - The label text describing the checkbox.
  8334. * @part mark - The checkmark used to indicate the checked state.
  8335. * @part supporting-text - Supporting text displayed beneath the checkbox label.
  8336. * @part helper-text - Supporting text displayed beneath the checkbox label when the checkbox is valid.
  8337. * @part error-text - Supporting text displayed beneath the checkbox label when the checkbox is invalid and touched.
  8338. */
  8339. class Checkbox {
  8340. constructor(hostRef) {
  8341. registerInstance(this, hostRef);
  8342. this.ionChange = createEvent(this, "ionChange", 7);
  8343. this.ionFocus = createEvent(this, "ionFocus", 7);
  8344. this.ionBlur = createEvent(this, "ionBlur", 7);
  8345. this.inputId = `ion-cb-${checkboxIds++}`;
  8346. this.inputLabelId = `${this.inputId}-lbl`;
  8347. this.helperTextId = `${this.inputId}-helper-text`;
  8348. this.errorTextId = `${this.inputId}-error-text`;
  8349. this.inheritedAttributes = {};
  8350. /**
  8351. * Sets the checked property and emits
  8352. * the ionChange event. Use this to update the
  8353. * checked state in response to user-generated
  8354. * actions such as a click.
  8355. */
  8356. this.setChecked = (state) => {
  8357. const isChecked = (this.checked = state);
  8358. this.ionChange.emit({
  8359. checked: isChecked,
  8360. value: this.value,
  8361. });
  8362. };
  8363. this.toggleChecked = (ev) => {
  8364. ev.preventDefault();
  8365. this.setFocus();
  8366. this.setChecked(!this.checked);
  8367. this.indeterminate = false;
  8368. };
  8369. this.onFocus = () => {
  8370. this.ionFocus.emit();
  8371. };
  8372. this.onBlur = () => {
  8373. this.ionBlur.emit();
  8374. };
  8375. this.onKeyDown = (ev) => {
  8376. if (ev.key === ' ') {
  8377. ev.preventDefault();
  8378. if (!this.disabled) {
  8379. this.toggleChecked(ev);
  8380. }
  8381. }
  8382. };
  8383. this.onClick = (ev) => {
  8384. if (this.disabled) {
  8385. return;
  8386. }
  8387. this.toggleChecked(ev);
  8388. };
  8389. /**
  8390. * Stops propagation when the display label is clicked,
  8391. * otherwise, two clicks will be triggered.
  8392. */
  8393. this.onDivLabelClick = (ev) => {
  8394. ev.stopPropagation();
  8395. };
  8396. this.color = undefined;
  8397. this.name = this.inputId;
  8398. this.checked = false;
  8399. this.indeterminate = false;
  8400. this.disabled = false;
  8401. this.errorText = undefined;
  8402. this.helperText = undefined;
  8403. this.value = 'on';
  8404. this.labelPlacement = 'start';
  8405. this.justify = undefined;
  8406. this.alignment = undefined;
  8407. this.required = false;
  8408. }
  8409. componentWillLoad() {
  8410. this.inheritedAttributes = Object.assign({}, inheritAriaAttributes(this.el));
  8411. }
  8412. /** @internal */
  8413. async setFocus() {
  8414. if (this.focusEl) {
  8415. this.focusEl.focus();
  8416. }
  8417. }
  8418. getHintTextID() {
  8419. const { el, helperText, errorText, helperTextId, errorTextId } = this;
  8420. if (el.classList.contains('ion-touched') && el.classList.contains('ion-invalid') && errorText) {
  8421. return errorTextId;
  8422. }
  8423. if (helperText) {
  8424. return helperTextId;
  8425. }
  8426. return undefined;
  8427. }
  8428. /**
  8429. * Responsible for rendering helper text and error text.
  8430. * This element should only be rendered if hint text is set.
  8431. */
  8432. renderHintText() {
  8433. const { helperText, errorText, helperTextId, errorTextId } = this;
  8434. /**
  8435. * undefined and empty string values should
  8436. * be treated as not having helper/error text.
  8437. */
  8438. const hasHintText = !!helperText || !!errorText;
  8439. if (!hasHintText) {
  8440. return;
  8441. }
  8442. 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)));
  8443. }
  8444. render() {
  8445. const { color, checked, disabled, el, getSVGPath, indeterminate, inheritedAttributes, inputId, justify, labelPlacement, name, value, alignment, required, } = this;
  8446. const mode = getIonMode$1(this);
  8447. const path = getSVGPath(mode, indeterminate);
  8448. const hasLabelContent = el.textContent !== '';
  8449. renderHiddenInput(true, el, name, checked ? value : '', disabled);
  8450. // The host element must have a checkbox role to ensure proper VoiceOver
  8451. // support in Safari for accessibility.
  8452. 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, {
  8453. [mode]: true,
  8454. 'in-item': hostContext('ion-item', el),
  8455. 'checkbox-checked': checked,
  8456. 'checkbox-disabled': disabled,
  8457. 'checkbox-indeterminate': indeterminate,
  8458. interactive: true,
  8459. [`checkbox-justify-${justify}`]: justify !== undefined,
  8460. [`checkbox-alignment-${alignment}`]: alignment !== undefined,
  8461. [`checkbox-label-placement-${labelPlacement}`]: true,
  8462. }), 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: {
  8463. 'label-text-wrapper': true,
  8464. 'label-text-wrapper-hidden': !hasLabelContent,
  8465. }, 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)))));
  8466. }
  8467. getSVGPath(mode, indeterminate) {
  8468. 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" }));
  8469. if (mode === 'md') {
  8470. 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" }));
  8471. }
  8472. return path;
  8473. }
  8474. get el() { return getElement(this); }
  8475. static get style() { return {
  8476. ios: IonCheckboxIosStyle0,
  8477. md: IonCheckboxMdStyle0
  8478. }; }
  8479. static get cmpMeta() { return {
  8480. "$flags$": 41,
  8481. "$tagName$": "ion-checkbox",
  8482. "$members$": {
  8483. "color": [513],
  8484. "name": [1],
  8485. "checked": [1028],
  8486. "indeterminate": [1028],
  8487. "disabled": [4],
  8488. "errorText": [1, "error-text"],
  8489. "helperText": [1, "helper-text"],
  8490. "value": [8],
  8491. "labelPlacement": [1, "label-placement"],
  8492. "justify": [1],
  8493. "alignment": [1],
  8494. "required": [4],
  8495. "setFocus": [64]
  8496. },
  8497. "$listeners$": undefined,
  8498. "$lazyBundleId$": "-",
  8499. "$attrsToReflect$": [["color", "color"]]
  8500. }; }
  8501. }
  8502. let checkboxIds = 0;
  8503. 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)}";
  8504. var IonChipIosStyle0 = chipIosCss;
  8505. 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}";
  8506. var IonChipMdStyle0 = chipMdCss;
  8507. /**
  8508. * @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
  8509. */
  8510. class Chip {
  8511. constructor(hostRef) {
  8512. registerInstance(this, hostRef);
  8513. this.color = undefined;
  8514. this.outline = false;
  8515. this.disabled = false;
  8516. }
  8517. render() {
  8518. const mode = getIonMode$1(this);
  8519. return (hAsync(Host, { key: 'fa2e9a4837ef87a17ef10f388e8caa7f604d9145', "aria-disabled": this.disabled ? 'true' : null, class: createColorClasses$1(this.color, {
  8520. [mode]: true,
  8521. 'chip-outline': this.outline,
  8522. 'chip-disabled': this.disabled,
  8523. 'ion-activatable': true,
  8524. }) }, hAsync("slot", { key: '3793fbd9d915cef7241fb101e2bc64c08b9ba482' }), mode === 'md' && hAsync("ion-ripple-effect", { key: 'd3b95b53918611dec095a50f2aaaab65617947a4' })));
  8525. }
  8526. static get style() { return {
  8527. ios: IonChipIosStyle0,
  8528. md: IonChipMdStyle0
  8529. }; }
  8530. static get cmpMeta() { return {
  8531. "$flags$": 41,
  8532. "$tagName$": "ion-chip",
  8533. "$members$": {
  8534. "color": [513],
  8535. "outline": [4],
  8536. "disabled": [4]
  8537. },
  8538. "$listeners$": undefined,
  8539. "$lazyBundleId$": "-",
  8540. "$attrsToReflect$": [["color", "color"]]
  8541. }; }
  8542. }
  8543. const SIZE_TO_MEDIA = {
  8544. xs: '(min-width: 0px)',
  8545. sm: '(min-width: 576px)',
  8546. md: '(min-width: 768px)',
  8547. lg: '(min-width: 992px)',
  8548. xl: '(min-width: 1200px)',
  8549. };
  8550. // Check if the window matches the media query
  8551. // at the breakpoint passed
  8552. // e.g. matchBreakpoint('sm') => true if screen width exceeds 576px
  8553. const matchBreakpoint = (breakpoint) => {
  8554. if (breakpoint === undefined || breakpoint === '') {
  8555. return true;
  8556. }
  8557. if (window.matchMedia) {
  8558. const mediaQuery = SIZE_TO_MEDIA[breakpoint];
  8559. return window.matchMedia(mediaQuery).matches;
  8560. }
  8561. return false;
  8562. };
  8563. 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))}}";
  8564. var IonColStyle0 = colCss;
  8565. const win = typeof window !== 'undefined' ? window : undefined;
  8566. // eslint-disable-next-line @typescript-eslint/prefer-optional-chain
  8567. const SUPPORTS_VARS = win && !!(win.CSS && win.CSS.supports && win.CSS.supports('--a: 0'));
  8568. const BREAKPOINTS = ['', 'xs', 'sm', 'md', 'lg', 'xl'];
  8569. class Col {
  8570. constructor(hostRef) {
  8571. registerInstance(this, hostRef);
  8572. this.offset = undefined;
  8573. this.offsetXs = undefined;
  8574. this.offsetSm = undefined;
  8575. this.offsetMd = undefined;
  8576. this.offsetLg = undefined;
  8577. this.offsetXl = undefined;
  8578. this.pull = undefined;
  8579. this.pullXs = undefined;
  8580. this.pullSm = undefined;
  8581. this.pullMd = undefined;
  8582. this.pullLg = undefined;
  8583. this.pullXl = undefined;
  8584. this.push = undefined;
  8585. this.pushXs = undefined;
  8586. this.pushSm = undefined;
  8587. this.pushMd = undefined;
  8588. this.pushLg = undefined;
  8589. this.pushXl = undefined;
  8590. this.size = undefined;
  8591. this.sizeXs = undefined;
  8592. this.sizeSm = undefined;
  8593. this.sizeMd = undefined;
  8594. this.sizeLg = undefined;
  8595. this.sizeXl = undefined;
  8596. }
  8597. onResize() {
  8598. }
  8599. // Loop through all of the breakpoints to see if the media query
  8600. // matches and grab the column value from the relevant prop if so
  8601. getColumns(property) {
  8602. let matched;
  8603. for (const breakpoint of BREAKPOINTS) {
  8604. const matches = matchBreakpoint(breakpoint);
  8605. // Grab the value of the property, if it exists and our
  8606. // media query matches we return the value
  8607. const columns = this[property + breakpoint.charAt(0).toUpperCase() + breakpoint.slice(1)];
  8608. if (matches && columns !== undefined) {
  8609. matched = columns;
  8610. }
  8611. }
  8612. // Return the last matched columns since the breakpoints
  8613. // increase in size and we want to return the largest match
  8614. return matched;
  8615. }
  8616. calculateSize() {
  8617. const columns = this.getColumns('size');
  8618. // If size wasn't set for any breakpoint
  8619. // or if the user set the size without a value
  8620. // it means we need to stick with the default and return
  8621. // e.g. <ion-col size-md>
  8622. if (!columns || columns === '') {
  8623. return;
  8624. }
  8625. // If the size is set to auto then don't calculate a size
  8626. const colSize = columns === 'auto'
  8627. ? 'auto'
  8628. : // If CSS supports variables we should use the grid columns var
  8629. SUPPORTS_VARS
  8630. ? `calc(calc(${columns} / var(--ion-grid-columns, 12)) * 100%)`
  8631. : // Convert the columns to a percentage by dividing by the total number
  8632. // of columns (12) and then multiplying by 100
  8633. (columns / 12) * 100 + '%';
  8634. return {
  8635. flex: `0 0 ${colSize}`,
  8636. width: `${colSize}`,
  8637. 'max-width': `${colSize}`,
  8638. };
  8639. }
  8640. // Called by push, pull, and offset since they use the same calculations
  8641. calculatePosition(property, modifier) {
  8642. const columns = this.getColumns(property);
  8643. if (!columns) {
  8644. return;
  8645. }
  8646. // If the number of columns passed are greater than 0 and less than
  8647. // 12 we can position the column, else default to auto
  8648. const amount = SUPPORTS_VARS
  8649. ? // If CSS supports variables we should use the grid columns var
  8650. `calc(calc(${columns} / var(--ion-grid-columns, 12)) * 100%)`
  8651. : // Convert the columns to a percentage by dividing by the total number
  8652. // of columns (12) and then multiplying by 100
  8653. columns > 0 && columns < 12
  8654. ? (columns / 12) * 100 + '%'
  8655. : 'auto';
  8656. return {
  8657. [modifier]: amount,
  8658. };
  8659. }
  8660. calculateOffset(isRTL) {
  8661. return this.calculatePosition('offset', isRTL ? 'margin-right' : 'margin-left');
  8662. }
  8663. calculatePull(isRTL) {
  8664. return this.calculatePosition('pull', isRTL ? 'left' : 'right');
  8665. }
  8666. calculatePush(isRTL) {
  8667. return this.calculatePosition('push', isRTL ? 'right' : 'left');
  8668. }
  8669. render() {
  8670. const isRTL = document.dir === 'rtl';
  8671. const mode = getIonMode$1(this);
  8672. return (hAsync(Host, { key: '32ed75d81dd09d9bc8999f6d42e5b3cb99c84d91', class: {
  8673. [mode]: true,
  8674. }, style: Object.assign(Object.assign(Object.assign(Object.assign({}, this.calculateOffset(isRTL)), this.calculatePull(isRTL)), this.calculatePush(isRTL)), this.calculateSize()) }, hAsync("slot", { key: '38f8d0440c20cc6d1b1d6a654d07f16de61d8134' })));
  8675. }
  8676. static get style() { return IonColStyle0; }
  8677. static get cmpMeta() { return {
  8678. "$flags$": 9,
  8679. "$tagName$": "ion-col",
  8680. "$members$": {
  8681. "offset": [1],
  8682. "offsetXs": [1, "offset-xs"],
  8683. "offsetSm": [1, "offset-sm"],
  8684. "offsetMd": [1, "offset-md"],
  8685. "offsetLg": [1, "offset-lg"],
  8686. "offsetXl": [1, "offset-xl"],
  8687. "pull": [1],
  8688. "pullXs": [1, "pull-xs"],
  8689. "pullSm": [1, "pull-sm"],
  8690. "pullMd": [1, "pull-md"],
  8691. "pullLg": [1, "pull-lg"],
  8692. "pullXl": [1, "pull-xl"],
  8693. "push": [1],
  8694. "pushXs": [1, "push-xs"],
  8695. "pushSm": [1, "push-sm"],
  8696. "pushMd": [1, "push-md"],
  8697. "pushLg": [1, "push-lg"],
  8698. "pushXl": [1, "push-xl"],
  8699. "size": [1],
  8700. "sizeXs": [1, "size-xs"],
  8701. "sizeSm": [1, "size-sm"],
  8702. "sizeMd": [1, "size-md"],
  8703. "sizeLg": [1, "size-lg"],
  8704. "sizeXl": [1, "size-xl"]
  8705. },
  8706. "$listeners$": [[9, "resize", "onResize"]],
  8707. "$lazyBundleId$": "-",
  8708. "$attrsToReflect$": []
  8709. }; }
  8710. }
  8711. /**
  8712. * Returns `true` if the document or host element
  8713. * has a `dir` set to `rtl`. The host value will always
  8714. * take priority over the root document value.
  8715. */
  8716. const isRTL$1 = (hostEl) => {
  8717. if (hostEl) {
  8718. if (hostEl.dir !== '') {
  8719. return hostEl.dir.toLowerCase() === 'rtl';
  8720. }
  8721. }
  8722. return (document === null || document === void 0 ? void 0 : document.dir.toLowerCase()) === 'rtl';
  8723. };
  8724. 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)}";
  8725. var IonContentStyle0 = contentCss;
  8726. /**
  8727. * @slot - Content is placed in the scrollable area if provided without a slot.
  8728. * @slot fixed - Should be used for fixed content that should not scroll.
  8729. *
  8730. * @part background - The background of the content.
  8731. * @part scroll - The scrollable container of the content.
  8732. */
  8733. class Content {
  8734. constructor(hostRef) {
  8735. registerInstance(this, hostRef);
  8736. this.ionScrollStart = createEvent(this, "ionScrollStart", 7);
  8737. this.ionScroll = createEvent(this, "ionScroll", 7);
  8738. this.ionScrollEnd = createEvent(this, "ionScrollEnd", 7);
  8739. this.watchDog = null;
  8740. this.isScrolling = false;
  8741. this.lastScroll = 0;
  8742. this.queued = false;
  8743. this.cTop = -1;
  8744. this.cBottom = -1;
  8745. this.isMainContent = true;
  8746. this.resizeTimeout = null;
  8747. this.inheritedAttributes = {};
  8748. this.tabsElement = null;
  8749. // Detail is used in a hot loop in the scroll event, by allocating it here
  8750. // V8 will be able to inline any read/write to it since it's a monomorphic class.
  8751. // https://mrale.ph/blog/2015/01/11/whats-up-with-monomorphism.html
  8752. this.detail = {
  8753. scrollTop: 0,
  8754. scrollLeft: 0,
  8755. type: 'scroll',
  8756. event: undefined,
  8757. startX: 0,
  8758. startY: 0,
  8759. startTime: 0,
  8760. currentX: 0,
  8761. currentY: 0,
  8762. velocityX: 0,
  8763. velocityY: 0,
  8764. deltaX: 0,
  8765. deltaY: 0,
  8766. currentTime: 0,
  8767. data: undefined,
  8768. isScrolling: true,
  8769. };
  8770. this.color = undefined;
  8771. this.fullscreen = false;
  8772. this.fixedSlotPlacement = 'after';
  8773. this.forceOverscroll = undefined;
  8774. this.scrollX = false;
  8775. this.scrollY = true;
  8776. this.scrollEvents = false;
  8777. }
  8778. componentWillLoad() {
  8779. this.inheritedAttributes = inheritAriaAttributes(this.el);
  8780. }
  8781. connectedCallback() {
  8782. this.isMainContent = this.el.closest('ion-menu, ion-popover, ion-modal') === null;
  8783. /**
  8784. * The fullscreen content offsets need to be
  8785. * computed after the tab bar has loaded. Since
  8786. * lazy evaluation means components are not hydrated
  8787. * at the same time, we need to wait for the ionTabBarLoaded
  8788. * event to fire. This does not impact dist-custom-elements
  8789. * because there is no hydration there.
  8790. */
  8791. if (hasLazyBuild(this.el)) {
  8792. /**
  8793. * We need to cache the reference to the tabs.
  8794. * If just the content is unmounted then we won't
  8795. * be able to query for the closest tabs on disconnectedCallback
  8796. * since the content has been removed from the DOM tree.
  8797. */
  8798. const closestTabs = (this.tabsElement = this.el.closest('ion-tabs'));
  8799. if (closestTabs !== null) {
  8800. /**
  8801. * When adding and removing the event listener
  8802. * we need to make sure we pass the same function reference
  8803. * otherwise the event listener will not be removed properly.
  8804. * We can't only pass `this.resize` because "this" in the function
  8805. * context becomes a reference to IonTabs instead of IonContent.
  8806. *
  8807. * Additionally, we listen for ionTabBarLoaded on the IonTabs
  8808. * instance rather than the IonTabBar instance. It's possible for
  8809. * a tab bar to be conditionally rendered/mounted. Since ionTabBarLoaded
  8810. * bubbles, we can catch any instances of child tab bars loading by listening
  8811. * on IonTabs.
  8812. */
  8813. this.tabsLoadCallback = () => this.resize();
  8814. closestTabs.addEventListener('ionTabBarLoaded', this.tabsLoadCallback);
  8815. }
  8816. }
  8817. }
  8818. disconnectedCallback() {
  8819. this.onScrollEnd();
  8820. if (hasLazyBuild(this.el)) {
  8821. /**
  8822. * The event listener and tabs caches need to
  8823. * be cleared otherwise this will create a memory
  8824. * leak where the IonTabs instance can never be
  8825. * garbage collected.
  8826. */
  8827. const { tabsElement, tabsLoadCallback } = this;
  8828. if (tabsElement !== null && tabsLoadCallback !== undefined) {
  8829. tabsElement.removeEventListener('ionTabBarLoaded', tabsLoadCallback);
  8830. }
  8831. this.tabsElement = null;
  8832. this.tabsLoadCallback = undefined;
  8833. }
  8834. }
  8835. /**
  8836. * Rotating certain devices can update
  8837. * the safe area insets. As a result,
  8838. * the fullscreen feature on ion-content
  8839. * needs to be recalculated.
  8840. *
  8841. * We listen for "resize" because we
  8842. * do not care what the orientation of
  8843. * the device is. Other APIs
  8844. * such as ScreenOrientation or
  8845. * the deviceorientation event must have
  8846. * permission from the user first whereas
  8847. * the "resize" event does not.
  8848. *
  8849. * We also throttle the callback to minimize
  8850. * thrashing when quickly resizing a window.
  8851. */
  8852. onResize() {
  8853. if (this.resizeTimeout) {
  8854. clearTimeout(this.resizeTimeout);
  8855. this.resizeTimeout = null;
  8856. }
  8857. this.resizeTimeout = setTimeout(() => {
  8858. /**
  8859. * Resize should only happen
  8860. * if the content is visible.
  8861. * When the content is hidden
  8862. * then offsetParent will be null.
  8863. */
  8864. if (this.el.offsetParent === null) {
  8865. return;
  8866. }
  8867. this.resize();
  8868. }, 100);
  8869. }
  8870. shouldForceOverscroll() {
  8871. const { forceOverscroll } = this;
  8872. const mode = getIonMode$1(this);
  8873. return forceOverscroll === undefined ? mode === 'ios' && isPlatform('ios') : forceOverscroll;
  8874. }
  8875. resize() {
  8876. }
  8877. readDimensions() {
  8878. const page = getPageElement(this.el);
  8879. const top = Math.max(this.el.offsetTop, 0);
  8880. const bottom = Math.max(page.offsetHeight - top - this.el.offsetHeight, 0);
  8881. const dirty = top !== this.cTop || bottom !== this.cBottom;
  8882. if (dirty) {
  8883. this.cTop = top;
  8884. this.cBottom = bottom;
  8885. }
  8886. }
  8887. onScroll(ev) {
  8888. const timeStamp = Date.now();
  8889. const shouldStart = !this.isScrolling;
  8890. this.lastScroll = timeStamp;
  8891. if (shouldStart) {
  8892. this.onScrollStart();
  8893. }
  8894. if (!this.queued && this.scrollEvents) {
  8895. this.queued = true;
  8896. readTask((ts) => {
  8897. this.queued = false;
  8898. this.detail.event = ev;
  8899. updateScrollDetail(this.detail, this.scrollEl, ts, shouldStart);
  8900. this.ionScroll.emit(this.detail);
  8901. });
  8902. }
  8903. }
  8904. /**
  8905. * Get the element where the actual scrolling takes place.
  8906. * This element can be used to subscribe to `scroll` events or manually modify
  8907. * `scrollTop`. However, it's recommended to use the API provided by `ion-content`:
  8908. *
  8909. * i.e. Using `ionScroll`, `ionScrollStart`, `ionScrollEnd` for scrolling events
  8910. * and `scrollToPoint()` to scroll the content into a certain point.
  8911. */
  8912. async getScrollElement() {
  8913. /**
  8914. * If this gets called in certain early lifecycle hooks (ex: Vue onMounted),
  8915. * scrollEl won't be defined yet with the custom elements build, so wait for it to load in.
  8916. */
  8917. if (!this.scrollEl) {
  8918. await new Promise((resolve) => componentOnReady(this.el, resolve));
  8919. }
  8920. return Promise.resolve(this.scrollEl);
  8921. }
  8922. /**
  8923. * Returns the background content element.
  8924. * @internal
  8925. */
  8926. async getBackgroundElement() {
  8927. if (!this.backgroundContentEl) {
  8928. await new Promise((resolve) => componentOnReady(this.el, resolve));
  8929. }
  8930. return Promise.resolve(this.backgroundContentEl);
  8931. }
  8932. /**
  8933. * Scroll to the top of the component.
  8934. *
  8935. * @param duration The amount of time to take scrolling to the top. Defaults to `0`.
  8936. */
  8937. scrollToTop(duration = 0) {
  8938. return this.scrollToPoint(undefined, 0, duration);
  8939. }
  8940. /**
  8941. * Scroll to the bottom of the component.
  8942. *
  8943. * @param duration The amount of time to take scrolling to the bottom. Defaults to `0`.
  8944. */
  8945. async scrollToBottom(duration = 0) {
  8946. const scrollEl = await this.getScrollElement();
  8947. const y = scrollEl.scrollHeight - scrollEl.clientHeight;
  8948. return this.scrollToPoint(undefined, y, duration);
  8949. }
  8950. /**
  8951. * Scroll by a specified X/Y distance in the component.
  8952. *
  8953. * @param x The amount to scroll by on the horizontal axis.
  8954. * @param y The amount to scroll by on the vertical axis.
  8955. * @param duration The amount of time to take scrolling by that amount.
  8956. */
  8957. async scrollByPoint(x, y, duration) {
  8958. const scrollEl = await this.getScrollElement();
  8959. return this.scrollToPoint(x + scrollEl.scrollLeft, y + scrollEl.scrollTop, duration);
  8960. }
  8961. /**
  8962. * Scroll to a specified X/Y location in the component.
  8963. *
  8964. * @param x The point to scroll to on the horizontal axis.
  8965. * @param y The point to scroll to on the vertical axis.
  8966. * @param duration The amount of time to take scrolling to that point. Defaults to `0`.
  8967. */
  8968. async scrollToPoint(x, y, duration = 0) {
  8969. const el = await this.getScrollElement();
  8970. if (duration < 32) {
  8971. if (y != null) {
  8972. el.scrollTop = y;
  8973. }
  8974. if (x != null) {
  8975. el.scrollLeft = x;
  8976. }
  8977. return;
  8978. }
  8979. let resolve;
  8980. let startTime = 0;
  8981. const promise = new Promise((r) => (resolve = r));
  8982. const fromY = el.scrollTop;
  8983. const fromX = el.scrollLeft;
  8984. const deltaY = y != null ? y - fromY : 0;
  8985. const deltaX = x != null ? x - fromX : 0;
  8986. // scroll loop
  8987. const step = (timeStamp) => {
  8988. const linearTime = Math.min(1, (timeStamp - startTime) / duration) - 1;
  8989. const easedT = Math.pow(linearTime, 3) + 1;
  8990. if (deltaY !== 0) {
  8991. el.scrollTop = Math.floor(easedT * deltaY + fromY);
  8992. }
  8993. if (deltaX !== 0) {
  8994. el.scrollLeft = Math.floor(easedT * deltaX + fromX);
  8995. }
  8996. if (easedT < 1) {
  8997. // do not use DomController here
  8998. // must use nativeRaf in order to fire in the next frame
  8999. requestAnimationFrame(step);
  9000. }
  9001. else {
  9002. resolve();
  9003. }
  9004. };
  9005. // chill out for a frame first
  9006. requestAnimationFrame((ts) => {
  9007. startTime = ts;
  9008. step(ts);
  9009. });
  9010. return promise;
  9011. }
  9012. onScrollStart() {
  9013. this.isScrolling = true;
  9014. this.ionScrollStart.emit({
  9015. isScrolling: true,
  9016. });
  9017. if (this.watchDog) {
  9018. clearInterval(this.watchDog);
  9019. }
  9020. // watchdog
  9021. this.watchDog = setInterval(() => {
  9022. if (this.lastScroll < Date.now() - 120) {
  9023. this.onScrollEnd();
  9024. }
  9025. }, 100);
  9026. }
  9027. onScrollEnd() {
  9028. if (this.watchDog)
  9029. clearInterval(this.watchDog);
  9030. this.watchDog = null;
  9031. if (this.isScrolling) {
  9032. this.isScrolling = false;
  9033. this.ionScrollEnd.emit({
  9034. isScrolling: false,
  9035. });
  9036. }
  9037. }
  9038. render() {
  9039. const { fixedSlotPlacement, inheritedAttributes, isMainContent, scrollX, scrollY, el } = this;
  9040. const rtl = isRTL$1(el) ? 'rtl' : 'ltr';
  9041. const mode = getIonMode$1(this);
  9042. const forceOverscroll = this.shouldForceOverscroll();
  9043. const transitionShadow = mode === 'ios';
  9044. this.resize();
  9045. return (hAsync(Host, Object.assign({ key: 'f2a24aa66dbf5c76f9d4b06f708eb73cadc239df', role: isMainContent ? 'main' : undefined, class: createColorClasses$1(this.color, {
  9046. [mode]: true,
  9047. 'content-sizing': hostContext('ion-popover', this.el),
  9048. overscroll: forceOverscroll,
  9049. [`content-${rtl}`]: true,
  9050. }), style: {
  9051. '--offset-top': `${this.cTop}px`,
  9052. '--offset-bottom': `${this.cBottom}px`,
  9053. } }, 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: {
  9054. 'inner-scroll': true,
  9055. 'scroll-x': scrollX,
  9056. 'scroll-y': scrollY,
  9057. overscroll: (scrollX || scrollY) && forceOverscroll,
  9058. }, 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));
  9059. }
  9060. get el() { return getElement(this); }
  9061. static get style() { return IonContentStyle0; }
  9062. static get cmpMeta() { return {
  9063. "$flags$": 9,
  9064. "$tagName$": "ion-content",
  9065. "$members$": {
  9066. "color": [513],
  9067. "fullscreen": [4],
  9068. "fixedSlotPlacement": [1, "fixed-slot-placement"],
  9069. "forceOverscroll": [1028, "force-overscroll"],
  9070. "scrollX": [4, "scroll-x"],
  9071. "scrollY": [4, "scroll-y"],
  9072. "scrollEvents": [4, "scroll-events"],
  9073. "getScrollElement": [64],
  9074. "getBackgroundElement": [64],
  9075. "scrollToTop": [64],
  9076. "scrollToBottom": [64],
  9077. "scrollByPoint": [64],
  9078. "scrollToPoint": [64]
  9079. },
  9080. "$listeners$": [[9, "resize", "onResize"]],
  9081. "$lazyBundleId$": "-",
  9082. "$attrsToReflect$": [["color", "color"]]
  9083. }; }
  9084. }
  9085. const getParentElement = (el) => {
  9086. var _a;
  9087. if (el.parentElement) {
  9088. // normal element with a parent element
  9089. return el.parentElement;
  9090. }
  9091. if ((_a = el.parentNode) === null || _a === void 0 ? void 0 : _a.host) {
  9092. // shadow dom's document fragment
  9093. return el.parentNode.host;
  9094. }
  9095. return null;
  9096. };
  9097. const getPageElement = (el) => {
  9098. const tabs = el.closest('ion-tabs');
  9099. if (tabs) {
  9100. return tabs;
  9101. }
  9102. /**
  9103. * If we're in a popover, we need to use its wrapper so we can account for space
  9104. * between the popover and the edges of the screen. But if the popover contains
  9105. * its own page element, we should use that instead.
  9106. */
  9107. const page = el.closest('ion-app, ion-page, .ion-page, page-inner, .popover-content');
  9108. if (page) {
  9109. return page;
  9110. }
  9111. return getParentElement(el);
  9112. };
  9113. // ******** DOM READ ****************
  9114. const updateScrollDetail = (detail, el, timestamp, shouldStart) => {
  9115. const prevX = detail.currentX;
  9116. const prevY = detail.currentY;
  9117. const prevT = detail.currentTime;
  9118. const currentX = el.scrollLeft;
  9119. const currentY = el.scrollTop;
  9120. const timeDelta = timestamp - prevT;
  9121. if (shouldStart) {
  9122. // remember the start positions
  9123. detail.startTime = timestamp;
  9124. detail.startX = currentX;
  9125. detail.startY = currentY;
  9126. detail.velocityX = detail.velocityY = 0;
  9127. }
  9128. detail.currentTime = timestamp;
  9129. detail.currentX = detail.scrollLeft = currentX;
  9130. detail.currentY = detail.scrollTop = currentY;
  9131. detail.deltaX = currentX - detail.startX;
  9132. detail.deltaY = currentY - detail.startY;
  9133. if (timeDelta > 0 && timeDelta < 100) {
  9134. const velocityX = (currentX - prevX) / timeDelta;
  9135. const velocityY = (currentY - prevY) / timeDelta;
  9136. detail.velocityX = velocityX * 0.7 + detail.velocityX * 0.3;
  9137. detail.velocityY = velocityY * 0.7 + detail.velocityY * 0.3;
  9138. }
  9139. };
  9140. const ION_FOCUSED = 'ion-focused';
  9141. const ION_FOCUSABLE = 'ion-focusable';
  9142. const FOCUS_KEYS = [
  9143. 'Tab',
  9144. 'ArrowDown',
  9145. 'Space',
  9146. 'Escape',
  9147. ' ',
  9148. 'Shift',
  9149. 'Enter',
  9150. 'ArrowLeft',
  9151. 'ArrowRight',
  9152. 'ArrowUp',
  9153. 'Home',
  9154. 'End',
  9155. ];
  9156. const startFocusVisible = (rootEl) => {
  9157. let currentFocus = [];
  9158. let keyboardMode = true;
  9159. const ref = rootEl ? rootEl.shadowRoot : document;
  9160. const root = rootEl ? rootEl : document.body;
  9161. const setFocus = (elements) => {
  9162. currentFocus.forEach((el) => el.classList.remove(ION_FOCUSED));
  9163. elements.forEach((el) => el.classList.add(ION_FOCUSED));
  9164. currentFocus = elements;
  9165. };
  9166. const pointerDown = () => {
  9167. keyboardMode = false;
  9168. setFocus([]);
  9169. };
  9170. const onKeydown = (ev) => {
  9171. keyboardMode = FOCUS_KEYS.includes(ev.key);
  9172. if (!keyboardMode) {
  9173. setFocus([]);
  9174. }
  9175. };
  9176. const onFocusin = (ev) => {
  9177. if (keyboardMode && ev.composedPath !== undefined) {
  9178. const toFocus = ev.composedPath().filter((el) => {
  9179. // TODO(FW-2832): type
  9180. if (el.classList) {
  9181. return el.classList.contains(ION_FOCUSABLE);
  9182. }
  9183. return false;
  9184. });
  9185. setFocus(toFocus);
  9186. }
  9187. };
  9188. const onFocusout = () => {
  9189. if (ref.activeElement === root) {
  9190. setFocus([]);
  9191. }
  9192. };
  9193. ref.addEventListener('keydown', onKeydown);
  9194. ref.addEventListener('focusin', onFocusin);
  9195. ref.addEventListener('focusout', onFocusout);
  9196. ref.addEventListener('touchstart', pointerDown, { passive: true });
  9197. ref.addEventListener('mousedown', pointerDown);
  9198. const destroy = () => {
  9199. ref.removeEventListener('keydown', onKeydown);
  9200. ref.removeEventListener('focusin', onFocusin);
  9201. ref.removeEventListener('focusout', onFocusout);
  9202. ref.removeEventListener('touchstart', pointerDown);
  9203. ref.removeEventListener('mousedown', pointerDown);
  9204. };
  9205. return {
  9206. destroy,
  9207. setFocus,
  9208. };
  9209. };
  9210. /**
  9211. * Returns true if the selected day is equal to the reference day
  9212. */
  9213. const isSameDay = (baseParts, compareParts) => {
  9214. return (baseParts.month === compareParts.month && baseParts.day === compareParts.day && baseParts.year === compareParts.year);
  9215. };
  9216. /**
  9217. * Returns true is the selected day is before the reference day.
  9218. */
  9219. const isBefore = (baseParts, compareParts) => {
  9220. return !!(baseParts.year < compareParts.year ||
  9221. (baseParts.year === compareParts.year && baseParts.month < compareParts.month) ||
  9222. (baseParts.year === compareParts.year &&
  9223. baseParts.month === compareParts.month &&
  9224. baseParts.day !== null &&
  9225. baseParts.day < compareParts.day));
  9226. };
  9227. /**
  9228. * Returns true is the selected day is after the reference day.
  9229. */
  9230. const isAfter = (baseParts, compareParts) => {
  9231. return !!(baseParts.year > compareParts.year ||
  9232. (baseParts.year === compareParts.year && baseParts.month > compareParts.month) ||
  9233. (baseParts.year === compareParts.year &&
  9234. baseParts.month === compareParts.month &&
  9235. baseParts.day !== null &&
  9236. baseParts.day > compareParts.day));
  9237. };
  9238. const warnIfValueOutOfBounds = (value, min, max) => {
  9239. const valueArray = Array.isArray(value) ? value : [value];
  9240. for (const val of valueArray) {
  9241. if ((min !== undefined && isBefore(val, min)) || (max !== undefined && isAfter(val, max))) {
  9242. printIonWarning('[ion-datetime] - The value provided to ion-datetime is out of bounds.\n\n' +
  9243. `Min: ${JSON.stringify(min)}\n` +
  9244. `Max: ${JSON.stringify(max)}\n` +
  9245. `Value: ${JSON.stringify(value)}`);
  9246. break;
  9247. }
  9248. }
  9249. };
  9250. /**
  9251. * Determines if given year is a
  9252. * leap year. Returns `true` if year
  9253. * is a leap year. Returns `false`
  9254. * otherwise.
  9255. */
  9256. const isLeapYear = (year) => {
  9257. return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;
  9258. };
  9259. /**
  9260. * Determines the hour cycle for a user.
  9261. * If the hour cycle is explicitly defined, just use that.
  9262. * Otherwise, we try to derive it from either the specified
  9263. * locale extension tags or from Intl.DateTimeFormat directly.
  9264. */
  9265. const getHourCycle = (locale, hourCycle) => {
  9266. /**
  9267. * If developer has explicitly enabled 24-hour time
  9268. * then return early and do not look at the system default.
  9269. */
  9270. if (hourCycle !== undefined) {
  9271. return hourCycle;
  9272. }
  9273. /**
  9274. * If hourCycle was not specified, check the locale
  9275. * that is set on the user's device. We first check the
  9276. * Intl.DateTimeFormat hourCycle option as developers can encode this
  9277. * option into the locale string. Example: `en-US-u-hc-h23`
  9278. */
  9279. const formatted = new Intl.DateTimeFormat(locale, { hour: 'numeric' });
  9280. const options = formatted.resolvedOptions();
  9281. if (options.hourCycle !== undefined) {
  9282. return options.hourCycle;
  9283. }
  9284. /**
  9285. * If hourCycle is not specified (either through lack
  9286. * of browser support or locale information) then fall
  9287. * back to this slower hourCycle check.
  9288. */
  9289. const date = new Date('5/18/2021 00:00');
  9290. const parts = formatted.formatToParts(date);
  9291. const hour = parts.find((p) => p.type === 'hour');
  9292. if (!hour) {
  9293. throw new Error('Hour value not found from DateTimeFormat');
  9294. }
  9295. /**
  9296. * Midnight for h11 starts at 0:00am
  9297. * Midnight for h12 starts at 12:00am
  9298. * Midnight for h23 starts at 00:00
  9299. * Midnight for h24 starts at 24:00
  9300. */
  9301. switch (hour.value) {
  9302. case '0':
  9303. return 'h11';
  9304. case '12':
  9305. return 'h12';
  9306. case '00':
  9307. return 'h23';
  9308. case '24':
  9309. return 'h24';
  9310. default:
  9311. throw new Error(`Invalid hour cycle "${hourCycle}"`);
  9312. }
  9313. };
  9314. /**
  9315. * Determine if the hour cycle uses a 24-hour format.
  9316. * Returns true for h23 and h24. Returns false otherwise.
  9317. * If you don't know the hourCycle, use getHourCycle above
  9318. * and pass the result into this function.
  9319. */
  9320. const is24Hour = (hourCycle) => {
  9321. return hourCycle === 'h23' || hourCycle === 'h24';
  9322. };
  9323. /**
  9324. * Given a date object, returns the number
  9325. * of days in that month.
  9326. * Month value begin at 1, not 0.
  9327. * i.e. January = month 1.
  9328. */
  9329. const getNumDaysInMonth = (month, year) => {
  9330. return month === 4 || month === 6 || month === 9 || month === 11
  9331. ? 30
  9332. : month === 2
  9333. ? isLeapYear(year)
  9334. ? 29
  9335. : 28
  9336. : 31;
  9337. };
  9338. /**
  9339. * Certain locales display month then year while
  9340. * others display year then month.
  9341. * We can use Intl.DateTimeFormat to determine
  9342. * the ordering for each locale.
  9343. * The formatOptions param can be used to customize
  9344. * which pieces of a date to compare against the month
  9345. * with. For example, some locales render dd/mm/yyyy
  9346. * while others render mm/dd/yyyy. This function can be
  9347. * used for variations of the same "month first" check.
  9348. */
  9349. const isMonthFirstLocale = (locale, formatOptions = {
  9350. month: 'numeric',
  9351. year: 'numeric',
  9352. }) => {
  9353. /**
  9354. * By setting month and year we guarantee that only
  9355. * month, year, and literal (slashes '/', for example)
  9356. * values are included in the formatToParts results.
  9357. *
  9358. * The ordering of the parts will be determined by
  9359. * the locale. So if the month is the first value,
  9360. * then we know month should be shown first. If the
  9361. * year is the first value, then we know year should be shown first.
  9362. *
  9363. * This ordering can be controlled by customizing the locale property.
  9364. */
  9365. const parts = new Intl.DateTimeFormat(locale, formatOptions).formatToParts(new Date());
  9366. return parts[0].type === 'month';
  9367. };
  9368. /**
  9369. * Determines if the given locale formats the day period (am/pm) to the
  9370. * left or right of the hour.
  9371. * @param locale The locale to check.
  9372. * @returns `true` if the locale formats the day period to the left of the hour.
  9373. */
  9374. const isLocaleDayPeriodRTL = (locale) => {
  9375. const parts = new Intl.DateTimeFormat(locale, { hour: 'numeric' }).formatToParts(new Date());
  9376. return parts[0].type === 'dayPeriod';
  9377. };
  9378. const ISO_8601_REGEXP =
  9379. // eslint-disable-next-line no-useless-escape
  9380. /^(\d{4}|[+\-]\d{6})(?:-(\d{2})(?:-(\d{2}))?)?(?:T(\d{2}):(\d{2})(?::(\d{2})(?:\.(\d{3}))?)?(?:(Z)|([+\-])(\d{2})(?::(\d{2}))?)?)?$/;
  9381. // eslint-disable-next-line no-useless-escape
  9382. const TIME_REGEXP = /^((\d{2}):(\d{2})(?::(\d{2})(?:\.(\d{3}))?)?(?:(Z)|([+\-])(\d{2})(?::(\d{2}))?)?)?$/;
  9383. /**
  9384. * Use to convert a string of comma separated numbers or
  9385. * an array of numbers, and clean up any user input
  9386. */
  9387. const convertToArrayOfNumbers = (input) => {
  9388. if (input === undefined) {
  9389. return;
  9390. }
  9391. let processedInput = input;
  9392. if (typeof input === 'string') {
  9393. // convert the string to an array of strings
  9394. // auto remove any whitespace and [] characters
  9395. processedInput = input.replace(/\[|\]|\s/g, '').split(',');
  9396. }
  9397. let values;
  9398. if (Array.isArray(processedInput)) {
  9399. // ensure each value is an actual number in the returned array
  9400. values = processedInput.map((num) => parseInt(num, 10)).filter(isFinite);
  9401. }
  9402. else {
  9403. values = [processedInput];
  9404. }
  9405. return values;
  9406. };
  9407. /**
  9408. * Extracts date information
  9409. * from a .calendar-day element
  9410. * into DatetimeParts.
  9411. */
  9412. const getPartsFromCalendarDay = (el) => {
  9413. return {
  9414. month: parseInt(el.getAttribute('data-month'), 10),
  9415. day: parseInt(el.getAttribute('data-day'), 10),
  9416. year: parseInt(el.getAttribute('data-year'), 10),
  9417. dayOfWeek: parseInt(el.getAttribute('data-day-of-week'), 10),
  9418. };
  9419. };
  9420. function parseDate(val) {
  9421. if (Array.isArray(val)) {
  9422. const parsedArray = [];
  9423. for (const valStr of val) {
  9424. const parsedVal = parseDate(valStr);
  9425. /**
  9426. * If any of the values weren't parsed correctly, consider
  9427. * the entire batch incorrect. This simplifies the type
  9428. * signatures by having "undefined" be a general error case
  9429. * instead of returning (Datetime | undefined)[], which is
  9430. * harder for TS to perform type narrowing on.
  9431. */
  9432. if (!parsedVal) {
  9433. return undefined;
  9434. }
  9435. parsedArray.push(parsedVal);
  9436. }
  9437. return parsedArray;
  9438. }
  9439. // manually parse IS0 cuz Date.parse cannot be trusted
  9440. // ISO 8601 format: 1994-12-15T13:47:20Z
  9441. let parse = null;
  9442. if (val != null && val !== '') {
  9443. // try parsing for just time first, HH:MM
  9444. parse = TIME_REGEXP.exec(val);
  9445. if (parse) {
  9446. // adjust the array so it fits nicely with the datetime parse
  9447. parse.unshift(undefined, undefined);
  9448. parse[2] = parse[3] = undefined;
  9449. }
  9450. else {
  9451. // try parsing for full ISO datetime
  9452. parse = ISO_8601_REGEXP.exec(val);
  9453. }
  9454. }
  9455. if (parse === null) {
  9456. // wasn't able to parse the ISO datetime
  9457. printIonWarning(`[ion-datetime] - Unable to parse date string: ${val}. Please provide a valid ISO 8601 datetime string.`);
  9458. return undefined;
  9459. }
  9460. // ensure all the parse values exist with at least 0
  9461. for (let i = 1; i < 8; i++) {
  9462. parse[i] = parse[i] !== undefined ? parseInt(parse[i], 10) : undefined;
  9463. }
  9464. // can also get second and millisecond from parse[6] and parse[7] if needed
  9465. return {
  9466. year: parse[1],
  9467. month: parse[2],
  9468. day: parse[3],
  9469. hour: parse[4],
  9470. minute: parse[5],
  9471. ampm: parse[4] < 12 ? 'am' : 'pm',
  9472. };
  9473. }
  9474. const clampDate = (dateParts, minParts, maxParts) => {
  9475. if (minParts && isBefore(dateParts, minParts)) {
  9476. return minParts;
  9477. }
  9478. else if (maxParts && isAfter(dateParts, maxParts)) {
  9479. return maxParts;
  9480. }
  9481. return dateParts;
  9482. };
  9483. /**
  9484. * Parses an hour and returns if the value is in the morning (am) or afternoon (pm).
  9485. * @param hour The hour to format, should be 0-23
  9486. * @returns `pm` if the hour is greater than or equal to 12, `am` if less than 12.
  9487. */
  9488. const parseAmPm = (hour) => {
  9489. return hour >= 12 ? 'pm' : 'am';
  9490. };
  9491. /**
  9492. * Takes a max date string and creates a DatetimeParts
  9493. * object, filling in any missing information.
  9494. * For example, max="2012" would fill in the missing
  9495. * month, day, hour, and minute information.
  9496. */
  9497. const parseMaxParts = (max, todayParts) => {
  9498. const result = parseDate(max);
  9499. /**
  9500. * If min was not a valid date then return undefined.
  9501. */
  9502. if (result === undefined) {
  9503. return;
  9504. }
  9505. const { month, day, year, hour, minute } = result;
  9506. /**
  9507. * When passing in `max` or `min`, developers
  9508. * can pass in any ISO-8601 string. This means
  9509. * that not all of the date/time fields are defined.
  9510. * For example, passing max="2012" is valid even though
  9511. * there is no month, day, hour, or minute data.
  9512. * However, all of this data is required when clamping the date
  9513. * so that the correct initial value can be selected. As a result,
  9514. * we need to fill in any omitted data with the min or max values.
  9515. */
  9516. const yearValue = year !== null && year !== void 0 ? year : todayParts.year;
  9517. const monthValue = month !== null && month !== void 0 ? month : 12;
  9518. return {
  9519. month: monthValue,
  9520. day: day !== null && day !== void 0 ? day : getNumDaysInMonth(monthValue, yearValue),
  9521. /**
  9522. * Passing in "HH:mm" is a valid ISO-8601
  9523. * string, so we just default to the current year
  9524. * in this case.
  9525. */
  9526. year: yearValue,
  9527. hour: hour !== null && hour !== void 0 ? hour : 23,
  9528. minute: minute !== null && minute !== void 0 ? minute : 59,
  9529. };
  9530. };
  9531. /**
  9532. * Takes a min date string and creates a DatetimeParts
  9533. * object, filling in any missing information.
  9534. * For example, min="2012" would fill in the missing
  9535. * month, day, hour, and minute information.
  9536. */
  9537. const parseMinParts = (min, todayParts) => {
  9538. const result = parseDate(min);
  9539. /**
  9540. * If min was not a valid date then return undefined.
  9541. */
  9542. if (result === undefined) {
  9543. return;
  9544. }
  9545. const { month, day, year, hour, minute } = result;
  9546. /**
  9547. * When passing in `max` or `min`, developers
  9548. * can pass in any ISO-8601 string. This means
  9549. * that not all of the date/time fields are defined.
  9550. * For example, passing max="2012" is valid even though
  9551. * there is no month, day, hour, or minute data.
  9552. * However, all of this data is required when clamping the date
  9553. * so that the correct initial value can be selected. As a result,
  9554. * we need to fill in any omitted data with the min or max values.
  9555. */
  9556. return {
  9557. month: month !== null && month !== void 0 ? month : 1,
  9558. day: day !== null && day !== void 0 ? day : 1,
  9559. /**
  9560. * Passing in "HH:mm" is a valid ISO-8601
  9561. * string, so we just default to the current year
  9562. * in this case.
  9563. */
  9564. year: year !== null && year !== void 0 ? year : todayParts.year,
  9565. hour: hour !== null && hour !== void 0 ? hour : 0,
  9566. minute: minute !== null && minute !== void 0 ? minute : 0,
  9567. };
  9568. };
  9569. const twoDigit = (val) => {
  9570. return ('0' + (val !== undefined ? Math.abs(val) : '0')).slice(-2);
  9571. };
  9572. const fourDigit = (val) => {
  9573. return ('000' + (val !== undefined ? Math.abs(val) : '0')).slice(-4);
  9574. };
  9575. function convertDataToISO(data) {
  9576. if (Array.isArray(data)) {
  9577. return data.map((parts) => convertDataToISO(parts));
  9578. }
  9579. // https://www.w3.org/TR/NOTE-datetime
  9580. let rtn = '';
  9581. if (data.year !== undefined) {
  9582. // YYYY
  9583. rtn = fourDigit(data.year);
  9584. if (data.month !== undefined) {
  9585. // YYYY-MM
  9586. rtn += '-' + twoDigit(data.month);
  9587. if (data.day !== undefined) {
  9588. // YYYY-MM-DD
  9589. rtn += '-' + twoDigit(data.day);
  9590. if (data.hour !== undefined) {
  9591. // YYYY-MM-DDTHH:mm:SS
  9592. rtn += `T${twoDigit(data.hour)}:${twoDigit(data.minute)}:00`;
  9593. }
  9594. }
  9595. }
  9596. }
  9597. else if (data.hour !== undefined) {
  9598. // HH:mm
  9599. rtn = twoDigit(data.hour) + ':' + twoDigit(data.minute);
  9600. }
  9601. return rtn;
  9602. }
  9603. /**
  9604. * Converts an 12 hour value to 24 hours.
  9605. */
  9606. const convert12HourTo24Hour = (hour, ampm) => {
  9607. if (ampm === undefined) {
  9608. return hour;
  9609. }
  9610. /**
  9611. * If AM and 12am
  9612. * then return 00:00.
  9613. * Otherwise just return
  9614. * the hour since it is
  9615. * already in 24 hour format.
  9616. */
  9617. if (ampm === 'am') {
  9618. if (hour === 12) {
  9619. return 0;
  9620. }
  9621. return hour;
  9622. }
  9623. /**
  9624. * If PM and 12pm
  9625. * just return 12:00
  9626. * since it is already
  9627. * in 24 hour format.
  9628. * Otherwise add 12 hours
  9629. * to the time.
  9630. */
  9631. if (hour === 12) {
  9632. return 12;
  9633. }
  9634. return hour + 12;
  9635. };
  9636. const getStartOfWeek = (refParts) => {
  9637. const { dayOfWeek } = refParts;
  9638. if (dayOfWeek === null || dayOfWeek === undefined) {
  9639. throw new Error('No day of week provided');
  9640. }
  9641. return subtractDays(refParts, dayOfWeek);
  9642. };
  9643. const getEndOfWeek = (refParts) => {
  9644. const { dayOfWeek } = refParts;
  9645. if (dayOfWeek === null || dayOfWeek === undefined) {
  9646. throw new Error('No day of week provided');
  9647. }
  9648. return addDays(refParts, 6 - dayOfWeek);
  9649. };
  9650. const getNextDay = (refParts) => {
  9651. return addDays(refParts, 1);
  9652. };
  9653. const getPreviousDay = (refParts) => {
  9654. return subtractDays(refParts, 1);
  9655. };
  9656. const getPreviousWeek = (refParts) => {
  9657. return subtractDays(refParts, 7);
  9658. };
  9659. const getNextWeek = (refParts) => {
  9660. return addDays(refParts, 7);
  9661. };
  9662. /**
  9663. * Given datetime parts, subtract
  9664. * numDays from the date.
  9665. * Returns a new DatetimeParts object
  9666. * Currently can only go backward at most 1 month.
  9667. */
  9668. const subtractDays = (refParts, numDays) => {
  9669. const { month, day, year } = refParts;
  9670. if (day === null) {
  9671. throw new Error('No day provided');
  9672. }
  9673. const workingParts = {
  9674. month,
  9675. day,
  9676. year,
  9677. };
  9678. workingParts.day = day - numDays;
  9679. /**
  9680. * If wrapping to previous month
  9681. * update days and decrement month
  9682. */
  9683. if (workingParts.day < 1) {
  9684. workingParts.month -= 1;
  9685. }
  9686. /**
  9687. * If moving to previous year, reset
  9688. * month to December and decrement year
  9689. */
  9690. if (workingParts.month < 1) {
  9691. workingParts.month = 12;
  9692. workingParts.year -= 1;
  9693. }
  9694. /**
  9695. * Determine how many days are in the current
  9696. * month
  9697. */
  9698. if (workingParts.day < 1) {
  9699. const daysInMonth = getNumDaysInMonth(workingParts.month, workingParts.year);
  9700. /**
  9701. * Take num days in month and add the
  9702. * number of underflow days. This number will
  9703. * be negative.
  9704. * Example: 1 week before Jan 2, 2021 is
  9705. * December 26, 2021 so:
  9706. * 2 - 7 = -5
  9707. * 31 + (-5) = 26
  9708. */
  9709. workingParts.day = daysInMonth + workingParts.day;
  9710. }
  9711. return workingParts;
  9712. };
  9713. /**
  9714. * Given datetime parts, add
  9715. * numDays to the date.
  9716. * Returns a new DatetimeParts object
  9717. * Currently can only go forward at most 1 month.
  9718. */
  9719. const addDays = (refParts, numDays) => {
  9720. const { month, day, year } = refParts;
  9721. if (day === null) {
  9722. throw new Error('No day provided');
  9723. }
  9724. const workingParts = {
  9725. month,
  9726. day,
  9727. year,
  9728. };
  9729. const daysInMonth = getNumDaysInMonth(month, year);
  9730. workingParts.day = day + numDays;
  9731. /**
  9732. * If wrapping to next month
  9733. * update days and increment month
  9734. */
  9735. if (workingParts.day > daysInMonth) {
  9736. workingParts.day -= daysInMonth;
  9737. workingParts.month += 1;
  9738. }
  9739. /**
  9740. * If moving to next year, reset
  9741. * month to January and increment year
  9742. */
  9743. if (workingParts.month > 12) {
  9744. workingParts.month = 1;
  9745. workingParts.year += 1;
  9746. }
  9747. return workingParts;
  9748. };
  9749. /**
  9750. * Given DatetimeParts, generate the previous month.
  9751. */
  9752. const getPreviousMonth = (refParts) => {
  9753. /**
  9754. * If current month is January, wrap backwards
  9755. * to December of the previous year.
  9756. */
  9757. const month = refParts.month === 1 ? 12 : refParts.month - 1;
  9758. const year = refParts.month === 1 ? refParts.year - 1 : refParts.year;
  9759. const numDaysInMonth = getNumDaysInMonth(month, year);
  9760. const day = numDaysInMonth < refParts.day ? numDaysInMonth : refParts.day;
  9761. return { month, year, day };
  9762. };
  9763. /**
  9764. * Given DatetimeParts, generate the next month.
  9765. */
  9766. const getNextMonth = (refParts) => {
  9767. /**
  9768. * If current month is December, wrap forwards
  9769. * to January of the next year.
  9770. */
  9771. const month = refParts.month === 12 ? 1 : refParts.month + 1;
  9772. const year = refParts.month === 12 ? refParts.year + 1 : refParts.year;
  9773. const numDaysInMonth = getNumDaysInMonth(month, year);
  9774. const day = numDaysInMonth < refParts.day ? numDaysInMonth : refParts.day;
  9775. return { month, year, day };
  9776. };
  9777. const changeYear = (refParts, yearDelta) => {
  9778. const month = refParts.month;
  9779. const year = refParts.year + yearDelta;
  9780. const numDaysInMonth = getNumDaysInMonth(month, year);
  9781. const day = numDaysInMonth < refParts.day ? numDaysInMonth : refParts.day;
  9782. return { month, year, day };
  9783. };
  9784. /**
  9785. * Given DatetimeParts, generate the previous year.
  9786. */
  9787. const getPreviousYear = (refParts) => {
  9788. return changeYear(refParts, -1);
  9789. };
  9790. /**
  9791. * Given DatetimeParts, generate the next year.
  9792. */
  9793. const getNextYear = (refParts) => {
  9794. return changeYear(refParts, 1);
  9795. };
  9796. /**
  9797. * If PM, then internal value should
  9798. * be converted to 24-hr time.
  9799. * Does not apply when public
  9800. * values are already 24-hr time.
  9801. */
  9802. const getInternalHourValue = (hour, use24Hour, ampm) => {
  9803. if (use24Hour) {
  9804. return hour;
  9805. }
  9806. return convert12HourTo24Hour(hour, ampm);
  9807. };
  9808. /**
  9809. * Unless otherwise stated, all month values are
  9810. * 1 indexed instead of the typical 0 index in JS Date.
  9811. * Example:
  9812. * January = Month 0 when using JS Date
  9813. * January = Month 1 when using this datetime util
  9814. */
  9815. /**
  9816. * Given the current datetime parts and a new AM/PM value
  9817. * calculate what the hour should be in 24-hour time format.
  9818. * Used when toggling the AM/PM segment since we store our hours
  9819. * in 24-hour time format internally.
  9820. */
  9821. const calculateHourFromAMPM = (currentParts, newAMPM) => {
  9822. const { ampm: currentAMPM, hour } = currentParts;
  9823. let newHour = hour;
  9824. /**
  9825. * If going from AM --> PM, need to update the
  9826. *
  9827. */
  9828. if (currentAMPM === 'am' && newAMPM === 'pm') {
  9829. newHour = convert12HourTo24Hour(newHour, 'pm');
  9830. /**
  9831. * If going from PM --> AM
  9832. */
  9833. }
  9834. else if (currentAMPM === 'pm' && newAMPM === 'am') {
  9835. newHour = Math.abs(newHour - 12);
  9836. }
  9837. return newHour;
  9838. };
  9839. /**
  9840. * Updates parts to ensure that month and day
  9841. * values are valid. For days that do not exist,
  9842. * or are outside the min/max bounds, the closest
  9843. * valid day is used.
  9844. */
  9845. const validateParts = (parts, minParts, maxParts) => {
  9846. const { month, day, year } = parts;
  9847. const partsCopy = clampDate(Object.assign({}, parts), minParts, maxParts);
  9848. const numDays = getNumDaysInMonth(month, year);
  9849. /**
  9850. * If the max number of days
  9851. * is greater than the day we want
  9852. * to set, update the DatetimeParts
  9853. * day field to be the max days.
  9854. */
  9855. if (day !== null && numDays < day) {
  9856. partsCopy.day = numDays;
  9857. }
  9858. /**
  9859. * If value is same day as min day,
  9860. * make sure the time value is in bounds.
  9861. */
  9862. if (minParts !== undefined && isSameDay(partsCopy, minParts)) {
  9863. /**
  9864. * If the hour is out of bounds,
  9865. * update both the hour and minute.
  9866. * This is done so that the new time
  9867. * is closest to what the user selected.
  9868. */
  9869. if (partsCopy.hour !== undefined && minParts.hour !== undefined) {
  9870. if (partsCopy.hour < minParts.hour) {
  9871. partsCopy.hour = minParts.hour;
  9872. partsCopy.minute = minParts.minute;
  9873. /**
  9874. * If only the minute is out of bounds,
  9875. * set it to the min minute.
  9876. */
  9877. }
  9878. else if (partsCopy.hour === minParts.hour &&
  9879. partsCopy.minute !== undefined &&
  9880. minParts.minute !== undefined &&
  9881. partsCopy.minute < minParts.minute) {
  9882. partsCopy.minute = minParts.minute;
  9883. }
  9884. }
  9885. }
  9886. /**
  9887. * If value is same day as max day,
  9888. * make sure the time value is in bounds.
  9889. */
  9890. if (maxParts !== undefined && isSameDay(parts, maxParts)) {
  9891. /**
  9892. * If the hour is out of bounds,
  9893. * update both the hour and minute.
  9894. * This is done so that the new time
  9895. * is closest to what the user selected.
  9896. */
  9897. if (partsCopy.hour !== undefined && maxParts.hour !== undefined) {
  9898. if (partsCopy.hour > maxParts.hour) {
  9899. partsCopy.hour = maxParts.hour;
  9900. partsCopy.minute = maxParts.minute;
  9901. /**
  9902. * If only the minute is out of bounds,
  9903. * set it to the max minute.
  9904. */
  9905. }
  9906. else if (partsCopy.hour === maxParts.hour &&
  9907. partsCopy.minute !== undefined &&
  9908. maxParts.minute !== undefined &&
  9909. partsCopy.minute > maxParts.minute) {
  9910. partsCopy.minute = maxParts.minute;
  9911. }
  9912. }
  9913. }
  9914. return partsCopy;
  9915. };
  9916. /**
  9917. * Returns the closest date to refParts
  9918. * that also meets the constraints of
  9919. * the *Values params.
  9920. */
  9921. const getClosestValidDate = ({ refParts, monthValues, dayValues, yearValues, hourValues, minuteValues, minParts, maxParts, }) => {
  9922. const { hour, minute, day, month, year } = refParts;
  9923. const copyParts = Object.assign(Object.assign({}, refParts), { dayOfWeek: undefined });
  9924. if (yearValues !== undefined) {
  9925. // Filters out years that are out of the min/max bounds
  9926. const filteredYears = yearValues.filter((year) => {
  9927. if (minParts !== undefined && year < minParts.year) {
  9928. return false;
  9929. }
  9930. if (maxParts !== undefined && year > maxParts.year) {
  9931. return false;
  9932. }
  9933. return true;
  9934. });
  9935. copyParts.year = findClosestValue(year, filteredYears);
  9936. }
  9937. if (monthValues !== undefined) {
  9938. // Filters out months that are out of the min/max bounds
  9939. const filteredMonths = monthValues.filter((month) => {
  9940. if (minParts !== undefined && copyParts.year === minParts.year && month < minParts.month) {
  9941. return false;
  9942. }
  9943. if (maxParts !== undefined && copyParts.year === maxParts.year && month > maxParts.month) {
  9944. return false;
  9945. }
  9946. return true;
  9947. });
  9948. copyParts.month = findClosestValue(month, filteredMonths);
  9949. }
  9950. // Day is nullable but cannot be undefined
  9951. if (day !== null && dayValues !== undefined) {
  9952. // Filters out days that are out of the min/max bounds
  9953. const filteredDays = dayValues.filter((day) => {
  9954. if (minParts !== undefined && isBefore(Object.assign(Object.assign({}, copyParts), { day }), minParts)) {
  9955. return false;
  9956. }
  9957. if (maxParts !== undefined && isAfter(Object.assign(Object.assign({}, copyParts), { day }), maxParts)) {
  9958. return false;
  9959. }
  9960. return true;
  9961. });
  9962. copyParts.day = findClosestValue(day, filteredDays);
  9963. }
  9964. if (hour !== undefined && hourValues !== undefined) {
  9965. // Filters out hours that are out of the min/max bounds
  9966. const filteredHours = hourValues.filter((hour) => {
  9967. if ((minParts === null || minParts === void 0 ? void 0 : minParts.hour) !== undefined && isSameDay(copyParts, minParts) && hour < minParts.hour) {
  9968. return false;
  9969. }
  9970. if ((maxParts === null || maxParts === void 0 ? void 0 : maxParts.hour) !== undefined && isSameDay(copyParts, maxParts) && hour > maxParts.hour) {
  9971. return false;
  9972. }
  9973. return true;
  9974. });
  9975. copyParts.hour = findClosestValue(hour, filteredHours);
  9976. copyParts.ampm = parseAmPm(copyParts.hour);
  9977. }
  9978. if (minute !== undefined && minuteValues !== undefined) {
  9979. // Filters out minutes that are out of the min/max bounds
  9980. const filteredMinutes = minuteValues.filter((minute) => {
  9981. if ((minParts === null || minParts === void 0 ? void 0 : minParts.minute) !== undefined &&
  9982. isSameDay(copyParts, minParts) &&
  9983. copyParts.hour === minParts.hour &&
  9984. minute < minParts.minute) {
  9985. return false;
  9986. }
  9987. if ((maxParts === null || maxParts === void 0 ? void 0 : maxParts.minute) !== undefined &&
  9988. isSameDay(copyParts, maxParts) &&
  9989. copyParts.hour === maxParts.hour &&
  9990. minute > maxParts.minute) {
  9991. return false;
  9992. }
  9993. return true;
  9994. });
  9995. copyParts.minute = findClosestValue(minute, filteredMinutes);
  9996. }
  9997. return copyParts;
  9998. };
  9999. /**
  10000. * Finds the value in "values" that is
  10001. * numerically closest to "reference".
  10002. * This function assumes that "values" is
  10003. * already sorted in ascending order.
  10004. * @param reference The reference number to use
  10005. * when finding the closest value
  10006. * @param values The allowed values that will be
  10007. * searched to find the closest value to "reference"
  10008. */
  10009. const findClosestValue = (reference, values) => {
  10010. let closestValue = values[0];
  10011. let rank = Math.abs(closestValue - reference);
  10012. for (let i = 1; i < values.length; i++) {
  10013. const value = values[i];
  10014. /**
  10015. * This code prioritizes the first
  10016. * closest result. Given two values
  10017. * with the same distance from reference,
  10018. * this code will prioritize the smaller of
  10019. * the two values.
  10020. */
  10021. const valueRank = Math.abs(value - reference);
  10022. if (valueRank < rank) {
  10023. closestValue = value;
  10024. rank = valueRank;
  10025. }
  10026. }
  10027. return closestValue;
  10028. };
  10029. const getFormattedDayPeriod = (dayPeriod) => {
  10030. if (dayPeriod === undefined) {
  10031. return '';
  10032. }
  10033. return dayPeriod.toUpperCase();
  10034. };
  10035. /**
  10036. * Including time zone options may lead to the rendered text showing a
  10037. * different time from what was selected in the Datetime, which could cause
  10038. * confusion.
  10039. */
  10040. const stripTimeZone = (formatOptions) => {
  10041. return Object.assign(Object.assign({}, formatOptions), {
  10042. /**
  10043. * Setting the time zone to UTC ensures that the value shown is always the
  10044. * same as what was selected and safeguards against older Safari bugs with
  10045. * Intl.DateTimeFormat.
  10046. */
  10047. timeZone: 'UTC',
  10048. /**
  10049. * We do not want to display the time zone name
  10050. */
  10051. timeZoneName: undefined });
  10052. };
  10053. const getLocalizedTime = (locale, refParts, hourCycle, formatOptions = { hour: 'numeric', minute: 'numeric' }) => {
  10054. const timeParts = {
  10055. hour: refParts.hour,
  10056. minute: refParts.minute,
  10057. };
  10058. if (timeParts.hour === undefined || timeParts.minute === undefined) {
  10059. return 'Invalid Time';
  10060. }
  10061. return new Intl.DateTimeFormat(locale, Object.assign(Object.assign({}, stripTimeZone(formatOptions)), {
  10062. /**
  10063. * We use hourCycle here instead of hour12 due to:
  10064. * https://bugs.chromium.org/p/chromium/issues/detail?id=1347316&q=hour12&can=2
  10065. */
  10066. hourCycle })).format(new Date(convertDataToISO(Object.assign({
  10067. /**
  10068. * JS uses a simplified ISO 8601 format which allows for
  10069. * date-only formats and date-time formats, but not
  10070. * time-only formats: https://tc39.es/ecma262/#sec-date-time-string-format
  10071. * As a result, developers who only pass a time will get
  10072. * an "Invalid Date" error. To account for this, we make sure that
  10073. * year/day/month values are set when passing to new Date().
  10074. * The Intl.DateTimeFormat call above only uses the hour/minute
  10075. * values, so passing these date values should have no impact
  10076. * on the time output.
  10077. */
  10078. year: 2023, day: 1, month: 1 }, timeParts)) + 'Z'));
  10079. };
  10080. /**
  10081. * Adds padding to a time value so
  10082. * that it is always 2 digits.
  10083. */
  10084. const addTimePadding = (value) => {
  10085. const valueToString = value.toString();
  10086. if (valueToString.length > 1) {
  10087. return valueToString;
  10088. }
  10089. return `0${valueToString}`;
  10090. };
  10091. /**
  10092. * Formats 24 hour times so that
  10093. * it always has 2 digits. For
  10094. * 12 hour times it ensures that
  10095. * hour 0 is formatted as '12'.
  10096. */
  10097. const getFormattedHour = (hour, hourCycle) => {
  10098. /**
  10099. * Midnight for h11 starts at 0:00am
  10100. * Midnight for h12 starts at 12:00am
  10101. * Midnight for h23 starts at 00:00
  10102. * Midnight for h24 starts at 24:00
  10103. */
  10104. if (hour === 0) {
  10105. switch (hourCycle) {
  10106. case 'h11':
  10107. return '0';
  10108. case 'h12':
  10109. return '12';
  10110. case 'h23':
  10111. return '00';
  10112. case 'h24':
  10113. return '24';
  10114. default:
  10115. throw new Error(`Invalid hour cycle "${hourCycle}"`);
  10116. }
  10117. }
  10118. const use24Hour = is24Hour(hourCycle);
  10119. /**
  10120. * h23 and h24 use 24 hour times.
  10121. */
  10122. if (use24Hour) {
  10123. return addTimePadding(hour);
  10124. }
  10125. return hour.toString();
  10126. };
  10127. /**
  10128. * Generates an aria-label to be read by screen readers
  10129. * given a local, a date, and whether or not that date is
  10130. * today's date.
  10131. */
  10132. const generateDayAriaLabel = (locale, today, refParts) => {
  10133. if (refParts.day === null) {
  10134. return null;
  10135. }
  10136. /**
  10137. * MM/DD/YYYY will return midnight in the user's timezone.
  10138. */
  10139. const date = getNormalizedDate(refParts);
  10140. const labelString = new Intl.DateTimeFormat(locale, {
  10141. weekday: 'long',
  10142. month: 'long',
  10143. day: 'numeric',
  10144. timeZone: 'UTC',
  10145. }).format(date);
  10146. /**
  10147. * If date is today, prepend "Today" so screen readers indicate
  10148. * that the date is today.
  10149. */
  10150. return today ? `Today, ${labelString}` : labelString;
  10151. };
  10152. /**
  10153. * Given a locale and a date object,
  10154. * return a formatted string that includes
  10155. * the month name and full year.
  10156. * Example: May 2021
  10157. */
  10158. const getMonthAndYear = (locale, refParts) => {
  10159. const date = getNormalizedDate(refParts);
  10160. return new Intl.DateTimeFormat(locale, { month: 'long', year: 'numeric', timeZone: 'UTC' }).format(date);
  10161. };
  10162. /**
  10163. * Given a locale and a date object,
  10164. * return a formatted string that includes
  10165. * the numeric day.
  10166. * Note: Some languages will add literal characters
  10167. * to the end. This function removes those literals.
  10168. * Example: 29
  10169. */
  10170. const getDay = (locale, refParts) => {
  10171. return getLocalizedDateTimeParts(locale, refParts, { day: 'numeric' }).find((obj) => obj.type === 'day').value;
  10172. };
  10173. /**
  10174. * Given a locale and a date object,
  10175. * return a formatted string that includes
  10176. * the numeric year.
  10177. * Example: 2022
  10178. */
  10179. const getYear = (locale, refParts) => {
  10180. return getLocalizedDateTime(locale, refParts, { year: 'numeric' });
  10181. };
  10182. /**
  10183. * Given reference parts, return a JS Date object
  10184. * with a normalized time.
  10185. */
  10186. const getNormalizedDate = (refParts) => {
  10187. var _a, _b, _c;
  10188. const timeString = refParts.hour !== undefined && refParts.minute !== undefined ? ` ${refParts.hour}:${refParts.minute}` : '';
  10189. /**
  10190. * We use / notation here for the date
  10191. * so we do not need to do extra work and pad values with zeroes.
  10192. * Values such as YYYY-MM are still valid, so
  10193. * we add fallback values so we still get
  10194. * a valid date otherwise we will pass in a string
  10195. * like "//2023". Some browsers, such as Chrome, will
  10196. * account for this and still return a valid date. However,
  10197. * this is not a consistent behavior across all browsers.
  10198. */
  10199. 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`);
  10200. };
  10201. /**
  10202. * Given a locale, DatetimeParts, and options
  10203. * format the DatetimeParts according to the options
  10204. * and locale combination. This returns a string. If
  10205. * you want an array of the individual pieces
  10206. * that make up the localized date string, use
  10207. * getLocalizedDateTimeParts.
  10208. */
  10209. const getLocalizedDateTime = (locale, refParts, options) => {
  10210. const date = getNormalizedDate(refParts);
  10211. return getDateTimeFormat(locale, stripTimeZone(options)).format(date);
  10212. };
  10213. /**
  10214. * Given a locale, DatetimeParts, and options
  10215. * format the DatetimeParts according to the options
  10216. * and locale combination. This returns an array of
  10217. * each piece of the date.
  10218. */
  10219. const getLocalizedDateTimeParts = (locale, refParts, options) => {
  10220. const date = getNormalizedDate(refParts);
  10221. return getDateTimeFormat(locale, options).formatToParts(date);
  10222. };
  10223. /**
  10224. * Wrapper function for Intl.DateTimeFormat.
  10225. * Allows developers to apply an allowed format to DatetimeParts.
  10226. * This function also has built in safeguards for older browser bugs
  10227. * with Intl.DateTimeFormat.
  10228. */
  10229. const getDateTimeFormat = (locale, options) => {
  10230. return new Intl.DateTimeFormat(locale, Object.assign(Object.assign({}, options), { timeZone: 'UTC' }));
  10231. };
  10232. /**
  10233. * Gets a localized version of "Today"
  10234. * Falls back to "Today" in English for
  10235. * browsers that do not support RelativeTimeFormat.
  10236. */
  10237. const getTodayLabel = (locale) => {
  10238. if ('RelativeTimeFormat' in Intl) {
  10239. const label = new Intl.RelativeTimeFormat(locale, { numeric: 'auto' }).format(0, 'day');
  10240. return label.charAt(0).toUpperCase() + label.slice(1);
  10241. }
  10242. else {
  10243. return 'Today';
  10244. }
  10245. };
  10246. /**
  10247. * When calling toISOString(), the browser
  10248. * will convert the date to UTC time by either adding
  10249. * or subtracting the time zone offset.
  10250. * To work around this, we need to either add
  10251. * or subtract the time zone offset to the Date
  10252. * object prior to calling toISOString().
  10253. * This allows us to get an ISO string
  10254. * that is in the user's time zone.
  10255. *
  10256. * Example:
  10257. * Time zone offset is 240
  10258. * Meaning: The browser needs to add 240 minutes
  10259. * to the Date object to get UTC time.
  10260. * What Ionic does: We subtract 240 minutes
  10261. * from the Date object. The browser then adds
  10262. * 240 minutes in toISOString(). The result
  10263. * is a time that is in the user's time zone
  10264. * and not UTC.
  10265. *
  10266. * Note: Some timezones include minute adjustments
  10267. * such as 30 or 45 minutes. This is why we use setMinutes
  10268. * instead of setHours.
  10269. * Example: India Standard Time
  10270. * Timezone offset: -330 = -5.5 hours.
  10271. *
  10272. * List of timezones with 30 and 45 minute timezones:
  10273. * https://www.timeanddate.com/time/time-zones-interesting.html
  10274. */
  10275. const removeDateTzOffset = (date) => {
  10276. const tzOffset = date.getTimezoneOffset();
  10277. date.setMinutes(date.getMinutes() - tzOffset);
  10278. return date;
  10279. };
  10280. const DATE_AM = removeDateTzOffset(new Date('2022T01:00'));
  10281. const DATE_PM = removeDateTzOffset(new Date('2022T13:00'));
  10282. /**
  10283. * Formats the locale's string representation of the day period (am/pm) for a given
  10284. * ref parts day period.
  10285. *
  10286. * @param locale The locale to format the day period in.
  10287. * @param value The date string, in ISO format.
  10288. * @returns The localized day period (am/pm) representation of the given value.
  10289. */
  10290. const getLocalizedDayPeriod = (locale, dayPeriod) => {
  10291. const date = dayPeriod === 'am' ? DATE_AM : DATE_PM;
  10292. const localizedDayPeriod = new Intl.DateTimeFormat(locale, {
  10293. hour: 'numeric',
  10294. timeZone: 'UTC',
  10295. })
  10296. .formatToParts(date)
  10297. .find((part) => part.type === 'dayPeriod');
  10298. if (localizedDayPeriod) {
  10299. return localizedDayPeriod.value;
  10300. }
  10301. return getFormattedDayPeriod(dayPeriod);
  10302. };
  10303. /**
  10304. * Formats the datetime's value to a string, for use in the native input.
  10305. *
  10306. * @param value The value to format, either an ISO string or an array thereof.
  10307. */
  10308. const formatValue = (value) => {
  10309. return Array.isArray(value) ? value.join(',') : value;
  10310. };
  10311. /**
  10312. * Returns the current date as
  10313. * an ISO string in the user's
  10314. * time zone.
  10315. */
  10316. const getToday = () => {
  10317. /**
  10318. * ion-datetime intentionally does not
  10319. * parse time zones/do automatic time zone
  10320. * conversion when accepting user input.
  10321. * However when we get today's date string,
  10322. * we want it formatted relative to the user's
  10323. * time zone.
  10324. *
  10325. * When calling toISOString(), the browser
  10326. * will convert the date to UTC time by either adding
  10327. * or subtracting the time zone offset.
  10328. * To work around this, we need to either add
  10329. * or subtract the time zone offset to the Date
  10330. * object prior to calling toISOString().
  10331. * This allows us to get an ISO string
  10332. * that is in the user's time zone.
  10333. */
  10334. return removeDateTzOffset(new Date()).toISOString();
  10335. };
  10336. const minutes = [
  10337. 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,
  10338. 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,
  10339. ];
  10340. // h11 hour system uses 0-11. Midnight starts at 0:00am.
  10341. const hour11 = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];
  10342. // h12 hour system uses 0-12. Midnight starts at 12:00am.
  10343. const hour12 = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];
  10344. // h23 hour system uses 0-23. Midnight starts at 0:00.
  10345. 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];
  10346. // h24 hour system uses 1-24. Midnight starts at 24:00.
  10347. 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];
  10348. /**
  10349. * Given a locale and a mode,
  10350. * return an array with formatted days
  10351. * of the week. iOS should display days
  10352. * such as "Mon" or "Tue".
  10353. * MD should display days such as "M"
  10354. * or "T".
  10355. */
  10356. const getDaysOfWeek = (locale, mode, firstDayOfWeek = 0) => {
  10357. /**
  10358. * Nov 1st, 2020 starts on a Sunday.
  10359. * ion-datetime assumes weeks start on Sunday,
  10360. * but is configurable via `firstDayOfWeek`.
  10361. */
  10362. const weekdayFormat = mode === 'ios' ? 'short' : 'narrow';
  10363. const intl = new Intl.DateTimeFormat(locale, { weekday: weekdayFormat });
  10364. const startDate = new Date('11/01/2020');
  10365. const daysOfWeek = [];
  10366. /**
  10367. * For each day of the week,
  10368. * get the day name.
  10369. */
  10370. for (let i = firstDayOfWeek; i < firstDayOfWeek + 7; i++) {
  10371. const currentDate = new Date(startDate);
  10372. currentDate.setDate(currentDate.getDate() + i);
  10373. daysOfWeek.push(intl.format(currentDate));
  10374. }
  10375. return daysOfWeek;
  10376. };
  10377. /**
  10378. * Returns an array containing all of the
  10379. * days in a month for a given year. Values are
  10380. * aligned with a week calendar starting on
  10381. * the firstDayOfWeek value (Sunday by default)
  10382. * using null values.
  10383. */
  10384. const getDaysOfMonth = (month, year, firstDayOfWeek) => {
  10385. const numDays = getNumDaysInMonth(month, year);
  10386. const firstOfMonth = new Date(`${month}/1/${year}`).getDay();
  10387. /**
  10388. * To get the first day of the month aligned on the correct
  10389. * day of the week, we need to determine how many "filler" days
  10390. * to generate. These filler days as empty/disabled buttons
  10391. * that fill the space of the days of the week before the first
  10392. * of the month.
  10393. *
  10394. * There are two cases here:
  10395. *
  10396. * 1. If firstOfMonth = 4, firstDayOfWeek = 0 then the offset
  10397. * is (4 - (0 + 1)) = 3. Since the offset loop goes from 0 to 3 inclusive,
  10398. * this will generate 4 filler days (0, 1, 2, 3), and then day of week 4 will have
  10399. * the first day of the month.
  10400. *
  10401. * 2. If firstOfMonth = 2, firstDayOfWeek = 4 then the offset
  10402. * is (6 - (4 - 2)) = 4. Since the offset loop goes from 0 to 4 inclusive,
  10403. * this will generate 5 filler days (0, 1, 2, 3, 4), and then day of week 5 will have
  10404. * the first day of the month.
  10405. */
  10406. const offset = firstOfMonth >= firstDayOfWeek ? firstOfMonth - (firstDayOfWeek + 1) : 6 - (firstDayOfWeek - firstOfMonth);
  10407. let days = [];
  10408. for (let i = 1; i <= numDays; i++) {
  10409. days.push({ day: i, dayOfWeek: (offset + i) % 7 });
  10410. }
  10411. for (let i = 0; i <= offset; i++) {
  10412. days = [{ day: null, dayOfWeek: null }, ...days];
  10413. }
  10414. return days;
  10415. };
  10416. /**
  10417. * Returns an array of pre-defined hour
  10418. * values based on the provided hourCycle.
  10419. */
  10420. const getHourData = (hourCycle) => {
  10421. switch (hourCycle) {
  10422. case 'h11':
  10423. return hour11;
  10424. case 'h12':
  10425. return hour12;
  10426. case 'h23':
  10427. return hour23;
  10428. case 'h24':
  10429. return hour24;
  10430. default:
  10431. throw new Error(`Invalid hour cycle "${hourCycle}"`);
  10432. }
  10433. };
  10434. /**
  10435. * Given a local, reference datetime parts and option
  10436. * max/min bound datetime parts, calculate the acceptable
  10437. * hour and minute values according to the bounds and locale.
  10438. */
  10439. const generateTime = (locale, refParts, hourCycle = 'h12', minParts, maxParts, hourValues, minuteValues) => {
  10440. const computedHourCycle = getHourCycle(locale, hourCycle);
  10441. const use24Hour = is24Hour(computedHourCycle);
  10442. let processedHours = getHourData(computedHourCycle);
  10443. let processedMinutes = minutes;
  10444. let isAMAllowed = true;
  10445. let isPMAllowed = true;
  10446. if (hourValues) {
  10447. processedHours = processedHours.filter((hour) => hourValues.includes(hour));
  10448. }
  10449. if (minuteValues) {
  10450. processedMinutes = processedMinutes.filter((minute) => minuteValues.includes(minute));
  10451. }
  10452. if (minParts) {
  10453. /**
  10454. * If ref day is the same as the
  10455. * minimum allowed day, filter hour/minute
  10456. * values according to min hour and minute.
  10457. */
  10458. if (isSameDay(refParts, minParts)) {
  10459. /**
  10460. * Users may not always set the hour/minute for
  10461. * min value (i.e. 2021-06-02) so we should allow
  10462. * all hours/minutes in that case.
  10463. */
  10464. if (minParts.hour !== undefined) {
  10465. processedHours = processedHours.filter((hour) => {
  10466. const convertedHour = refParts.ampm === 'pm' ? (hour + 12) % 24 : hour;
  10467. return (use24Hour ? hour : convertedHour) >= minParts.hour;
  10468. });
  10469. isAMAllowed = minParts.hour < 13;
  10470. }
  10471. if (minParts.minute !== undefined) {
  10472. /**
  10473. * The minimum minute range should not be enforced when
  10474. * the hour is greater than the min hour.
  10475. *
  10476. * For example with a minimum range of 09:30, users
  10477. * should be able to select 10:00-10:29 and beyond.
  10478. */
  10479. let isPastMinHour = false;
  10480. if (minParts.hour !== undefined && refParts.hour !== undefined) {
  10481. if (refParts.hour > minParts.hour) {
  10482. isPastMinHour = true;
  10483. }
  10484. }
  10485. processedMinutes = processedMinutes.filter((minute) => {
  10486. if (isPastMinHour) {
  10487. return true;
  10488. }
  10489. return minute >= minParts.minute;
  10490. });
  10491. }
  10492. /**
  10493. * If ref day is before minimum
  10494. * day do not render any hours/minute values
  10495. */
  10496. }
  10497. else if (isBefore(refParts, minParts)) {
  10498. processedHours = [];
  10499. processedMinutes = [];
  10500. isAMAllowed = isPMAllowed = false;
  10501. }
  10502. }
  10503. if (maxParts) {
  10504. /**
  10505. * If ref day is the same as the
  10506. * maximum allowed day, filter hour/minute
  10507. * values according to max hour and minute.
  10508. */
  10509. if (isSameDay(refParts, maxParts)) {
  10510. /**
  10511. * Users may not always set the hour/minute for
  10512. * max value (i.e. 2021-06-02) so we should allow
  10513. * all hours/minutes in that case.
  10514. */
  10515. if (maxParts.hour !== undefined) {
  10516. processedHours = processedHours.filter((hour) => {
  10517. const convertedHour = refParts.ampm === 'pm' ? (hour + 12) % 24 : hour;
  10518. return (use24Hour ? hour : convertedHour) <= maxParts.hour;
  10519. });
  10520. isPMAllowed = maxParts.hour >= 12;
  10521. }
  10522. if (maxParts.minute !== undefined && refParts.hour === maxParts.hour) {
  10523. // The available minutes should only be filtered when the hour is the same as the max hour.
  10524. // For example if the max hour is 10:30 and the current hour is 10:00,
  10525. // users should be able to select 00-30 minutes.
  10526. // If the current hour is 09:00, users should be able to select 00-60 minutes.
  10527. processedMinutes = processedMinutes.filter((minute) => minute <= maxParts.minute);
  10528. }
  10529. /**
  10530. * If ref day is after minimum
  10531. * day do not render any hours/minute values
  10532. */
  10533. }
  10534. else if (isAfter(refParts, maxParts)) {
  10535. processedHours = [];
  10536. processedMinutes = [];
  10537. isAMAllowed = isPMAllowed = false;
  10538. }
  10539. }
  10540. return {
  10541. hours: processedHours,
  10542. minutes: processedMinutes,
  10543. am: isAMAllowed,
  10544. pm: isPMAllowed,
  10545. };
  10546. };
  10547. /**
  10548. * Given DatetimeParts, generate the previous,
  10549. * current, and and next months.
  10550. */
  10551. const generateMonths = (refParts, forcedDate) => {
  10552. const current = { month: refParts.month, year: refParts.year, day: refParts.day };
  10553. /**
  10554. * If we're forcing a month to appear, and it's different from the current month,
  10555. * ensure it appears by replacing the next or previous month as appropriate.
  10556. */
  10557. if (forcedDate !== undefined && (refParts.month !== forcedDate.month || refParts.year !== forcedDate.year)) {
  10558. const forced = { month: forcedDate.month, year: forcedDate.year, day: forcedDate.day };
  10559. const forcedMonthIsBefore = isBefore(forced, current);
  10560. return forcedMonthIsBefore
  10561. ? [forced, current, getNextMonth(refParts)]
  10562. : [getPreviousMonth(refParts), current, forced];
  10563. }
  10564. return [getPreviousMonth(refParts), current, getNextMonth(refParts)];
  10565. };
  10566. const getMonthColumnData = (locale, refParts, minParts, maxParts, monthValues, formatOptions = {
  10567. month: 'long',
  10568. }) => {
  10569. const { year } = refParts;
  10570. const months = [];
  10571. if (monthValues !== undefined) {
  10572. let processedMonths = monthValues;
  10573. if ((maxParts === null || maxParts === void 0 ? void 0 : maxParts.month) !== undefined) {
  10574. processedMonths = processedMonths.filter((month) => month <= maxParts.month);
  10575. }
  10576. if ((minParts === null || minParts === void 0 ? void 0 : minParts.month) !== undefined) {
  10577. processedMonths = processedMonths.filter((month) => month >= minParts.month);
  10578. }
  10579. processedMonths.forEach((processedMonth) => {
  10580. const date = new Date(`${processedMonth}/1/${year} GMT+0000`);
  10581. const monthString = new Intl.DateTimeFormat(locale, Object.assign(Object.assign({}, formatOptions), { timeZone: 'UTC' })).format(date);
  10582. months.push({ text: monthString, value: processedMonth });
  10583. });
  10584. }
  10585. else {
  10586. const maxMonth = maxParts && maxParts.year === year ? maxParts.month : 12;
  10587. const minMonth = minParts && minParts.year === year ? minParts.month : 1;
  10588. for (let i = minMonth; i <= maxMonth; i++) {
  10589. /**
  10590. *
  10591. * There is a bug on iOS 14 where
  10592. * Intl.DateTimeFormat takes into account
  10593. * the local timezone offset when formatting dates.
  10594. *
  10595. * Forcing the timezone to 'UTC' fixes the issue. However,
  10596. * we should keep this workaround as it is safer. In the event
  10597. * this breaks in another browser, we will not be impacted
  10598. * because all dates will be interpreted in UTC.
  10599. *
  10600. * Example:
  10601. * new Intl.DateTimeFormat('en-US', { month: 'long' }).format(new Date('Sat Apr 01 2006 00:00:00 GMT-0400 (EDT)')) // "March"
  10602. * new Intl.DateTimeFormat('en-US', { month: 'long', timeZone: 'UTC' }).format(new Date('Sat Apr 01 2006 00:00:00 GMT-0400 (EDT)')) // "April"
  10603. *
  10604. * In certain timezones, iOS 14 shows the wrong
  10605. * date for .toUTCString(). To combat this, we
  10606. * force all of the timezones to GMT+0000 (UTC).
  10607. *
  10608. * Example:
  10609. * Time Zone: Central European Standard Time
  10610. * new Date('1/1/1992').toUTCString() // "Tue, 31 Dec 1991 23:00:00 GMT"
  10611. * new Date('1/1/1992 GMT+0000').toUTCString() // "Wed, 01 Jan 1992 00:00:00 GMT"
  10612. */
  10613. const date = new Date(`${i}/1/${year} GMT+0000`);
  10614. const monthString = new Intl.DateTimeFormat(locale, Object.assign(Object.assign({}, formatOptions), { timeZone: 'UTC' })).format(date);
  10615. months.push({ text: monthString, value: i });
  10616. }
  10617. }
  10618. return months;
  10619. };
  10620. /**
  10621. * Returns information regarding
  10622. * selectable dates (i.e 1st, 2nd, 3rd, etc)
  10623. * within a reference month.
  10624. * @param locale The locale to format the date with
  10625. * @param refParts The reference month/year to generate dates for
  10626. * @param minParts The minimum bound on the date that can be returned
  10627. * @param maxParts The maximum bound on the date that can be returned
  10628. * @param dayValues The allowed date values
  10629. * @returns Date data to be used in ion-picker-column
  10630. */
  10631. const getDayColumnData = (locale, refParts, minParts, maxParts, dayValues, formatOptions = {
  10632. day: 'numeric',
  10633. }) => {
  10634. const { month, year } = refParts;
  10635. const days = [];
  10636. /**
  10637. * If we have max/min bounds that in the same
  10638. * month/year as the refParts, we should
  10639. * use the define day as the max/min day.
  10640. * Otherwise, fallback to the max/min days in a month.
  10641. */
  10642. const numDaysInMonth = getNumDaysInMonth(month, year);
  10643. 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
  10644. ? maxParts.day
  10645. : numDaysInMonth;
  10646. 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
  10647. ? minParts.day
  10648. : 1;
  10649. if (dayValues !== undefined) {
  10650. let processedDays = dayValues;
  10651. processedDays = processedDays.filter((day) => day >= minDay && day <= maxDay);
  10652. processedDays.forEach((processedDay) => {
  10653. const date = new Date(`${month}/${processedDay}/${year} GMT+0000`);
  10654. const dayString = new Intl.DateTimeFormat(locale, Object.assign(Object.assign({}, formatOptions), { timeZone: 'UTC' })).format(date);
  10655. days.push({ text: dayString, value: processedDay });
  10656. });
  10657. }
  10658. else {
  10659. for (let i = minDay; i <= maxDay; i++) {
  10660. const date = new Date(`${month}/${i}/${year} GMT+0000`);
  10661. const dayString = new Intl.DateTimeFormat(locale, Object.assign(Object.assign({}, formatOptions), { timeZone: 'UTC' })).format(date);
  10662. days.push({ text: dayString, value: i });
  10663. }
  10664. }
  10665. return days;
  10666. };
  10667. const getYearColumnData = (locale, refParts, minParts, maxParts, yearValues) => {
  10668. var _a, _b;
  10669. let processedYears = [];
  10670. if (yearValues !== undefined) {
  10671. processedYears = yearValues;
  10672. if ((maxParts === null || maxParts === void 0 ? void 0 : maxParts.year) !== undefined) {
  10673. processedYears = processedYears.filter((year) => year <= maxParts.year);
  10674. }
  10675. if ((minParts === null || minParts === void 0 ? void 0 : minParts.year) !== undefined) {
  10676. processedYears = processedYears.filter((year) => year >= minParts.year);
  10677. }
  10678. }
  10679. else {
  10680. const { year } = refParts;
  10681. const maxYear = (_a = maxParts === null || maxParts === void 0 ? void 0 : maxParts.year) !== null && _a !== void 0 ? _a : year;
  10682. const minYear = (_b = minParts === null || minParts === void 0 ? void 0 : minParts.year) !== null && _b !== void 0 ? _b : year - 100;
  10683. for (let i = minYear; i <= maxYear; i++) {
  10684. processedYears.push(i);
  10685. }
  10686. }
  10687. return processedYears.map((year) => ({
  10688. text: getYear(locale, { year, month: refParts.month, day: refParts.day }),
  10689. value: year,
  10690. }));
  10691. };
  10692. /**
  10693. * Given a starting date and an upper bound,
  10694. * this functions returns an array of all
  10695. * month objects in that range.
  10696. */
  10697. const getAllMonthsInRange = (currentParts, maxParts) => {
  10698. if (currentParts.month === maxParts.month && currentParts.year === maxParts.year) {
  10699. return [currentParts];
  10700. }
  10701. return [currentParts, ...getAllMonthsInRange(getNextMonth(currentParts), maxParts)];
  10702. };
  10703. /**
  10704. * Creates and returns picker items
  10705. * that represent the days in a month.
  10706. * Example: "Thu, Jun 2"
  10707. */
  10708. const getCombinedDateColumnData = (locale, todayParts, minParts, maxParts, dayValues, monthValues) => {
  10709. let items = [];
  10710. let parts = [];
  10711. /**
  10712. * Get all month objects from the min date
  10713. * to the max date. Note: Do not use getMonthColumnData
  10714. * as that function only generates dates within a
  10715. * single year.
  10716. */
  10717. let months = getAllMonthsInRange(minParts, maxParts);
  10718. /**
  10719. * Filter out any disallowed month values.
  10720. */
  10721. if (monthValues) {
  10722. months = months.filter(({ month }) => monthValues.includes(month));
  10723. }
  10724. /**
  10725. * Get all of the days in the month.
  10726. * From there, generate an array where
  10727. * each item has the month, date, and day
  10728. * of work as the text.
  10729. */
  10730. months.forEach((monthObject) => {
  10731. const referenceMonth = { month: monthObject.month, day: null, year: monthObject.year };
  10732. const monthDays = getDayColumnData(locale, referenceMonth, minParts, maxParts, dayValues, {
  10733. month: 'short',
  10734. day: 'numeric',
  10735. weekday: 'short',
  10736. });
  10737. const dateParts = [];
  10738. const dateColumnItems = [];
  10739. monthDays.forEach((dayObject) => {
  10740. const isToday = isSameDay(Object.assign(Object.assign({}, referenceMonth), { day: dayObject.value }), todayParts);
  10741. /**
  10742. * Today's date should read as "Today" (localized)
  10743. * not the actual date string
  10744. */
  10745. dateColumnItems.push({
  10746. text: isToday ? getTodayLabel(locale) : dayObject.text,
  10747. value: `${referenceMonth.year}-${referenceMonth.month}-${dayObject.value}`,
  10748. });
  10749. /**
  10750. * When selecting a date in the wheel picker
  10751. * we need access to the raw datetime parts data.
  10752. * The picker column only accepts values of
  10753. * type string or number, so we need to return
  10754. * two sets of data: A data set to be passed
  10755. * to the picker column, and a data set to
  10756. * be used to reference the raw data when
  10757. * updating the picker column value.
  10758. */
  10759. dateParts.push({
  10760. month: referenceMonth.month,
  10761. year: referenceMonth.year,
  10762. day: dayObject.value,
  10763. });
  10764. });
  10765. parts = [...parts, ...dateParts];
  10766. items = [...items, ...dateColumnItems];
  10767. });
  10768. return {
  10769. parts,
  10770. items,
  10771. };
  10772. };
  10773. const getTimeColumnsData = (locale, refParts, hourCycle, minParts, maxParts, allowedHourValues, allowedMinuteValues) => {
  10774. const computedHourCycle = getHourCycle(locale, hourCycle);
  10775. const use24Hour = is24Hour(computedHourCycle);
  10776. const { hours, minutes, am, pm } = generateTime(locale, refParts, computedHourCycle, minParts, maxParts, allowedHourValues, allowedMinuteValues);
  10777. const hoursItems = hours.map((hour) => {
  10778. return {
  10779. text: getFormattedHour(hour, computedHourCycle),
  10780. value: getInternalHourValue(hour, use24Hour, refParts.ampm),
  10781. };
  10782. });
  10783. const minutesItems = minutes.map((minute) => {
  10784. return {
  10785. text: addTimePadding(minute),
  10786. value: minute,
  10787. };
  10788. });
  10789. const dayPeriodItems = [];
  10790. if (am && !use24Hour) {
  10791. dayPeriodItems.push({
  10792. text: getLocalizedDayPeriod(locale, 'am'),
  10793. value: 'am',
  10794. });
  10795. }
  10796. if (pm && !use24Hour) {
  10797. dayPeriodItems.push({
  10798. text: getLocalizedDayPeriod(locale, 'pm'),
  10799. value: 'pm',
  10800. });
  10801. }
  10802. return {
  10803. minutesData: minutesItems,
  10804. hoursData: hoursItems,
  10805. dayPeriodData: dayPeriodItems,
  10806. };
  10807. };
  10808. const isYearDisabled = (refYear, minParts, maxParts) => {
  10809. if (minParts && minParts.year > refYear) {
  10810. return true;
  10811. }
  10812. if (maxParts && maxParts.year < refYear) {
  10813. return true;
  10814. }
  10815. return false;
  10816. };
  10817. /**
  10818. * Returns true if a given day should
  10819. * not be interactive according to its value,
  10820. * or the max/min dates.
  10821. */
  10822. const isDayDisabled = (refParts, minParts, maxParts, dayValues) => {
  10823. /**
  10824. * If this is a filler date (i.e. padding)
  10825. * then the date is disabled.
  10826. */
  10827. if (refParts.day === null) {
  10828. return true;
  10829. }
  10830. /**
  10831. * If user passed in a list of acceptable day values
  10832. * check to make sure that the date we are looking
  10833. * at is in this array.
  10834. */
  10835. if (dayValues !== undefined && !dayValues.includes(refParts.day)) {
  10836. return true;
  10837. }
  10838. /**
  10839. * Given a min date, perform the following
  10840. * checks. If any of them are true, then the
  10841. * day should be disabled:
  10842. * 1. Is the current year < the min allowed year?
  10843. * 2. Is the current year === min allowed year,
  10844. * but the current month < the min allowed month?
  10845. * 3. Is the current year === min allowed year, the
  10846. * current month === min allow month, but the current
  10847. * day < the min allowed day?
  10848. */
  10849. if (minParts && isBefore(refParts, minParts)) {
  10850. return true;
  10851. }
  10852. /**
  10853. * Given a max date, perform the following
  10854. * checks. If any of them are true, then the
  10855. * day should be disabled:
  10856. * 1. Is the current year > the max allowed year?
  10857. * 2. Is the current year === max allowed year,
  10858. * but the current month > the max allowed month?
  10859. * 3. Is the current year === max allowed year, the
  10860. * current month === max allow month, but the current
  10861. * day > the max allowed day?
  10862. */
  10863. if (maxParts && isAfter(refParts, maxParts)) {
  10864. return true;
  10865. }
  10866. /**
  10867. * If none of these checks
  10868. * passed then the date should
  10869. * be interactive.
  10870. */
  10871. return false;
  10872. };
  10873. /**
  10874. * Given a locale, a date, the selected date(s), and today's date,
  10875. * generate the state for a given calendar day button.
  10876. */
  10877. const getCalendarDayState = (locale, refParts, activeParts, todayParts, minParts, maxParts, dayValues) => {
  10878. /**
  10879. * activeParts signals what day(s) are currently selected in the datetime.
  10880. * If multiple="true", this will be an array, but the logic in this util
  10881. * is the same whether we have one selected day or many because we're only
  10882. * calculating the state for one button. So, we treat a single activeParts value
  10883. * the same as an array of length one.
  10884. */
  10885. const activePartsArray = Array.isArray(activeParts) ? activeParts : [activeParts];
  10886. /**
  10887. * The day button is active if it is selected, or in other words, if refParts
  10888. * matches at least one selected date.
  10889. */
  10890. const isActive = activePartsArray.find((parts) => isSameDay(refParts, parts)) !== undefined;
  10891. const isToday = isSameDay(refParts, todayParts);
  10892. const disabled = isDayDisabled(refParts, minParts, maxParts, dayValues);
  10893. /**
  10894. * Note that we always return one object regardless of whether activeParts
  10895. * was an array, since we pare down to one value for isActive.
  10896. */
  10897. return {
  10898. disabled,
  10899. isActive,
  10900. isToday,
  10901. ariaSelected: isActive ? 'true' : null,
  10902. ariaLabel: generateDayAriaLabel(locale, isToday, refParts),
  10903. text: refParts.day != null ? getDay(locale, refParts) : null,
  10904. };
  10905. };
  10906. /**
  10907. * Returns `true` if the month is disabled given the
  10908. * current date value and min/max date constraints.
  10909. */
  10910. const isMonthDisabled = (refParts, { minParts, maxParts, }) => {
  10911. // If the year is disabled then the month is disabled.
  10912. if (isYearDisabled(refParts.year, minParts, maxParts)) {
  10913. return true;
  10914. }
  10915. // If the date value is before the min date, then the month is disabled.
  10916. // If the date value is after the max date, then the month is disabled.
  10917. if ((minParts && isBefore(refParts, minParts)) || (maxParts && isAfter(refParts, maxParts))) {
  10918. return true;
  10919. }
  10920. return false;
  10921. };
  10922. /**
  10923. * Given a working date, an optional minimum date range,
  10924. * and an optional maximum date range; determine if the
  10925. * previous navigation button is disabled.
  10926. */
  10927. const isPrevMonthDisabled = (refParts, minParts, maxParts) => {
  10928. const prevMonth = Object.assign(Object.assign({}, getPreviousMonth(refParts)), { day: null });
  10929. return isMonthDisabled(prevMonth, {
  10930. minParts,
  10931. maxParts,
  10932. });
  10933. };
  10934. /**
  10935. * Given a working date and a maximum date range,
  10936. * determine if the next navigation button is disabled.
  10937. */
  10938. const isNextMonthDisabled = (refParts, maxParts) => {
  10939. const nextMonth = Object.assign(Object.assign({}, getNextMonth(refParts)), { day: null });
  10940. return isMonthDisabled(nextMonth, {
  10941. maxParts,
  10942. });
  10943. };
  10944. /**
  10945. * Given the value of the highlightedDates property
  10946. * and an ISO string, return the styles to use for
  10947. * that date, or undefined if none are found.
  10948. */
  10949. const getHighlightStyles = (highlightedDates, dateIsoString, el) => {
  10950. if (Array.isArray(highlightedDates)) {
  10951. const dateStringWithoutTime = dateIsoString.split('T')[0];
  10952. const matchingHighlight = highlightedDates.find((hd) => hd.date === dateStringWithoutTime);
  10953. if (matchingHighlight) {
  10954. return {
  10955. textColor: matchingHighlight.textColor,
  10956. backgroundColor: matchingHighlight.backgroundColor,
  10957. };
  10958. }
  10959. }
  10960. else {
  10961. /**
  10962. * Wrap in a try-catch to prevent exceptions in the user's function
  10963. * from interrupting the calendar's rendering.
  10964. */
  10965. try {
  10966. return highlightedDates(dateIsoString);
  10967. }
  10968. catch (e) {
  10969. printIonError('[ion-datetime] - Exception thrown from provided `highlightedDates` callback. Please check your function and try again.', el, e);
  10970. }
  10971. }
  10972. return undefined;
  10973. };
  10974. /**
  10975. * If a time zone is provided in the format options, the rendered text could
  10976. * differ from what was selected in the Datetime, which could cause
  10977. * confusion.
  10978. */
  10979. const warnIfTimeZoneProvided = (el, formatOptions) => {
  10980. var _a, _b, _c, _d;
  10981. if (((_a = formatOptions === null || formatOptions === void 0 ? void 0 : formatOptions.date) === null || _a === void 0 ? void 0 : _a.timeZone) ||
  10982. ((_b = formatOptions === null || formatOptions === void 0 ? void 0 : formatOptions.date) === null || _b === void 0 ? void 0 : _b.timeZoneName) ||
  10983. ((_c = formatOptions === null || formatOptions === void 0 ? void 0 : formatOptions.time) === null || _c === void 0 ? void 0 : _c.timeZone) ||
  10984. ((_d = formatOptions === null || formatOptions === void 0 ? void 0 : formatOptions.time) === null || _d === void 0 ? void 0 : _d.timeZoneName)) {
  10985. printIonWarning('[ion-datetime] - "timeZone" and "timeZoneName" are not supported in "formatOptions".', el);
  10986. }
  10987. };
  10988. const checkForPresentationFormatMismatch = (el, presentation, formatOptions) => {
  10989. // formatOptions is not required
  10990. if (!formatOptions)
  10991. return;
  10992. // If formatOptions is provided, the date and/or time objects are required, depending on the presentation
  10993. switch (presentation) {
  10994. case 'date':
  10995. case 'month-year':
  10996. case 'month':
  10997. case 'year':
  10998. if (formatOptions.date === undefined) {
  10999. printIonWarning(`[ion-datetime] - The '${presentation}' presentation requires a date object in formatOptions.`, el);
  11000. }
  11001. break;
  11002. case 'time':
  11003. if (formatOptions.time === undefined) {
  11004. printIonWarning(`[ion-datetime] - The 'time' presentation requires a time object in formatOptions.`, el);
  11005. }
  11006. break;
  11007. case 'date-time':
  11008. case 'time-date':
  11009. if (formatOptions.date === undefined && formatOptions.time === undefined) {
  11010. printIonWarning(`[ion-datetime] - The '${presentation}' presentation requires either a date or time object (or both) in formatOptions.`, el);
  11011. }
  11012. break;
  11013. }
  11014. };
  11015. 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%}";
  11016. var IonDatetimeIosStyle0 = datetimeIosCss;
  11017. 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}";
  11018. var IonDatetimeMdStyle0 = datetimeMdCss;
  11019. /**
  11020. * @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
  11021. *
  11022. * @slot title - The title of the datetime.
  11023. * @slot buttons - The buttons in the datetime.
  11024. * @slot time-label - The label for the time selector in the datetime.
  11025. *
  11026. * @part wheel-item - The individual items when using a wheel style layout, or in the
  11027. * month/year picker when using a grid style layout.
  11028. * @part wheel-item active - The currently selected wheel-item.
  11029. *
  11030. * @part time-button - The button that opens the time picker when using a grid style
  11031. * layout with `presentation="date-time"` or `"time-date"`.
  11032. * @part time-button active - The time picker button when the picker is open.
  11033. *
  11034. * @part month-year-button - The button that opens the month/year picker when
  11035. * using a grid style layout.
  11036. *
  11037. * @part calendar-day - The individual buttons that display a day inside of the datetime
  11038. * calendar.
  11039. * @part calendar-day active - The currently selected calendar day.
  11040. * @part calendar-day today - The calendar day that contains the current day.
  11041. * @part calendar-day disabled - The calendar day that is disabled.
  11042. */
  11043. class Datetime {
  11044. constructor(hostRef) {
  11045. registerInstance(this, hostRef);
  11046. this.ionCancel = createEvent(this, "ionCancel", 7);
  11047. this.ionChange = createEvent(this, "ionChange", 7);
  11048. this.ionValueChange = createEvent(this, "ionValueChange", 7);
  11049. this.ionFocus = createEvent(this, "ionFocus", 7);
  11050. this.ionBlur = createEvent(this, "ionBlur", 7);
  11051. this.ionStyle = createEvent(this, "ionStyle", 7);
  11052. this.ionRender = createEvent(this, "ionRender", 7);
  11053. this.inputId = `ion-dt-${datetimeIds++}`;
  11054. this.prevPresentation = null;
  11055. this.warnIfIncorrectValueUsage = () => {
  11056. const { multiple, value } = this;
  11057. if (!multiple && Array.isArray(value)) {
  11058. /**
  11059. * We do some processing on the `value` array so
  11060. * that it looks more like an array when logged to
  11061. * the console.
  11062. * Example given ['a', 'b']
  11063. * Default toString() behavior: a,b
  11064. * Custom behavior: ['a', 'b']
  11065. */
  11066. 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".
  11067. Value Passed: [${value.map((v) => `'${v}'`).join(', ')}]
  11068. `, this.el);
  11069. }
  11070. };
  11071. this.setValue = (value) => {
  11072. this.value = value;
  11073. this.ionChange.emit({ value });
  11074. };
  11075. /**
  11076. * Returns the DatetimePart interface
  11077. * to use when rendering an initial set of
  11078. * data. This should be used when rendering an
  11079. * interface in an environment where the `value`
  11080. * may not be set. This function works
  11081. * by returning the first selected date and then
  11082. * falling back to defaultParts if no active date
  11083. * is selected.
  11084. */
  11085. this.getActivePartsWithFallback = () => {
  11086. var _a;
  11087. const { defaultParts } = this;
  11088. return (_a = this.getActivePart()) !== null && _a !== void 0 ? _a : defaultParts;
  11089. };
  11090. this.getActivePart = () => {
  11091. const { activeParts } = this;
  11092. return Array.isArray(activeParts) ? activeParts[0] : activeParts;
  11093. };
  11094. this.closeParentOverlay = (role) => {
  11095. const popoverOrModal = this.el.closest('ion-modal, ion-popover');
  11096. if (popoverOrModal) {
  11097. popoverOrModal.dismiss(undefined, role);
  11098. }
  11099. };
  11100. this.setWorkingParts = (parts) => {
  11101. this.workingParts = Object.assign({}, parts);
  11102. };
  11103. this.setActiveParts = (parts, removeDate = false) => {
  11104. /** if the datetime component is in readonly mode,
  11105. * allow browsing of the calendar without changing
  11106. * the set value
  11107. */
  11108. if (this.readonly) {
  11109. return;
  11110. }
  11111. const { multiple, minParts, maxParts, activeParts } = this;
  11112. /**
  11113. * When setting the active parts, it is possible
  11114. * to set invalid data. For example,
  11115. * when updating January 31 to February,
  11116. * February 31 does not exist. As a result
  11117. * we need to validate the active parts and
  11118. * ensure that we are only setting valid dates.
  11119. * Additionally, we need to update the working parts
  11120. * too in the event that the validated parts are different.
  11121. */
  11122. const validatedParts = validateParts(parts, minParts, maxParts);
  11123. this.setWorkingParts(validatedParts);
  11124. if (multiple) {
  11125. const activePartsArray = Array.isArray(activeParts) ? activeParts : [activeParts];
  11126. if (removeDate) {
  11127. this.activeParts = activePartsArray.filter((p) => !isSameDay(p, validatedParts));
  11128. }
  11129. else {
  11130. this.activeParts = [...activePartsArray, validatedParts];
  11131. }
  11132. }
  11133. else {
  11134. this.activeParts = Object.assign({}, validatedParts);
  11135. }
  11136. const hasSlottedButtons = this.el.querySelector('[slot="buttons"]') !== null;
  11137. if (hasSlottedButtons || this.showDefaultButtons) {
  11138. return;
  11139. }
  11140. this.confirm();
  11141. };
  11142. this.initializeKeyboardListeners = () => {
  11143. const calendarBodyRef = this.calendarBodyRef;
  11144. if (!calendarBodyRef) {
  11145. return;
  11146. }
  11147. const root = this.el.shadowRoot;
  11148. /**
  11149. * Get a reference to the month
  11150. * element we are currently viewing.
  11151. */
  11152. const currentMonth = calendarBodyRef.querySelector('.calendar-month:nth-of-type(2)');
  11153. /**
  11154. * When focusing the calendar body, we want to pass focus
  11155. * to the working day, but other days should
  11156. * only be accessible using the arrow keys. Pressing
  11157. * Tab should jump between bodies of selectable content.
  11158. */
  11159. const checkCalendarBodyFocus = (ev) => {
  11160. var _a;
  11161. const record = ev[0];
  11162. /**
  11163. * If calendar body was already focused
  11164. * when this fired or if the calendar body
  11165. * if not currently focused, we should not re-focus
  11166. * the inner day.
  11167. */
  11168. if (((_a = record.oldValue) === null || _a === void 0 ? void 0 : _a.includes('ion-focused')) || !calendarBodyRef.classList.contains('ion-focused')) {
  11169. return;
  11170. }
  11171. this.focusWorkingDay(currentMonth);
  11172. };
  11173. const mo = new MutationObserver(checkCalendarBodyFocus);
  11174. mo.observe(calendarBodyRef, { attributeFilter: ['class'], attributeOldValue: true });
  11175. this.destroyKeyboardMO = () => {
  11176. mo === null || mo === void 0 ? void 0 : mo.disconnect();
  11177. };
  11178. /**
  11179. * We must use keydown not keyup as we want
  11180. * to prevent scrolling when using the arrow keys.
  11181. */
  11182. calendarBodyRef.addEventListener('keydown', (ev) => {
  11183. const activeElement = root.activeElement;
  11184. if (!activeElement || !activeElement.classList.contains('calendar-day')) {
  11185. return;
  11186. }
  11187. const parts = getPartsFromCalendarDay(activeElement);
  11188. let partsToFocus;
  11189. switch (ev.key) {
  11190. case 'ArrowDown':
  11191. ev.preventDefault();
  11192. partsToFocus = getNextWeek(parts);
  11193. break;
  11194. case 'ArrowUp':
  11195. ev.preventDefault();
  11196. partsToFocus = getPreviousWeek(parts);
  11197. break;
  11198. case 'ArrowRight':
  11199. ev.preventDefault();
  11200. partsToFocus = getNextDay(parts);
  11201. break;
  11202. case 'ArrowLeft':
  11203. ev.preventDefault();
  11204. partsToFocus = getPreviousDay(parts);
  11205. break;
  11206. case 'Home':
  11207. ev.preventDefault();
  11208. partsToFocus = getStartOfWeek(parts);
  11209. break;
  11210. case 'End':
  11211. ev.preventDefault();
  11212. partsToFocus = getEndOfWeek(parts);
  11213. break;
  11214. case 'PageUp':
  11215. ev.preventDefault();
  11216. partsToFocus = ev.shiftKey ? getPreviousYear(parts) : getPreviousMonth(parts);
  11217. break;
  11218. case 'PageDown':
  11219. ev.preventDefault();
  11220. partsToFocus = ev.shiftKey ? getNextYear(parts) : getNextMonth(parts);
  11221. break;
  11222. /**
  11223. * Do not preventDefault here
  11224. * as we do not want to override other
  11225. * browser defaults such as pressing Enter/Space
  11226. * to select a day.
  11227. */
  11228. default:
  11229. return;
  11230. }
  11231. /**
  11232. * If the day we want to move focus to is
  11233. * disabled, do not do anything.
  11234. */
  11235. if (isDayDisabled(partsToFocus, this.minParts, this.maxParts)) {
  11236. return;
  11237. }
  11238. this.setWorkingParts(Object.assign(Object.assign({}, this.workingParts), partsToFocus));
  11239. /**
  11240. * Give view a chance to re-render
  11241. * then move focus to the new working day
  11242. */
  11243. requestAnimationFrame(() => this.focusWorkingDay(currentMonth));
  11244. });
  11245. };
  11246. this.focusWorkingDay = (currentMonth) => {
  11247. /**
  11248. * Get the number of padding days so
  11249. * we know how much to offset our next selector by
  11250. * to grab the correct calendar-day element.
  11251. */
  11252. const padding = currentMonth.querySelectorAll('.calendar-day-padding');
  11253. const { day } = this.workingParts;
  11254. if (day === null) {
  11255. return;
  11256. }
  11257. /**
  11258. * Get the calendar day element
  11259. * and focus it.
  11260. */
  11261. const dayEl = currentMonth.querySelector(`.calendar-day-wrapper:nth-of-type(${padding.length + day}) .calendar-day`);
  11262. if (dayEl) {
  11263. dayEl.focus();
  11264. }
  11265. };
  11266. this.processMinParts = () => {
  11267. const { min, defaultParts } = this;
  11268. if (min === undefined) {
  11269. this.minParts = undefined;
  11270. return;
  11271. }
  11272. this.minParts = parseMinParts(min, defaultParts);
  11273. };
  11274. this.processMaxParts = () => {
  11275. const { max, defaultParts } = this;
  11276. if (max === undefined) {
  11277. this.maxParts = undefined;
  11278. return;
  11279. }
  11280. this.maxParts = parseMaxParts(max, defaultParts);
  11281. };
  11282. this.initializeCalendarListener = () => {
  11283. const calendarBodyRef = this.calendarBodyRef;
  11284. if (!calendarBodyRef) {
  11285. return;
  11286. }
  11287. /**
  11288. * For performance reasons, we only render 3
  11289. * months at a time: The current month, the previous
  11290. * month, and the next month. We have a scroll listener
  11291. * on the calendar body to append/prepend new months.
  11292. *
  11293. * We can do this because Stencil is smart enough to not
  11294. * re-create the .calendar-month containers, but rather
  11295. * update the content within those containers.
  11296. *
  11297. * As an added bonus, WebKit has some troubles with
  11298. * scroll-snap-stop: always, so not rendering all of
  11299. * the months in a row allows us to mostly sidestep
  11300. * that issue.
  11301. */
  11302. const months = calendarBodyRef.querySelectorAll('.calendar-month');
  11303. const startMonth = months[0];
  11304. const workingMonth = months[1];
  11305. const endMonth = months[2];
  11306. const mode = getIonMode$1(this);
  11307. const needsiOSRubberBandFix = mode === 'ios' && typeof navigator !== 'undefined' && navigator.maxTouchPoints > 1;
  11308. /**
  11309. * Before setting up the scroll listener,
  11310. * scroll the middle month into view.
  11311. * scrollIntoView() will scroll entire page
  11312. * if element is not in viewport. Use scrollLeft instead.
  11313. */
  11314. writeTask(() => {
  11315. calendarBodyRef.scrollLeft = startMonth.clientWidth * (isRTL$1(this.el) ? -1 : 1);
  11316. const getChangedMonth = (parts) => {
  11317. const box = calendarBodyRef.getBoundingClientRect();
  11318. /**
  11319. * If the current scroll position is all the way to the left
  11320. * then we have scrolled to the previous month.
  11321. * Otherwise, assume that we have scrolled to the next
  11322. * month. We have a tolerance of 2px to account for
  11323. * sub pixel rendering.
  11324. *
  11325. * Check below the next line ensures that we did not
  11326. * swipe and abort (i.e. we swiped but we are still on the current month).
  11327. */
  11328. const condition = isRTL$1(this.el) ? calendarBodyRef.scrollLeft >= -2 : calendarBodyRef.scrollLeft <= 2;
  11329. const month = condition ? startMonth : endMonth;
  11330. /**
  11331. * The edge of the month must be lined up with
  11332. * the edge of the calendar body in order for
  11333. * the component to update. Otherwise, it
  11334. * may be the case that the user has paused their
  11335. * swipe or the browser has not finished snapping yet.
  11336. * Rather than check if the x values are equal,
  11337. * we give it a tolerance of 2px to account for
  11338. * sub pixel rendering.
  11339. */
  11340. const monthBox = month.getBoundingClientRect();
  11341. if (Math.abs(monthBox.x - box.x) > 2)
  11342. return;
  11343. /**
  11344. * If we're force-rendering a month, assume we've
  11345. * scrolled to that and return it.
  11346. *
  11347. * If forceRenderDate is ever used in a context where the
  11348. * forced month is not immediately auto-scrolled to, this
  11349. * should be updated to also check whether `month` has the
  11350. * same month and year as the forced date.
  11351. */
  11352. const { forceRenderDate } = this;
  11353. if (forceRenderDate !== undefined) {
  11354. return { month: forceRenderDate.month, year: forceRenderDate.year, day: forceRenderDate.day };
  11355. }
  11356. /**
  11357. * From here, we can determine if the start
  11358. * month or the end month was scrolled into view.
  11359. * If no month was changed, then we can return from
  11360. * the scroll callback early.
  11361. */
  11362. if (month === startMonth) {
  11363. return getPreviousMonth(parts);
  11364. }
  11365. else if (month === endMonth) {
  11366. return getNextMonth(parts);
  11367. }
  11368. else {
  11369. return;
  11370. }
  11371. };
  11372. const updateActiveMonth = () => {
  11373. if (needsiOSRubberBandFix) {
  11374. calendarBodyRef.style.removeProperty('pointer-events');
  11375. appliediOSRubberBandFix = false;
  11376. }
  11377. /**
  11378. * If the month did not change
  11379. * then we can return early.
  11380. */
  11381. const newDate = getChangedMonth(this.workingParts);
  11382. if (!newDate)
  11383. return;
  11384. const { month, day, year } = newDate;
  11385. if (isMonthDisabled({ month, year, day: null }, {
  11386. minParts: Object.assign(Object.assign({}, this.minParts), { day: null }),
  11387. maxParts: Object.assign(Object.assign({}, this.maxParts), { day: null }),
  11388. })) {
  11389. return;
  11390. }
  11391. /**
  11392. * Prevent scrolling for other browsers
  11393. * to give the DOM time to update and the container
  11394. * time to properly snap.
  11395. */
  11396. calendarBodyRef.style.setProperty('overflow', 'hidden');
  11397. /**
  11398. * Use a writeTask here to ensure
  11399. * that the state is updated and the
  11400. * correct month is scrolled into view
  11401. * in the same frame. This is not
  11402. * typically a problem on newer devices
  11403. * but older/slower device may have a flicker
  11404. * if we did not do this.
  11405. */
  11406. writeTask(() => {
  11407. this.setWorkingParts(Object.assign(Object.assign({}, this.workingParts), { month, day: day, year }));
  11408. calendarBodyRef.scrollLeft = workingMonth.clientWidth * (isRTL$1(this.el) ? -1 : 1);
  11409. calendarBodyRef.style.removeProperty('overflow');
  11410. if (this.resolveForceDateScrolling) {
  11411. this.resolveForceDateScrolling();
  11412. }
  11413. });
  11414. };
  11415. /**
  11416. * When the container finishes scrolling we
  11417. * need to update the DOM with the selected month.
  11418. */
  11419. let scrollTimeout;
  11420. /**
  11421. * We do not want to attempt to set pointer-events
  11422. * multiple times within a single swipe gesture as
  11423. * that adds unnecessary work to the main thread.
  11424. */
  11425. let appliediOSRubberBandFix = false;
  11426. const scrollCallback = () => {
  11427. if (scrollTimeout) {
  11428. clearTimeout(scrollTimeout);
  11429. }
  11430. /**
  11431. * On iOS it is possible to quickly rubber band
  11432. * the scroll area before the scroll timeout has fired.
  11433. * This results in users reaching the end of the scrollable
  11434. * container before the DOM has updated.
  11435. * By setting `pointer-events: none` we can ensure that
  11436. * subsequent swipes do not happen while the container
  11437. * is snapping.
  11438. */
  11439. if (!appliediOSRubberBandFix && needsiOSRubberBandFix) {
  11440. calendarBodyRef.style.setProperty('pointer-events', 'none');
  11441. appliediOSRubberBandFix = true;
  11442. }
  11443. // Wait ~3 frames
  11444. scrollTimeout = setTimeout(updateActiveMonth, 50);
  11445. };
  11446. calendarBodyRef.addEventListener('scroll', scrollCallback);
  11447. this.destroyCalendarListener = () => {
  11448. calendarBodyRef.removeEventListener('scroll', scrollCallback);
  11449. };
  11450. });
  11451. };
  11452. /**
  11453. * Clean up all listeners except for the overlay
  11454. * listener. This is so that we can re-create the listeners
  11455. * if the datetime has been hidden/presented by a modal or popover.
  11456. */
  11457. this.destroyInteractionListeners = () => {
  11458. const { destroyCalendarListener, destroyKeyboardMO } = this;
  11459. if (destroyCalendarListener !== undefined) {
  11460. destroyCalendarListener();
  11461. }
  11462. if (destroyKeyboardMO !== undefined) {
  11463. destroyKeyboardMO();
  11464. }
  11465. };
  11466. this.processValue = (value) => {
  11467. const hasValue = value !== null && value !== undefined && value !== '' && (!Array.isArray(value) || value.length > 0);
  11468. const valueToProcess = hasValue ? parseDate(value) : this.defaultParts;
  11469. const { minParts, maxParts, workingParts, el } = this;
  11470. this.warnIfIncorrectValueUsage();
  11471. /**
  11472. * Return early if the value wasn't parsed correctly, such as
  11473. * if an improperly formatted date string was provided.
  11474. */
  11475. if (!valueToProcess) {
  11476. return;
  11477. }
  11478. /**
  11479. * Datetime should only warn of out of bounds values
  11480. * if set by the user. If the `value` is undefined,
  11481. * we will default to today's date which may be out
  11482. * of bounds. In this case, the warning makes it look
  11483. * like the developer did something wrong which is
  11484. * not true.
  11485. */
  11486. if (hasValue) {
  11487. warnIfValueOutOfBounds(valueToProcess, minParts, maxParts);
  11488. }
  11489. /**
  11490. * If there are multiple values, pick an arbitrary one to clamp to. This way,
  11491. * if the values are across months, we always show at least one of them. Note
  11492. * that the values don't necessarily have to be in order.
  11493. */
  11494. const singleValue = Array.isArray(valueToProcess) ? valueToProcess[0] : valueToProcess;
  11495. const targetValue = clampDate(singleValue, minParts, maxParts);
  11496. const { month, day, year, hour, minute } = targetValue;
  11497. const ampm = parseAmPm(hour);
  11498. /**
  11499. * Since `activeParts` indicates a value that
  11500. * been explicitly selected either by the
  11501. * user or the app, only update `activeParts`
  11502. * if the `value` property is set.
  11503. */
  11504. if (hasValue) {
  11505. if (Array.isArray(valueToProcess)) {
  11506. this.activeParts = [...valueToProcess];
  11507. }
  11508. else {
  11509. this.activeParts = {
  11510. month,
  11511. day,
  11512. year,
  11513. hour,
  11514. minute,
  11515. ampm,
  11516. };
  11517. }
  11518. }
  11519. else {
  11520. /**
  11521. * Reset the active parts if the value is not set.
  11522. * This will clear the selected calendar day when
  11523. * performing a clear action or using the reset() method.
  11524. */
  11525. this.activeParts = [];
  11526. }
  11527. /**
  11528. * Only animate if:
  11529. * 1. We're using grid style (wheel style pickers should just jump to new value)
  11530. * 2. The month and/or year actually changed, and both are defined (otherwise there's nothing to animate to)
  11531. * 3. The calendar body is visible (prevents animation when in collapsed datetime-button, for example)
  11532. * 4. The month/year picker is not open (since you wouldn't see the animation anyway)
  11533. */
  11534. const didChangeMonth = (month !== undefined && month !== workingParts.month) || (year !== undefined && year !== workingParts.year);
  11535. const bodyIsVisible = el.classList.contains('datetime-ready');
  11536. const { isGridStyle, showMonthAndYear } = this;
  11537. let areAllSelectedDatesInSameMonth = true;
  11538. if (Array.isArray(valueToProcess)) {
  11539. const firstMonth = valueToProcess[0].month;
  11540. for (const date of valueToProcess) {
  11541. if (date.month !== firstMonth) {
  11542. areAllSelectedDatesInSameMonth = false;
  11543. break;
  11544. }
  11545. }
  11546. }
  11547. /**
  11548. * If there is more than one date selected
  11549. * and the dates aren't all in the same month,
  11550. * then we should neither animate to the date
  11551. * nor update the working parts because we do
  11552. * not know which date the user wants to view.
  11553. */
  11554. if (areAllSelectedDatesInSameMonth) {
  11555. if (isGridStyle && didChangeMonth && bodyIsVisible && !showMonthAndYear) {
  11556. this.animateToDate(targetValue);
  11557. }
  11558. else {
  11559. /**
  11560. * We only need to do this if we didn't just animate to a new month,
  11561. * since that calls prevMonth/nextMonth which calls setWorkingParts for us.
  11562. */
  11563. this.setWorkingParts({
  11564. month,
  11565. day,
  11566. year,
  11567. hour,
  11568. minute,
  11569. ampm,
  11570. });
  11571. }
  11572. }
  11573. };
  11574. this.animateToDate = async (targetValue) => {
  11575. const { workingParts } = this;
  11576. /**
  11577. * Tell other render functions that we need to force the
  11578. * target month to appear in place of the actual next/prev month.
  11579. * Because this is a State variable, a rerender will be triggered
  11580. * automatically, updating the rendered months.
  11581. */
  11582. this.forceRenderDate = targetValue;
  11583. /**
  11584. * Flag that we've started scrolling to the forced date.
  11585. * The resolve function will be called by the datetime's
  11586. * scroll listener when it's done updating everything.
  11587. * This is a replacement for making prev/nextMonth async,
  11588. * since the logic we're waiting on is in a listener.
  11589. */
  11590. const forceDateScrollingPromise = new Promise((resolve) => {
  11591. this.resolveForceDateScrolling = resolve;
  11592. });
  11593. /**
  11594. * Animate smoothly to the forced month. This will also update
  11595. * workingParts and correct the surrounding months for us.
  11596. */
  11597. const targetMonthIsBefore = isBefore(targetValue, workingParts);
  11598. targetMonthIsBefore ? this.prevMonth() : this.nextMonth();
  11599. await forceDateScrollingPromise;
  11600. this.resolveForceDateScrolling = undefined;
  11601. this.forceRenderDate = undefined;
  11602. };
  11603. this.onFocus = () => {
  11604. this.ionFocus.emit();
  11605. };
  11606. this.onBlur = () => {
  11607. this.ionBlur.emit();
  11608. };
  11609. this.hasValue = () => {
  11610. return this.value != null;
  11611. };
  11612. this.nextMonth = () => {
  11613. const calendarBodyRef = this.calendarBodyRef;
  11614. if (!calendarBodyRef) {
  11615. return;
  11616. }
  11617. const nextMonth = calendarBodyRef.querySelector('.calendar-month:last-of-type');
  11618. if (!nextMonth) {
  11619. return;
  11620. }
  11621. const left = nextMonth.offsetWidth * 2;
  11622. calendarBodyRef.scrollTo({
  11623. top: 0,
  11624. left: left * (isRTL$1(this.el) ? -1 : 1),
  11625. behavior: 'smooth',
  11626. });
  11627. };
  11628. this.prevMonth = () => {
  11629. const calendarBodyRef = this.calendarBodyRef;
  11630. if (!calendarBodyRef) {
  11631. return;
  11632. }
  11633. const prevMonth = calendarBodyRef.querySelector('.calendar-month:first-of-type');
  11634. if (!prevMonth) {
  11635. return;
  11636. }
  11637. calendarBodyRef.scrollTo({
  11638. top: 0,
  11639. left: 0,
  11640. behavior: 'smooth',
  11641. });
  11642. };
  11643. this.toggleMonthAndYearView = () => {
  11644. this.showMonthAndYear = !this.showMonthAndYear;
  11645. };
  11646. this.showMonthAndYear = false;
  11647. this.activeParts = [];
  11648. this.workingParts = {
  11649. month: 5,
  11650. day: 28,
  11651. year: 2021,
  11652. hour: 13,
  11653. minute: 52,
  11654. ampm: 'pm',
  11655. };
  11656. this.isTimePopoverOpen = false;
  11657. this.forceRenderDate = undefined;
  11658. this.color = 'primary';
  11659. this.name = this.inputId;
  11660. this.disabled = false;
  11661. this.formatOptions = undefined;
  11662. this.readonly = false;
  11663. this.isDateEnabled = undefined;
  11664. this.min = undefined;
  11665. this.max = undefined;
  11666. this.presentation = 'date-time';
  11667. this.cancelText = 'Cancel';
  11668. this.doneText = 'Done';
  11669. this.clearText = 'Clear';
  11670. this.yearValues = undefined;
  11671. this.monthValues = undefined;
  11672. this.dayValues = undefined;
  11673. this.hourValues = undefined;
  11674. this.minuteValues = undefined;
  11675. this.locale = 'default';
  11676. this.firstDayOfWeek = 0;
  11677. this.titleSelectedDatesFormatter = undefined;
  11678. this.multiple = false;
  11679. this.highlightedDates = undefined;
  11680. this.value = undefined;
  11681. this.showDefaultTitle = false;
  11682. this.showDefaultButtons = false;
  11683. this.showClearButton = false;
  11684. this.showDefaultTimeLabel = true;
  11685. this.hourCycle = undefined;
  11686. this.size = 'fixed';
  11687. this.preferWheel = false;
  11688. }
  11689. formatOptionsChanged() {
  11690. const { el, formatOptions, presentation } = this;
  11691. checkForPresentationFormatMismatch(el, presentation, formatOptions);
  11692. warnIfTimeZoneProvided(el, formatOptions);
  11693. }
  11694. disabledChanged() {
  11695. this.emitStyle();
  11696. }
  11697. minChanged() {
  11698. this.processMinParts();
  11699. }
  11700. maxChanged() {
  11701. this.processMaxParts();
  11702. }
  11703. presentationChanged() {
  11704. const { el, formatOptions, presentation } = this;
  11705. checkForPresentationFormatMismatch(el, presentation, formatOptions);
  11706. }
  11707. get isGridStyle() {
  11708. const { presentation, preferWheel } = this;
  11709. const hasDatePresentation = presentation === 'date' || presentation === 'date-time' || presentation === 'time-date';
  11710. return hasDatePresentation && !preferWheel;
  11711. }
  11712. yearValuesChanged() {
  11713. this.parsedYearValues = convertToArrayOfNumbers(this.yearValues);
  11714. }
  11715. monthValuesChanged() {
  11716. this.parsedMonthValues = convertToArrayOfNumbers(this.monthValues);
  11717. }
  11718. dayValuesChanged() {
  11719. this.parsedDayValues = convertToArrayOfNumbers(this.dayValues);
  11720. }
  11721. hourValuesChanged() {
  11722. this.parsedHourValues = convertToArrayOfNumbers(this.hourValues);
  11723. }
  11724. minuteValuesChanged() {
  11725. this.parsedMinuteValues = convertToArrayOfNumbers(this.minuteValues);
  11726. }
  11727. /**
  11728. * Update the datetime value when the value changes
  11729. */
  11730. async valueChanged() {
  11731. const { value } = this;
  11732. if (this.hasValue()) {
  11733. this.processValue(value);
  11734. }
  11735. this.emitStyle();
  11736. this.ionValueChange.emit({ value });
  11737. }
  11738. /**
  11739. * Confirms the selected datetime value, updates the
  11740. * `value` property, and optionally closes the popover
  11741. * or modal that the datetime was presented in.
  11742. */
  11743. async confirm(closeOverlay = false) {
  11744. const { isCalendarPicker, activeParts, preferWheel, workingParts } = this;
  11745. /**
  11746. * We only update the value if the presentation is not a calendar picker.
  11747. */
  11748. if (activeParts !== undefined || !isCalendarPicker) {
  11749. const activePartsIsArray = Array.isArray(activeParts);
  11750. if (activePartsIsArray && activeParts.length === 0) {
  11751. if (preferWheel) {
  11752. /**
  11753. * If the datetime is using a wheel picker, but the
  11754. * active parts are empty, then the user has confirmed the
  11755. * initial value (working parts) presented to them.
  11756. */
  11757. this.setValue(convertDataToISO(workingParts));
  11758. }
  11759. else {
  11760. this.setValue(undefined);
  11761. }
  11762. }
  11763. else {
  11764. this.setValue(convertDataToISO(activeParts));
  11765. }
  11766. }
  11767. if (closeOverlay) {
  11768. this.closeParentOverlay(CONFIRM_ROLE);
  11769. }
  11770. }
  11771. /**
  11772. * Resets the internal state of the datetime but does not update the value.
  11773. * Passing a valid ISO-8601 string will reset the state of the component to the provided date.
  11774. * If no value is provided, the internal state will be reset to the clamped value of the min, max and today.
  11775. */
  11776. async reset(startDate) {
  11777. this.processValue(startDate);
  11778. }
  11779. /**
  11780. * Emits the ionCancel event and
  11781. * optionally closes the popover
  11782. * or modal that the datetime was
  11783. * presented in.
  11784. */
  11785. async cancel(closeOverlay = false) {
  11786. this.ionCancel.emit();
  11787. if (closeOverlay) {
  11788. this.closeParentOverlay(CANCEL_ROLE);
  11789. }
  11790. }
  11791. get isCalendarPicker() {
  11792. const { presentation } = this;
  11793. return presentation === 'date' || presentation === 'date-time' || presentation === 'time-date';
  11794. }
  11795. connectedCallback() {
  11796. this.clearFocusVisible = startFocusVisible(this.el).destroy;
  11797. }
  11798. disconnectedCallback() {
  11799. if (this.clearFocusVisible) {
  11800. this.clearFocusVisible();
  11801. this.clearFocusVisible = undefined;
  11802. }
  11803. }
  11804. initializeListeners() {
  11805. this.initializeCalendarListener();
  11806. this.initializeKeyboardListeners();
  11807. }
  11808. componentDidLoad() {
  11809. const { el, intersectionTrackerRef } = this;
  11810. /**
  11811. * If a scrollable element is hidden using `display: none`,
  11812. * it will not have a scroll height meaning we cannot scroll elements
  11813. * into view. As a result, we will need to wait for the datetime to become
  11814. * visible if used inside of a modal or a popover otherwise the scrollable
  11815. * areas will not have the correct values snapped into place.
  11816. */
  11817. const visibleCallback = (entries) => {
  11818. const ev = entries[0];
  11819. if (!ev.isIntersecting) {
  11820. return;
  11821. }
  11822. this.initializeListeners();
  11823. /**
  11824. * TODO FW-2793: Datetime needs a frame to ensure that it
  11825. * can properly scroll contents into view. As a result
  11826. * we hide the scrollable content until after that frame
  11827. * so users do not see the content quickly shifting. The downside
  11828. * is that the content will pop into view a frame after. Maybe there
  11829. * is a better way to handle this?
  11830. */
  11831. writeTask(() => {
  11832. this.el.classList.add('datetime-ready');
  11833. });
  11834. };
  11835. const visibleIO = new IntersectionObserver(visibleCallback, { threshold: 0.01, root: el });
  11836. /**
  11837. * Use raf to avoid a race condition between the component loading and
  11838. * its display animation starting (such as when shown in a modal). This
  11839. * could cause the datetime to start at a visibility of 0, erroneously
  11840. * triggering the `hiddenIO` observer below.
  11841. */
  11842. raf(() => visibleIO === null || visibleIO === void 0 ? void 0 : visibleIO.observe(intersectionTrackerRef));
  11843. /**
  11844. * We need to clean up listeners when the datetime is hidden
  11845. * in a popover/modal so that we can properly scroll containers
  11846. * back into view if they are re-presented. When the datetime is hidden
  11847. * the scroll areas have scroll widths/heights of 0px, so any snapping
  11848. * we did originally has been lost.
  11849. */
  11850. const hiddenCallback = (entries) => {
  11851. const ev = entries[0];
  11852. if (ev.isIntersecting) {
  11853. return;
  11854. }
  11855. this.destroyInteractionListeners();
  11856. /**
  11857. * When datetime is hidden, we need to make sure that
  11858. * the month/year picker is closed. Otherwise,
  11859. * it will be open when the datetime re-appears
  11860. * and the scroll area of the calendar grid will be 0.
  11861. * As a result, the wrong month will be shown.
  11862. */
  11863. this.showMonthAndYear = false;
  11864. writeTask(() => {
  11865. this.el.classList.remove('datetime-ready');
  11866. });
  11867. };
  11868. const hiddenIO = new IntersectionObserver(hiddenCallback, { threshold: 0, root: el });
  11869. raf(() => hiddenIO === null || hiddenIO === void 0 ? void 0 : hiddenIO.observe(intersectionTrackerRef));
  11870. /**
  11871. * Datetime uses Ionic components that emit
  11872. * ionFocus and ionBlur. These events are
  11873. * composed meaning they will cross
  11874. * the shadow dom boundary. We need to
  11875. * stop propagation on these events otherwise
  11876. * developers will see 2 ionFocus or 2 ionBlur
  11877. * events at a time.
  11878. */
  11879. const root = getElementRoot(this.el);
  11880. root.addEventListener('ionFocus', (ev) => ev.stopPropagation());
  11881. root.addEventListener('ionBlur', (ev) => ev.stopPropagation());
  11882. }
  11883. /**
  11884. * When the presentation is changed, all calendar content is recreated,
  11885. * so we need to re-init behavior with the new elements.
  11886. */
  11887. componentDidRender() {
  11888. const { presentation, prevPresentation, calendarBodyRef, minParts, preferWheel, forceRenderDate } = this;
  11889. /**
  11890. * TODO(FW-2165)
  11891. * Remove this when https://bugs.webkit.org/show_bug.cgi?id=235960 is fixed.
  11892. * When using `min`, we add `scroll-snap-align: none`
  11893. * to the disabled month so that users cannot scroll to it.
  11894. * This triggers a bug in WebKit where the scroll position is reset.
  11895. * Since the month change logic is handled by a scroll listener,
  11896. * this causes the month to change leading to `scroll-snap-align`
  11897. * changing again, thus changing the scroll position again and causing
  11898. * an infinite loop.
  11899. * This issue only applies to the calendar grid, so we can disable
  11900. * it if the calendar grid is not being used.
  11901. */
  11902. const hasCalendarGrid = !preferWheel && ['date-time', 'time-date', 'date'].includes(presentation);
  11903. if (minParts !== undefined && hasCalendarGrid && calendarBodyRef) {
  11904. const workingMonth = calendarBodyRef.querySelector('.calendar-month:nth-of-type(1)');
  11905. /**
  11906. * We need to make sure the datetime is not in the process
  11907. * of scrolling to a new datetime value if the value
  11908. * is updated programmatically.
  11909. * Otherwise, the datetime will appear to not scroll at all because
  11910. * we are resetting the scroll position to the center of the view.
  11911. * Prior to the datetime's value being updated programmatically,
  11912. * the calendarBodyRef is scrolled such that the middle month is centered
  11913. * in the view. The below code updates the scroll position so the middle
  11914. * month is also centered in the view. Since the scroll position did not change,
  11915. * the scroll callback in this file does not fire,
  11916. * and the resolveForceDateScrolling promise never resolves.
  11917. */
  11918. if (workingMonth && forceRenderDate === undefined) {
  11919. calendarBodyRef.scrollLeft = workingMonth.clientWidth * (isRTL$1(this.el) ? -1 : 1);
  11920. }
  11921. }
  11922. if (prevPresentation === null) {
  11923. this.prevPresentation = presentation;
  11924. return;
  11925. }
  11926. if (presentation === prevPresentation) {
  11927. return;
  11928. }
  11929. this.prevPresentation = presentation;
  11930. this.destroyInteractionListeners();
  11931. this.initializeListeners();
  11932. /**
  11933. * The month/year picker from the date interface
  11934. * should be closed as it is not available in non-date
  11935. * interfaces.
  11936. */
  11937. this.showMonthAndYear = false;
  11938. raf(() => {
  11939. this.ionRender.emit();
  11940. });
  11941. }
  11942. componentWillLoad() {
  11943. const { el, formatOptions, highlightedDates, multiple, presentation, preferWheel } = this;
  11944. if (multiple) {
  11945. if (presentation !== 'date') {
  11946. printIonWarning('[ion-datetime] - Multiple date selection is only supported for presentation="date".', el);
  11947. }
  11948. if (preferWheel) {
  11949. printIonWarning('[ion-datetime] - Multiple date selection is not supported with preferWheel="true".', el);
  11950. }
  11951. }
  11952. if (highlightedDates !== undefined) {
  11953. if (presentation !== 'date' && presentation !== 'date-time' && presentation !== 'time-date') {
  11954. printIonWarning('[ion-datetime] - The highlightedDates property is only supported with the date, date-time, and time-date presentations.', el);
  11955. }
  11956. if (preferWheel) {
  11957. printIonWarning('[ion-datetime] - The highlightedDates property is not supported with preferWheel="true".', el);
  11958. }
  11959. }
  11960. if (formatOptions) {
  11961. checkForPresentationFormatMismatch(el, presentation, formatOptions);
  11962. warnIfTimeZoneProvided(el, formatOptions);
  11963. }
  11964. const hourValues = (this.parsedHourValues = convertToArrayOfNumbers(this.hourValues));
  11965. const minuteValues = (this.parsedMinuteValues = convertToArrayOfNumbers(this.minuteValues));
  11966. const monthValues = (this.parsedMonthValues = convertToArrayOfNumbers(this.monthValues));
  11967. const yearValues = (this.parsedYearValues = convertToArrayOfNumbers(this.yearValues));
  11968. const dayValues = (this.parsedDayValues = convertToArrayOfNumbers(this.dayValues));
  11969. const todayParts = (this.todayParts = parseDate(getToday()));
  11970. this.processMinParts();
  11971. this.processMaxParts();
  11972. this.defaultParts = getClosestValidDate({
  11973. refParts: todayParts,
  11974. monthValues,
  11975. dayValues,
  11976. yearValues,
  11977. hourValues,
  11978. minuteValues,
  11979. minParts: this.minParts,
  11980. maxParts: this.maxParts,
  11981. });
  11982. this.processValue(this.value);
  11983. this.emitStyle();
  11984. }
  11985. emitStyle() {
  11986. this.ionStyle.emit({
  11987. interactive: true,
  11988. datetime: true,
  11989. 'interactive-disabled': this.disabled,
  11990. });
  11991. }
  11992. /**
  11993. * Universal render methods
  11994. * These are pieces of datetime that
  11995. * are rendered independently of presentation.
  11996. */
  11997. renderFooter() {
  11998. const { disabled, readonly, showDefaultButtons, showClearButton } = this;
  11999. /**
  12000. * The cancel, clear, and confirm buttons
  12001. * should not be interactive if the datetime
  12002. * is disabled or readonly.
  12003. */
  12004. const isButtonDisabled = disabled || readonly;
  12005. const hasSlottedButtons = this.el.querySelector('[slot="buttons"]') !== null;
  12006. if (!hasSlottedButtons && !showDefaultButtons && !showClearButton) {
  12007. return;
  12008. }
  12009. const clearButtonClick = () => {
  12010. this.reset();
  12011. this.setValue(undefined);
  12012. };
  12013. /**
  12014. * By default we render two buttons:
  12015. * Cancel - Dismisses the datetime and
  12016. * does not update the `value` prop.
  12017. * OK - Dismisses the datetime and
  12018. * updates the `value` prop.
  12019. */
  12020. return (hAsync("div", { class: "datetime-footer" }, hAsync("div", { class: "datetime-buttons" }, hAsync("div", { class: {
  12021. ['datetime-action-buttons']: true,
  12022. ['has-clear-button']: this.showClearButton,
  12023. } }, 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)))))))));
  12024. }
  12025. /**
  12026. * Wheel picker render methods
  12027. */
  12028. renderWheelPicker(forcePresentation = this.presentation) {
  12029. /**
  12030. * If presentation="time-date" we switch the
  12031. * order of the render array here instead of
  12032. * manually reordering each date/time picker
  12033. * column with CSS. This allows for additional
  12034. * flexibility if we need to render subsets
  12035. * of the date/time data or do additional ordering
  12036. * within the child render functions.
  12037. */
  12038. const renderArray = forcePresentation === 'time-date'
  12039. ? [this.renderTimePickerColumns(forcePresentation), this.renderDatePickerColumns(forcePresentation)]
  12040. : [this.renderDatePickerColumns(forcePresentation), this.renderTimePickerColumns(forcePresentation)];
  12041. return hAsync("ion-picker", null, renderArray);
  12042. }
  12043. renderDatePickerColumns(forcePresentation) {
  12044. return forcePresentation === 'date-time' || forcePresentation === 'time-date'
  12045. ? this.renderCombinedDatePickerColumn()
  12046. : this.renderIndividualDatePickerColumns(forcePresentation);
  12047. }
  12048. renderCombinedDatePickerColumn() {
  12049. const { defaultParts, disabled, workingParts, locale, minParts, maxParts, todayParts, isDateEnabled } = this;
  12050. const activePart = this.getActivePartsWithFallback();
  12051. /**
  12052. * By default, generate a range of 3 months:
  12053. * Previous month, current month, and next month
  12054. */
  12055. const monthsToRender = generateMonths(workingParts);
  12056. const lastMonth = monthsToRender[monthsToRender.length - 1];
  12057. /**
  12058. * Ensure that users can select the entire window of dates.
  12059. */
  12060. monthsToRender[0].day = 1;
  12061. lastMonth.day = getNumDaysInMonth(lastMonth.month, lastMonth.year);
  12062. /**
  12063. * Narrow the dates rendered based on min/max dates (if any).
  12064. * The `min` date is used if the min is after the generated min month.
  12065. * The `max` date is used if the max is before the generated max month.
  12066. * This ensures that the sliding window always stays at 3 months
  12067. * but still allows future dates to be lazily rendered based on any min/max
  12068. * constraints.
  12069. */
  12070. const min = minParts !== undefined && isAfter(minParts, monthsToRender[0]) ? minParts : monthsToRender[0];
  12071. const max = maxParts !== undefined && isBefore(maxParts, lastMonth) ? maxParts : lastMonth;
  12072. const result = getCombinedDateColumnData(locale, todayParts, min, max, this.parsedDayValues, this.parsedMonthValues);
  12073. let items = result.items;
  12074. const parts = result.parts;
  12075. if (isDateEnabled) {
  12076. items = items.map((itemObject, index) => {
  12077. const referenceParts = parts[index];
  12078. let disabled;
  12079. try {
  12080. /**
  12081. * The `isDateEnabled` implementation is try-catch wrapped
  12082. * to prevent exceptions in the user's function from
  12083. * interrupting the calendar rendering.
  12084. */
  12085. disabled = !isDateEnabled(convertDataToISO(referenceParts));
  12086. }
  12087. catch (e) {
  12088. printIonError('[ion-datetime] - Exception thrown from provided `isDateEnabled` function. Please check your function and try again.', e);
  12089. }
  12090. return Object.assign(Object.assign({}, itemObject), { disabled });
  12091. });
  12092. }
  12093. /**
  12094. * If we have selected a day already, then default the column
  12095. * to that value. Otherwise, set it to the default date.
  12096. */
  12097. const todayString = workingParts.day !== null
  12098. ? `${workingParts.year}-${workingParts.month}-${workingParts.day}`
  12099. : `${defaultParts.year}-${defaultParts.month}-${defaultParts.day}`;
  12100. return (hAsync("ion-picker-column", { "aria-label": "Select a date", class: "date-column", color: this.color, disabled: disabled, value: todayString, onIonChange: (ev) => {
  12101. const { value } = ev.detail;
  12102. const findPart = parts.find(({ month, day, year }) => value === `${year}-${month}-${day}`);
  12103. this.setWorkingParts(Object.assign(Object.assign({}, workingParts), findPart));
  12104. this.setActiveParts(Object.assign(Object.assign({}, activePart), findPart));
  12105. ev.stopPropagation();
  12106. } }, 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)))));
  12107. }
  12108. renderIndividualDatePickerColumns(forcePresentation) {
  12109. const { workingParts, isDateEnabled } = this;
  12110. const shouldRenderMonths = forcePresentation !== 'year' && forcePresentation !== 'time';
  12111. const months = shouldRenderMonths
  12112. ? getMonthColumnData(this.locale, workingParts, this.minParts, this.maxParts, this.parsedMonthValues)
  12113. : [];
  12114. const shouldRenderDays = forcePresentation === 'date';
  12115. let days = shouldRenderDays
  12116. ? getDayColumnData(this.locale, workingParts, this.minParts, this.maxParts, this.parsedDayValues)
  12117. : [];
  12118. if (isDateEnabled) {
  12119. days = days.map((dayObject) => {
  12120. const { value } = dayObject;
  12121. const valueNum = typeof value === 'string' ? parseInt(value) : value;
  12122. const referenceParts = {
  12123. month: workingParts.month,
  12124. day: valueNum,
  12125. year: workingParts.year,
  12126. };
  12127. let disabled;
  12128. try {
  12129. /**
  12130. * The `isDateEnabled` implementation is try-catch wrapped
  12131. * to prevent exceptions in the user's function from
  12132. * interrupting the calendar rendering.
  12133. */
  12134. disabled = !isDateEnabled(convertDataToISO(referenceParts));
  12135. }
  12136. catch (e) {
  12137. printIonError('[ion-datetime] - Exception thrown from provided `isDateEnabled` function. Please check your function and try again.', e);
  12138. }
  12139. return Object.assign(Object.assign({}, dayObject), { disabled });
  12140. });
  12141. }
  12142. const shouldRenderYears = forcePresentation !== 'month' && forcePresentation !== 'time';
  12143. const years = shouldRenderYears
  12144. ? getYearColumnData(this.locale, this.defaultParts, this.minParts, this.maxParts, this.parsedYearValues)
  12145. : [];
  12146. /**
  12147. * Certain locales show the day before the month.
  12148. */
  12149. const showMonthFirst = isMonthFirstLocale(this.locale, { month: 'numeric', day: 'numeric' });
  12150. let renderArray = [];
  12151. if (showMonthFirst) {
  12152. renderArray = [
  12153. this.renderMonthPickerColumn(months),
  12154. this.renderDayPickerColumn(days),
  12155. this.renderYearPickerColumn(years),
  12156. ];
  12157. }
  12158. else {
  12159. renderArray = [
  12160. this.renderDayPickerColumn(days),
  12161. this.renderMonthPickerColumn(months),
  12162. this.renderYearPickerColumn(years),
  12163. ];
  12164. }
  12165. return renderArray;
  12166. }
  12167. renderDayPickerColumn(days) {
  12168. var _a;
  12169. if (days.length === 0) {
  12170. return [];
  12171. }
  12172. const { disabled, workingParts } = this;
  12173. const activePart = this.getActivePartsWithFallback();
  12174. const pickerColumnValue = (_a = (workingParts.day !== null ? workingParts.day : this.defaultParts.day)) !== null && _a !== void 0 ? _a : undefined;
  12175. return (hAsync("ion-picker-column", { "aria-label": "Select a day", class: "day-column", color: this.color, disabled: disabled, value: pickerColumnValue, onIonChange: (ev) => {
  12176. this.setWorkingParts(Object.assign(Object.assign({}, workingParts), { day: ev.detail.value }));
  12177. this.setActiveParts(Object.assign(Object.assign({}, activePart), { day: ev.detail.value }));
  12178. ev.stopPropagation();
  12179. } }, 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)))));
  12180. }
  12181. renderMonthPickerColumn(months) {
  12182. if (months.length === 0) {
  12183. return [];
  12184. }
  12185. const { disabled, workingParts } = this;
  12186. const activePart = this.getActivePartsWithFallback();
  12187. return (hAsync("ion-picker-column", { "aria-label": "Select a month", class: "month-column", color: this.color, disabled: disabled, value: workingParts.month, onIonChange: (ev) => {
  12188. this.setWorkingParts(Object.assign(Object.assign({}, workingParts), { month: ev.detail.value }));
  12189. this.setActiveParts(Object.assign(Object.assign({}, activePart), { month: ev.detail.value }));
  12190. ev.stopPropagation();
  12191. } }, 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)))));
  12192. }
  12193. renderYearPickerColumn(years) {
  12194. if (years.length === 0) {
  12195. return [];
  12196. }
  12197. const { disabled, workingParts } = this;
  12198. const activePart = this.getActivePartsWithFallback();
  12199. return (hAsync("ion-picker-column", { "aria-label": "Select a year", class: "year-column", color: this.color, disabled: disabled, value: workingParts.year, onIonChange: (ev) => {
  12200. this.setWorkingParts(Object.assign(Object.assign({}, workingParts), { year: ev.detail.value }));
  12201. this.setActiveParts(Object.assign(Object.assign({}, activePart), { year: ev.detail.value }));
  12202. ev.stopPropagation();
  12203. } }, 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)))));
  12204. }
  12205. renderTimePickerColumns(forcePresentation) {
  12206. if (['date', 'month', 'month-year', 'year'].includes(forcePresentation)) {
  12207. return [];
  12208. }
  12209. /**
  12210. * If a user has not selected a date,
  12211. * then we should show all times. If the
  12212. * user has selected a date (even if it has
  12213. * not been confirmed yet), we should apply
  12214. * the max and min restrictions so that the
  12215. * time picker shows values that are
  12216. * appropriate for the selected date.
  12217. */
  12218. const activePart = this.getActivePart();
  12219. const userHasSelectedDate = activePart !== undefined;
  12220. const { hoursData, minutesData, dayPeriodData } = getTimeColumnsData(this.locale, this.workingParts, this.hourCycle, userHasSelectedDate ? this.minParts : undefined, userHasSelectedDate ? this.maxParts : undefined, this.parsedHourValues, this.parsedMinuteValues);
  12221. return [
  12222. this.renderHourPickerColumn(hoursData),
  12223. this.renderMinutePickerColumn(minutesData),
  12224. this.renderDayPeriodPickerColumn(dayPeriodData),
  12225. ];
  12226. }
  12227. renderHourPickerColumn(hoursData) {
  12228. const { disabled, workingParts } = this;
  12229. if (hoursData.length === 0)
  12230. return [];
  12231. const activePart = this.getActivePartsWithFallback();
  12232. return (hAsync("ion-picker-column", { "aria-label": "Select an hour", color: this.color, disabled: disabled, value: activePart.hour, numericInput: true, onIonChange: (ev) => {
  12233. this.setWorkingParts(Object.assign(Object.assign({}, workingParts), { hour: ev.detail.value }));
  12234. this.setActiveParts(Object.assign(Object.assign({}, this.getActivePartsWithFallback()), { hour: ev.detail.value }));
  12235. ev.stopPropagation();
  12236. } }, 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)))));
  12237. }
  12238. renderMinutePickerColumn(minutesData) {
  12239. const { disabled, workingParts } = this;
  12240. if (minutesData.length === 0)
  12241. return [];
  12242. const activePart = this.getActivePartsWithFallback();
  12243. return (hAsync("ion-picker-column", { "aria-label": "Select a minute", color: this.color, disabled: disabled, value: activePart.minute, numericInput: true, onIonChange: (ev) => {
  12244. this.setWorkingParts(Object.assign(Object.assign({}, workingParts), { minute: ev.detail.value }));
  12245. this.setActiveParts(Object.assign(Object.assign({}, this.getActivePartsWithFallback()), { minute: ev.detail.value }));
  12246. ev.stopPropagation();
  12247. } }, 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)))));
  12248. }
  12249. renderDayPeriodPickerColumn(dayPeriodData) {
  12250. const { disabled, workingParts } = this;
  12251. if (dayPeriodData.length === 0) {
  12252. return [];
  12253. }
  12254. const activePart = this.getActivePartsWithFallback();
  12255. const isDayPeriodRTL = isLocaleDayPeriodRTL(this.locale);
  12256. 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) => {
  12257. const hour = calculateHourFromAMPM(workingParts, ev.detail.value);
  12258. this.setWorkingParts(Object.assign(Object.assign({}, workingParts), { ampm: ev.detail.value, hour }));
  12259. this.setActiveParts(Object.assign(Object.assign({}, this.getActivePartsWithFallback()), { ampm: ev.detail.value, hour }));
  12260. ev.stopPropagation();
  12261. } }, 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)))));
  12262. }
  12263. renderWheelView(forcePresentation) {
  12264. const { locale } = this;
  12265. const showMonthFirst = isMonthFirstLocale(locale);
  12266. const columnOrder = showMonthFirst ? 'month-first' : 'year-first';
  12267. return (hAsync("div", { class: {
  12268. [`wheel-order-${columnOrder}`]: true,
  12269. } }, this.renderWheelPicker(forcePresentation)));
  12270. }
  12271. /**
  12272. * Grid Render Methods
  12273. */
  12274. renderCalendarHeader(mode) {
  12275. const { disabled } = this;
  12276. const expandedIcon = mode === 'ios' ? chevronDown : caretUpSharp;
  12277. const collapsedIcon = mode === 'ios' ? chevronForward : caretDownSharp;
  12278. const prevMonthDisabled = disabled || isPrevMonthDisabled(this.workingParts, this.minParts, this.maxParts);
  12279. const nextMonthDisabled = disabled || isNextMonthDisabled(this.workingParts, this.maxParts);
  12280. // don't use the inheritAttributes util because it removes dir from the host, and we still need that
  12281. const hostDir = this.el.getAttribute('dir') || undefined;
  12282. return (hAsync("div", { class: "calendar-header" }, hAsync("div", { class: "calendar-action-buttons" }, hAsync("div", { class: "calendar-month-year" }, hAsync("button", { class: {
  12283. 'calendar-month-year-toggle': true,
  12284. 'ion-activatable': true,
  12285. 'ion-focusable': true,
  12286. }, 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) => {
  12287. return hAsync("div", { class: "day-of-week" }, d);
  12288. }))));
  12289. }
  12290. renderMonth(month, year) {
  12291. const { disabled, readonly } = this;
  12292. const yearAllowed = this.parsedYearValues === undefined || this.parsedYearValues.includes(year);
  12293. const monthAllowed = this.parsedMonthValues === undefined || this.parsedMonthValues.includes(month);
  12294. const isCalMonthDisabled = !yearAllowed || !monthAllowed;
  12295. const isDatetimeDisabled = disabled || readonly;
  12296. const swipeDisabled = disabled ||
  12297. isMonthDisabled({
  12298. month,
  12299. year,
  12300. day: null,
  12301. }, {
  12302. // The day is not used when checking if a month is disabled.
  12303. // Users should be able to access the min or max month, even if the
  12304. // min/max date is out of bounds (e.g. min is set to Feb 15, Feb should not be disabled).
  12305. minParts: Object.assign(Object.assign({}, this.minParts), { day: null }),
  12306. maxParts: Object.assign(Object.assign({}, this.maxParts), { day: null }),
  12307. });
  12308. // The working month should never have swipe disabled.
  12309. // Otherwise the CSS scroll snap will not work and the user
  12310. // can free-scroll the calendar.
  12311. const isWorkingMonth = this.workingParts.month === month && this.workingParts.year === year;
  12312. const activePart = this.getActivePartsWithFallback();
  12313. return (hAsync("div", { "aria-hidden": !isWorkingMonth ? 'true' : null, class: {
  12314. 'calendar-month': true,
  12315. // Prevents scroll snap swipe gestures for months outside of the min/max bounds
  12316. 'calendar-month-disabled': !isWorkingMonth && swipeDisabled,
  12317. } }, hAsync("div", { class: "calendar-month-grid" }, getDaysOfMonth(month, year, this.firstDayOfWeek % 7).map((dateObject, index) => {
  12318. const { day, dayOfWeek } = dateObject;
  12319. const { el, highlightedDates, isDateEnabled, multiple } = this;
  12320. const referenceParts = { month, day, year };
  12321. const isCalendarPadding = day === null;
  12322. const { isActive, isToday, ariaLabel, ariaSelected, disabled: isDayDisabled, text, } = getCalendarDayState(this.locale, referenceParts, this.activeParts, this.todayParts, this.minParts, this.maxParts, this.parsedDayValues);
  12323. const dateIsoString = convertDataToISO(referenceParts);
  12324. let isCalDayDisabled = isCalMonthDisabled || isDayDisabled;
  12325. if (!isCalDayDisabled && isDateEnabled !== undefined) {
  12326. try {
  12327. /**
  12328. * The `isDateEnabled` implementation is try-catch wrapped
  12329. * to prevent exceptions in the user's function from
  12330. * interrupting the calendar rendering.
  12331. */
  12332. isCalDayDisabled = !isDateEnabled(dateIsoString);
  12333. }
  12334. catch (e) {
  12335. printIonError('[ion-datetime] - Exception thrown from provided `isDateEnabled` function. Please check your function and try again.', el, e);
  12336. }
  12337. }
  12338. /**
  12339. * Some days are constrained through max & min or allowed dates
  12340. * and also disabled because the component is readonly or disabled.
  12341. * These need to be displayed differently.
  12342. */
  12343. const isCalDayConstrained = isCalDayDisabled && isDatetimeDisabled;
  12344. const isButtonDisabled = isCalDayDisabled || isDatetimeDisabled;
  12345. let dateStyle = undefined;
  12346. /**
  12347. * Custom highlight styles should not override the style for selected dates,
  12348. * nor apply to "filler days" at the start of the grid.
  12349. */
  12350. if (highlightedDates !== undefined && !isActive && day !== null) {
  12351. dateStyle = getHighlightStyles(highlightedDates, dateIsoString, el);
  12352. }
  12353. let dateParts = undefined;
  12354. // "Filler days" at the beginning of the grid should not get the calendar day
  12355. // CSS parts added to them
  12356. if (!isCalendarPadding) {
  12357. dateParts = `calendar-day${isActive ? ' active' : ''}${isToday ? ' today' : ''}${isCalDayDisabled ? ' disabled' : ''}`;
  12358. }
  12359. return (hAsync("div", { class: "calendar-day-wrapper" }, hAsync("button", {
  12360. // We need to use !important for the inline styles here because
  12361. // otherwise the CSS shadow parts will override these styles.
  12362. // See https://github.com/WICG/webcomponents/issues/847
  12363. // Both the CSS shadow parts and highlightedDates styles are
  12364. // provided by the developer, but highlightedDates styles should
  12365. // always take priority.
  12366. ref: (el) => {
  12367. if (el) {
  12368. el.style.setProperty('color', `${dateStyle ? dateStyle.textColor : ''}`, 'important');
  12369. el.style.setProperty('background-color', `${dateStyle ? dateStyle.backgroundColor : ''}`, 'important');
  12370. }
  12371. }, tabindex: "-1", "data-day": day, "data-month": month, "data-year": year, "data-index": index, "data-day-of-week": dayOfWeek, disabled: isButtonDisabled, class: {
  12372. 'calendar-day-padding': isCalendarPadding,
  12373. 'calendar-day': true,
  12374. 'calendar-day-active': isActive,
  12375. 'calendar-day-constrained': isCalDayConstrained,
  12376. 'calendar-day-today': isToday,
  12377. }, part: dateParts, "aria-hidden": isCalendarPadding ? 'true' : null, "aria-selected": ariaSelected, "aria-label": ariaLabel, onClick: () => {
  12378. if (isCalendarPadding) {
  12379. return;
  12380. }
  12381. this.setWorkingParts(Object.assign(Object.assign({}, this.workingParts), { month,
  12382. day,
  12383. year }));
  12384. // multiple only needs date info, so we can wipe out other fields like time
  12385. if (multiple) {
  12386. this.setActiveParts({
  12387. month,
  12388. day,
  12389. year,
  12390. }, isActive);
  12391. }
  12392. else {
  12393. this.setActiveParts(Object.assign(Object.assign({}, activePart), { month,
  12394. day,
  12395. year }));
  12396. }
  12397. }
  12398. }, text)));
  12399. }))));
  12400. }
  12401. renderCalendarBody() {
  12402. return (hAsync("div", { class: "calendar-body ion-focusable", ref: (el) => (this.calendarBodyRef = el), tabindex: "0" }, generateMonths(this.workingParts, this.forceRenderDate).map(({ month, year }) => {
  12403. return this.renderMonth(month, year);
  12404. })));
  12405. }
  12406. renderCalendar(mode) {
  12407. return (hAsync("div", { class: "datetime-calendar", key: "datetime-calendar" }, this.renderCalendarHeader(mode), this.renderCalendarBody()));
  12408. }
  12409. renderTimeLabel() {
  12410. const hasSlottedTimeLabel = this.el.querySelector('[slot="time-label"]') !== null;
  12411. if (!hasSlottedTimeLabel && !this.showDefaultTimeLabel) {
  12412. return;
  12413. }
  12414. return hAsync("slot", { name: "time-label" }, "Time");
  12415. }
  12416. renderTimeOverlay() {
  12417. const { disabled, hourCycle, isTimePopoverOpen, locale, formatOptions } = this;
  12418. const computedHourCycle = getHourCycle(locale, hourCycle);
  12419. const activePart = this.getActivePartsWithFallback();
  12420. return [
  12421. hAsync("div", { class: "time-header" }, this.renderTimeLabel()),
  12422. hAsync("button", { class: {
  12423. 'time-body': true,
  12424. 'time-body-active': isTimePopoverOpen,
  12425. }, part: `time-button${isTimePopoverOpen ? ' active' : ''}`, "aria-expanded": "false", "aria-haspopup": "true", disabled: disabled, onClick: async (ev) => {
  12426. const { popoverRef } = this;
  12427. if (popoverRef) {
  12428. this.isTimePopoverOpen = true;
  12429. popoverRef.present(new CustomEvent('ionShadowTarget', {
  12430. detail: {
  12431. ionShadowTarget: ev.target,
  12432. },
  12433. }));
  12434. await popoverRef.onWillDismiss();
  12435. this.isTimePopoverOpen = false;
  12436. }
  12437. } }, getLocalizedTime(locale, activePart, computedHourCycle, formatOptions === null || formatOptions === void 0 ? void 0 : formatOptions.time)),
  12438. hAsync("ion-popover", { alignment: "center", translucent: true, overlayIndex: 1, arrow: false, onWillPresent: (ev) => {
  12439. /**
  12440. * Intersection Observers do not consistently fire between Blink and Webkit
  12441. * when toggling the visibility of the popover and trying to scroll the picker
  12442. * column to the correct time value.
  12443. *
  12444. * This will correctly scroll the element position to the correct time value,
  12445. * before the popover is fully presented.
  12446. */
  12447. const cols = ev.target.querySelectorAll('ion-picker-column');
  12448. // TODO (FW-615): Potentially remove this when intersection observers are fixed in picker column
  12449. cols.forEach((col) => col.scrollActiveItemIntoView());
  12450. }, style: {
  12451. '--offset-y': '-10px',
  12452. '--min-width': 'fit-content',
  12453. },
  12454. // Allow native browser keyboard events to support up/down/home/end key
  12455. // navigation within the time picker.
  12456. keyboardEvents: true, ref: (el) => (this.popoverRef = el) }, this.renderWheelPicker('time')),
  12457. ];
  12458. }
  12459. getHeaderSelectedDateText() {
  12460. var _a;
  12461. const { activeParts, formatOptions, multiple, titleSelectedDatesFormatter } = this;
  12462. const isArray = Array.isArray(activeParts);
  12463. let headerText;
  12464. if (multiple && isArray && activeParts.length !== 1) {
  12465. headerText = `${activeParts.length} days`; // default/fallback for multiple selection
  12466. if (titleSelectedDatesFormatter !== undefined) {
  12467. try {
  12468. headerText = titleSelectedDatesFormatter(convertDataToISO(activeParts));
  12469. }
  12470. catch (e) {
  12471. printIonError('[ion-datetime] - Exception in provided `titleSelectedDatesFormatter`:', e);
  12472. }
  12473. }
  12474. }
  12475. else {
  12476. // for exactly 1 day selected (multiple set or not), show a formatted version of that
  12477. 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' });
  12478. }
  12479. return headerText;
  12480. }
  12481. renderHeader(showExpandedHeader = true) {
  12482. const hasSlottedTitle = this.el.querySelector('[slot="title"]') !== null;
  12483. if (!hasSlottedTitle && !this.showDefaultTitle) {
  12484. return;
  12485. }
  12486. 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())));
  12487. }
  12488. /**
  12489. * Render time picker inside of datetime.
  12490. * Do not pass color prop to segment on
  12491. * iOS mode. MD segment has been customized and
  12492. * should take on the color prop, but iOS
  12493. * should just be the default segment.
  12494. */
  12495. renderTime() {
  12496. const { presentation } = this;
  12497. const timeOnlyPresentation = presentation === 'time';
  12498. return (hAsync("div", { class: "datetime-time" }, timeOnlyPresentation ? this.renderWheelPicker() : this.renderTimeOverlay()));
  12499. }
  12500. /**
  12501. * Renders the month/year picker that is
  12502. * displayed on the calendar grid.
  12503. * The .datetime-year class has additional
  12504. * styles that let us show/hide the
  12505. * picker when the user clicks on the
  12506. * toggle in the calendar header.
  12507. */
  12508. renderCalendarViewMonthYearPicker() {
  12509. return hAsync("div", { class: "datetime-year" }, this.renderWheelView('month-year'));
  12510. }
  12511. /**
  12512. * Render entry point
  12513. * All presentation types are rendered from here.
  12514. */
  12515. renderDatetime(mode) {
  12516. const { presentation, preferWheel } = this;
  12517. /**
  12518. * Certain presentation types have separate grid and wheel displays.
  12519. * If preferWheel is true then we should show a wheel picker instead.
  12520. */
  12521. const hasWheelVariant = presentation === 'date' || presentation === 'date-time' || presentation === 'time-date';
  12522. if (preferWheel && hasWheelVariant) {
  12523. return [this.renderHeader(false), this.renderWheelView(), this.renderFooter()];
  12524. }
  12525. switch (presentation) {
  12526. case 'date-time':
  12527. return [
  12528. this.renderHeader(),
  12529. this.renderCalendar(mode),
  12530. this.renderCalendarViewMonthYearPicker(),
  12531. this.renderTime(),
  12532. this.renderFooter(),
  12533. ];
  12534. case 'time-date':
  12535. return [
  12536. this.renderHeader(),
  12537. this.renderTime(),
  12538. this.renderCalendar(mode),
  12539. this.renderCalendarViewMonthYearPicker(),
  12540. this.renderFooter(),
  12541. ];
  12542. case 'time':
  12543. return [this.renderHeader(false), this.renderTime(), this.renderFooter()];
  12544. case 'month':
  12545. case 'month-year':
  12546. case 'year':
  12547. return [this.renderHeader(false), this.renderWheelView(), this.renderFooter()];
  12548. default:
  12549. return [
  12550. this.renderHeader(),
  12551. this.renderCalendar(mode),
  12552. this.renderCalendarViewMonthYearPicker(),
  12553. this.renderFooter(),
  12554. ];
  12555. }
  12556. }
  12557. render() {
  12558. const { name, value, disabled, el, color, readonly, showMonthAndYear, preferWheel, presentation, size, isGridStyle, } = this;
  12559. const mode = getIonMode$1(this);
  12560. const isMonthAndYearPresentation = presentation === 'year' || presentation === 'month' || presentation === 'month-year';
  12561. const shouldShowMonthAndYear = showMonthAndYear || isMonthAndYearPresentation;
  12562. const monthYearPickerOpen = showMonthAndYear && !isMonthAndYearPresentation;
  12563. const hasDatePresentation = presentation === 'date' || presentation === 'date-time' || presentation === 'time-date';
  12564. const hasWheelVariant = hasDatePresentation && preferWheel;
  12565. renderHiddenInput(true, el, name, formatValue(value), disabled);
  12566. return (hAsync(Host, { key: 'c3dfea8f46fcbcef38eb9e8a69b1b46a4e4b82fd', "aria-disabled": disabled ? 'true' : null, onFocus: this.onFocus, onBlur: this.onBlur, class: Object.assign({}, createColorClasses$1(color, {
  12567. [mode]: true,
  12568. ['datetime-readonly']: readonly,
  12569. ['datetime-disabled']: disabled,
  12570. 'show-month-and-year': shouldShowMonthAndYear,
  12571. 'month-year-picker-open': monthYearPickerOpen,
  12572. [`datetime-presentation-${presentation}`]: true,
  12573. [`datetime-size-${size}`]: true,
  12574. [`datetime-prefer-wheel`]: hasWheelVariant,
  12575. [`datetime-grid`]: isGridStyle,
  12576. })) }, hAsync("div", { key: '75c91243cf6a51f44b83d7cf7d8c0c96bfd3c83f', class: "intersection-tracker", ref: (el) => (this.intersectionTrackerRef = el) }), this.renderDatetime(mode)));
  12577. }
  12578. get el() { return getElement(this); }
  12579. static get watchers() { return {
  12580. "formatOptions": ["formatOptionsChanged"],
  12581. "disabled": ["disabledChanged"],
  12582. "min": ["minChanged"],
  12583. "max": ["maxChanged"],
  12584. "presentation": ["presentationChanged"],
  12585. "yearValues": ["yearValuesChanged"],
  12586. "monthValues": ["monthValuesChanged"],
  12587. "dayValues": ["dayValuesChanged"],
  12588. "hourValues": ["hourValuesChanged"],
  12589. "minuteValues": ["minuteValuesChanged"],
  12590. "value": ["valueChanged"]
  12591. }; }
  12592. static get style() { return {
  12593. ios: IonDatetimeIosStyle0,
  12594. md: IonDatetimeMdStyle0
  12595. }; }
  12596. static get cmpMeta() { return {
  12597. "$flags$": 41,
  12598. "$tagName$": "ion-datetime",
  12599. "$members$": {
  12600. "color": [1],
  12601. "name": [1],
  12602. "disabled": [4],
  12603. "formatOptions": [16],
  12604. "readonly": [4],
  12605. "isDateEnabled": [16],
  12606. "min": [1025],
  12607. "max": [1025],
  12608. "presentation": [1],
  12609. "cancelText": [1, "cancel-text"],
  12610. "doneText": [1, "done-text"],
  12611. "clearText": [1, "clear-text"],
  12612. "yearValues": [8, "year-values"],
  12613. "monthValues": [8, "month-values"],
  12614. "dayValues": [8, "day-values"],
  12615. "hourValues": [8, "hour-values"],
  12616. "minuteValues": [8, "minute-values"],
  12617. "locale": [1],
  12618. "firstDayOfWeek": [2, "first-day-of-week"],
  12619. "titleSelectedDatesFormatter": [16],
  12620. "multiple": [4],
  12621. "highlightedDates": [16],
  12622. "value": [1025],
  12623. "showDefaultTitle": [4, "show-default-title"],
  12624. "showDefaultButtons": [4, "show-default-buttons"],
  12625. "showClearButton": [4, "show-clear-button"],
  12626. "showDefaultTimeLabel": [4, "show-default-time-label"],
  12627. "hourCycle": [1, "hour-cycle"],
  12628. "size": [1],
  12629. "preferWheel": [4, "prefer-wheel"],
  12630. "showMonthAndYear": [32],
  12631. "activeParts": [32],
  12632. "workingParts": [32],
  12633. "isTimePopoverOpen": [32],
  12634. "forceRenderDate": [32],
  12635. "confirm": [64],
  12636. "reset": [64],
  12637. "cancel": [64]
  12638. },
  12639. "$listeners$": undefined,
  12640. "$lazyBundleId$": "-",
  12641. "$attrsToReflect$": []
  12642. }; }
  12643. }
  12644. let datetimeIds = 0;
  12645. const CANCEL_ROLE = 'datetime-cancel';
  12646. const CONFIRM_ROLE = 'datetime-confirm';
  12647. const WHEEL_ITEM_PART = 'wheel-item';
  12648. const WHEEL_ITEM_ACTIVE_PART = `active`;
  12649. 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))}";
  12650. var IonDatetimeButtonIosStyle0 = datetimeButtonIosCss;
  12651. 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}";
  12652. var IonDatetimeButtonMdStyle0 = datetimeButtonMdCss;
  12653. /**
  12654. * @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
  12655. *
  12656. * @slot date-target - Content displayed inside of the date button.
  12657. * @slot time-target - Content displayed inside of the time button.
  12658. *
  12659. * @part native - The native HTML button that wraps the slotted text.
  12660. */
  12661. class DatetimeButton {
  12662. constructor(hostRef) {
  12663. registerInstance(this, hostRef);
  12664. this.datetimeEl = null;
  12665. this.overlayEl = null;
  12666. /**
  12667. * Accepts one or more string values and converts
  12668. * them to DatetimeParts. This is done so datetime-button
  12669. * can work with an array internally and not need
  12670. * to keep checking if the datetime value is `string` or `string[]`.
  12671. */
  12672. this.getParsedDateValues = (value) => {
  12673. if (value === undefined || value === null) {
  12674. return [];
  12675. }
  12676. if (Array.isArray(value)) {
  12677. return value;
  12678. }
  12679. return [value];
  12680. };
  12681. /**
  12682. * Check the value property on the linked
  12683. * ion-datetime and then format it according
  12684. * to the locale specified on ion-datetime.
  12685. */
  12686. this.setDateTimeText = () => {
  12687. var _a, _b, _c, _d, _e;
  12688. const { datetimeEl, datetimePresentation } = this;
  12689. if (!datetimeEl) {
  12690. return;
  12691. }
  12692. const { value, locale, formatOptions, hourCycle, preferWheel, multiple, titleSelectedDatesFormatter } = datetimeEl;
  12693. const parsedValues = this.getParsedDateValues(value);
  12694. /**
  12695. * Both ion-datetime and ion-datetime-button default
  12696. * to today's date and time if no value is set.
  12697. */
  12698. const parsedDatetimes = parseDate(parsedValues.length > 0 ? parsedValues : [getToday()]);
  12699. if (!parsedDatetimes) {
  12700. return;
  12701. }
  12702. /**
  12703. * If developers incorrectly use multiple="true"
  12704. * with non "date" datetimes, then just select
  12705. * the first value so the interface does
  12706. * not appear broken. Datetime will provide a
  12707. * warning in the console.
  12708. */
  12709. const firstParsedDatetime = parsedDatetimes[0];
  12710. const computedHourCycle = getHourCycle(locale, hourCycle);
  12711. this.dateText = this.timeText = undefined;
  12712. switch (datetimePresentation) {
  12713. case 'date-time':
  12714. case 'time-date':
  12715. 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' });
  12716. const timeText = getLocalizedTime(locale, firstParsedDatetime, computedHourCycle, formatOptions === null || formatOptions === void 0 ? void 0 : formatOptions.time);
  12717. if (preferWheel) {
  12718. this.dateText = `${dateText} ${timeText}`;
  12719. }
  12720. else {
  12721. this.dateText = dateText;
  12722. this.timeText = timeText;
  12723. }
  12724. break;
  12725. case 'date':
  12726. if (multiple && parsedValues.length !== 1) {
  12727. let headerText = `${parsedValues.length} days`; // default/fallback for multiple selection
  12728. if (titleSelectedDatesFormatter !== undefined) {
  12729. try {
  12730. headerText = titleSelectedDatesFormatter(parsedValues);
  12731. }
  12732. catch (e) {
  12733. printIonError('[ion-datetime-button] - Exception in provided `titleSelectedDatesFormatter`:', e);
  12734. }
  12735. }
  12736. this.dateText = headerText;
  12737. }
  12738. else {
  12739. 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' });
  12740. }
  12741. break;
  12742. case 'time':
  12743. this.timeText = getLocalizedTime(locale, firstParsedDatetime, computedHourCycle, formatOptions === null || formatOptions === void 0 ? void 0 : formatOptions.time);
  12744. break;
  12745. case 'month-year':
  12746. this.dateText = getLocalizedDateTime(locale, firstParsedDatetime, (_c = formatOptions === null || formatOptions === void 0 ? void 0 : formatOptions.date) !== null && _c !== void 0 ? _c : { month: 'long', year: 'numeric' });
  12747. break;
  12748. case 'month':
  12749. this.dateText = getLocalizedDateTime(locale, firstParsedDatetime, (_d = formatOptions === null || formatOptions === void 0 ? void 0 : formatOptions.time) !== null && _d !== void 0 ? _d : { month: 'long' });
  12750. break;
  12751. case 'year':
  12752. this.dateText = getLocalizedDateTime(locale, firstParsedDatetime, (_e = formatOptions === null || formatOptions === void 0 ? void 0 : formatOptions.time) !== null && _e !== void 0 ? _e : { year: 'numeric' });
  12753. break;
  12754. }
  12755. };
  12756. /**
  12757. * Waits for the ion-datetime to re-render.
  12758. * This is needed in order to correctly position
  12759. * a popover relative to the trigger element.
  12760. */
  12761. this.waitForDatetimeChanges = async () => {
  12762. const { datetimeEl } = this;
  12763. if (!datetimeEl) {
  12764. return Promise.resolve();
  12765. }
  12766. return new Promise((resolve) => {
  12767. addEventListener$1(datetimeEl, 'ionRender', resolve, { once: true });
  12768. });
  12769. };
  12770. this.handleDateClick = async (ev) => {
  12771. const { datetimeEl, datetimePresentation } = this;
  12772. if (!datetimeEl) {
  12773. return;
  12774. }
  12775. let needsPresentationChange = false;
  12776. /**
  12777. * When clicking the date button,
  12778. * we need to make sure that only a date
  12779. * picker is displayed. For presentation styles
  12780. * that display content other than a date picker,
  12781. * we need to update the presentation style.
  12782. */
  12783. switch (datetimePresentation) {
  12784. case 'date-time':
  12785. case 'time-date':
  12786. const needsChange = datetimeEl.presentation !== 'date';
  12787. /**
  12788. * The date+time wheel picker
  12789. * shows date and time together,
  12790. * so do not adjust the presentation
  12791. * in that case.
  12792. */
  12793. if (!datetimeEl.preferWheel && needsChange) {
  12794. datetimeEl.presentation = 'date';
  12795. needsPresentationChange = true;
  12796. }
  12797. break;
  12798. }
  12799. /**
  12800. * Track which button was clicked
  12801. * so that it can have the correct
  12802. * activated styles applied when
  12803. * the modal/popover containing
  12804. * the datetime is opened.
  12805. */
  12806. this.selectedButton = 'date';
  12807. this.presentOverlay(ev, needsPresentationChange, this.dateTargetEl);
  12808. };
  12809. this.handleTimeClick = (ev) => {
  12810. const { datetimeEl, datetimePresentation } = this;
  12811. if (!datetimeEl) {
  12812. return;
  12813. }
  12814. let needsPresentationChange = false;
  12815. /**
  12816. * When clicking the time button,
  12817. * we need to make sure that only a time
  12818. * picker is displayed. For presentation styles
  12819. * that display content other than a time picker,
  12820. * we need to update the presentation style.
  12821. */
  12822. switch (datetimePresentation) {
  12823. case 'date-time':
  12824. case 'time-date':
  12825. const needsChange = datetimeEl.presentation !== 'time';
  12826. if (needsChange) {
  12827. datetimeEl.presentation = 'time';
  12828. needsPresentationChange = true;
  12829. }
  12830. break;
  12831. }
  12832. /**
  12833. * Track which button was clicked
  12834. * so that it can have the correct
  12835. * activated styles applied when
  12836. * the modal/popover containing
  12837. * the datetime is opened.
  12838. */
  12839. this.selectedButton = 'time';
  12840. this.presentOverlay(ev, needsPresentationChange, this.timeTargetEl);
  12841. };
  12842. /**
  12843. * If the datetime is presented in an
  12844. * overlay, the datetime and overlay
  12845. * should be appropriately sized.
  12846. * These classes provide default sizing values
  12847. * that developers can customize.
  12848. * The goal is to provide an overlay that is
  12849. * reasonably sized with a datetime that
  12850. * fills the entire container.
  12851. */
  12852. this.presentOverlay = async (ev, needsPresentationChange, triggerEl) => {
  12853. const { overlayEl } = this;
  12854. if (!overlayEl) {
  12855. return;
  12856. }
  12857. if (overlayEl.tagName === 'ION-POPOVER') {
  12858. /**
  12859. * When the presentation on datetime changes,
  12860. * we need to wait for the component to re-render
  12861. * otherwise the computed width/height of the
  12862. * popover content will be wrong, causing
  12863. * the popover to not align with the trigger element.
  12864. */
  12865. if (needsPresentationChange) {
  12866. await this.waitForDatetimeChanges();
  12867. }
  12868. /**
  12869. * We pass the trigger button element
  12870. * so that the popover aligns with the individual
  12871. * button that was clicked, not the component container.
  12872. */
  12873. overlayEl.present(Object.assign(Object.assign({}, ev), { detail: {
  12874. ionShadowTarget: triggerEl,
  12875. } }));
  12876. }
  12877. else {
  12878. overlayEl.present();
  12879. }
  12880. };
  12881. this.datetimePresentation = 'date-time';
  12882. this.dateText = undefined;
  12883. this.timeText = undefined;
  12884. this.datetimeActive = false;
  12885. this.selectedButton = undefined;
  12886. this.color = 'primary';
  12887. this.disabled = false;
  12888. this.datetime = undefined;
  12889. }
  12890. async componentWillLoad() {
  12891. const { datetime } = this;
  12892. if (!datetime) {
  12893. printIonError('[ion-datetime-button] - An ID associated with an ion-datetime instance is required to function properly.', this.el);
  12894. return;
  12895. }
  12896. const datetimeEl = (this.datetimeEl = document.getElementById(datetime));
  12897. if (!datetimeEl) {
  12898. printIonError(`[ion-datetime-button] - No ion-datetime instance found for ID '${datetime}'.`, this.el);
  12899. return;
  12900. }
  12901. /**
  12902. * The element reference must be an ion-datetime. Print an error
  12903. * if a non-datetime element was provided.
  12904. */
  12905. if (datetimeEl.tagName !== 'ION-DATETIME') {
  12906. printIonError(`[ion-datetime-button] - Expected an ion-datetime instance for ID '${datetime}' but received '${datetimeEl.tagName.toLowerCase()}' instead.`, datetimeEl);
  12907. return;
  12908. }
  12909. /**
  12910. * Since the datetime can be used in any context (overlays, accordion, etc)
  12911. * we track when it is visible to determine when it is active.
  12912. * This informs which button is highlighted as well as the
  12913. * aria-expanded state.
  12914. */
  12915. const io = new IntersectionObserver((entries) => {
  12916. const ev = entries[0];
  12917. this.datetimeActive = ev.isIntersecting;
  12918. }, {
  12919. threshold: 0.01,
  12920. });
  12921. io.observe(datetimeEl);
  12922. /**
  12923. * Get a reference to any modal/popover
  12924. * the datetime is being used in so we can
  12925. * correctly size it when it is presented.
  12926. */
  12927. const overlayEl = (this.overlayEl = datetimeEl.closest('ion-modal, ion-popover'));
  12928. /**
  12929. * The .ion-datetime-button-overlay class contains
  12930. * styles that allow any modal/popover to be
  12931. * sized according to the dimensions of the datetime.
  12932. * If developers want a smaller/larger overlay all they need
  12933. * to do is change the width/height of the datetime.
  12934. * Additionally, this lets us avoid having to set
  12935. * explicit widths on each variant of datetime.
  12936. */
  12937. if (overlayEl) {
  12938. overlayEl.classList.add('ion-datetime-button-overlay');
  12939. }
  12940. componentOnReady(datetimeEl, () => {
  12941. const datetimePresentation = (this.datetimePresentation = datetimeEl.presentation || 'date-time');
  12942. /**
  12943. * Set the initial display
  12944. * in the rendered buttons.
  12945. *
  12946. * From there, we need to listen
  12947. * for ionChange to be emitted
  12948. * from datetime so we know when
  12949. * to re-render the displayed
  12950. * text in the buttons.
  12951. */
  12952. this.setDateTimeText();
  12953. addEventListener$1(datetimeEl, 'ionValueChange', this.setDateTimeText);
  12954. /**
  12955. * Configure the initial selected button
  12956. * in the event that the datetime is displayed
  12957. * without clicking one of the datetime buttons.
  12958. * For example, a datetime could be expanded
  12959. * in an accordion. In this case users only
  12960. * need to click the accordion header to show
  12961. * the datetime.
  12962. */
  12963. switch (datetimePresentation) {
  12964. case 'date-time':
  12965. case 'date':
  12966. case 'month-year':
  12967. case 'month':
  12968. case 'year':
  12969. this.selectedButton = 'date';
  12970. break;
  12971. case 'time-date':
  12972. case 'time':
  12973. this.selectedButton = 'time';
  12974. break;
  12975. }
  12976. });
  12977. }
  12978. render() {
  12979. const { color, dateText, timeText, selectedButton, datetimeActive, disabled } = this;
  12980. const mode = getIonMode$1(this);
  12981. return (hAsync(Host, { key: '11d037e6ab061e5116842970760b04850b42f2c7', class: createColorClasses$1(color, {
  12982. [mode]: true,
  12983. [`${selectedButton}-active`]: datetimeActive,
  12984. ['datetime-button-disabled']: disabled,
  12985. }) }, 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' })))));
  12986. }
  12987. get el() { return getElement(this); }
  12988. static get style() { return {
  12989. ios: IonDatetimeButtonIosStyle0,
  12990. md: IonDatetimeButtonMdStyle0
  12991. }; }
  12992. static get cmpMeta() { return {
  12993. "$flags$": 41,
  12994. "$tagName$": "ion-datetime-button",
  12995. "$members$": {
  12996. "color": [513],
  12997. "disabled": [516],
  12998. "datetime": [1],
  12999. "datetimePresentation": [32],
  13000. "dateText": [32],
  13001. "timeText": [32],
  13002. "datetimeActive": [32],
  13003. "selectedButton": [32]
  13004. },
  13005. "$listeners$": undefined,
  13006. "$lazyBundleId$": "-",
  13007. "$attrsToReflect$": [["color", "color"], ["disabled", "disabled"]]
  13008. }; }
  13009. }
  13010. 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}";
  13011. var IonFabStyle0 = fabCss;
  13012. class Fab {
  13013. constructor(hostRef) {
  13014. registerInstance(this, hostRef);
  13015. this.horizontal = undefined;
  13016. this.vertical = undefined;
  13017. this.edge = false;
  13018. this.activated = false;
  13019. }
  13020. activatedChanged() {
  13021. const activated = this.activated;
  13022. const fab = this.getFab();
  13023. if (fab) {
  13024. fab.activated = activated;
  13025. }
  13026. Array.from(this.el.querySelectorAll('ion-fab-list')).forEach((list) => {
  13027. list.activated = activated;
  13028. });
  13029. }
  13030. componentDidLoad() {
  13031. if (this.activated) {
  13032. this.activatedChanged();
  13033. }
  13034. }
  13035. /**
  13036. * Close an active FAB list container.
  13037. */
  13038. async close() {
  13039. this.activated = false;
  13040. }
  13041. getFab() {
  13042. return this.el.querySelector('ion-fab-button');
  13043. }
  13044. /**
  13045. * Opens/Closes the FAB list container.
  13046. * @internal
  13047. */
  13048. async toggle() {
  13049. const hasList = !!this.el.querySelector('ion-fab-list');
  13050. if (hasList) {
  13051. this.activated = !this.activated;
  13052. }
  13053. }
  13054. render() {
  13055. const { horizontal, vertical, edge } = this;
  13056. const mode = getIonMode$1(this);
  13057. return (hAsync(Host, { key: '8a310806d0e748d7ebb0ed3d9a2652038e0f2960', class: {
  13058. [mode]: true,
  13059. [`fab-horizontal-${horizontal}`]: horizontal !== undefined,
  13060. [`fab-vertical-${vertical}`]: vertical !== undefined,
  13061. 'fab-edge': edge,
  13062. } }, hAsync("slot", { key: '9394ef6d6e5b0410fa6ba212171f687fb178ce2d' })));
  13063. }
  13064. get el() { return getElement(this); }
  13065. static get watchers() { return {
  13066. "activated": ["activatedChanged"]
  13067. }; }
  13068. static get style() { return IonFabStyle0; }
  13069. static get cmpMeta() { return {
  13070. "$flags$": 9,
  13071. "$tagName$": "ion-fab",
  13072. "$members$": {
  13073. "horizontal": [1],
  13074. "vertical": [1],
  13075. "edge": [4],
  13076. "activated": [1028],
  13077. "close": [64],
  13078. "toggle": [64]
  13079. },
  13080. "$listeners$": undefined,
  13081. "$lazyBundleId$": "-",
  13082. "$attrsToReflect$": []
  13083. }; }
  13084. }
  13085. 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)}}";
  13086. var IonFabButtonIosStyle0 = fabButtonIosCss;
  13087. 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)}}";
  13088. var IonFabButtonMdStyle0 = fabButtonMdCss;
  13089. /**
  13090. * @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
  13091. *
  13092. * @part native - The native HTML button or anchor element that wraps all child elements.
  13093. * @part close-icon - The close icon that is displayed when a fab list opens (uses ion-icon).
  13094. */
  13095. class FabButton {
  13096. constructor(hostRef) {
  13097. registerInstance(this, hostRef);
  13098. this.ionFocus = createEvent(this, "ionFocus", 7);
  13099. this.ionBlur = createEvent(this, "ionBlur", 7);
  13100. this.fab = null;
  13101. this.inheritedAttributes = {};
  13102. this.onFocus = () => {
  13103. this.ionFocus.emit();
  13104. };
  13105. this.onBlur = () => {
  13106. this.ionBlur.emit();
  13107. };
  13108. this.onClick = () => {
  13109. const { fab } = this;
  13110. if (!fab) {
  13111. return;
  13112. }
  13113. fab.toggle();
  13114. };
  13115. this.color = undefined;
  13116. this.activated = false;
  13117. this.disabled = false;
  13118. this.download = undefined;
  13119. this.href = undefined;
  13120. this.rel = undefined;
  13121. this.routerDirection = 'forward';
  13122. this.routerAnimation = undefined;
  13123. this.target = undefined;
  13124. this.show = false;
  13125. this.translucent = false;
  13126. this.type = 'button';
  13127. this.size = undefined;
  13128. this.closeIcon = close;
  13129. }
  13130. connectedCallback() {
  13131. this.fab = this.el.closest('ion-fab');
  13132. }
  13133. componentWillLoad() {
  13134. this.inheritedAttributes = inheritAriaAttributes(this.el);
  13135. }
  13136. render() {
  13137. const { el, disabled, color, href, activated, show, translucent, size, inheritedAttributes } = this;
  13138. const inList = hostContext('ion-fab-list', el);
  13139. const mode = getIonMode$1(this);
  13140. const TagType = href === undefined ? 'button' : 'a';
  13141. const attrs = TagType === 'button'
  13142. ? { type: this.type }
  13143. : {
  13144. download: this.download,
  13145. href,
  13146. rel: this.rel,
  13147. target: this.target,
  13148. };
  13149. return (hAsync(Host, { key: '4eee204d20b0e2ffed49a88f6cb3e04b6697965c', onClick: this.onClick, "aria-disabled": disabled ? 'true' : null, class: createColorClasses$1(color, {
  13150. [mode]: true,
  13151. 'fab-button-in-list': inList,
  13152. 'fab-button-translucent-in-list': inList && translucent,
  13153. 'fab-button-close-active': activated,
  13154. 'fab-button-show': show,
  13155. 'fab-button-disabled': disabled,
  13156. 'fab-button-translucent': translucent,
  13157. 'ion-activatable': true,
  13158. 'ion-focusable': true,
  13159. [`fab-button-${size}`]: size !== undefined,
  13160. }) }, 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' }))));
  13161. }
  13162. get el() { return getElement(this); }
  13163. static get style() { return {
  13164. ios: IonFabButtonIosStyle0,
  13165. md: IonFabButtonMdStyle0
  13166. }; }
  13167. static get cmpMeta() { return {
  13168. "$flags$": 41,
  13169. "$tagName$": "ion-fab-button",
  13170. "$members$": {
  13171. "color": [513],
  13172. "activated": [4],
  13173. "disabled": [4],
  13174. "download": [1],
  13175. "href": [1],
  13176. "rel": [1],
  13177. "routerDirection": [1, "router-direction"],
  13178. "routerAnimation": [16],
  13179. "target": [1],
  13180. "show": [4],
  13181. "translucent": [4],
  13182. "type": [1],
  13183. "size": [1],
  13184. "closeIcon": [1, "close-icon"]
  13185. },
  13186. "$listeners$": undefined,
  13187. "$lazyBundleId$": "-",
  13188. "$attrsToReflect$": [["color", "color"]]
  13189. }; }
  13190. }
  13191. 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}";
  13192. var IonFabListStyle0 = fabListCss;
  13193. class FabList {
  13194. constructor(hostRef) {
  13195. registerInstance(this, hostRef);
  13196. this.activated = false;
  13197. this.side = 'bottom';
  13198. }
  13199. activatedChanged(activated) {
  13200. const fabs = Array.from(this.el.querySelectorAll('ion-fab-button'));
  13201. // if showing the fabs add a timeout, else show immediately
  13202. const timeout = activated ? 30 : 0;
  13203. fabs.forEach((fab, i) => {
  13204. setTimeout(() => (fab.show = activated), i * timeout);
  13205. });
  13206. }
  13207. render() {
  13208. const mode = getIonMode$1(this);
  13209. return (hAsync(Host, { key: '64b33366447f66c7f979cfac56307fbb1a6fac1c', class: {
  13210. [mode]: true,
  13211. 'fab-list-active': this.activated,
  13212. [`fab-list-side-${this.side}`]: true,
  13213. } }, hAsync("slot", { key: 'd9f474f7f20fd7e813db358fddc720534ca05bb6' })));
  13214. }
  13215. get el() { return getElement(this); }
  13216. static get watchers() { return {
  13217. "activated": ["activatedChanged"]
  13218. }; }
  13219. static get style() { return IonFabListStyle0; }
  13220. static get cmpMeta() { return {
  13221. "$flags$": 9,
  13222. "$tagName$": "ion-fab-list",
  13223. "$members$": {
  13224. "activated": [4],
  13225. "side": [1]
  13226. },
  13227. "$listeners$": undefined,
  13228. "$lazyBundleId$": "-",
  13229. "$attrsToReflect$": []
  13230. }; }
  13231. }
  13232. const ION_CONTENT_TAG_NAME = 'ION-CONTENT';
  13233. const ION_CONTENT_ELEMENT_SELECTOR = 'ion-content';
  13234. const ION_CONTENT_CLASS_SELECTOR = '.ion-content-scroll-host';
  13235. /**
  13236. * Selector used for implementations reliant on `<ion-content>` for scroll event changes.
  13237. *
  13238. * Developers should use the `.ion-content-scroll-host` selector to target the element emitting
  13239. * scroll events. With virtual scroll implementations this will be the host element for
  13240. * the scroll viewport.
  13241. */
  13242. const ION_CONTENT_SELECTOR = `${ION_CONTENT_ELEMENT_SELECTOR}, ${ION_CONTENT_CLASS_SELECTOR}`;
  13243. const isIonContent = (el) => el.tagName === ION_CONTENT_TAG_NAME;
  13244. /**
  13245. * Waits for the element host fully initialize before
  13246. * returning the inner scroll element.
  13247. *
  13248. * For `ion-content` the scroll target will be the result
  13249. * of the `getScrollElement` function.
  13250. *
  13251. * For custom implementations it will be the element host
  13252. * or a selector within the host, if supplied through `scrollTarget`.
  13253. */
  13254. const getScrollElement = async (el) => {
  13255. if (isIonContent(el)) {
  13256. await new Promise((resolve) => componentOnReady(el, resolve));
  13257. return el.getScrollElement();
  13258. }
  13259. return el;
  13260. };
  13261. /**
  13262. * Queries the element matching the selector for IonContent.
  13263. * See ION_CONTENT_SELECTOR for the selector used.
  13264. */
  13265. const findIonContent = (el) => {
  13266. /**
  13267. * First we try to query the custom scroll host selector in cases where
  13268. * the implementation is using an outer `ion-content` with an inner custom
  13269. * scroll container.
  13270. */
  13271. const customContentHost = el.querySelector(ION_CONTENT_CLASS_SELECTOR);
  13272. if (customContentHost) {
  13273. return customContentHost;
  13274. }
  13275. return el.querySelector(ION_CONTENT_SELECTOR);
  13276. };
  13277. /**
  13278. * Queries the closest element matching the selector for IonContent.
  13279. */
  13280. const findClosestIonContent = (el) => {
  13281. return el.closest(ION_CONTENT_SELECTOR);
  13282. };
  13283. /**
  13284. * Prints an error informing developers that an implementation requires an element to be used
  13285. * within either the `ion-content` selector or the `.ion-content-scroll-host` class.
  13286. */
  13287. const printIonContentErrorMsg = (el) => {
  13288. return printRequiredElementError(el, ION_CONTENT_ELEMENT_SELECTOR);
  13289. };
  13290. /**
  13291. * Several components in Ionic need to prevent scrolling
  13292. * during a gesture (card modal, range, item sliding, etc).
  13293. * Use this utility to account for ion-content and custom content hosts.
  13294. */
  13295. const disableContentScrollY = (contentEl) => {
  13296. if (isIonContent(contentEl)) {
  13297. const ionContent = contentEl;
  13298. const initialScrollY = ionContent.scrollY;
  13299. ionContent.scrollY = false;
  13300. /**
  13301. * This should be passed into resetContentScrollY
  13302. * so that we can revert ion-content's scrollY to the
  13303. * correct state. For example, if scrollY = false
  13304. * initially, we do not want to enable scrolling
  13305. * when we call resetContentScrollY.
  13306. */
  13307. return initialScrollY;
  13308. }
  13309. else {
  13310. contentEl.style.setProperty('overflow', 'hidden');
  13311. return true;
  13312. }
  13313. };
  13314. const resetContentScrollY = (contentEl, initialScrollY) => {
  13315. if (isIonContent(contentEl)) {
  13316. contentEl.scrollY = initialScrollY;
  13317. }
  13318. else {
  13319. contentEl.style.removeProperty('overflow');
  13320. }
  13321. };
  13322. var ExceptionCode;
  13323. (function (ExceptionCode) {
  13324. /**
  13325. * API is not implemented.
  13326. *
  13327. * This usually means the API can't be used because it is not implemented for
  13328. * the current platform.
  13329. */
  13330. ExceptionCode["Unimplemented"] = "UNIMPLEMENTED";
  13331. /**
  13332. * API is not available.
  13333. *
  13334. * This means the API can't be used right now because:
  13335. * - it is currently missing a prerequisite, such as network connectivity
  13336. * - it requires a particular platform or browser version
  13337. */
  13338. ExceptionCode["Unavailable"] = "UNAVAILABLE";
  13339. })(ExceptionCode || (ExceptionCode = {}));
  13340. var KeyboardResize;
  13341. (function (KeyboardResize) {
  13342. /**
  13343. * Only the `body` HTML element will be resized.
  13344. * Relative units are not affected, because the viewport does not change.
  13345. *
  13346. * @since 1.0.0
  13347. */
  13348. KeyboardResize["Body"] = "body";
  13349. /**
  13350. * Only the `ion-app` HTML element will be resized.
  13351. * Use it only for Ionic Framework apps.
  13352. *
  13353. * @since 1.0.0
  13354. */
  13355. KeyboardResize["Ionic"] = "ionic";
  13356. /**
  13357. * The whole native Web View will be resized when the keyboard shows/hides.
  13358. * This affects the `vh` relative unit.
  13359. *
  13360. * @since 1.0.0
  13361. */
  13362. KeyboardResize["Native"] = "native";
  13363. /**
  13364. * Neither the app nor the Web View are resized.
  13365. *
  13366. * @since 1.0.0
  13367. */
  13368. KeyboardResize["None"] = "none";
  13369. })(KeyboardResize || (KeyboardResize = {}));
  13370. const Keyboard = {
  13371. getEngine() {
  13372. const capacitor = getCapacitor();
  13373. if (capacitor === null || capacitor === void 0 ? void 0 : capacitor.isPluginAvailable('Keyboard')) {
  13374. return capacitor.Plugins.Keyboard;
  13375. }
  13376. return undefined;
  13377. },
  13378. getResizeMode() {
  13379. const engine = this.getEngine();
  13380. if (!(engine === null || engine === void 0 ? void 0 : engine.getResizeMode)) {
  13381. return Promise.resolve(undefined);
  13382. }
  13383. return engine.getResizeMode().catch((e) => {
  13384. if (e.code === ExceptionCode.Unimplemented) {
  13385. // If the native implementation is not available
  13386. // we treat it the same as if the plugin is not available.
  13387. return undefined;
  13388. }
  13389. throw e;
  13390. });
  13391. },
  13392. };
  13393. /**
  13394. * The element that resizes when the keyboard opens
  13395. * is going to depend on the resize mode
  13396. * which is why we check that here.
  13397. */
  13398. const getResizeContainer = (resizeMode) => {
  13399. /**
  13400. * If doc is undefined then we are
  13401. * in an SSR environment, so the keyboard
  13402. * adjustment does not apply.
  13403. * If the webview does not resize then there
  13404. * is no container to resize.
  13405. */
  13406. if (doc === undefined || resizeMode === KeyboardResize.None || resizeMode === undefined) {
  13407. return null;
  13408. }
  13409. /**
  13410. * The three remaining resize modes: Native, Ionic, and Body
  13411. * all cause `ion-app` to resize, so we can listen for changes
  13412. * on that. In the event `ion-app` is not available then
  13413. * we can fall back to `body`.
  13414. */
  13415. const ionApp = doc.querySelector('ion-app');
  13416. return ionApp !== null && ionApp !== void 0 ? ionApp : doc.body;
  13417. };
  13418. /**
  13419. * Get the height of ion-app or body.
  13420. * This is used for determining if the webview
  13421. * has resized before the keyboard closed.
  13422. * */
  13423. const getResizeContainerHeight = (resizeMode) => {
  13424. const containerElement = getResizeContainer(resizeMode);
  13425. return containerElement === null ? 0 : containerElement.clientHeight;
  13426. };
  13427. /**
  13428. * Creates a controller that tracks and reacts to opening or closing the keyboard.
  13429. *
  13430. * @internal
  13431. * @param keyboardChangeCallback A function to call when the keyboard opens or closes.
  13432. */
  13433. const createKeyboardController = async (keyboardChangeCallback) => {
  13434. let keyboardWillShowHandler;
  13435. let keyboardWillHideHandler;
  13436. let keyboardVisible;
  13437. /**
  13438. * This lets us determine if the webview content
  13439. * has resized as a result of the keyboard.
  13440. */
  13441. let initialResizeContainerHeight;
  13442. const init = async () => {
  13443. const resizeOptions = await Keyboard.getResizeMode();
  13444. const resizeMode = resizeOptions === undefined ? undefined : resizeOptions.mode;
  13445. keyboardWillShowHandler = () => {
  13446. /**
  13447. * We need to compute initialResizeContainerHeight right before
  13448. * the keyboard opens to guarantee the resize container is visible.
  13449. * The resize container may not be visible if we compute this
  13450. * as soon as the keyboard controller is created.
  13451. * We should only need to do this once to avoid additional clientHeight
  13452. * computations.
  13453. */
  13454. if (initialResizeContainerHeight === undefined) {
  13455. initialResizeContainerHeight = getResizeContainerHeight(resizeMode);
  13456. }
  13457. keyboardVisible = true;
  13458. fireChangeCallback(keyboardVisible, resizeMode);
  13459. };
  13460. keyboardWillHideHandler = () => {
  13461. keyboardVisible = false;
  13462. fireChangeCallback(keyboardVisible, resizeMode);
  13463. };
  13464. win$1 === null || win$1 === void 0 ? void 0 : win$1.addEventListener('keyboardWillShow', keyboardWillShowHandler);
  13465. win$1 === null || win$1 === void 0 ? void 0 : win$1.addEventListener('keyboardWillHide', keyboardWillHideHandler);
  13466. };
  13467. const fireChangeCallback = (state, resizeMode) => {
  13468. if (keyboardChangeCallback) {
  13469. keyboardChangeCallback(state, createResizePromiseIfNeeded(resizeMode));
  13470. }
  13471. };
  13472. /**
  13473. * Code responding to keyboard lifecycles may need
  13474. * to show/hide content once the webview has
  13475. * resized as a result of the keyboard showing/hiding.
  13476. * createResizePromiseIfNeeded provides a way for code to wait for the
  13477. * resize event that was triggered as a result of the keyboard.
  13478. */
  13479. const createResizePromiseIfNeeded = (resizeMode) => {
  13480. if (
  13481. /**
  13482. * If we are in an SSR environment then there is
  13483. * no window to resize. Additionally, if there
  13484. * is no resize mode or the resize mode is "None"
  13485. * then initialResizeContainerHeight will be 0
  13486. */
  13487. initialResizeContainerHeight === 0 ||
  13488. /**
  13489. * If the keyboard is closed before the webview resizes initially
  13490. * then the webview will never resize.
  13491. */
  13492. initialResizeContainerHeight === getResizeContainerHeight(resizeMode)) {
  13493. return;
  13494. }
  13495. /**
  13496. * Get the resize container so we can
  13497. * attach the ResizeObserver below to
  13498. * the correct element.
  13499. */
  13500. const containerElement = getResizeContainer(resizeMode);
  13501. if (containerElement === null) {
  13502. return;
  13503. }
  13504. /**
  13505. * Some part of the web content should resize,
  13506. * and we need to listen for a resize.
  13507. */
  13508. return new Promise((resolve) => {
  13509. const callback = () => {
  13510. /**
  13511. * As per the spec, the ResizeObserver
  13512. * will fire when observation starts if
  13513. * the observed element is rendered and does not
  13514. * have a size of 0 x 0. However, the watched element
  13515. * may or may not have resized by the time this first
  13516. * callback is fired. As a result, we need to check
  13517. * the dimensions of the element.
  13518. *
  13519. * https://www.w3.org/TR/resize-observer/#intro
  13520. */
  13521. if (containerElement.clientHeight === initialResizeContainerHeight) {
  13522. /**
  13523. * The resize happened, so stop listening
  13524. * for resize on this element.
  13525. */
  13526. ro.disconnect();
  13527. resolve();
  13528. }
  13529. };
  13530. /**
  13531. * In Capacitor there can be delay between when the window
  13532. * resizes and when the container element resizes, so we cannot
  13533. * rely on a 'resize' event listener on the window.
  13534. * Instead, we need to determine when the container
  13535. * element resizes using a ResizeObserver.
  13536. */
  13537. const ro = new ResizeObserver(callback);
  13538. ro.observe(containerElement);
  13539. });
  13540. };
  13541. const destroy = () => {
  13542. win$1 === null || win$1 === void 0 ? void 0 : win$1.removeEventListener('keyboardWillShow', keyboardWillShowHandler);
  13543. win$1 === null || win$1 === void 0 ? void 0 : win$1.removeEventListener('keyboardWillHide', keyboardWillHideHandler);
  13544. keyboardWillShowHandler = keyboardWillHideHandler = undefined;
  13545. };
  13546. const isKeyboardVisible = () => keyboardVisible;
  13547. await init();
  13548. return { init, destroy, isKeyboardVisible };
  13549. };
  13550. const handleFooterFade = (scrollEl, baseEl) => {
  13551. readTask(() => {
  13552. const scrollTop = scrollEl.scrollTop;
  13553. const maxScroll = scrollEl.scrollHeight - scrollEl.clientHeight;
  13554. /**
  13555. * Toolbar background will fade
  13556. * out over fadeDuration in pixels.
  13557. */
  13558. const fadeDuration = 10;
  13559. /**
  13560. * Begin fading out maxScroll - 30px
  13561. * from the bottom of the content.
  13562. * Also determine how close we are
  13563. * to starting the fade. If we are
  13564. * before the starting point, the
  13565. * scale value will get clamped to 0.
  13566. * If we are after the maxScroll (rubber
  13567. * band scrolling), the scale value will
  13568. * get clamped to 1.
  13569. */
  13570. const fadeStart = maxScroll - fadeDuration;
  13571. const distanceToStart = scrollTop - fadeStart;
  13572. const scale = clamp(0, 1 - distanceToStart / fadeDuration, 1);
  13573. writeTask(() => {
  13574. baseEl.style.setProperty('--opacity-scale', scale.toString());
  13575. });
  13576. });
  13577. };
  13578. 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}";
  13579. var IonFooterIosStyle0 = footerIosCss;
  13580. 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}";
  13581. var IonFooterMdStyle0 = footerMdCss;
  13582. /**
  13583. * @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
  13584. */
  13585. class Footer {
  13586. constructor(hostRef) {
  13587. registerInstance(this, hostRef);
  13588. this.keyboardCtrl = null;
  13589. this.checkCollapsibleFooter = () => {
  13590. const mode = getIonMode$1(this);
  13591. if (mode !== 'ios') {
  13592. return;
  13593. }
  13594. const { collapse } = this;
  13595. const hasFade = collapse === 'fade';
  13596. this.destroyCollapsibleFooter();
  13597. if (hasFade) {
  13598. const pageEl = this.el.closest('ion-app,ion-page,.ion-page,page-inner');
  13599. const contentEl = pageEl ? findIonContent(pageEl) : null;
  13600. if (!contentEl) {
  13601. printIonContentErrorMsg(this.el);
  13602. return;
  13603. }
  13604. this.setupFadeFooter(contentEl);
  13605. }
  13606. };
  13607. this.setupFadeFooter = async (contentEl) => {
  13608. const scrollEl = (this.scrollEl = await getScrollElement(contentEl));
  13609. /**
  13610. * Handle fading of toolbars on scroll
  13611. */
  13612. this.contentScrollCallback = () => {
  13613. handleFooterFade(scrollEl, this.el);
  13614. };
  13615. scrollEl.addEventListener('scroll', this.contentScrollCallback);
  13616. handleFooterFade(scrollEl, this.el);
  13617. };
  13618. this.keyboardVisible = false;
  13619. this.collapse = undefined;
  13620. this.translucent = false;
  13621. }
  13622. componentDidLoad() {
  13623. this.checkCollapsibleFooter();
  13624. }
  13625. componentDidUpdate() {
  13626. this.checkCollapsibleFooter();
  13627. }
  13628. async connectedCallback() {
  13629. this.keyboardCtrl = await createKeyboardController(async (keyboardOpen, waitForResize) => {
  13630. /**
  13631. * If the keyboard is hiding, then we need to wait
  13632. * for the webview to resize. Otherwise, the footer
  13633. * will flicker before the webview resizes.
  13634. */
  13635. if (keyboardOpen === false && waitForResize !== undefined) {
  13636. await waitForResize;
  13637. }
  13638. this.keyboardVisible = keyboardOpen; // trigger re-render by updating state
  13639. });
  13640. }
  13641. disconnectedCallback() {
  13642. if (this.keyboardCtrl) {
  13643. this.keyboardCtrl.destroy();
  13644. }
  13645. }
  13646. destroyCollapsibleFooter() {
  13647. if (this.scrollEl && this.contentScrollCallback) {
  13648. this.scrollEl.removeEventListener('scroll', this.contentScrollCallback);
  13649. this.contentScrollCallback = undefined;
  13650. }
  13651. }
  13652. render() {
  13653. const { translucent, collapse } = this;
  13654. const mode = getIonMode$1(this);
  13655. const tabs = this.el.closest('ion-tabs');
  13656. const tabBar = tabs === null || tabs === void 0 ? void 0 : tabs.querySelector(':scope > ion-tab-bar');
  13657. return (hAsync(Host, { key: 'ddc228f1a1e7fa4f707dccf74db2490ca3241137', role: "contentinfo", class: {
  13658. [mode]: true,
  13659. // Used internally for styling
  13660. [`footer-${mode}`]: true,
  13661. [`footer-translucent`]: translucent,
  13662. [`footer-translucent-${mode}`]: translucent,
  13663. ['footer-toolbar-padding']: !this.keyboardVisible && (!tabBar || tabBar.slot !== 'bottom'),
  13664. [`footer-collapse-${collapse}`]: collapse !== undefined,
  13665. } }, mode === 'ios' && translucent && hAsync("div", { key: 'e16ed4963ff94e06de77eb8038201820af73937c', class: "footer-background" }), hAsync("slot", { key: 'f186934febf85d37133d9351a96c1a64b0a4b203' })));
  13666. }
  13667. get el() { return getElement(this); }
  13668. static get style() { return {
  13669. ios: IonFooterIosStyle0,
  13670. md: IonFooterMdStyle0
  13671. }; }
  13672. static get cmpMeta() { return {
  13673. "$flags$": 36,
  13674. "$tagName$": "ion-footer",
  13675. "$members$": {
  13676. "collapse": [1],
  13677. "translucent": [4],
  13678. "keyboardVisible": [32]
  13679. },
  13680. "$listeners$": undefined,
  13681. "$lazyBundleId$": "-",
  13682. "$attrsToReflect$": []
  13683. }; }
  13684. }
  13685. 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}";
  13686. var IonGridStyle0 = gridCss;
  13687. class Grid {
  13688. constructor(hostRef) {
  13689. registerInstance(this, hostRef);
  13690. this.fixed = false;
  13691. }
  13692. render() {
  13693. const mode = getIonMode$1(this);
  13694. return (hAsync(Host, { key: '617127ecfabf9bf615bef1dda1be3fed5a065949', class: {
  13695. [mode]: true,
  13696. 'grid-fixed': this.fixed,
  13697. } }, hAsync("slot", { key: 'c781fff853b093d8f44bdb7943bbc4f17c903803' })));
  13698. }
  13699. static get style() { return IonGridStyle0; }
  13700. static get cmpMeta() { return {
  13701. "$flags$": 9,
  13702. "$tagName$": "ion-grid",
  13703. "$members$": {
  13704. "fixed": [4]
  13705. },
  13706. "$listeners$": undefined,
  13707. "$lazyBundleId$": "-",
  13708. "$attrsToReflect$": []
  13709. }; }
  13710. }
  13711. const TRANSITION = 'all 0.2s ease-in-out';
  13712. const cloneElement = (tagName) => {
  13713. const getCachedEl = document.querySelector(`${tagName}.ion-cloned-element`);
  13714. if (getCachedEl !== null) {
  13715. return getCachedEl;
  13716. }
  13717. const clonedEl = document.createElement(tagName);
  13718. clonedEl.classList.add('ion-cloned-element');
  13719. clonedEl.style.setProperty('display', 'none');
  13720. document.body.appendChild(clonedEl);
  13721. return clonedEl;
  13722. };
  13723. const createHeaderIndex = (headerEl) => {
  13724. if (!headerEl) {
  13725. return;
  13726. }
  13727. const toolbars = headerEl.querySelectorAll('ion-toolbar');
  13728. return {
  13729. el: headerEl,
  13730. toolbars: Array.from(toolbars).map((toolbar) => {
  13731. const ionTitleEl = toolbar.querySelector('ion-title');
  13732. return {
  13733. el: toolbar,
  13734. background: toolbar.shadowRoot.querySelector('.toolbar-background'),
  13735. ionTitleEl,
  13736. innerTitleEl: ionTitleEl ? ionTitleEl.shadowRoot.querySelector('.toolbar-title') : null,
  13737. ionButtonsEl: Array.from(toolbar.querySelectorAll('ion-buttons')),
  13738. };
  13739. }),
  13740. };
  13741. };
  13742. const handleContentScroll = (scrollEl, scrollHeaderIndex, contentEl) => {
  13743. readTask(() => {
  13744. const scrollTop = scrollEl.scrollTop;
  13745. const scale = clamp(1, 1 + -scrollTop / 500, 1.1);
  13746. // Native refresher should not cause titles to scale
  13747. const nativeRefresher = contentEl.querySelector('ion-refresher.refresher-native');
  13748. if (nativeRefresher === null) {
  13749. writeTask(() => {
  13750. scaleLargeTitles(scrollHeaderIndex.toolbars, scale);
  13751. });
  13752. }
  13753. });
  13754. };
  13755. const setToolbarBackgroundOpacity = (headerEl, opacity) => {
  13756. /**
  13757. * Fading in the backdrop opacity
  13758. * should happen after the large title
  13759. * has collapsed, so it is handled
  13760. * by handleHeaderFade()
  13761. */
  13762. if (headerEl.collapse === 'fade') {
  13763. return;
  13764. }
  13765. if (opacity === undefined) {
  13766. headerEl.style.removeProperty('--opacity-scale');
  13767. }
  13768. else {
  13769. headerEl.style.setProperty('--opacity-scale', opacity.toString());
  13770. }
  13771. };
  13772. const handleToolbarBorderIntersection = (ev, mainHeaderIndex, scrollTop) => {
  13773. if (!ev[0].isIntersecting) {
  13774. return;
  13775. }
  13776. /**
  13777. * There is a bug in Safari where overflow scrolling on a non-body element
  13778. * does not always reset the scrollTop position to 0 when letting go. It will
  13779. * set to 1 once the rubber band effect has ended. This causes the background to
  13780. * appear slightly on certain app setups.
  13781. *
  13782. * Additionally, we check if user is rubber banding (scrolling is negative)
  13783. * as this can mean they are using pull to refresh. Once the refresher starts,
  13784. * the content is transformed which can cause the intersection observer to erroneously
  13785. * fire here as well.
  13786. */
  13787. const scale = ev[0].intersectionRatio > 0.9 || scrollTop <= 0 ? 0 : ((1 - ev[0].intersectionRatio) * 100) / 75;
  13788. setToolbarBackgroundOpacity(mainHeaderIndex.el, scale === 1 ? undefined : scale);
  13789. };
  13790. /**
  13791. * If toolbars are intersecting, hide the scrollable toolbar content
  13792. * and show the primary toolbar content. If the toolbars are not intersecting,
  13793. * hide the primary toolbar content and show the scrollable toolbar content
  13794. */
  13795. const handleToolbarIntersection = (ev, // TODO(FW-2832): type (IntersectionObserverEntry[] triggers errors which should be sorted)
  13796. mainHeaderIndex, scrollHeaderIndex, scrollEl) => {
  13797. writeTask(() => {
  13798. const scrollTop = scrollEl.scrollTop;
  13799. handleToolbarBorderIntersection(ev, mainHeaderIndex, scrollTop);
  13800. const event = ev[0];
  13801. const intersection = event.intersectionRect;
  13802. const intersectionArea = intersection.width * intersection.height;
  13803. const rootArea = event.rootBounds.width * event.rootBounds.height;
  13804. const isPageHidden = intersectionArea === 0 && rootArea === 0;
  13805. const leftDiff = Math.abs(intersection.left - event.boundingClientRect.left);
  13806. const rightDiff = Math.abs(intersection.right - event.boundingClientRect.right);
  13807. const isPageTransitioning = intersectionArea > 0 && (leftDiff >= 5 || rightDiff >= 5);
  13808. if (isPageHidden || isPageTransitioning) {
  13809. return;
  13810. }
  13811. if (event.isIntersecting) {
  13812. setHeaderActive(mainHeaderIndex, false);
  13813. setHeaderActive(scrollHeaderIndex);
  13814. }
  13815. else {
  13816. /**
  13817. * There is a bug with IntersectionObserver on Safari
  13818. * where `event.isIntersecting === false` when cancelling
  13819. * a swipe to go back gesture. Checking the intersection
  13820. * x, y, width, and height provides a workaround. This bug
  13821. * does not happen when using Safari + Web Animations,
  13822. * only Safari + CSS Animations.
  13823. */
  13824. const hasValidIntersection = (intersection.x === 0 && intersection.y === 0) || (intersection.width !== 0 && intersection.height !== 0);
  13825. if (hasValidIntersection && scrollTop > 0) {
  13826. setHeaderActive(mainHeaderIndex);
  13827. setHeaderActive(scrollHeaderIndex, false);
  13828. setToolbarBackgroundOpacity(mainHeaderIndex.el);
  13829. }
  13830. }
  13831. });
  13832. };
  13833. const setHeaderActive = (headerIndex, active = true) => {
  13834. const headerEl = headerIndex.el;
  13835. const toolbars = headerIndex.toolbars;
  13836. const ionTitles = toolbars.map((toolbar) => toolbar.ionTitleEl);
  13837. if (active) {
  13838. headerEl.classList.remove('header-collapse-condense-inactive');
  13839. ionTitles.forEach((ionTitle) => {
  13840. if (ionTitle) {
  13841. ionTitle.removeAttribute('aria-hidden');
  13842. }
  13843. });
  13844. }
  13845. else {
  13846. headerEl.classList.add('header-collapse-condense-inactive');
  13847. /**
  13848. * The small title should only be accessed by screen readers
  13849. * when the large title collapses into the small title due
  13850. * to scrolling.
  13851. *
  13852. * Originally, the header was given `aria-hidden="true"`
  13853. * but this caused issues with screen readers not being
  13854. * able to access any focusable elements within the header.
  13855. */
  13856. ionTitles.forEach((ionTitle) => {
  13857. if (ionTitle) {
  13858. ionTitle.setAttribute('aria-hidden', 'true');
  13859. }
  13860. });
  13861. }
  13862. };
  13863. const scaleLargeTitles = (toolbars = [], scale = 1, transition = false) => {
  13864. toolbars.forEach((toolbar) => {
  13865. const ionTitle = toolbar.ionTitleEl;
  13866. const titleDiv = toolbar.innerTitleEl;
  13867. if (!ionTitle || ionTitle.size !== 'large') {
  13868. return;
  13869. }
  13870. titleDiv.style.transition = transition ? TRANSITION : '';
  13871. titleDiv.style.transform = `scale3d(${scale}, ${scale}, 1)`;
  13872. });
  13873. };
  13874. const handleHeaderFade = (scrollEl, baseEl, condenseHeader) => {
  13875. readTask(() => {
  13876. const scrollTop = scrollEl.scrollTop;
  13877. const baseElHeight = baseEl.clientHeight;
  13878. const fadeStart = condenseHeader ? condenseHeader.clientHeight : 0;
  13879. /**
  13880. * If we are using fade header with a condense
  13881. * header, then the toolbar backgrounds should
  13882. * not begin to fade in until the condense
  13883. * header has fully collapsed.
  13884. *
  13885. * Additionally, the main content should not
  13886. * overflow out of the container until the
  13887. * condense header has fully collapsed. When
  13888. * using just the condense header the content
  13889. * should overflow out of the container.
  13890. */
  13891. if (condenseHeader !== null && scrollTop < fadeStart) {
  13892. baseEl.style.setProperty('--opacity-scale', '0');
  13893. scrollEl.style.setProperty('clip-path', `inset(${baseElHeight}px 0px 0px 0px)`);
  13894. return;
  13895. }
  13896. const distanceToStart = scrollTop - fadeStart;
  13897. const fadeDuration = 10;
  13898. const scale = clamp(0, distanceToStart / fadeDuration, 1);
  13899. writeTask(() => {
  13900. scrollEl.style.removeProperty('clip-path');
  13901. baseEl.style.setProperty('--opacity-scale', scale.toString());
  13902. });
  13903. });
  13904. };
  13905. 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}";
  13906. var IonHeaderIosStyle0 = headerIosCss;
  13907. 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}";
  13908. var IonHeaderMdStyle0 = headerMdCss;
  13909. /**
  13910. * @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
  13911. */
  13912. class Header {
  13913. constructor(hostRef) {
  13914. registerInstance(this, hostRef);
  13915. this.inheritedAttributes = {};
  13916. this.setupFadeHeader = async (contentEl, condenseHeader) => {
  13917. const scrollEl = (this.scrollEl = await getScrollElement(contentEl));
  13918. /**
  13919. * Handle fading of toolbars on scroll
  13920. */
  13921. this.contentScrollCallback = () => {
  13922. handleHeaderFade(this.scrollEl, this.el, condenseHeader);
  13923. };
  13924. scrollEl.addEventListener('scroll', this.contentScrollCallback);
  13925. handleHeaderFade(this.scrollEl, this.el, condenseHeader);
  13926. };
  13927. this.collapse = undefined;
  13928. this.translucent = false;
  13929. }
  13930. componentWillLoad() {
  13931. this.inheritedAttributes = inheritAriaAttributes(this.el);
  13932. }
  13933. componentDidLoad() {
  13934. this.checkCollapsibleHeader();
  13935. }
  13936. componentDidUpdate() {
  13937. this.checkCollapsibleHeader();
  13938. }
  13939. disconnectedCallback() {
  13940. this.destroyCollapsibleHeader();
  13941. }
  13942. async checkCollapsibleHeader() {
  13943. const mode = getIonMode$1(this);
  13944. if (mode !== 'ios') {
  13945. return;
  13946. }
  13947. const { collapse } = this;
  13948. const hasCondense = collapse === 'condense';
  13949. const hasFade = collapse === 'fade';
  13950. this.destroyCollapsibleHeader();
  13951. if (hasCondense) {
  13952. const pageEl = this.el.closest('ion-app,ion-page,.ion-page,page-inner');
  13953. const contentEl = pageEl ? findIonContent(pageEl) : null;
  13954. // Cloned elements are always needed in iOS transition
  13955. writeTask(() => {
  13956. const title = cloneElement('ion-title');
  13957. title.size = 'large';
  13958. cloneElement('ion-back-button');
  13959. });
  13960. await this.setupCondenseHeader(contentEl, pageEl);
  13961. }
  13962. else if (hasFade) {
  13963. const pageEl = this.el.closest('ion-app,ion-page,.ion-page,page-inner');
  13964. const contentEl = pageEl ? findIonContent(pageEl) : null;
  13965. if (!contentEl) {
  13966. printIonContentErrorMsg(this.el);
  13967. return;
  13968. }
  13969. const condenseHeader = contentEl.querySelector('ion-header[collapse="condense"]');
  13970. await this.setupFadeHeader(contentEl, condenseHeader);
  13971. }
  13972. }
  13973. destroyCollapsibleHeader() {
  13974. if (this.intersectionObserver) {
  13975. this.intersectionObserver.disconnect();
  13976. this.intersectionObserver = undefined;
  13977. }
  13978. if (this.scrollEl && this.contentScrollCallback) {
  13979. this.scrollEl.removeEventListener('scroll', this.contentScrollCallback);
  13980. this.contentScrollCallback = undefined;
  13981. }
  13982. if (this.collapsibleMainHeader) {
  13983. this.collapsibleMainHeader.classList.remove('header-collapse-main');
  13984. this.collapsibleMainHeader = undefined;
  13985. }
  13986. }
  13987. async setupCondenseHeader(contentEl, pageEl) {
  13988. if (!contentEl || !pageEl) {
  13989. printIonContentErrorMsg(this.el);
  13990. return;
  13991. }
  13992. if (typeof IntersectionObserver === 'undefined') {
  13993. return;
  13994. }
  13995. this.scrollEl = await getScrollElement(contentEl);
  13996. const headers = pageEl.querySelectorAll('ion-header');
  13997. this.collapsibleMainHeader = Array.from(headers).find((header) => header.collapse !== 'condense');
  13998. if (!this.collapsibleMainHeader) {
  13999. return;
  14000. }
  14001. const mainHeaderIndex = createHeaderIndex(this.collapsibleMainHeader);
  14002. const scrollHeaderIndex = createHeaderIndex(this.el);
  14003. if (!mainHeaderIndex || !scrollHeaderIndex) {
  14004. return;
  14005. }
  14006. setHeaderActive(mainHeaderIndex, false);
  14007. setToolbarBackgroundOpacity(mainHeaderIndex.el, 0);
  14008. /**
  14009. * Handle interaction between toolbar collapse and
  14010. * showing/hiding content in the primary ion-header
  14011. * as well as progressively showing/hiding the main header
  14012. * border as the top-most toolbar collapses or expands.
  14013. */
  14014. const toolbarIntersection = (ev) => {
  14015. handleToolbarIntersection(ev, mainHeaderIndex, scrollHeaderIndex, this.scrollEl);
  14016. };
  14017. this.intersectionObserver = new IntersectionObserver(toolbarIntersection, {
  14018. root: contentEl,
  14019. threshold: [0.25, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1],
  14020. });
  14021. this.intersectionObserver.observe(scrollHeaderIndex.toolbars[scrollHeaderIndex.toolbars.length - 1].el);
  14022. /**
  14023. * Handle scaling of large iOS titles and
  14024. * showing/hiding border on last toolbar
  14025. * in primary header
  14026. */
  14027. this.contentScrollCallback = () => {
  14028. handleContentScroll(this.scrollEl, scrollHeaderIndex, contentEl);
  14029. };
  14030. this.scrollEl.addEventListener('scroll', this.contentScrollCallback);
  14031. writeTask(() => {
  14032. if (this.collapsibleMainHeader !== undefined) {
  14033. this.collapsibleMainHeader.classList.add('header-collapse-main');
  14034. }
  14035. });
  14036. }
  14037. render() {
  14038. const { translucent, inheritedAttributes } = this;
  14039. const mode = getIonMode$1(this);
  14040. const collapse = this.collapse || 'none';
  14041. // banner role must be at top level, so remove role if inside a menu
  14042. const roleType = hostContext('ion-menu', this.el) ? 'none' : 'banner';
  14043. return (hAsync(Host, Object.assign({ key: 'b6cc27f0b08afc9fcc889683525da765d80ba672', role: roleType, class: {
  14044. [mode]: true,
  14045. // Used internally for styling
  14046. [`header-${mode}`]: true,
  14047. [`header-translucent`]: this.translucent,
  14048. [`header-collapse-${collapse}`]: true,
  14049. [`header-translucent-${mode}`]: this.translucent,
  14050. } }, inheritedAttributes), mode === 'ios' && translucent && hAsync("div", { key: '395766d4dcee3398bc91960db21f922095292f14', class: "header-background" }), hAsync("slot", { key: '09a67ece27b258ff1248805d43d92a49b2c6859a' })));
  14051. }
  14052. get el() { return getElement(this); }
  14053. static get style() { return {
  14054. ios: IonHeaderIosStyle0,
  14055. md: IonHeaderMdStyle0
  14056. }; }
  14057. static get cmpMeta() { return {
  14058. "$flags$": 36,
  14059. "$tagName$": "ion-header",
  14060. "$members$": {
  14061. "collapse": [1],
  14062. "translucent": [4]
  14063. },
  14064. "$listeners$": undefined,
  14065. "$lazyBundleId$": "-",
  14066. "$attrsToReflect$": []
  14067. }; }
  14068. }
  14069. const getName = (iconName, icon, mode, ios, md) => {
  14070. // default to "md" if somehow the mode wasn't set
  14071. mode = (mode && toLower(mode)) === 'ios' ? 'ios' : 'md';
  14072. // if an icon was passed in using the ios or md attributes
  14073. // set the iconName to whatever was passed in
  14074. if (ios && mode === 'ios') {
  14075. iconName = toLower(ios);
  14076. }
  14077. else if (md && mode === 'md') {
  14078. iconName = toLower(md);
  14079. }
  14080. else {
  14081. if (!iconName && icon && !isSrc(icon)) {
  14082. iconName = icon;
  14083. }
  14084. if (isStr(iconName)) {
  14085. iconName = toLower(iconName);
  14086. }
  14087. }
  14088. if (!isStr(iconName) || iconName.trim() === '') {
  14089. return null;
  14090. }
  14091. // only allow alpha characters and dash
  14092. const invalidChars = iconName.replace(/[a-z]|-|\d/gi, '');
  14093. if (invalidChars !== '') {
  14094. return null;
  14095. }
  14096. return iconName;
  14097. };
  14098. const isSrc = (str) => str.length > 0 && /(\/|\.)/.test(str);
  14099. const isStr = (val) => typeof val === 'string';
  14100. const toLower = (val) => val.toLowerCase();
  14101. /**
  14102. * Elements inside of web components sometimes need to inherit global attributes
  14103. * set on the host. For example, the inner input in `ion-input` should inherit
  14104. * the `title` attribute that developers set directly on `ion-input`. This
  14105. * helper function should be called in componentWillLoad and assigned to a variable
  14106. * that is later used in the render function.
  14107. *
  14108. * This does not need to be reactive as changing attributes on the host element
  14109. * does not trigger a re-render.
  14110. */
  14111. const inheritAttributes = (el, attributes = []) => {
  14112. const attributeObject = {};
  14113. attributes.forEach(attr => {
  14114. if (el.hasAttribute(attr)) {
  14115. const value = el.getAttribute(attr);
  14116. if (value !== null) {
  14117. attributeObject[attr] = el.getAttribute(attr);
  14118. }
  14119. el.removeAttribute(attr);
  14120. }
  14121. });
  14122. return attributeObject;
  14123. };
  14124. /**
  14125. * Returns `true` if the document or host element
  14126. * has a `dir` set to `rtl`. The host value will always
  14127. * take priority over the root document value.
  14128. */
  14129. const isRTL = (hostEl) => {
  14130. if (hostEl) {
  14131. if (hostEl.dir !== '') {
  14132. return hostEl.dir.toLowerCase() === 'rtl';
  14133. }
  14134. }
  14135. return (document === null || document === void 0 ? void 0 : document.dir.toLowerCase()) === 'rtl';
  14136. };
  14137. 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)}";
  14138. var IonIconStyle0 = iconCss;
  14139. class Icon {
  14140. constructor(hostRef) {
  14141. registerInstance(this, hostRef);
  14142. this.iconName = null;
  14143. this.inheritedAttributes = {};
  14144. this.didLoadIcon = false;
  14145. this.svgContent = undefined;
  14146. this.isVisible = false;
  14147. this.mode = getIonMode();
  14148. this.color = undefined;
  14149. this.ios = undefined;
  14150. this.md = undefined;
  14151. this.flipRtl = undefined;
  14152. this.name = undefined;
  14153. this.src = undefined;
  14154. this.icon = undefined;
  14155. this.size = undefined;
  14156. this.lazy = false;
  14157. this.sanitize = true;
  14158. }
  14159. componentWillLoad() {
  14160. this.inheritedAttributes = inheritAttributes(this.el, ['aria-label']);
  14161. }
  14162. connectedCallback() {
  14163. // purposely do not return the promise here because loading
  14164. // the svg file should not hold up loading the app
  14165. // only load the svg if it's visible
  14166. this.waitUntilVisible(this.el, '50px', () => {
  14167. this.isVisible = true;
  14168. this.loadIcon();
  14169. });
  14170. }
  14171. componentDidLoad() {
  14172. /**
  14173. * Addresses an Angular issue where property values are assigned after the 'connectedCallback' but prior to the registration of watchers.
  14174. * This enhancement ensures the loading of an icon when the component has finished rendering and the icon has yet to apply the SVG data.
  14175. * This modification pertains to the usage of Angular's binding syntax:
  14176. * `<ion-icon [name]="myIconName"></ion-icon>`
  14177. */
  14178. if (!this.didLoadIcon) {
  14179. this.loadIcon();
  14180. }
  14181. }
  14182. disconnectedCallback() {
  14183. if (this.io) {
  14184. this.io.disconnect();
  14185. this.io = undefined;
  14186. }
  14187. }
  14188. waitUntilVisible(el, rootMargin, cb) {
  14189. {
  14190. // browser doesn't support IntersectionObserver
  14191. // so just fallback to always show it
  14192. cb();
  14193. }
  14194. }
  14195. loadIcon() {
  14196. this.iconName = getName(this.name, this.icon, this.mode, this.ios, this.md);
  14197. }
  14198. render() {
  14199. const { flipRtl, iconName, inheritedAttributes, el } = this;
  14200. const mode = this.mode || 'md';
  14201. // 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
  14202. const shouldAutoFlip = iconName
  14203. ? (iconName.includes('arrow') || iconName.includes('chevron')) && flipRtl !== false
  14204. : false;
  14205. // if shouldBeFlippable is true, the icon should change direction when `dir` changes
  14206. const shouldBeFlippable = flipRtl || shouldAutoFlip;
  14207. 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" }))));
  14208. }
  14209. static get assetsDirs() { return ["svg"]; }
  14210. get el() { return getElement(this); }
  14211. static get watchers() { return {
  14212. "name": ["loadIcon"],
  14213. "src": ["loadIcon"],
  14214. "icon": ["loadIcon"],
  14215. "ios": ["loadIcon"],
  14216. "md": ["loadIcon"]
  14217. }; }
  14218. static get style() { return IonIconStyle0; }
  14219. static get cmpMeta() { return {
  14220. "$flags$": 9,
  14221. "$tagName$": "ion-icon",
  14222. "$members$": {
  14223. "mode": [1025],
  14224. "color": [1],
  14225. "ios": [1],
  14226. "md": [1],
  14227. "flipRtl": [4, "flip-rtl"],
  14228. "name": [513],
  14229. "src": [1],
  14230. "icon": [8],
  14231. "size": [1],
  14232. "lazy": [4],
  14233. "sanitize": [4],
  14234. "svgContent": [32],
  14235. "isVisible": [32]
  14236. },
  14237. "$listeners$": undefined,
  14238. "$lazyBundleId$": "-",
  14239. "$attrsToReflect$": [["name", "name"]]
  14240. }; }
  14241. }
  14242. const getIonMode = () => 'md';
  14243. const createColorClasses = (color) => {
  14244. return color
  14245. ? {
  14246. 'ion-color': true,
  14247. [`ion-color-${color}`]: true,
  14248. }
  14249. : null;
  14250. };
  14251. 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}";
  14252. var IonImgStyle0 = imgCss;
  14253. /**
  14254. * @part image - The inner `img` element.
  14255. */
  14256. class Img {
  14257. constructor(hostRef) {
  14258. registerInstance(this, hostRef);
  14259. this.ionImgWillLoad = createEvent(this, "ionImgWillLoad", 7);
  14260. this.ionImgDidLoad = createEvent(this, "ionImgDidLoad", 7);
  14261. this.ionError = createEvent(this, "ionError", 7);
  14262. this.inheritedAttributes = {};
  14263. this.onLoad = () => {
  14264. this.ionImgDidLoad.emit();
  14265. };
  14266. this.onError = () => {
  14267. this.ionError.emit();
  14268. };
  14269. this.loadSrc = undefined;
  14270. this.loadError = undefined;
  14271. this.alt = undefined;
  14272. this.src = undefined;
  14273. }
  14274. srcChanged() {
  14275. this.addIO();
  14276. }
  14277. componentWillLoad() {
  14278. this.inheritedAttributes = inheritAttributes$1(this.el, ['draggable']);
  14279. }
  14280. componentDidLoad() {
  14281. this.addIO();
  14282. }
  14283. addIO() {
  14284. if (this.src === undefined) {
  14285. return;
  14286. }
  14287. if (typeof window !== 'undefined' &&
  14288. 'IntersectionObserver' in window &&
  14289. 'IntersectionObserverEntry' in window &&
  14290. 'isIntersecting' in window.IntersectionObserverEntry.prototype) {
  14291. this.removeIO();
  14292. this.io = new IntersectionObserver((data) => {
  14293. /**
  14294. * On slower devices, it is possible for an intersection observer entry to contain multiple
  14295. * objects in the array. This happens when quickly scrolling an image into view and then out of
  14296. * view. In this case, the last object represents the current state of the component.
  14297. */
  14298. if (data[data.length - 1].isIntersecting) {
  14299. this.load();
  14300. this.removeIO();
  14301. }
  14302. });
  14303. this.io.observe(this.el);
  14304. }
  14305. else {
  14306. // fall back to setTimeout for Safari and IE
  14307. setTimeout(() => this.load(), 200);
  14308. }
  14309. }
  14310. load() {
  14311. this.loadError = this.onError;
  14312. this.loadSrc = this.src;
  14313. this.ionImgWillLoad.emit();
  14314. }
  14315. removeIO() {
  14316. if (this.io) {
  14317. this.io.disconnect();
  14318. this.io = undefined;
  14319. }
  14320. }
  14321. render() {
  14322. const { loadSrc, alt, onLoad, loadError, inheritedAttributes } = this;
  14323. const { draggable } = inheritedAttributes;
  14324. 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) })));
  14325. }
  14326. get el() { return getElement(this); }
  14327. static get watchers() { return {
  14328. "src": ["srcChanged"]
  14329. }; }
  14330. static get style() { return IonImgStyle0; }
  14331. static get cmpMeta() { return {
  14332. "$flags$": 9,
  14333. "$tagName$": "ion-img",
  14334. "$members$": {
  14335. "alt": [1],
  14336. "src": [1],
  14337. "loadSrc": [32],
  14338. "loadError": [32]
  14339. },
  14340. "$listeners$": undefined,
  14341. "$lazyBundleId$": "-",
  14342. "$attrsToReflect$": []
  14343. }; }
  14344. }
  14345. /**
  14346. * Enumerated strings must be set as booleans
  14347. * as Stencil will not render 'false' in the DOM.
  14348. * The need to explicitly render draggable="true"
  14349. * as only certain elements are draggable by default.
  14350. * https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/draggable.
  14351. */
  14352. const isDraggable = (draggable) => {
  14353. switch (draggable) {
  14354. case 'true':
  14355. return true;
  14356. case 'false':
  14357. return false;
  14358. default:
  14359. return undefined;
  14360. }
  14361. };
  14362. const infiniteScrollCss = "ion-infinite-scroll{display:none;width:100%}.infinite-scroll-enabled{display:block}";
  14363. var IonInfiniteScrollStyle0 = infiniteScrollCss;
  14364. class InfiniteScroll {
  14365. constructor(hostRef) {
  14366. registerInstance(this, hostRef);
  14367. this.ionInfinite = createEvent(this, "ionInfinite", 7);
  14368. this.thrPx = 0;
  14369. this.thrPc = 0;
  14370. /**
  14371. * didFire exists so that ionInfinite
  14372. * does not fire multiple times if
  14373. * users continue to scroll after
  14374. * scrolling into the infinite
  14375. * scroll threshold.
  14376. */
  14377. this.didFire = false;
  14378. this.isBusy = false;
  14379. this.onScroll = () => {
  14380. const scrollEl = this.scrollEl;
  14381. if (!scrollEl || !this.canStart()) {
  14382. return 1;
  14383. }
  14384. const infiniteHeight = this.el.offsetHeight;
  14385. if (infiniteHeight === 0) {
  14386. // if there is no height of this element then do nothing
  14387. return 2;
  14388. }
  14389. const scrollTop = scrollEl.scrollTop;
  14390. const scrollHeight = scrollEl.scrollHeight;
  14391. const height = scrollEl.offsetHeight;
  14392. const threshold = this.thrPc !== 0 ? height * this.thrPc : this.thrPx;
  14393. const distanceFromInfinite = this.position === 'bottom'
  14394. ? scrollHeight - infiniteHeight - scrollTop - threshold - height
  14395. : scrollTop - infiniteHeight - threshold;
  14396. if (distanceFromInfinite < 0) {
  14397. if (!this.didFire) {
  14398. this.isLoading = true;
  14399. this.didFire = true;
  14400. this.ionInfinite.emit();
  14401. return 3;
  14402. }
  14403. }
  14404. return 4;
  14405. };
  14406. this.isLoading = false;
  14407. this.threshold = '15%';
  14408. this.disabled = false;
  14409. this.position = 'bottom';
  14410. }
  14411. thresholdChanged() {
  14412. const val = this.threshold;
  14413. if (val.lastIndexOf('%') > -1) {
  14414. this.thrPx = 0;
  14415. this.thrPc = parseFloat(val) / 100;
  14416. }
  14417. else {
  14418. this.thrPx = parseFloat(val);
  14419. this.thrPc = 0;
  14420. }
  14421. }
  14422. disabledChanged() {
  14423. const disabled = this.disabled;
  14424. if (disabled) {
  14425. this.isLoading = false;
  14426. this.isBusy = false;
  14427. }
  14428. this.enableScrollEvents(!disabled);
  14429. }
  14430. async connectedCallback() {
  14431. const contentEl = findClosestIonContent(this.el);
  14432. if (!contentEl) {
  14433. printIonContentErrorMsg(this.el);
  14434. return;
  14435. }
  14436. this.scrollEl = await getScrollElement(contentEl);
  14437. this.thresholdChanged();
  14438. this.disabledChanged();
  14439. if (this.position === 'top') {
  14440. writeTask(() => {
  14441. if (this.scrollEl) {
  14442. this.scrollEl.scrollTop = this.scrollEl.scrollHeight - this.scrollEl.clientHeight;
  14443. }
  14444. });
  14445. }
  14446. }
  14447. disconnectedCallback() {
  14448. this.enableScrollEvents(false);
  14449. this.scrollEl = undefined;
  14450. }
  14451. /**
  14452. * Call `complete()` within the `ionInfinite` output event handler when
  14453. * your async operation has completed. For example, the `loading`
  14454. * state is while the app is performing an asynchronous operation,
  14455. * such as receiving more data from an AJAX request to add more items
  14456. * to a data list. Once the data has been received and UI updated, you
  14457. * then call this method to signify that the loading has completed.
  14458. * This method will change the infinite scroll's state from `loading`
  14459. * to `enabled`.
  14460. */
  14461. async complete() {
  14462. const scrollEl = this.scrollEl;
  14463. if (!this.isLoading || !scrollEl) {
  14464. return;
  14465. }
  14466. this.isLoading = false;
  14467. if (this.position === 'top') {
  14468. /**
  14469. * New content is being added at the top, but the scrollTop position stays the same,
  14470. * which causes a scroll jump visually. This algorithm makes sure to prevent this.
  14471. * (Frame 1)
  14472. * - complete() is called, but the UI hasn't had time to update yet.
  14473. * - Save the current content dimensions.
  14474. * - Wait for the next frame using _dom.read, so the UI will be updated.
  14475. * (Frame 2)
  14476. * - Read the new content dimensions.
  14477. * - Calculate the height difference and the new scroll position.
  14478. * - Delay the scroll position change until other possible dom reads are done using _dom.write to be performant.
  14479. * (Still frame 2, if I'm correct)
  14480. * - Change the scroll position (= visually maintain the scroll position).
  14481. * - Change the state to re-enable the InfiniteScroll.
  14482. * - This should be after changing the scroll position, or it could
  14483. * cause the InfiniteScroll to be triggered again immediately.
  14484. * (Frame 3)
  14485. * Done.
  14486. */
  14487. this.isBusy = true;
  14488. // ******** DOM READ ****************
  14489. // Save the current content dimensions before the UI updates
  14490. const prev = scrollEl.scrollHeight - scrollEl.scrollTop;
  14491. // ******** DOM READ ****************
  14492. requestAnimationFrame(() => {
  14493. readTask(() => {
  14494. // UI has updated, save the new content dimensions
  14495. const scrollHeight = scrollEl.scrollHeight;
  14496. // New content was added on top, so the scroll position should be changed immediately to prevent it from jumping around
  14497. const newScrollTop = scrollHeight - prev;
  14498. // ******** DOM WRITE ****************
  14499. requestAnimationFrame(() => {
  14500. writeTask(() => {
  14501. scrollEl.scrollTop = newScrollTop;
  14502. this.isBusy = false;
  14503. this.didFire = false;
  14504. });
  14505. });
  14506. });
  14507. });
  14508. }
  14509. else {
  14510. this.didFire = false;
  14511. }
  14512. }
  14513. canStart() {
  14514. return !this.disabled && !this.isBusy && !!this.scrollEl && !this.isLoading;
  14515. }
  14516. enableScrollEvents(shouldListen) {
  14517. if (this.scrollEl) {
  14518. if (shouldListen) {
  14519. this.scrollEl.addEventListener('scroll', this.onScroll);
  14520. }
  14521. else {
  14522. this.scrollEl.removeEventListener('scroll', this.onScroll);
  14523. }
  14524. }
  14525. }
  14526. render() {
  14527. const mode = getIonMode$1(this);
  14528. const disabled = this.disabled;
  14529. return (hAsync(Host, { key: 'e844956795f69be33396ce4480aa7a54ad01b28c', class: {
  14530. [mode]: true,
  14531. 'infinite-scroll-loading': this.isLoading,
  14532. 'infinite-scroll-enabled': !disabled,
  14533. } }));
  14534. }
  14535. get el() { return getElement(this); }
  14536. static get watchers() { return {
  14537. "threshold": ["thresholdChanged"],
  14538. "disabled": ["disabledChanged"]
  14539. }; }
  14540. static get style() { return IonInfiniteScrollStyle0; }
  14541. static get cmpMeta() { return {
  14542. "$flags$": 0,
  14543. "$tagName$": "ion-infinite-scroll",
  14544. "$members$": {
  14545. "threshold": [1],
  14546. "disabled": [4],
  14547. "position": [1],
  14548. "isLoading": [32],
  14549. "complete": [64]
  14550. },
  14551. "$listeners$": undefined,
  14552. "$lazyBundleId$": "-",
  14553. "$attrsToReflect$": []
  14554. }; }
  14555. }
  14556. 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))}";
  14557. var IonInfiniteScrollContentIosStyle0 = infiniteScrollContentIosCss;
  14558. 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))}";
  14559. var IonInfiniteScrollContentMdStyle0 = infiniteScrollContentMdCss;
  14560. class InfiniteScrollContent {
  14561. constructor(hostRef) {
  14562. registerInstance(this, hostRef);
  14563. this.customHTMLEnabled = config.get('innerHTMLTemplatesEnabled', ENABLE_HTML_CONTENT_DEFAULT);
  14564. this.loadingSpinner = undefined;
  14565. this.loadingText = undefined;
  14566. }
  14567. componentDidLoad() {
  14568. if (this.loadingSpinner === undefined) {
  14569. const mode = getIonMode$1(this);
  14570. this.loadingSpinner = config.get('infiniteLoadingSpinner', config.get('spinner', mode === 'ios' ? 'lines' : 'crescent'));
  14571. }
  14572. }
  14573. renderLoadingText() {
  14574. const { customHTMLEnabled, loadingText } = this;
  14575. if (customHTMLEnabled) {
  14576. return hAsync("div", { class: "infinite-loading-text", innerHTML: sanitizeDOMString(loadingText) });
  14577. }
  14578. return hAsync("div", { class: "infinite-loading-text" }, this.loadingText);
  14579. }
  14580. render() {
  14581. const mode = getIonMode$1(this);
  14582. return (hAsync(Host, { key: '7c16060dcfe2a0b0fb3e2f8f4c449589a76f1baa', class: {
  14583. [mode]: true,
  14584. // Used internally for styling
  14585. [`infinite-scroll-content-${mode}`]: true,
  14586. } }, 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())));
  14587. }
  14588. static get style() { return {
  14589. ios: IonInfiniteScrollContentIosStyle0,
  14590. md: IonInfiniteScrollContentMdStyle0
  14591. }; }
  14592. static get cmpMeta() { return {
  14593. "$flags$": 32,
  14594. "$tagName$": "ion-infinite-scroll-content",
  14595. "$members$": {
  14596. "loadingSpinner": [1025, "loading-spinner"],
  14597. "loadingText": [1, "loading-text"]
  14598. },
  14599. "$listeners$": undefined,
  14600. "$lazyBundleId$": "-",
  14601. "$attrsToReflect$": []
  14602. }; }
  14603. }
  14604. /**
  14605. * A utility to calculate the size of an outline notch
  14606. * width relative to the content passed. This is used in
  14607. * components such as `ion-select` with `fill="outline"`
  14608. * where we need to pass slotted HTML content. This is not
  14609. * needed when rendering plaintext content because we can
  14610. * render the plaintext again hidden with `opacity: 0` inside
  14611. * of the notch. As a result we can rely on the intrinsic size
  14612. * of the element to correctly compute the notch width. We
  14613. * cannot do this with slotted content because we cannot project
  14614. * it into 2 places at once.
  14615. *
  14616. * @internal
  14617. * @param el: The host element
  14618. * @param getNotchSpacerEl: A function that returns a reference to the notch spacer element inside of the component template.
  14619. * @param getLabelSlot: A function that returns a reference to the slotted content.
  14620. */
  14621. const createNotchController = (el, getNotchSpacerEl, getLabelSlot) => {
  14622. let notchVisibilityIO;
  14623. const needsExplicitNotchWidth = () => {
  14624. const notchSpacerEl = getNotchSpacerEl();
  14625. if (
  14626. /**
  14627. * If the notch is not being used
  14628. * then we do not need to set the notch width.
  14629. */
  14630. notchSpacerEl === undefined ||
  14631. /**
  14632. * If either the label property is being
  14633. * used or the label slot is not defined,
  14634. * then we do not need to estimate the notch width.
  14635. */
  14636. el.label !== undefined ||
  14637. getLabelSlot() === null) {
  14638. return false;
  14639. }
  14640. return true;
  14641. };
  14642. const calculateNotchWidth = () => {
  14643. if (needsExplicitNotchWidth()) {
  14644. /**
  14645. * Run this the frame after
  14646. * the browser has re-painted the host element.
  14647. * Otherwise, the label element may have a width
  14648. * of 0 and the IntersectionObserver will be used.
  14649. */
  14650. raf(() => {
  14651. setNotchWidth();
  14652. });
  14653. }
  14654. };
  14655. /**
  14656. * When using a label prop we can render
  14657. * the label value inside of the notch and
  14658. * let the browser calculate the size of the notch.
  14659. * However, we cannot render the label slot in multiple
  14660. * places so we need to manually calculate the notch dimension
  14661. * based on the size of the slotted content.
  14662. *
  14663. * This function should only be used to set the notch width
  14664. * on slotted label content. The notch width for label prop
  14665. * content is automatically calculated based on the
  14666. * intrinsic size of the label text.
  14667. */
  14668. const setNotchWidth = () => {
  14669. const notchSpacerEl = getNotchSpacerEl();
  14670. if (notchSpacerEl === undefined) {
  14671. return;
  14672. }
  14673. if (!needsExplicitNotchWidth()) {
  14674. notchSpacerEl.style.removeProperty('width');
  14675. return;
  14676. }
  14677. const width = getLabelSlot().scrollWidth;
  14678. if (
  14679. /**
  14680. * If the computed width of the label is 0
  14681. * and notchSpacerEl's offsetParent is null
  14682. * then that means the element is hidden.
  14683. * As a result, we need to wait for the element
  14684. * to become visible before setting the notch width.
  14685. *
  14686. * We do not check el.offsetParent because
  14687. * that can be null if the host element has
  14688. * position: fixed applied to it.
  14689. * notchSpacerEl does not have position: fixed.
  14690. */
  14691. width === 0 &&
  14692. notchSpacerEl.offsetParent === null &&
  14693. win$1 !== undefined &&
  14694. 'IntersectionObserver' in win$1) {
  14695. /**
  14696. * If there is an IO already attached
  14697. * then that will update the notch
  14698. * once the element becomes visible.
  14699. * As a result, there is no need to create
  14700. * another one.
  14701. */
  14702. if (notchVisibilityIO !== undefined) {
  14703. return;
  14704. }
  14705. const io = (notchVisibilityIO = new IntersectionObserver((ev) => {
  14706. /**
  14707. * If the element is visible then we
  14708. * can try setting the notch width again.
  14709. */
  14710. if (ev[0].intersectionRatio === 1) {
  14711. setNotchWidth();
  14712. io.disconnect();
  14713. notchVisibilityIO = undefined;
  14714. }
  14715. },
  14716. /**
  14717. * Set the root to be the host element
  14718. * This causes the IO callback
  14719. * to be fired in WebKit as soon as the element
  14720. * is visible. If we used the default root value
  14721. * then WebKit would only fire the IO callback
  14722. * after any animations (such as a modal transition)
  14723. * finished, and there would potentially be a flicker.
  14724. */
  14725. { threshold: 0.01, root: el }));
  14726. io.observe(notchSpacerEl);
  14727. return;
  14728. }
  14729. /**
  14730. * If the element is visible then we can set the notch width.
  14731. * The notch is only visible when the label is scaled,
  14732. * which is why we multiply the width by 0.75 as this is
  14733. * the same amount the label element is scaled by in the host CSS.
  14734. * (See $form-control-label-stacked-scale in ionic.globals.scss).
  14735. */
  14736. notchSpacerEl.style.setProperty('width', `${width * 0.75}px`);
  14737. };
  14738. const destroy = () => {
  14739. if (notchVisibilityIO) {
  14740. notchVisibilityIO.disconnect();
  14741. notchVisibilityIO = undefined;
  14742. }
  14743. };
  14744. return {
  14745. calculateNotchWidth,
  14746. destroy,
  14747. };
  14748. };
  14749. /**
  14750. * Uses the compareWith param to compare two values to determine if they are equal.
  14751. *
  14752. * @param currentValue The current value of the control.
  14753. * @param compareValue The value to compare against.
  14754. * @param compareWith The function or property name to use to compare values.
  14755. */
  14756. const compareOptions = (currentValue, compareValue, compareWith) => {
  14757. if (typeof compareWith === 'function') {
  14758. return compareWith(currentValue, compareValue);
  14759. }
  14760. else if (typeof compareWith === 'string') {
  14761. return currentValue[compareWith] === compareValue[compareWith];
  14762. }
  14763. else {
  14764. return Array.isArray(compareValue) ? compareValue.includes(currentValue) : currentValue === compareValue;
  14765. }
  14766. };
  14767. /**
  14768. * Compares a value against the current value(s) to determine if it is selected.
  14769. *
  14770. * @param currentValue The current value of the control.
  14771. * @param compareValue The value to compare against.
  14772. * @param compareWith The function or property name to use to compare values.
  14773. */
  14774. const isOptionSelected = (currentValue, compareValue, compareWith) => {
  14775. if (currentValue === undefined) {
  14776. return false;
  14777. }
  14778. if (Array.isArray(currentValue)) {
  14779. return currentValue.some((val) => compareOptions(val, compareValue, compareWith));
  14780. }
  14781. else {
  14782. return compareOptions(currentValue, compareValue, compareWith);
  14783. }
  14784. };
  14785. /**
  14786. * Used to update a scoped component that uses emulated slots. This fires when
  14787. * content is passed into the slot or when the content inside of a slot changes.
  14788. * This is not needed for components using native slots in the Shadow DOM.
  14789. * @internal
  14790. * @param el The host element to observe
  14791. * @param slotName mutationCallback will fire when nodes on these slot(s) change
  14792. * @param mutationCallback The callback to fire whenever the slotted content changes
  14793. */
  14794. const createSlotMutationController = (el, slotName, mutationCallback) => {
  14795. let hostMutationObserver;
  14796. let slottedContentMutationObserver;
  14797. if (win$1 !== undefined && 'MutationObserver' in win$1) {
  14798. const slots = Array.isArray(slotName) ? slotName : [slotName];
  14799. hostMutationObserver = new MutationObserver((entries) => {
  14800. for (const entry of entries) {
  14801. for (const node of entry.addedNodes) {
  14802. /**
  14803. * Check to see if the added node
  14804. * is our slotted content.
  14805. */
  14806. if (node.nodeType === Node.ELEMENT_NODE && slots.includes(node.slot)) {
  14807. /**
  14808. * If so, we want to watch the slotted
  14809. * content itself for changes. This lets us
  14810. * detect when content inside of the slot changes.
  14811. */
  14812. mutationCallback();
  14813. /**
  14814. * Adding the listener in an raf
  14815. * waits until Stencil moves the slotted element
  14816. * into the correct place in the event that
  14817. * slotted content is being added.
  14818. */
  14819. raf(() => watchForSlotChange(node));
  14820. return;
  14821. }
  14822. }
  14823. }
  14824. });
  14825. hostMutationObserver.observe(el, {
  14826. childList: true,
  14827. /**
  14828. * This fixes an issue with the `ion-input` and
  14829. * `ion-textarea` not re-rendering in some cases
  14830. * when using the label slot functionality.
  14831. *
  14832. * HTML element patches in Stencil that are enabled
  14833. * by the `experimentalSlotFixes` flag in Stencil v4
  14834. * result in DOM manipulations that won't trigger
  14835. * the current mutation observer configuration and
  14836. * callback.
  14837. */
  14838. subtree: true,
  14839. });
  14840. }
  14841. /**
  14842. * Listen for changes inside of the slotted content.
  14843. * We can listen for subtree changes here to be
  14844. * informed of text within the slotted content
  14845. * changing. Doing this on the host is possible
  14846. * but it is much more expensive to do because
  14847. * it also listens for changes to the internals
  14848. * of the component.
  14849. */
  14850. const watchForSlotChange = (slottedEl) => {
  14851. var _a;
  14852. if (slottedContentMutationObserver) {
  14853. slottedContentMutationObserver.disconnect();
  14854. slottedContentMutationObserver = undefined;
  14855. }
  14856. slottedContentMutationObserver = new MutationObserver((entries) => {
  14857. mutationCallback();
  14858. for (const entry of entries) {
  14859. for (const node of entry.removedNodes) {
  14860. /**
  14861. * If the element was removed then we
  14862. * need to destroy the MutationObserver
  14863. * so the element can be garbage collected.
  14864. */
  14865. if (node.nodeType === Node.ELEMENT_NODE && node.slot === slotName) {
  14866. destroySlottedContentObserver();
  14867. }
  14868. }
  14869. }
  14870. });
  14871. /**
  14872. * Listen for changes inside of the element
  14873. * as well as anything deep in the tree.
  14874. * We listen on the parentElement so that we can
  14875. * detect when slotted element itself is removed.
  14876. */
  14877. slottedContentMutationObserver.observe((_a = slottedEl.parentElement) !== null && _a !== void 0 ? _a : slottedEl, { subtree: true, childList: true });
  14878. };
  14879. const destroy = () => {
  14880. if (hostMutationObserver) {
  14881. hostMutationObserver.disconnect();
  14882. hostMutationObserver = undefined;
  14883. }
  14884. destroySlottedContentObserver();
  14885. };
  14886. const destroySlottedContentObserver = () => {
  14887. if (slottedContentMutationObserver) {
  14888. slottedContentMutationObserver.disconnect();
  14889. slottedContentMutationObserver = undefined;
  14890. }
  14891. };
  14892. return {
  14893. destroy,
  14894. };
  14895. };
  14896. const getCounterText = (value, maxLength, counterFormatter) => {
  14897. const valueLength = value == null ? 0 : value.toString().length;
  14898. const defaultCounterText = defaultCounterFormatter(valueLength, maxLength);
  14899. /**
  14900. * If developers did not pass a custom formatter,
  14901. * use the default one.
  14902. */
  14903. if (counterFormatter === undefined) {
  14904. return defaultCounterText;
  14905. }
  14906. /**
  14907. * Otherwise, try to use the custom formatter
  14908. * and fallback to the default formatter if
  14909. * there was an error.
  14910. */
  14911. try {
  14912. return counterFormatter(valueLength, maxLength);
  14913. }
  14914. catch (e) {
  14915. printIonError('[ion-input] - Exception in provided `counterFormatter`:', e);
  14916. return defaultCounterText;
  14917. }
  14918. };
  14919. const defaultCounterFormatter = (length, maxlength) => {
  14920. return `${length} / ${maxlength}`;
  14921. };
  14922. 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}";
  14923. var IonInputIosStyle0 = inputIosCss;
  14924. 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}";
  14925. var IonInputMdStyle0 = inputMdCss;
  14926. /**
  14927. * @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
  14928. *
  14929. * @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)
  14930. * @slot start - Content to display at the leading edge of the input. (EXPERIMENTAL)
  14931. * @slot end - Content to display at the trailing edge of the input. (EXPERIMENTAL)
  14932. */
  14933. class Input {
  14934. constructor(hostRef) {
  14935. registerInstance(this, hostRef);
  14936. this.ionInput = createEvent(this, "ionInput", 7);
  14937. this.ionChange = createEvent(this, "ionChange", 7);
  14938. this.ionBlur = createEvent(this, "ionBlur", 7);
  14939. this.ionFocus = createEvent(this, "ionFocus", 7);
  14940. this.inputId = `ion-input-${inputIds++}`;
  14941. this.helperTextId = `${this.inputId}-helper-text`;
  14942. this.errorTextId = `${this.inputId}-error-text`;
  14943. this.inheritedAttributes = {};
  14944. this.isComposing = false;
  14945. /**
  14946. * `true` if the input was cleared as a result of the user typing
  14947. * with `clearOnEdit` enabled.
  14948. *
  14949. * Resets when the input loses focus.
  14950. */
  14951. this.didInputClearOnEdit = false;
  14952. this.onInput = (ev) => {
  14953. const input = ev.target;
  14954. if (input) {
  14955. this.value = input.value || '';
  14956. }
  14957. this.emitInputChange(ev);
  14958. };
  14959. this.onChange = (ev) => {
  14960. this.emitValueChange(ev);
  14961. };
  14962. this.onBlur = (ev) => {
  14963. this.hasFocus = false;
  14964. if (this.focusedValue !== this.value) {
  14965. /**
  14966. * Emits the `ionChange` event when the input value
  14967. * is different than the value when the input was focused.
  14968. */
  14969. this.emitValueChange(ev);
  14970. }
  14971. this.didInputClearOnEdit = false;
  14972. this.ionBlur.emit(ev);
  14973. };
  14974. this.onFocus = (ev) => {
  14975. this.hasFocus = true;
  14976. this.focusedValue = this.value;
  14977. this.ionFocus.emit(ev);
  14978. };
  14979. this.onKeydown = (ev) => {
  14980. this.checkClearOnEdit(ev);
  14981. };
  14982. this.onCompositionStart = () => {
  14983. this.isComposing = true;
  14984. };
  14985. this.onCompositionEnd = () => {
  14986. this.isComposing = false;
  14987. };
  14988. this.clearTextInput = (ev) => {
  14989. if (this.clearInput && !this.readonly && !this.disabled && ev) {
  14990. ev.preventDefault();
  14991. ev.stopPropagation();
  14992. // Attempt to focus input again after pressing clear button
  14993. this.setFocus();
  14994. }
  14995. this.value = '';
  14996. this.emitInputChange(ev);
  14997. };
  14998. /**
  14999. * Stops propagation when the label is clicked,
  15000. * otherwise, two clicks will be triggered.
  15001. */
  15002. this.onLabelClick = (ev) => {
  15003. // Only stop propagation if the click was directly on the label
  15004. // and not on the input or other child elements
  15005. if (ev.target === ev.currentTarget) {
  15006. ev.stopPropagation();
  15007. }
  15008. };
  15009. this.hasFocus = false;
  15010. this.color = undefined;
  15011. this.autocapitalize = 'off';
  15012. this.autocomplete = 'off';
  15013. this.autocorrect = 'off';
  15014. this.autofocus = false;
  15015. this.clearInput = false;
  15016. this.clearInputIcon = undefined;
  15017. this.clearOnEdit = undefined;
  15018. this.counter = false;
  15019. this.counterFormatter = undefined;
  15020. this.debounce = undefined;
  15021. this.disabled = false;
  15022. this.enterkeyhint = undefined;
  15023. this.errorText = undefined;
  15024. this.fill = undefined;
  15025. this.inputmode = undefined;
  15026. this.helperText = undefined;
  15027. this.label = undefined;
  15028. this.labelPlacement = 'start';
  15029. this.max = undefined;
  15030. this.maxlength = undefined;
  15031. this.min = undefined;
  15032. this.minlength = undefined;
  15033. this.multiple = undefined;
  15034. this.name = this.inputId;
  15035. this.pattern = undefined;
  15036. this.placeholder = undefined;
  15037. this.readonly = false;
  15038. this.required = false;
  15039. this.shape = undefined;
  15040. this.spellcheck = false;
  15041. this.step = undefined;
  15042. this.type = 'text';
  15043. this.value = '';
  15044. }
  15045. debounceChanged() {
  15046. const { ionInput, debounce, originalIonInput } = this;
  15047. /**
  15048. * If debounce is undefined, we have to manually revert the ionInput emitter in case
  15049. * debounce used to be set to a number. Otherwise, the event would stay debounced.
  15050. */
  15051. this.ionInput = debounce === undefined ? originalIonInput !== null && originalIonInput !== void 0 ? originalIonInput : ionInput : debounceEvent(ionInput, debounce);
  15052. }
  15053. /**
  15054. * Whenever the type on the input changes we need
  15055. * to update the internal type prop on the password
  15056. * toggle so that that correct icon is shown.
  15057. */
  15058. onTypeChange() {
  15059. const passwordToggle = this.el.querySelector('ion-input-password-toggle');
  15060. if (passwordToggle) {
  15061. passwordToggle.type = this.type;
  15062. }
  15063. }
  15064. /**
  15065. * Update the native input element when the value changes
  15066. */
  15067. valueChanged() {
  15068. const nativeInput = this.nativeInput;
  15069. const value = this.getValue();
  15070. if (nativeInput && nativeInput.value !== value && !this.isComposing) {
  15071. /**
  15072. * Assigning the native input's value on attribute
  15073. * value change, allows `ionInput` implementations
  15074. * to override the control's value.
  15075. *
  15076. * Used for patterns such as input trimming (removing whitespace),
  15077. * or input masking.
  15078. */
  15079. nativeInput.value = value;
  15080. }
  15081. }
  15082. /**
  15083. * dir is a globally enumerated attribute.
  15084. * As a result, creating these as properties
  15085. * can have unintended side effects. Instead, we
  15086. * listen for attribute changes and inherit them
  15087. * to the inner `<input>` element.
  15088. */
  15089. onDirChanged(newValue) {
  15090. this.inheritedAttributes = Object.assign(Object.assign({}, this.inheritedAttributes), { dir: newValue });
  15091. }
  15092. /**
  15093. * This prevents the native input from emitting the click event.
  15094. * Instead, the click event from the ion-input is emitted.
  15095. */
  15096. onClickCapture(ev) {
  15097. const nativeInput = this.nativeInput;
  15098. if (nativeInput && ev.target === nativeInput) {
  15099. ev.stopPropagation();
  15100. this.el.click();
  15101. }
  15102. }
  15103. componentWillLoad() {
  15104. this.inheritedAttributes = Object.assign(Object.assign({}, inheritAriaAttributes(this.el)), inheritAttributes$1(this.el, ['tabindex', 'title', 'data-form-type', 'dir']));
  15105. }
  15106. connectedCallback() {
  15107. const { el } = this;
  15108. this.slotMutationController = createSlotMutationController(el, ['label', 'start', 'end'], () => forceUpdate());
  15109. this.notchController = createNotchController(el, () => this.notchSpacerEl, () => this.labelSlot);
  15110. this.debounceChanged();
  15111. }
  15112. componentDidLoad() {
  15113. this.originalIonInput = this.ionInput;
  15114. /**
  15115. * Set the type on the password toggle in the event that this input's
  15116. * type was set async and does not match the default type for the password toggle.
  15117. * This can happen when the type is bound using a JS framework binding syntax
  15118. * such as [type] in Angular.
  15119. */
  15120. this.onTypeChange();
  15121. this.debounceChanged();
  15122. }
  15123. componentDidRender() {
  15124. var _a;
  15125. (_a = this.notchController) === null || _a === void 0 ? void 0 : _a.calculateNotchWidth();
  15126. }
  15127. disconnectedCallback() {
  15128. if (this.slotMutationController) {
  15129. this.slotMutationController.destroy();
  15130. this.slotMutationController = undefined;
  15131. }
  15132. if (this.notchController) {
  15133. this.notchController.destroy();
  15134. this.notchController = undefined;
  15135. }
  15136. }
  15137. /**
  15138. * Sets focus on the native `input` in `ion-input`. Use this method instead of the global
  15139. * `input.focus()`.
  15140. *
  15141. * Developers who wish to focus an input when a page enters
  15142. * should call `setFocus()` in the `ionViewDidEnter()` lifecycle method.
  15143. *
  15144. * Developers who wish to focus an input when an overlay is presented
  15145. * should call `setFocus` after `didPresent` has resolved.
  15146. *
  15147. * See [managing focus](/docs/developing/managing-focus) for more information.
  15148. */
  15149. async setFocus() {
  15150. if (this.nativeInput) {
  15151. this.nativeInput.focus();
  15152. }
  15153. }
  15154. /**
  15155. * Returns the native `<input>` element used under the hood.
  15156. */
  15157. async getInputElement() {
  15158. /**
  15159. * If this gets called in certain early lifecycle hooks (ex: Vue onMounted),
  15160. * nativeInput won't be defined yet with the custom elements build, so wait for it to load in.
  15161. */
  15162. if (!this.nativeInput) {
  15163. await new Promise((resolve) => componentOnReady(this.el, resolve));
  15164. }
  15165. return Promise.resolve(this.nativeInput);
  15166. }
  15167. /**
  15168. * Emits an `ionChange` event.
  15169. *
  15170. * This API should be called for user committed changes.
  15171. * This API should not be used for external value changes.
  15172. */
  15173. emitValueChange(event) {
  15174. const { value } = this;
  15175. // Checks for both null and undefined values
  15176. const newValue = value == null ? value : value.toString();
  15177. // Emitting a value change should update the internal state for tracking the focused value
  15178. this.focusedValue = newValue;
  15179. this.ionChange.emit({ value: newValue, event });
  15180. }
  15181. /**
  15182. * Emits an `ionInput` event.
  15183. */
  15184. emitInputChange(event) {
  15185. const { value } = this;
  15186. // Checks for both null and undefined values
  15187. const newValue = value == null ? value : value.toString();
  15188. this.ionInput.emit({ value: newValue, event });
  15189. }
  15190. shouldClearOnEdit() {
  15191. const { type, clearOnEdit } = this;
  15192. return clearOnEdit === undefined ? type === 'password' : clearOnEdit;
  15193. }
  15194. getValue() {
  15195. return typeof this.value === 'number' ? this.value.toString() : (this.value || '').toString();
  15196. }
  15197. checkClearOnEdit(ev) {
  15198. if (!this.shouldClearOnEdit()) {
  15199. return;
  15200. }
  15201. /**
  15202. * The following keys do not modify the
  15203. * contents of the input. As a result, pressing
  15204. * them should not edit the input.
  15205. *
  15206. * We can't check to see if the value of the input
  15207. * was changed because we call checkClearOnEdit
  15208. * in a keydown listener, and the key has not yet
  15209. * been added to the input.
  15210. */
  15211. const IGNORED_KEYS = ['Enter', 'Tab', 'Shift', 'Meta', 'Alt', 'Control'];
  15212. const pressedIgnoredKey = IGNORED_KEYS.includes(ev.key);
  15213. /**
  15214. * Clear the input if the control has not been previously cleared during focus.
  15215. * Do not clear if the user hitting enter to submit a form.
  15216. */
  15217. if (!this.didInputClearOnEdit && this.hasValue() && !pressedIgnoredKey) {
  15218. this.value = '';
  15219. this.emitInputChange(ev);
  15220. }
  15221. /**
  15222. * Pressing an IGNORED_KEYS first and
  15223. * then an allowed key will cause the input to not
  15224. * be cleared.
  15225. */
  15226. if (!pressedIgnoredKey) {
  15227. this.didInputClearOnEdit = true;
  15228. }
  15229. }
  15230. hasValue() {
  15231. return this.getValue().length > 0;
  15232. }
  15233. /**
  15234. * Renders the helper text or error text values
  15235. */
  15236. renderHintText() {
  15237. const { helperText, errorText, helperTextId, errorTextId } = this;
  15238. return [
  15239. hAsync("div", { id: helperTextId, class: "helper-text" }, helperText),
  15240. hAsync("div", { id: errorTextId, class: "error-text" }, errorText),
  15241. ];
  15242. }
  15243. getHintTextID() {
  15244. const { el, helperText, errorText, helperTextId, errorTextId } = this;
  15245. if (el.classList.contains('ion-touched') && el.classList.contains('ion-invalid') && errorText) {
  15246. return errorTextId;
  15247. }
  15248. if (helperText) {
  15249. return helperTextId;
  15250. }
  15251. return undefined;
  15252. }
  15253. renderCounter() {
  15254. const { counter, maxlength, counterFormatter, value } = this;
  15255. if (counter !== true || maxlength === undefined) {
  15256. return;
  15257. }
  15258. return hAsync("div", { class: "counter" }, getCounterText(value, maxlength, counterFormatter));
  15259. }
  15260. /**
  15261. * Responsible for rendering helper text,
  15262. * error text, and counter. This element should only
  15263. * be rendered if hint text is set or counter is enabled.
  15264. */
  15265. renderBottomContent() {
  15266. const { counter, helperText, errorText, maxlength } = this;
  15267. /**
  15268. * undefined and empty string values should
  15269. * be treated as not having helper/error text.
  15270. */
  15271. const hasHintText = !!helperText || !!errorText;
  15272. const hasCounter = counter === true && maxlength !== undefined;
  15273. if (!hasHintText && !hasCounter) {
  15274. return;
  15275. }
  15276. return (hAsync("div", { class: "input-bottom" }, this.renderHintText(), this.renderCounter()));
  15277. }
  15278. renderLabel() {
  15279. const { label } = this;
  15280. return (hAsync("div", { class: {
  15281. 'label-text-wrapper': true,
  15282. 'label-text-wrapper-hidden': !this.hasLabel,
  15283. } }, label === undefined ? hAsync("slot", { name: "label" }) : hAsync("div", { class: "label-text" }, label)));
  15284. }
  15285. /**
  15286. * Gets any content passed into the `label` slot,
  15287. * not the <slot> definition.
  15288. */
  15289. get labelSlot() {
  15290. return this.el.querySelector('[slot="label"]');
  15291. }
  15292. /**
  15293. * Returns `true` if label content is provided
  15294. * either by a prop or a content. If you want
  15295. * to get the plaintext value of the label use
  15296. * the `labelText` getter instead.
  15297. */
  15298. get hasLabel() {
  15299. return this.label !== undefined || this.labelSlot !== null;
  15300. }
  15301. /**
  15302. * Renders the border container
  15303. * when fill="outline".
  15304. */
  15305. renderLabelContainer() {
  15306. const mode = getIonMode$1(this);
  15307. const hasOutlineFill = mode === 'md' && this.fill === 'outline';
  15308. if (hasOutlineFill) {
  15309. /**
  15310. * The outline fill has a special outline
  15311. * that appears around the input and the label.
  15312. * Certain stacked and floating label placements cause the
  15313. * label to translate up and create a "cut out"
  15314. * inside of that border by using the notch-spacer element.
  15315. */
  15316. return [
  15317. hAsync("div", { class: "input-outline-container" }, hAsync("div", { class: "input-outline-start" }), hAsync("div", { class: {
  15318. 'input-outline-notch': true,
  15319. 'input-outline-notch-hidden': !this.hasLabel,
  15320. } }, hAsync("div", { class: "notch-spacer", "aria-hidden": "true", ref: (el) => (this.notchSpacerEl = el) }, this.label)), hAsync("div", { class: "input-outline-end" })),
  15321. this.renderLabel(),
  15322. ];
  15323. }
  15324. /**
  15325. * If not using the outline style,
  15326. * we can render just the label.
  15327. */
  15328. return this.renderLabel();
  15329. }
  15330. render() {
  15331. const { disabled, fill, readonly, shape, inputId, labelPlacement, el, hasFocus, clearInputIcon } = this;
  15332. const mode = getIonMode$1(this);
  15333. const value = this.getValue();
  15334. const inItem = hostContext('ion-item', this.el);
  15335. const shouldRenderHighlight = mode === 'md' && fill !== 'outline' && !inItem;
  15336. const defaultClearIcon = mode === 'ios' ? closeCircle : closeSharp;
  15337. const clearIconData = clearInputIcon !== null && clearInputIcon !== void 0 ? clearInputIcon : defaultClearIcon;
  15338. const hasValue = this.hasValue();
  15339. const hasStartEndSlots = el.querySelector('[slot="start"], [slot="end"]') !== null;
  15340. /**
  15341. * If the label is stacked, it should always sit above the input.
  15342. * For floating labels, the label should move above the input if
  15343. * the input has a value, is focused, or has anything in either
  15344. * the start or end slot.
  15345. *
  15346. * If there is content in the start slot, the label would overlap
  15347. * it if not forced to float. This is also applied to the end slot
  15348. * because with the default or solid fills, the input is not
  15349. * vertically centered in the container, but the label is. This
  15350. * causes the slots and label to appear vertically offset from each
  15351. * other when the label isn't floating above the input. This doesn't
  15352. * apply to the outline fill, but this was not accounted for to keep
  15353. * things consistent.
  15354. *
  15355. * TODO(FW-5592): Remove hasStartEndSlots condition
  15356. */
  15357. const labelShouldFloat = labelPlacement === 'stacked' || (labelPlacement === 'floating' && (hasValue || hasFocus || hasStartEndSlots));
  15358. return (hAsync(Host, { key: '41b2526627e7d2773a80f011b123284203a71ca0', class: createColorClasses$1(this.color, {
  15359. [mode]: true,
  15360. 'has-value': hasValue,
  15361. 'has-focus': hasFocus,
  15362. 'label-floating': labelShouldFloat,
  15363. [`input-fill-${fill}`]: fill !== undefined,
  15364. [`input-shape-${shape}`]: shape !== undefined,
  15365. [`input-label-placement-${labelPlacement}`]: true,
  15366. 'in-item': inItem,
  15367. 'in-item-color': hostContext('ion-item.ion-color', this.el),
  15368. 'input-disabled': disabled,
  15369. }) }, 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) => {
  15370. /**
  15371. * This prevents mobile browsers from
  15372. * blurring the input when the clear
  15373. * button is activated.
  15374. */
  15375. ev.preventDefault();
  15376. }, onFocusin: (ev) => {
  15377. /**
  15378. * Prevent the focusin event from bubbling otherwise it will cause the focusin
  15379. * event listener in scroll assist to fire. When this fires, focus will be moved
  15380. * back to the input even if the clear button was never tapped. This poses issues
  15381. * for screen readers as it means users would be unable to swipe past the clear button.
  15382. */
  15383. ev.stopPropagation();
  15384. }, 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()));
  15385. }
  15386. get el() { return getElement(this); }
  15387. static get watchers() { return {
  15388. "debounce": ["debounceChanged"],
  15389. "type": ["onTypeChange"],
  15390. "value": ["valueChanged"],
  15391. "dir": ["onDirChanged"]
  15392. }; }
  15393. static get style() { return {
  15394. ios: IonInputIosStyle0,
  15395. md: IonInputMdStyle0
  15396. }; }
  15397. static get cmpMeta() { return {
  15398. "$flags$": 38,
  15399. "$tagName$": "ion-input",
  15400. "$members$": {
  15401. "color": [513],
  15402. "autocapitalize": [1],
  15403. "autocomplete": [1],
  15404. "autocorrect": [1],
  15405. "autofocus": [4],
  15406. "clearInput": [4, "clear-input"],
  15407. "clearInputIcon": [1, "clear-input-icon"],
  15408. "clearOnEdit": [4, "clear-on-edit"],
  15409. "counter": [4],
  15410. "counterFormatter": [16],
  15411. "debounce": [2],
  15412. "disabled": [516],
  15413. "enterkeyhint": [1],
  15414. "errorText": [1, "error-text"],
  15415. "fill": [1],
  15416. "inputmode": [1],
  15417. "helperText": [1, "helper-text"],
  15418. "label": [1],
  15419. "labelPlacement": [1, "label-placement"],
  15420. "max": [8],
  15421. "maxlength": [2],
  15422. "min": [8],
  15423. "minlength": [2],
  15424. "multiple": [4],
  15425. "name": [1],
  15426. "pattern": [1],
  15427. "placeholder": [1],
  15428. "readonly": [516],
  15429. "required": [4],
  15430. "shape": [1],
  15431. "spellcheck": [4],
  15432. "step": [1],
  15433. "type": [1],
  15434. "value": [1032],
  15435. "hasFocus": [32],
  15436. "setFocus": [64],
  15437. "getInputElement": [64]
  15438. },
  15439. "$listeners$": [[2, "click", "onClickCapture"]],
  15440. "$lazyBundleId$": "-",
  15441. "$attrsToReflect$": [["color", "color"], ["disabled", "disabled"], ["readonly", "readonly"]]
  15442. }; }
  15443. }
  15444. let inputIds = 0;
  15445. const iosInputPasswordToggleCss = "";
  15446. var IonInputPasswordToggleIosStyle0 = iosInputPasswordToggleCss;
  15447. const mdInputPasswordToggleCss = "";
  15448. var IonInputPasswordToggleMdStyle0 = mdInputPasswordToggleCss;
  15449. /**
  15450. * @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
  15451. */
  15452. class InputPasswordToggle {
  15453. constructor(hostRef) {
  15454. registerInstance(this, hostRef);
  15455. this.togglePasswordVisibility = () => {
  15456. const { inputElRef } = this;
  15457. if (!inputElRef) {
  15458. return;
  15459. }
  15460. inputElRef.type = inputElRef.type === 'text' ? 'password' : 'text';
  15461. };
  15462. this.color = undefined;
  15463. this.showIcon = undefined;
  15464. this.hideIcon = undefined;
  15465. this.type = 'password';
  15466. }
  15467. /**
  15468. * Whenever the input type changes we need to re-run validation to ensure the password
  15469. * toggle is being used with the correct input type. If the application changes the type
  15470. * outside of this component we also need to re-render so the correct icon is shown.
  15471. */
  15472. onTypeChange(newValue) {
  15473. if (newValue !== 'text' && newValue !== 'password') {
  15474. printIonWarning(`[ion-input-password-toggle] - Only inputs of type "text" or "password" are supported. Input of type "${newValue}" is not compatible.`, this.el);
  15475. return;
  15476. }
  15477. }
  15478. connectedCallback() {
  15479. const { el } = this;
  15480. const inputElRef = (this.inputElRef = el.closest('ion-input'));
  15481. if (!inputElRef) {
  15482. printIonWarning('[ion-input-password-toggle] - No ancestor ion-input found. This component must be slotted inside of an ion-input.', el);
  15483. return;
  15484. }
  15485. /**
  15486. * Important: Set the type in connectedCallback because the default value
  15487. * of this.type may not always be accurate. Usually inputs have the "password" type
  15488. * but it is possible to have the input to initially have the "text" type. In that scenario
  15489. * the wrong icon will show briefly before switching to the correct icon. Setting the
  15490. * type here allows us to avoid that flicker.
  15491. */
  15492. this.type = inputElRef.type;
  15493. }
  15494. disconnectedCallback() {
  15495. this.inputElRef = null;
  15496. }
  15497. render() {
  15498. var _a, _b;
  15499. const { color, type } = this;
  15500. const mode = getIonMode$1(this);
  15501. const showPasswordIcon = (_a = this.showIcon) !== null && _a !== void 0 ? _a : eye;
  15502. const hidePasswordIcon = (_b = this.hideIcon) !== null && _b !== void 0 ? _b : eyeOff;
  15503. const isPasswordVisible = type === 'text';
  15504. return (hAsync(Host, { key: '1a28e078c83e74c72d8bb8189ece93ec2e3fa3d0', class: createColorClasses$1(color, {
  15505. [mode]: true,
  15506. }) }, 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) => {
  15507. /**
  15508. * This prevents mobile browsers from
  15509. * blurring the input when the password toggle
  15510. * button is activated.
  15511. */
  15512. ev.preventDefault();
  15513. }, onClick: this.togglePasswordVisibility }, hAsync("ion-icon", { key: '26477ee97b808c3d79944bf5e33d4e05f1ae0b3f', slot: "icon-only", "aria-hidden": "true", icon: isPasswordVisible ? hidePasswordIcon : showPasswordIcon }))));
  15514. }
  15515. get el() { return getElement(this); }
  15516. static get watchers() { return {
  15517. "type": ["onTypeChange"]
  15518. }; }
  15519. static get style() { return {
  15520. ios: IonInputPasswordToggleIosStyle0,
  15521. md: IonInputPasswordToggleMdStyle0
  15522. }; }
  15523. static get cmpMeta() { return {
  15524. "$flags$": 41,
  15525. "$tagName$": "ion-input-password-toggle",
  15526. "$members$": {
  15527. "color": [513],
  15528. "showIcon": [1, "show-icon"],
  15529. "hideIcon": [1, "hide-icon"],
  15530. "type": [1025]
  15531. },
  15532. "$listeners$": undefined,
  15533. "$lazyBundleId$": "-",
  15534. "$attrsToReflect$": [["color", "color"]]
  15535. }; }
  15536. }
  15537. 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}";
  15538. var IonItemIosStyle0 = itemIosCss;
  15539. 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)}";
  15540. var IonItemMdStyle0 = itemMdCss;
  15541. /**
  15542. * @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
  15543. *
  15544. * @slot - Content is placed between the named slots if provided without a slot.
  15545. * @slot start - Content is placed to the left of the item text in LTR, and to the right in RTL.
  15546. * @slot end - Content is placed to the right of the item text in LTR, and to the left in RTL.
  15547. *
  15548. * @part native - The native HTML button, anchor or div element that wraps all child elements.
  15549. * @part detail-icon - The chevron icon for the item. Only applies when `detail="true"`.
  15550. */
  15551. class Item {
  15552. constructor(hostRef) {
  15553. registerInstance(this, hostRef);
  15554. this.labelColorStyles = {};
  15555. this.itemStyles = new Map();
  15556. this.inheritedAriaAttributes = {};
  15557. this.multipleInputs = false;
  15558. this.focusable = true;
  15559. this.color = undefined;
  15560. this.button = false;
  15561. this.detail = undefined;
  15562. this.detailIcon = chevronForward;
  15563. this.disabled = false;
  15564. this.download = undefined;
  15565. this.href = undefined;
  15566. this.rel = undefined;
  15567. this.lines = undefined;
  15568. this.routerAnimation = undefined;
  15569. this.routerDirection = 'forward';
  15570. this.target = undefined;
  15571. this.type = 'button';
  15572. }
  15573. buttonChanged() {
  15574. // Update the focusable option when the button option is changed
  15575. this.focusable = this.isFocusable();
  15576. }
  15577. labelColorChanged(ev) {
  15578. const { color } = this;
  15579. // There will be a conflict with item color if
  15580. // we apply the label color to item, so we ignore
  15581. // the label color if the user sets a color on item
  15582. if (color === undefined) {
  15583. this.labelColorStyles = ev.detail;
  15584. }
  15585. }
  15586. itemStyle(ev) {
  15587. ev.stopPropagation();
  15588. const tagName = ev.target.tagName;
  15589. const updatedStyles = ev.detail;
  15590. const newStyles = {};
  15591. const childStyles = this.itemStyles.get(tagName) || {};
  15592. let hasStyleChange = false;
  15593. Object.keys(updatedStyles).forEach((key) => {
  15594. if (updatedStyles[key]) {
  15595. const itemKey = `item-${key}`;
  15596. if (!childStyles[itemKey]) {
  15597. hasStyleChange = true;
  15598. }
  15599. newStyles[itemKey] = true;
  15600. }
  15601. });
  15602. if (!hasStyleChange && Object.keys(newStyles).length !== Object.keys(childStyles).length) {
  15603. hasStyleChange = true;
  15604. }
  15605. if (hasStyleChange) {
  15606. this.itemStyles.set(tagName, newStyles);
  15607. }
  15608. }
  15609. connectedCallback() {
  15610. this.hasStartEl();
  15611. }
  15612. componentWillLoad() {
  15613. this.inheritedAriaAttributes = inheritAttributes$1(this.el, ['aria-label']);
  15614. }
  15615. componentDidLoad() {
  15616. raf(() => {
  15617. this.setMultipleInputs();
  15618. this.focusable = this.isFocusable();
  15619. });
  15620. }
  15621. // If the item contains multiple clickable elements and/or inputs, then the item
  15622. // should not have a clickable input cover over the entire item to prevent
  15623. // interfering with their individual click events
  15624. setMultipleInputs() {
  15625. // The following elements have a clickable cover that is relative to the entire item
  15626. const covers = this.el.querySelectorAll('ion-checkbox, ion-datetime, ion-select, ion-radio');
  15627. // The following elements can accept focus alongside the previous elements
  15628. // therefore if these elements are also a child of item, we don't want the
  15629. // input cover on top of those interfering with their clicks
  15630. const inputs = this.el.querySelectorAll('ion-input, ion-range, ion-searchbar, ion-segment, ion-textarea, ion-toggle');
  15631. // The following elements should also stay clickable when an input with cover is present
  15632. const clickables = this.el.querySelectorAll('ion-router-link, ion-button, a, button');
  15633. // Check for multiple inputs to change the position of the input cover to relative
  15634. // for all of the covered inputs above
  15635. this.multipleInputs =
  15636. covers.length + inputs.length > 1 ||
  15637. covers.length + clickables.length > 1 ||
  15638. (covers.length > 0 && this.isClickable());
  15639. }
  15640. // If the item contains an input including a checkbox, datetime, select, or radio
  15641. // then the item will have a clickable input cover that covers the item
  15642. // that should get the hover, focused and activated states UNLESS it has multiple
  15643. // inputs, then those need to individually get each click
  15644. hasCover() {
  15645. const inputs = this.el.querySelectorAll('ion-checkbox, ion-datetime, ion-select, ion-radio');
  15646. return inputs.length === 1 && !this.multipleInputs;
  15647. }
  15648. // If the item has an href or button property it will render a native
  15649. // anchor or button that is clickable
  15650. isClickable() {
  15651. return this.href !== undefined || this.button;
  15652. }
  15653. canActivate() {
  15654. return this.isClickable() || this.hasCover();
  15655. }
  15656. isFocusable() {
  15657. const focusableChild = this.el.querySelector('.ion-focusable');
  15658. return this.canActivate() || focusableChild !== null;
  15659. }
  15660. hasStartEl() {
  15661. const startEl = this.el.querySelector('[slot="start"]');
  15662. if (startEl !== null) {
  15663. this.el.classList.add('item-has-start-slot');
  15664. }
  15665. }
  15666. getFirstInteractive() {
  15667. 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])');
  15668. return controls[0];
  15669. }
  15670. render() {
  15671. const { detail, detailIcon, download, labelColorStyles, lines, disabled, href, rel, target, routerAnimation, routerDirection, inheritedAriaAttributes, multipleInputs, } = this;
  15672. const childStyles = {};
  15673. const mode = getIonMode$1(this);
  15674. const clickable = this.isClickable();
  15675. const canActivate = this.canActivate();
  15676. const TagType = clickable ? (href === undefined ? 'button' : 'a') : 'div';
  15677. const attrs = TagType === 'button'
  15678. ? { type: this.type }
  15679. : {
  15680. download,
  15681. href,
  15682. rel,
  15683. target,
  15684. };
  15685. let clickFn = {};
  15686. const firstInteractive = this.getFirstInteractive();
  15687. // Only set onClick if the item is clickable to prevent screen
  15688. // readers from reading all items as clickable
  15689. if (clickable || (firstInteractive !== undefined && !multipleInputs)) {
  15690. clickFn = {
  15691. onClick: (ev) => {
  15692. if (clickable) {
  15693. openURL(href, ev, routerDirection, routerAnimation);
  15694. }
  15695. if (firstInteractive !== undefined && !multipleInputs) {
  15696. const path = ev.composedPath();
  15697. const target = path[0];
  15698. if (ev.isTrusted) {
  15699. /**
  15700. * Dispatches a click event to the first interactive element,
  15701. * when it is the result of a user clicking on the item.
  15702. *
  15703. * We check if the click target is in the shadow root,
  15704. * which means the user clicked on the .item-native or
  15705. * .item-inner padding.
  15706. */
  15707. const clickedWithinShadowRoot = this.el.shadowRoot.contains(target);
  15708. if (clickedWithinShadowRoot) {
  15709. /**
  15710. * For input/textarea clicking the padding should focus the
  15711. * text field (thus making it editable). For everything else,
  15712. * we want to click the control so it activates.
  15713. */
  15714. if (firstInteractive.tagName === 'ION-INPUT' || firstInteractive.tagName === 'ION-TEXTAREA') {
  15715. firstInteractive.setFocus();
  15716. }
  15717. firstInteractive.click();
  15718. /**
  15719. * Stop the item event from being triggered
  15720. * as the firstInteractive click event will also
  15721. * trigger the item click event.
  15722. */
  15723. ev.stopImmediatePropagation();
  15724. }
  15725. }
  15726. }
  15727. },
  15728. };
  15729. }
  15730. const showDetail = detail !== undefined ? detail : mode === 'ios' && clickable;
  15731. this.itemStyles.forEach((value) => {
  15732. Object.assign(childStyles, value);
  15733. });
  15734. const ariaDisabled = disabled || childStyles['item-interactive-disabled'] ? 'true' : null;
  15735. const inList = hostContext('ion-list', this.el) && !hostContext('ion-radio-group', this.el);
  15736. /**
  15737. * Inputs and textareas do not need to show a cursor pointer.
  15738. * However, other form controls such as checkboxes and radios do.
  15739. */
  15740. const firstInteractiveNeedsPointerCursor = firstInteractive !== undefined && !['ION-INPUT', 'ION-TEXTAREA'].includes(firstInteractive.tagName);
  15741. return (hAsync(Host, { key: '15e7d3b674c25232bc2d51573b291c72548690e5', "aria-disabled": ariaDisabled, class: Object.assign(Object.assign(Object.assign({}, childStyles), labelColorStyles), createColorClasses$1(this.color, {
  15742. item: true,
  15743. [mode]: true,
  15744. 'item-lines-default': lines === undefined,
  15745. [`item-lines-${lines}`]: lines !== undefined,
  15746. 'item-control-needs-pointer-cursor': firstInteractiveNeedsPointerCursor,
  15747. 'item-disabled': disabled,
  15748. 'in-list': inList,
  15749. 'item-multiple-inputs': this.multipleInputs,
  15750. 'ion-activatable': canActivate,
  15751. 'ion-focusable': this.focusable,
  15752. 'item-rtl': document.dir === 'rtl',
  15753. })), 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' }))));
  15754. }
  15755. get el() { return getElement(this); }
  15756. static get watchers() { return {
  15757. "button": ["buttonChanged"]
  15758. }; }
  15759. static get style() { return {
  15760. ios: IonItemIosStyle0,
  15761. md: IonItemMdStyle0
  15762. }; }
  15763. static get cmpMeta() { return {
  15764. "$flags$": 41,
  15765. "$tagName$": "ion-item",
  15766. "$members$": {
  15767. "color": [513],
  15768. "button": [4],
  15769. "detail": [4],
  15770. "detailIcon": [1, "detail-icon"],
  15771. "disabled": [516],
  15772. "download": [1],
  15773. "href": [1],
  15774. "rel": [1],
  15775. "lines": [1],
  15776. "routerAnimation": [16],
  15777. "routerDirection": [1, "router-direction"],
  15778. "target": [1],
  15779. "type": [1],
  15780. "multipleInputs": [32],
  15781. "focusable": [32]
  15782. },
  15783. "$listeners$": [[0, "ionColor", "labelColorChanged"], [0, "ionStyle", "itemStyle"]],
  15784. "$lazyBundleId$": "-",
  15785. "$attrsToReflect$": [["color", "color"], ["disabled", "disabled"]]
  15786. }; }
  15787. }
  15788. 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}";
  15789. var IonItemDividerIosStyle0 = itemDividerIosCss;
  15790. 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}";
  15791. var IonItemDividerMdStyle0 = itemDividerMdCss;
  15792. /**
  15793. * @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
  15794. *
  15795. * @slot - Content is placed between the named slots if provided without a slot.
  15796. * @slot start - Content is placed to the left of the divider text in LTR, and to the right in RTL.
  15797. * @slot end - Content is placed to the right of the divider text in LTR, and to the left in RTL.
  15798. */
  15799. class ItemDivider {
  15800. constructor(hostRef) {
  15801. registerInstance(this, hostRef);
  15802. this.color = undefined;
  15803. this.sticky = false;
  15804. }
  15805. render() {
  15806. const mode = getIonMode$1(this);
  15807. return (hAsync(Host, { key: '7150b1a3a881c3c312db40821acb9830c2885ccf', class: createColorClasses$1(this.color, {
  15808. [mode]: true,
  15809. 'item-divider-sticky': this.sticky,
  15810. item: true,
  15811. }) }, 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" }))));
  15812. }
  15813. get el() { return getElement(this); }
  15814. static get style() { return {
  15815. ios: IonItemDividerIosStyle0,
  15816. md: IonItemDividerMdStyle0
  15817. }; }
  15818. static get cmpMeta() { return {
  15819. "$flags$": 41,
  15820. "$tagName$": "ion-item-divider",
  15821. "$members$": {
  15822. "color": [513],
  15823. "sticky": [4]
  15824. },
  15825. "$listeners$": undefined,
  15826. "$lazyBundleId$": "-",
  15827. "$attrsToReflect$": [["color", "color"]]
  15828. }; }
  15829. }
  15830. const itemGroupIosCss = "ion-item-group{display:block}";
  15831. var IonItemGroupIosStyle0 = itemGroupIosCss;
  15832. const itemGroupMdCss = "ion-item-group{display:block}";
  15833. var IonItemGroupMdStyle0 = itemGroupMdCss;
  15834. class ItemGroup {
  15835. constructor(hostRef) {
  15836. registerInstance(this, hostRef);
  15837. }
  15838. render() {
  15839. const mode = getIonMode$1(this);
  15840. return (hAsync(Host, { key: 'de2a969ed0dda880bc560a325848b28d0287fdb9', role: "group", class: {
  15841. [mode]: true,
  15842. // Used internally for styling
  15843. [`item-group-${mode}`]: true,
  15844. item: true,
  15845. } }));
  15846. }
  15847. static get style() { return {
  15848. ios: IonItemGroupIosStyle0,
  15849. md: IonItemGroupMdStyle0
  15850. }; }
  15851. static get cmpMeta() { return {
  15852. "$flags$": 32,
  15853. "$tagName$": "ion-item-group",
  15854. "$members$": undefined,
  15855. "$listeners$": undefined,
  15856. "$lazyBundleId$": "-",
  15857. "$attrsToReflect$": []
  15858. }; }
  15859. }
  15860. 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)}";
  15861. var IonItemOptionIosStyle0 = itemOptionIosCss;
  15862. 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}";
  15863. var IonItemOptionMdStyle0 = itemOptionMdCss;
  15864. /**
  15865. * @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
  15866. *
  15867. * @slot - Content is placed between the named slots if provided without a slot.
  15868. * @slot start - Content is placed to the left of the option text in LTR, and to the right in RTL.
  15869. * @slot top - Content is placed above the option text.
  15870. * @slot icon-only - Should be used on an icon in an option that has no text.
  15871. * @slot bottom - Content is placed below the option text.
  15872. * @slot end - Content is placed to the right of the option text in LTR, and to the left in RTL.
  15873. *
  15874. * @part native - The native HTML button or anchor element that wraps all child elements.
  15875. */
  15876. class ItemOption {
  15877. constructor(hostRef) {
  15878. registerInstance(this, hostRef);
  15879. this.onClick = (ev) => {
  15880. const el = ev.target.closest('ion-item-option');
  15881. if (el) {
  15882. ev.preventDefault();
  15883. }
  15884. };
  15885. this.color = undefined;
  15886. this.disabled = false;
  15887. this.download = undefined;
  15888. this.expandable = false;
  15889. this.href = undefined;
  15890. this.rel = undefined;
  15891. this.target = undefined;
  15892. this.type = 'button';
  15893. }
  15894. render() {
  15895. const { disabled, expandable, href } = this;
  15896. const TagType = href === undefined ? 'button' : 'a';
  15897. const mode = getIonMode$1(this);
  15898. const attrs = TagType === 'button'
  15899. ? { type: this.type }
  15900. : {
  15901. download: this.download,
  15902. href: this.href,
  15903. target: this.target,
  15904. };
  15905. return (hAsync(Host, { key: '1b7708dd178dc2c9280652ca3da38c84ba7b767f', onClick: this.onClick, class: createColorClasses$1(this.color, {
  15906. [mode]: true,
  15907. 'item-option-disabled': disabled,
  15908. 'item-option-expandable': expandable,
  15909. 'ion-activatable': true,
  15910. }) }, 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' }))));
  15911. }
  15912. get el() { return getElement(this); }
  15913. static get style() { return {
  15914. ios: IonItemOptionIosStyle0,
  15915. md: IonItemOptionMdStyle0
  15916. }; }
  15917. static get cmpMeta() { return {
  15918. "$flags$": 41,
  15919. "$tagName$": "ion-item-option",
  15920. "$members$": {
  15921. "color": [513],
  15922. "disabled": [4],
  15923. "download": [1],
  15924. "expandable": [4],
  15925. "href": [1],
  15926. "rel": [1],
  15927. "target": [1],
  15928. "type": [1]
  15929. },
  15930. "$listeners$": undefined,
  15931. "$lazyBundleId$": "-",
  15932. "$attrsToReflect$": [["color", "color"]]
  15933. }; }
  15934. }
  15935. 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}";
  15936. var IonItemOptionsIosStyle0 = itemOptionsIosCss;
  15937. 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}";
  15938. var IonItemOptionsMdStyle0 = itemOptionsMdCss;
  15939. class ItemOptions {
  15940. constructor(hostRef) {
  15941. registerInstance(this, hostRef);
  15942. this.ionSwipe = createEvent(this, "ionSwipe", 7);
  15943. this.side = 'end';
  15944. }
  15945. /** @internal */
  15946. async fireSwipeEvent() {
  15947. this.ionSwipe.emit({
  15948. side: this.side,
  15949. });
  15950. }
  15951. render() {
  15952. const mode = getIonMode$1(this);
  15953. const isEnd = isEndSide(this.side);
  15954. return (hAsync(Host, { key: '7df4b71547524bf359c48e1b40ccbc44e850f632', class: {
  15955. [mode]: true,
  15956. // Used internally for styling
  15957. [`item-options-${mode}`]: true,
  15958. /**
  15959. * Note: The "start" and "end" terms refer to the
  15960. * direction ion-item-option instances within ion-item-options flow.
  15961. * They do not refer to how ion-item-options flows within ion-item-sliding.
  15962. * As a result, "item-options-start" means the ion-item-options container
  15963. * always appears on the left, and "item-options-end" means the ion-item-options
  15964. * container always appears on the right.
  15965. */
  15966. 'item-options-start': !isEnd,
  15967. 'item-options-end': isEnd,
  15968. } }));
  15969. }
  15970. get el() { return getElement(this); }
  15971. static get style() { return {
  15972. ios: IonItemOptionsIosStyle0,
  15973. md: IonItemOptionsMdStyle0
  15974. }; }
  15975. static get cmpMeta() { return {
  15976. "$flags$": 32,
  15977. "$tagName$": "ion-item-options",
  15978. "$members$": {
  15979. "side": [1],
  15980. "fireSwipeEvent": [64]
  15981. },
  15982. "$listeners$": undefined,
  15983. "$lazyBundleId$": "-",
  15984. "$attrsToReflect$": []
  15985. }; }
  15986. }
  15987. const watchForOptions = (containerEl, tagName, onChange) => {
  15988. if (typeof MutationObserver === 'undefined') {
  15989. return;
  15990. }
  15991. const mutation = new MutationObserver((mutationList) => {
  15992. onChange(getSelectedOption(mutationList, tagName));
  15993. });
  15994. mutation.observe(containerEl, {
  15995. childList: true,
  15996. subtree: true,
  15997. });
  15998. return mutation;
  15999. };
  16000. const getSelectedOption = (mutationList, tagName) => {
  16001. let newOption;
  16002. mutationList.forEach((mut) => {
  16003. // eslint-disable-next-line @typescript-eslint/prefer-for-of
  16004. for (let i = 0; i < mut.addedNodes.length; i++) {
  16005. newOption = findCheckedOption(mut.addedNodes[i], tagName) || newOption;
  16006. }
  16007. });
  16008. return newOption;
  16009. };
  16010. /**
  16011. * The "value" key is only set on some components such as ion-select-option.
  16012. * As a result, we create a default union type of HTMLElement and the "value" key.
  16013. * However, implementers are required to provide the appropriate component type
  16014. * such as HTMLIonSelectOptionElement.
  16015. */
  16016. const findCheckedOption = (node, tagName) => {
  16017. /**
  16018. * https://developer.mozilla.org/en-US/docs/Web/API/Node/nodeType
  16019. * The above check ensures "node" is an Element (nodeType 1).
  16020. */
  16021. if (node.nodeType !== 1) {
  16022. return undefined;
  16023. }
  16024. // HTMLElement inherits from Element, so we cast "el" as T.
  16025. const el = node;
  16026. const options = el.tagName === tagName.toUpperCase() ? [el] : Array.from(el.querySelectorAll(tagName));
  16027. return options.find((o) => o.value === el.value);
  16028. };
  16029. 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}}";
  16030. var IonItemSlidingStyle0 = itemSlidingCss;
  16031. const SWIPE_MARGIN = 30;
  16032. const ELASTIC_FACTOR = 0.55;
  16033. let openSlidingItem;
  16034. class ItemSliding {
  16035. constructor(hostRef) {
  16036. registerInstance(this, hostRef);
  16037. this.ionDrag = createEvent(this, "ionDrag", 7);
  16038. this.item = null;
  16039. this.openAmount = 0;
  16040. this.initialOpenAmount = 0;
  16041. this.optsWidthRightSide = 0;
  16042. this.optsWidthLeftSide = 0;
  16043. this.sides = 0 /* ItemSide.None */;
  16044. this.optsDirty = true;
  16045. this.contentEl = null;
  16046. this.initialContentScrollY = true;
  16047. this.state = 2 /* SlidingState.Disabled */;
  16048. this.disabled = false;
  16049. }
  16050. disabledChanged() {
  16051. if (this.gesture) {
  16052. this.gesture.enable(!this.disabled);
  16053. }
  16054. }
  16055. async connectedCallback() {
  16056. const { el } = this;
  16057. this.item = el.querySelector('ion-item');
  16058. this.contentEl = findClosestIonContent(el);
  16059. /**
  16060. * The MutationObserver needs to be added before we
  16061. * call updateOptions below otherwise we may miss
  16062. * ion-item-option elements that are added to the DOM
  16063. * while updateOptions is running and before the MutationObserver
  16064. * has been initialized.
  16065. */
  16066. this.mutationObserver = watchForOptions(el, 'ion-item-option', async () => {
  16067. await this.updateOptions();
  16068. });
  16069. await this.updateOptions();
  16070. this.gesture = (await Promise.resolve().then(function () { return index; })).createGesture({
  16071. el,
  16072. gestureName: 'item-swipe',
  16073. gesturePriority: 100,
  16074. threshold: 5,
  16075. canStart: (ev) => this.canStart(ev),
  16076. onStart: () => this.onStart(),
  16077. onMove: (ev) => this.onMove(ev),
  16078. onEnd: (ev) => this.onEnd(ev),
  16079. });
  16080. this.disabledChanged();
  16081. }
  16082. disconnectedCallback() {
  16083. if (this.gesture) {
  16084. this.gesture.destroy();
  16085. this.gesture = undefined;
  16086. }
  16087. this.item = null;
  16088. this.leftOptions = this.rightOptions = undefined;
  16089. if (openSlidingItem === this.el) {
  16090. openSlidingItem = undefined;
  16091. }
  16092. if (this.mutationObserver) {
  16093. this.mutationObserver.disconnect();
  16094. this.mutationObserver = undefined;
  16095. }
  16096. }
  16097. /**
  16098. * Get the amount the item is open in pixels.
  16099. */
  16100. getOpenAmount() {
  16101. return Promise.resolve(this.openAmount);
  16102. }
  16103. /**
  16104. * Get the ratio of the open amount of the item compared to the width of the options.
  16105. * If the number returned is positive, then the options on the right side are open.
  16106. * If the number returned is negative, then the options on the left side are open.
  16107. * If the absolute value of the number is greater than 1, the item is open more than
  16108. * the width of the options.
  16109. */
  16110. getSlidingRatio() {
  16111. return Promise.resolve(this.getSlidingRatioSync());
  16112. }
  16113. /**
  16114. * Open the sliding item.
  16115. *
  16116. * @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.
  16117. */
  16118. async open(side) {
  16119. var _a;
  16120. /**
  16121. * It is possible for the item to be added to the DOM
  16122. * after the item-sliding component was created. As a result,
  16123. * if this.item is null, then we should attempt to
  16124. * query for the ion-item again.
  16125. * However, if the item is already defined then
  16126. * we do not query for it again.
  16127. */
  16128. const item = (this.item = (_a = this.item) !== null && _a !== void 0 ? _a : this.el.querySelector('ion-item'));
  16129. if (item === null) {
  16130. return;
  16131. }
  16132. const optionsToOpen = this.getOptions(side);
  16133. if (!optionsToOpen) {
  16134. return;
  16135. }
  16136. /**
  16137. * If side is not set, we need to infer the side
  16138. * so we know which direction to move the options
  16139. */
  16140. if (side === undefined) {
  16141. side = optionsToOpen === this.leftOptions ? 'start' : 'end';
  16142. }
  16143. // In RTL we want to switch the sides
  16144. side = isEndSide(side) ? 'end' : 'start';
  16145. const isStartOpen = this.openAmount < 0;
  16146. const isEndOpen = this.openAmount > 0;
  16147. /**
  16148. * If a side is open and a user tries to
  16149. * re-open the same side, we should not do anything
  16150. */
  16151. if (isStartOpen && optionsToOpen === this.leftOptions) {
  16152. return;
  16153. }
  16154. if (isEndOpen && optionsToOpen === this.rightOptions) {
  16155. return;
  16156. }
  16157. this.closeOpened();
  16158. this.state = 4 /* SlidingState.Enabled */;
  16159. requestAnimationFrame(() => {
  16160. this.calculateOptsWidth();
  16161. const width = side === 'end' ? this.optsWidthRightSide : -this.optsWidthLeftSide;
  16162. openSlidingItem = this.el;
  16163. this.setOpenAmount(width, false);
  16164. this.state = side === 'end' ? 8 /* SlidingState.End */ : 16 /* SlidingState.Start */;
  16165. });
  16166. }
  16167. /**
  16168. * Close the sliding item. Items can also be closed from the [List](./list).
  16169. */
  16170. async close() {
  16171. this.setOpenAmount(0, true);
  16172. }
  16173. /**
  16174. * Close all of the sliding items in the list. Items can also be closed from the [List](./list).
  16175. */
  16176. async closeOpened() {
  16177. if (openSlidingItem !== undefined) {
  16178. openSlidingItem.close();
  16179. openSlidingItem = undefined;
  16180. return true;
  16181. }
  16182. return false;
  16183. }
  16184. /**
  16185. * Given an optional side, return the ion-item-options element.
  16186. *
  16187. * @param side This side of the options to get. If a side is not provided it will
  16188. * return the first one available.
  16189. */
  16190. getOptions(side) {
  16191. if (side === undefined) {
  16192. return this.leftOptions || this.rightOptions;
  16193. }
  16194. else if (side === 'start') {
  16195. return this.leftOptions;
  16196. }
  16197. else {
  16198. return this.rightOptions;
  16199. }
  16200. }
  16201. async updateOptions() {
  16202. const options = this.el.querySelectorAll('ion-item-options');
  16203. let sides = 0;
  16204. // Reset left and right options in case they were removed
  16205. this.leftOptions = this.rightOptions = undefined;
  16206. for (let i = 0; i < options.length; i++) {
  16207. const item = options.item(i);
  16208. /**
  16209. * We cannot use the componentOnReady helper
  16210. * util here since we need to wait for all of these items
  16211. * to be ready before we set `this.sides` and `this.optsDirty`.
  16212. */
  16213. // eslint-disable-next-line custom-rules/no-component-on-ready-method
  16214. const option = item.componentOnReady !== undefined ? await item.componentOnReady() : item;
  16215. const side = isEndSide(option.side) ? 'end' : 'start';
  16216. if (side === 'start') {
  16217. this.leftOptions = option;
  16218. sides |= 1 /* ItemSide.Start */;
  16219. }
  16220. else {
  16221. this.rightOptions = option;
  16222. sides |= 2 /* ItemSide.End */;
  16223. }
  16224. }
  16225. this.optsDirty = true;
  16226. this.sides = sides;
  16227. }
  16228. canStart(gesture) {
  16229. /**
  16230. * If very close to start of the screen
  16231. * do not open left side so swipe to go
  16232. * back will still work.
  16233. */
  16234. const rtl = document.dir === 'rtl';
  16235. const atEdge = rtl ? window.innerWidth - gesture.startX < 15 : gesture.startX < 15;
  16236. if (atEdge) {
  16237. return false;
  16238. }
  16239. const selected = openSlidingItem;
  16240. if (selected && selected !== this.el) {
  16241. this.closeOpened();
  16242. }
  16243. return !!(this.rightOptions || this.leftOptions);
  16244. }
  16245. onStart() {
  16246. /**
  16247. * We need to query for the ion-item
  16248. * every time the gesture starts. Developers
  16249. * may toggle ion-item elements via *ngIf.
  16250. */
  16251. this.item = this.el.querySelector('ion-item');
  16252. const { contentEl } = this;
  16253. if (contentEl) {
  16254. this.initialContentScrollY = disableContentScrollY(contentEl);
  16255. }
  16256. openSlidingItem = this.el;
  16257. if (this.tmr !== undefined) {
  16258. clearTimeout(this.tmr);
  16259. this.tmr = undefined;
  16260. }
  16261. if (this.openAmount === 0) {
  16262. this.optsDirty = true;
  16263. this.state = 4 /* SlidingState.Enabled */;
  16264. }
  16265. this.initialOpenAmount = this.openAmount;
  16266. if (this.item) {
  16267. this.item.style.transition = 'none';
  16268. }
  16269. }
  16270. onMove(gesture) {
  16271. if (this.optsDirty) {
  16272. this.calculateOptsWidth();
  16273. }
  16274. let openAmount = this.initialOpenAmount - gesture.deltaX;
  16275. switch (this.sides) {
  16276. case 2 /* ItemSide.End */:
  16277. openAmount = Math.max(0, openAmount);
  16278. break;
  16279. case 1 /* ItemSide.Start */:
  16280. openAmount = Math.min(0, openAmount);
  16281. break;
  16282. case 3 /* ItemSide.Both */:
  16283. break;
  16284. case 0 /* ItemSide.None */:
  16285. return;
  16286. default:
  16287. printIonWarning('[ion-item-sliding] - invalid ItemSideFlags value', this.sides);
  16288. break;
  16289. }
  16290. let optsWidth;
  16291. if (openAmount > this.optsWidthRightSide) {
  16292. optsWidth = this.optsWidthRightSide;
  16293. openAmount = optsWidth + (openAmount - optsWidth) * ELASTIC_FACTOR;
  16294. }
  16295. else if (openAmount < -this.optsWidthLeftSide) {
  16296. optsWidth = -this.optsWidthLeftSide;
  16297. openAmount = optsWidth + (openAmount - optsWidth) * ELASTIC_FACTOR;
  16298. }
  16299. this.setOpenAmount(openAmount, false);
  16300. }
  16301. onEnd(gesture) {
  16302. const { contentEl, initialContentScrollY } = this;
  16303. if (contentEl) {
  16304. resetContentScrollY(contentEl, initialContentScrollY);
  16305. }
  16306. const velocity = gesture.velocityX;
  16307. let restingPoint = this.openAmount > 0 ? this.optsWidthRightSide : -this.optsWidthLeftSide;
  16308. // Check if the drag didn't clear the buttons mid-point
  16309. // and we aren't moving fast enough to swipe open
  16310. const isResetDirection = this.openAmount > 0 === !(velocity < 0);
  16311. const isMovingFast = Math.abs(velocity) > 0.3;
  16312. const isOnCloseZone = Math.abs(this.openAmount) < Math.abs(restingPoint / 2);
  16313. if (swipeShouldReset(isResetDirection, isMovingFast, isOnCloseZone)) {
  16314. restingPoint = 0;
  16315. }
  16316. const state = this.state;
  16317. this.setOpenAmount(restingPoint, true);
  16318. if ((state & 32 /* SlidingState.SwipeEnd */) !== 0 && this.rightOptions) {
  16319. this.rightOptions.fireSwipeEvent();
  16320. }
  16321. else if ((state & 64 /* SlidingState.SwipeStart */) !== 0 && this.leftOptions) {
  16322. this.leftOptions.fireSwipeEvent();
  16323. }
  16324. }
  16325. calculateOptsWidth() {
  16326. this.optsWidthRightSide = 0;
  16327. if (this.rightOptions) {
  16328. this.rightOptions.style.display = 'flex';
  16329. this.optsWidthRightSide = this.rightOptions.offsetWidth;
  16330. this.rightOptions.style.display = '';
  16331. }
  16332. this.optsWidthLeftSide = 0;
  16333. if (this.leftOptions) {
  16334. this.leftOptions.style.display = 'flex';
  16335. this.optsWidthLeftSide = this.leftOptions.offsetWidth;
  16336. this.leftOptions.style.display = '';
  16337. }
  16338. this.optsDirty = false;
  16339. }
  16340. setOpenAmount(openAmount, isFinal) {
  16341. if (this.tmr !== undefined) {
  16342. clearTimeout(this.tmr);
  16343. this.tmr = undefined;
  16344. }
  16345. if (!this.item) {
  16346. return;
  16347. }
  16348. const { el } = this;
  16349. const style = this.item.style;
  16350. this.openAmount = openAmount;
  16351. if (isFinal) {
  16352. style.transition = '';
  16353. }
  16354. if (openAmount > 0) {
  16355. this.state =
  16356. openAmount >= this.optsWidthRightSide + SWIPE_MARGIN
  16357. ? 8 /* SlidingState.End */ | 32 /* SlidingState.SwipeEnd */
  16358. : 8 /* SlidingState.End */;
  16359. }
  16360. else if (openAmount < 0) {
  16361. this.state =
  16362. openAmount <= -this.optsWidthLeftSide - SWIPE_MARGIN
  16363. ? 16 /* SlidingState.Start */ | 64 /* SlidingState.SwipeStart */
  16364. : 16 /* SlidingState.Start */;
  16365. }
  16366. else {
  16367. /**
  16368. * The sliding options should not be
  16369. * clickable while the item is closing.
  16370. */
  16371. el.classList.add('item-sliding-closing');
  16372. /**
  16373. * Item sliding cannot be interrupted
  16374. * while closing the item. If it did,
  16375. * it would allow the item to get into an
  16376. * inconsistent state where multiple
  16377. * items are then open at the same time.
  16378. */
  16379. if (this.gesture) {
  16380. this.gesture.enable(false);
  16381. }
  16382. this.tmr = setTimeout(() => {
  16383. this.state = 2 /* SlidingState.Disabled */;
  16384. this.tmr = undefined;
  16385. if (this.gesture) {
  16386. this.gesture.enable(!this.disabled);
  16387. }
  16388. el.classList.remove('item-sliding-closing');
  16389. }, 600);
  16390. openSlidingItem = undefined;
  16391. style.transform = '';
  16392. return;
  16393. }
  16394. style.transform = `translate3d(${-openAmount}px,0,0)`;
  16395. this.ionDrag.emit({
  16396. amount: openAmount,
  16397. ratio: this.getSlidingRatioSync(),
  16398. });
  16399. }
  16400. getSlidingRatioSync() {
  16401. if (this.openAmount > 0) {
  16402. return this.openAmount / this.optsWidthRightSide;
  16403. }
  16404. else if (this.openAmount < 0) {
  16405. return this.openAmount / this.optsWidthLeftSide;
  16406. }
  16407. else {
  16408. return 0;
  16409. }
  16410. }
  16411. render() {
  16412. const mode = getIonMode$1(this);
  16413. return (hAsync(Host, { key: 'f8aea4bb9802b111ef358cc6c172a635637ae1f8', class: {
  16414. [mode]: true,
  16415. 'item-sliding-active-slide': this.state !== 2 /* SlidingState.Disabled */,
  16416. 'item-sliding-active-options-end': (this.state & 8 /* SlidingState.End */) !== 0,
  16417. 'item-sliding-active-options-start': (this.state & 16 /* SlidingState.Start */) !== 0,
  16418. 'item-sliding-active-swipe-end': (this.state & 32 /* SlidingState.SwipeEnd */) !== 0,
  16419. 'item-sliding-active-swipe-start': (this.state & 64 /* SlidingState.SwipeStart */) !== 0,
  16420. } }));
  16421. }
  16422. get el() { return getElement(this); }
  16423. static get watchers() { return {
  16424. "disabled": ["disabledChanged"]
  16425. }; }
  16426. static get style() { return IonItemSlidingStyle0; }
  16427. static get cmpMeta() { return {
  16428. "$flags$": 0,
  16429. "$tagName$": "ion-item-sliding",
  16430. "$members$": {
  16431. "disabled": [4],
  16432. "state": [32],
  16433. "getOpenAmount": [64],
  16434. "getSlidingRatio": [64],
  16435. "open": [64],
  16436. "close": [64],
  16437. "closeOpened": [64]
  16438. },
  16439. "$listeners$": undefined,
  16440. "$lazyBundleId$": "-",
  16441. "$attrsToReflect$": []
  16442. }; }
  16443. }
  16444. const swipeShouldReset = (isResetDirection, isMovingFast, isOnResetZone) => {
  16445. // The logic required to know when the sliding item should close (openAmount=0)
  16446. // depends on three booleans (isResetDirection, isMovingFast, isOnResetZone)
  16447. // and it ended up being too complicated to be written manually without errors
  16448. // so the truth table is attached below: (0=false, 1=true)
  16449. // isResetDirection | isMovingFast | isOnResetZone || shouldClose
  16450. // 0 | 0 | 0 || 0
  16451. // 0 | 0 | 1 || 1
  16452. // 0 | 1 | 0 || 0
  16453. // 0 | 1 | 1 || 0
  16454. // 1 | 0 | 0 || 0
  16455. // 1 | 0 | 1 || 1
  16456. // 1 | 1 | 0 || 1
  16457. // 1 | 1 | 1 || 1
  16458. // The resulting expression was generated by resolving the K-map (Karnaugh map):
  16459. return (!isMovingFast && isOnResetZone) || (isResetDirection && isMovingFast);
  16460. };
  16461. 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}";
  16462. var IonLabelIosStyle0 = labelIosCss;
  16463. 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}";
  16464. var IonLabelMdStyle0 = labelMdCss;
  16465. /**
  16466. * @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
  16467. */
  16468. class Label {
  16469. constructor(hostRef) {
  16470. registerInstance(this, hostRef);
  16471. this.ionColor = createEvent(this, "ionColor", 7);
  16472. this.ionStyle = createEvent(this, "ionStyle", 7);
  16473. this.inRange = false;
  16474. this.color = undefined;
  16475. this.position = undefined;
  16476. this.noAnimate = false;
  16477. }
  16478. componentWillLoad() {
  16479. this.inRange = !!this.el.closest('ion-range');
  16480. this.noAnimate = this.position === 'floating';
  16481. this.emitStyle();
  16482. this.emitColor();
  16483. }
  16484. componentDidLoad() {
  16485. if (this.noAnimate) {
  16486. setTimeout(() => {
  16487. this.noAnimate = false;
  16488. }, 1000);
  16489. }
  16490. }
  16491. colorChanged() {
  16492. this.emitColor();
  16493. }
  16494. positionChanged() {
  16495. this.emitStyle();
  16496. }
  16497. emitColor() {
  16498. const { color } = this;
  16499. this.ionColor.emit({
  16500. 'item-label-color': color !== undefined,
  16501. [`ion-color-${color}`]: color !== undefined,
  16502. });
  16503. }
  16504. emitStyle() {
  16505. const { inRange, position } = this;
  16506. // If the label is inside of a range we don't want
  16507. // to override the classes added by the label that
  16508. // is a direct child of the item
  16509. if (!inRange) {
  16510. this.ionStyle.emit({
  16511. label: true,
  16512. [`label-${position}`]: position !== undefined,
  16513. });
  16514. }
  16515. }
  16516. render() {
  16517. const position = this.position;
  16518. const mode = getIonMode$1(this);
  16519. return (hAsync(Host, { key: '4da84c95351a74b547f8224ecfa66924d21398c5', class: createColorClasses$1(this.color, {
  16520. [mode]: true,
  16521. 'in-item-color': hostContext('ion-item.ion-color', this.el),
  16522. [`label-${position}`]: position !== undefined,
  16523. [`label-no-animate`]: this.noAnimate,
  16524. 'label-rtl': document.dir === 'rtl',
  16525. }) }, hAsync("slot", { key: 'ea158ebb620275e5492965234d0ab925d391f919' })));
  16526. }
  16527. get el() { return getElement(this); }
  16528. static get watchers() { return {
  16529. "color": ["colorChanged"],
  16530. "position": ["positionChanged"]
  16531. }; }
  16532. static get style() { return {
  16533. ios: IonLabelIosStyle0,
  16534. md: IonLabelMdStyle0
  16535. }; }
  16536. static get cmpMeta() { return {
  16537. "$flags$": 38,
  16538. "$tagName$": "ion-label",
  16539. "$members$": {
  16540. "color": [513],
  16541. "position": [1],
  16542. "noAnimate": [32]
  16543. },
  16544. "$listeners$": undefined,
  16545. "$lazyBundleId$": "-",
  16546. "$attrsToReflect$": [["color", "color"]]
  16547. }; }
  16548. }
  16549. 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}";
  16550. var IonListIosStyle0 = listIosCss;
  16551. 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}";
  16552. var IonListMdStyle0 = listMdCss;
  16553. /**
  16554. * @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
  16555. */
  16556. class List {
  16557. constructor(hostRef) {
  16558. registerInstance(this, hostRef);
  16559. this.lines = undefined;
  16560. this.inset = false;
  16561. }
  16562. /**
  16563. * If `ion-item-sliding` are used inside the list, this method closes
  16564. * any open sliding item.
  16565. *
  16566. * Returns `true` if an actual `ion-item-sliding` is closed.
  16567. */
  16568. async closeSlidingItems() {
  16569. const item = this.el.querySelector('ion-item-sliding');
  16570. if (item === null || item === void 0 ? void 0 : item.closeOpened) {
  16571. return item.closeOpened();
  16572. }
  16573. return false;
  16574. }
  16575. render() {
  16576. const mode = getIonMode$1(this);
  16577. const { lines, inset } = this;
  16578. return (hAsync(Host, { key: '5ff2b0b3989cc99ce17abb8bcd7ec1847940d1ec', role: "list", class: {
  16579. [mode]: true,
  16580. // Used internally for styling
  16581. [`list-${mode}`]: true,
  16582. 'list-inset': inset,
  16583. [`list-lines-${lines}`]: lines !== undefined,
  16584. [`list-${mode}-lines-${lines}`]: lines !== undefined,
  16585. } }));
  16586. }
  16587. get el() { return getElement(this); }
  16588. static get style() { return {
  16589. ios: IonListIosStyle0,
  16590. md: IonListMdStyle0
  16591. }; }
  16592. static get cmpMeta() { return {
  16593. "$flags$": 32,
  16594. "$tagName$": "ion-list",
  16595. "$members$": {
  16596. "lines": [1],
  16597. "inset": [4],
  16598. "closeSlidingItems": [64]
  16599. },
  16600. "$listeners$": undefined,
  16601. "$lazyBundleId$": "-",
  16602. "$attrsToReflect$": []
  16603. }; }
  16604. }
  16605. 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}";
  16606. var IonListHeaderIosStyle0 = listHeaderIosCss;
  16607. 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}";
  16608. var IonListHeaderMdStyle0 = listHeaderMdCss;
  16609. /**
  16610. * @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
  16611. */
  16612. class ListHeader {
  16613. constructor(hostRef) {
  16614. registerInstance(this, hostRef);
  16615. this.color = undefined;
  16616. this.lines = undefined;
  16617. }
  16618. render() {
  16619. const { lines } = this;
  16620. const mode = getIonMode$1(this);
  16621. return (hAsync(Host, { key: '95ce2135e2b1ad4d7d6020b0fb9bc6e02b3c0851', class: createColorClasses$1(this.color, {
  16622. [mode]: true,
  16623. [`list-header-lines-${lines}`]: lines !== undefined,
  16624. }) }, hAsync("div", { key: '3065b0a094bc31a90518898a5126a813c8a33816', class: "list-header-inner" }, hAsync("slot", { key: 'fe15c87d7867f3e5d8185645c49c0228496697b8' }))));
  16625. }
  16626. static get style() { return {
  16627. ios: IonListHeaderIosStyle0,
  16628. md: IonListHeaderMdStyle0
  16629. }; }
  16630. static get cmpMeta() { return {
  16631. "$flags$": 41,
  16632. "$tagName$": "ion-list-header",
  16633. "$members$": {
  16634. "color": [513],
  16635. "lines": [1]
  16636. },
  16637. "$listeners$": undefined,
  16638. "$lazyBundleId$": "-",
  16639. "$attrsToReflect$": [["color", "color"]]
  16640. }; }
  16641. }
  16642. /**
  16643. * iOS Loading Enter Animation
  16644. */
  16645. const iosEnterAnimation$4 = (baseEl) => {
  16646. const baseAnimation = createAnimation();
  16647. const backdropAnimation = createAnimation();
  16648. const wrapperAnimation = createAnimation();
  16649. backdropAnimation
  16650. .addElement(baseEl.querySelector('ion-backdrop'))
  16651. .fromTo('opacity', 0.01, 'var(--backdrop-opacity)')
  16652. .beforeStyles({
  16653. 'pointer-events': 'none',
  16654. })
  16655. .afterClearStyles(['pointer-events']);
  16656. wrapperAnimation.addElement(baseEl.querySelector('.loading-wrapper')).keyframes([
  16657. { offset: 0, opacity: 0.01, transform: 'scale(1.1)' },
  16658. { offset: 1, opacity: 1, transform: 'scale(1)' },
  16659. ]);
  16660. return baseAnimation
  16661. .addElement(baseEl)
  16662. .easing('ease-in-out')
  16663. .duration(200)
  16664. .addAnimation([backdropAnimation, wrapperAnimation]);
  16665. };
  16666. /**
  16667. * iOS Loading Leave Animation
  16668. */
  16669. const iosLeaveAnimation$4 = (baseEl) => {
  16670. const baseAnimation = createAnimation();
  16671. const backdropAnimation = createAnimation();
  16672. const wrapperAnimation = createAnimation();
  16673. backdropAnimation.addElement(baseEl.querySelector('ion-backdrop')).fromTo('opacity', 'var(--backdrop-opacity)', 0);
  16674. wrapperAnimation.addElement(baseEl.querySelector('.loading-wrapper')).keyframes([
  16675. { offset: 0, opacity: 0.99, transform: 'scale(1)' },
  16676. { offset: 1, opacity: 0, transform: 'scale(0.9)' },
  16677. ]);
  16678. return baseAnimation
  16679. .addElement(baseEl)
  16680. .easing('ease-in-out')
  16681. .duration(200)
  16682. .addAnimation([backdropAnimation, wrapperAnimation]);
  16683. };
  16684. /**
  16685. * Md Loading Enter Animation
  16686. */
  16687. const mdEnterAnimation$3 = (baseEl) => {
  16688. const baseAnimation = createAnimation();
  16689. const backdropAnimation = createAnimation();
  16690. const wrapperAnimation = createAnimation();
  16691. backdropAnimation
  16692. .addElement(baseEl.querySelector('ion-backdrop'))
  16693. .fromTo('opacity', 0.01, 'var(--backdrop-opacity)')
  16694. .beforeStyles({
  16695. 'pointer-events': 'none',
  16696. })
  16697. .afterClearStyles(['pointer-events']);
  16698. wrapperAnimation.addElement(baseEl.querySelector('.loading-wrapper')).keyframes([
  16699. { offset: 0, opacity: 0.01, transform: 'scale(1.1)' },
  16700. { offset: 1, opacity: 1, transform: 'scale(1)' },
  16701. ]);
  16702. return baseAnimation
  16703. .addElement(baseEl)
  16704. .easing('ease-in-out')
  16705. .duration(200)
  16706. .addAnimation([backdropAnimation, wrapperAnimation]);
  16707. };
  16708. /**
  16709. * Md Loading Leave Animation
  16710. */
  16711. const mdLeaveAnimation$3 = (baseEl) => {
  16712. const baseAnimation = createAnimation();
  16713. const backdropAnimation = createAnimation();
  16714. const wrapperAnimation = createAnimation();
  16715. backdropAnimation.addElement(baseEl.querySelector('ion-backdrop')).fromTo('opacity', 'var(--backdrop-opacity)', 0);
  16716. wrapperAnimation.addElement(baseEl.querySelector('.loading-wrapper')).keyframes([
  16717. { offset: 0, opacity: 0.99, transform: 'scale(1)' },
  16718. { offset: 1, opacity: 0, transform: 'scale(0.9)' },
  16719. ]);
  16720. return baseAnimation
  16721. .addElement(baseEl)
  16722. .easing('ease-in-out')
  16723. .duration(200)
  16724. .addAnimation([backdropAnimation, wrapperAnimation]);
  16725. };
  16726. 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}";
  16727. var IonLoadingIosStyle0 = loadingIosCss;
  16728. 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}";
  16729. var IonLoadingMdStyle0 = loadingMdCss;
  16730. // TODO(FW-2832): types
  16731. /**
  16732. * @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
  16733. */
  16734. class Loading {
  16735. constructor(hostRef) {
  16736. registerInstance(this, hostRef);
  16737. this.didPresent = createEvent(this, "ionLoadingDidPresent", 7);
  16738. this.willPresent = createEvent(this, "ionLoadingWillPresent", 7);
  16739. this.willDismiss = createEvent(this, "ionLoadingWillDismiss", 7);
  16740. this.didDismiss = createEvent(this, "ionLoadingDidDismiss", 7);
  16741. this.didPresentShorthand = createEvent(this, "didPresent", 7);
  16742. this.willPresentShorthand = createEvent(this, "willPresent", 7);
  16743. this.willDismissShorthand = createEvent(this, "willDismiss", 7);
  16744. this.didDismissShorthand = createEvent(this, "didDismiss", 7);
  16745. this.delegateController = createDelegateController(this);
  16746. this.lockController = createLockController();
  16747. this.triggerController = createTriggerController();
  16748. this.customHTMLEnabled = config.get('innerHTMLTemplatesEnabled', ENABLE_HTML_CONTENT_DEFAULT);
  16749. this.presented = false;
  16750. this.onBackdropTap = () => {
  16751. this.dismiss(undefined, BACKDROP);
  16752. };
  16753. this.overlayIndex = undefined;
  16754. this.delegate = undefined;
  16755. this.hasController = false;
  16756. this.keyboardClose = true;
  16757. this.enterAnimation = undefined;
  16758. this.leaveAnimation = undefined;
  16759. this.message = undefined;
  16760. this.cssClass = undefined;
  16761. this.duration = 0;
  16762. this.backdropDismiss = false;
  16763. this.showBackdrop = true;
  16764. this.spinner = undefined;
  16765. this.translucent = false;
  16766. this.animated = true;
  16767. this.htmlAttributes = undefined;
  16768. this.isOpen = false;
  16769. this.trigger = undefined;
  16770. }
  16771. onIsOpenChange(newValue, oldValue) {
  16772. if (newValue === true && oldValue === false) {
  16773. this.present();
  16774. }
  16775. else if (newValue === false && oldValue === true) {
  16776. this.dismiss();
  16777. }
  16778. }
  16779. triggerChanged() {
  16780. const { trigger, el, triggerController } = this;
  16781. if (trigger) {
  16782. triggerController.addClickListener(el, trigger);
  16783. }
  16784. }
  16785. connectedCallback() {
  16786. prepareOverlay(this.el);
  16787. this.triggerChanged();
  16788. }
  16789. componentWillLoad() {
  16790. var _a;
  16791. if (this.spinner === undefined) {
  16792. const mode = getIonMode$1(this);
  16793. this.spinner = config.get('loadingSpinner', config.get('spinner', mode === 'ios' ? 'lines' : 'crescent'));
  16794. }
  16795. if (!((_a = this.htmlAttributes) === null || _a === void 0 ? void 0 : _a.id)) {
  16796. setOverlayId(this.el);
  16797. }
  16798. }
  16799. componentDidLoad() {
  16800. /**
  16801. * If loading indicator was rendered with isOpen="true"
  16802. * then we should open loading indicator immediately.
  16803. */
  16804. if (this.isOpen === true) {
  16805. raf(() => this.present());
  16806. }
  16807. /**
  16808. * When binding values in frameworks such as Angular
  16809. * it is possible for the value to be set after the Web Component
  16810. * initializes but before the value watcher is set up in Stencil.
  16811. * As a result, the watcher callback may not be fired.
  16812. * We work around this by manually calling the watcher
  16813. * callback when the component has loaded and the watcher
  16814. * is configured.
  16815. */
  16816. this.triggerChanged();
  16817. }
  16818. disconnectedCallback() {
  16819. this.triggerController.removeClickListener();
  16820. }
  16821. /**
  16822. * Present the loading overlay after it has been created.
  16823. */
  16824. async present() {
  16825. const unlock = await this.lockController.lock();
  16826. await this.delegateController.attachViewToDom();
  16827. await present(this, 'loadingEnter', iosEnterAnimation$4, mdEnterAnimation$3);
  16828. if (this.duration > 0) {
  16829. this.durationTimeout = setTimeout(() => this.dismiss(), this.duration + 10);
  16830. }
  16831. unlock();
  16832. }
  16833. /**
  16834. * Dismiss the loading overlay after it has been presented.
  16835. *
  16836. * @param data Any data to emit in the dismiss events.
  16837. * @param role The role of the element that is dismissing the loading.
  16838. * This can be useful in a button handler for determining which button was
  16839. * clicked to dismiss the loading.
  16840. * Some examples include: ``"cancel"`, `"destructive"`, "selected"`, and `"backdrop"`.
  16841. *
  16842. * This is a no-op if the overlay has not been presented yet. If you want
  16843. * to remove an overlay from the DOM that was never presented, use the
  16844. * [remove](https://developer.mozilla.org/en-US/docs/Web/API/Element/remove) method.
  16845. */
  16846. async dismiss(data, role) {
  16847. const unlock = await this.lockController.lock();
  16848. if (this.durationTimeout) {
  16849. clearTimeout(this.durationTimeout);
  16850. }
  16851. const dismissed = await dismiss(this, data, role, 'loadingLeave', iosLeaveAnimation$4, mdLeaveAnimation$3);
  16852. if (dismissed) {
  16853. this.delegateController.removeViewFromDom();
  16854. }
  16855. unlock();
  16856. return dismissed;
  16857. }
  16858. /**
  16859. * Returns a promise that resolves when the loading did dismiss.
  16860. */
  16861. onDidDismiss() {
  16862. return eventMethod(this.el, 'ionLoadingDidDismiss');
  16863. }
  16864. /**
  16865. * Returns a promise that resolves when the loading will dismiss.
  16866. */
  16867. onWillDismiss() {
  16868. return eventMethod(this.el, 'ionLoadingWillDismiss');
  16869. }
  16870. renderLoadingMessage(msgId) {
  16871. const { customHTMLEnabled, message } = this;
  16872. if (customHTMLEnabled) {
  16873. return hAsync("div", { class: "loading-content", id: msgId, innerHTML: sanitizeDOMString(message) });
  16874. }
  16875. return (hAsync("div", { class: "loading-content", id: msgId }, message));
  16876. }
  16877. render() {
  16878. const { message, spinner, htmlAttributes, overlayIndex } = this;
  16879. const mode = getIonMode$1(this);
  16880. const msgId = `loading-${overlayIndex}-msg`;
  16881. /**
  16882. * If the message is defined, use that as the label.
  16883. * Otherwise, don't set aria-labelledby.
  16884. */
  16885. const ariaLabelledBy = message !== undefined ? msgId : null;
  16886. return (hAsync(Host, Object.assign({ key: 'd6066c8b56b1fe4b597a243a7dab191ef0d21286', role: "dialog", "aria-modal": "true", "aria-labelledby": ariaLabelledBy, tabindex: "-1" }, htmlAttributes, { style: {
  16887. zIndex: `${40000 + this.overlayIndex}`,
  16888. }, 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" })));
  16889. }
  16890. get el() { return getElement(this); }
  16891. static get watchers() { return {
  16892. "isOpen": ["onIsOpenChange"],
  16893. "trigger": ["triggerChanged"]
  16894. }; }
  16895. static get style() { return {
  16896. ios: IonLoadingIosStyle0,
  16897. md: IonLoadingMdStyle0
  16898. }; }
  16899. static get cmpMeta() { return {
  16900. "$flags$": 34,
  16901. "$tagName$": "ion-loading",
  16902. "$members$": {
  16903. "overlayIndex": [2, "overlay-index"],
  16904. "delegate": [16],
  16905. "hasController": [4, "has-controller"],
  16906. "keyboardClose": [4, "keyboard-close"],
  16907. "enterAnimation": [16],
  16908. "leaveAnimation": [16],
  16909. "message": [1],
  16910. "cssClass": [1, "css-class"],
  16911. "duration": [2],
  16912. "backdropDismiss": [4, "backdrop-dismiss"],
  16913. "showBackdrop": [4, "show-backdrop"],
  16914. "spinner": [1025],
  16915. "translucent": [4],
  16916. "animated": [4],
  16917. "htmlAttributes": [16],
  16918. "isOpen": [4, "is-open"],
  16919. "trigger": [1],
  16920. "present": [64],
  16921. "dismiss": [64],
  16922. "onDidDismiss": [64],
  16923. "onWillDismiss": [64]
  16924. },
  16925. "$listeners$": undefined,
  16926. "$lazyBundleId$": "-",
  16927. "$attrsToReflect$": []
  16928. }; }
  16929. }
  16930. /**
  16931. * Based on:
  16932. * https://stackoverflow.com/questions/7348009/y-coordinate-for-a-given-x-cubic-bezier
  16933. * https://math.stackexchange.com/questions/26846/is-there-an-explicit-form-for-cubic-b%C3%A9zier-curves
  16934. */
  16935. /**
  16936. * EXPERIMENTAL
  16937. * Given a cubic-bezier curve, get the x value (time) given
  16938. * the y value (progression).
  16939. * Ex: cubic-bezier(0.32, 0.72, 0, 1);
  16940. * P0: (0, 0)
  16941. * P1: (0.32, 0.72)
  16942. * P2: (0, 1)
  16943. * P3: (1, 1)
  16944. *
  16945. * If you give a cubic bezier curve that never reaches the
  16946. * provided progression, this function will return an empty array.
  16947. */
  16948. const getTimeGivenProgression = (p0, p1, p2, p3, progression) => {
  16949. return solveCubicBezier(p0[1], p1[1], p2[1], p3[1], progression).map((tValue) => {
  16950. return solveCubicParametricEquation(p0[0], p1[0], p2[0], p3[0], tValue);
  16951. });
  16952. };
  16953. /**
  16954. * Solve a cubic equation in one dimension (time)
  16955. */
  16956. const solveCubicParametricEquation = (p0, p1, p2, p3, t) => {
  16957. const partA = 3 * p1 * Math.pow(t - 1, 2);
  16958. const partB = -3 * p2 * t + 3 * p2 + p3 * t;
  16959. const partC = p0 * Math.pow(t - 1, 3);
  16960. return t * (partA + t * partB) - partC;
  16961. };
  16962. /**
  16963. * Find the `t` value for a cubic bezier using Cardano's formula
  16964. */
  16965. const solveCubicBezier = (p0, p1, p2, p3, refPoint) => {
  16966. p0 -= refPoint;
  16967. p1 -= refPoint;
  16968. p2 -= refPoint;
  16969. p3 -= refPoint;
  16970. const roots = solveCubicEquation(p3 - 3 * p2 + 3 * p1 - p0, 3 * p2 - 6 * p1 + 3 * p0, 3 * p1 - 3 * p0, p0);
  16971. return roots.filter((root) => root >= 0 && root <= 1);
  16972. };
  16973. const solveQuadraticEquation = (a, b, c) => {
  16974. const discriminant = b * b - 4 * a * c;
  16975. if (discriminant < 0) {
  16976. return [];
  16977. }
  16978. else {
  16979. return [(-b + Math.sqrt(discriminant)) / (2 * a), (-b - Math.sqrt(discriminant)) / (2 * a)];
  16980. }
  16981. };
  16982. const solveCubicEquation = (a, b, c, d) => {
  16983. if (a === 0) {
  16984. return solveQuadraticEquation(b, c, d);
  16985. }
  16986. b /= a;
  16987. c /= a;
  16988. d /= a;
  16989. const p = (3 * c - b * b) / 3;
  16990. const q = (2 * b * b * b - 9 * b * c + 27 * d) / 27;
  16991. if (p === 0) {
  16992. return [Math.pow(-q, 1 / 3)];
  16993. }
  16994. else if (q === 0) {
  16995. return [Math.sqrt(-p), -Math.sqrt(-p)];
  16996. }
  16997. const discriminant = Math.pow(q / 2, 2) + Math.pow(p / 3, 3);
  16998. if (discriminant === 0) {
  16999. return [Math.pow(q / 2, 1 / 2) - b / 3];
  17000. }
  17001. else if (discriminant > 0) {
  17002. return [
  17003. Math.pow(-(q / 2) + Math.sqrt(discriminant), 1 / 3) - Math.pow(q / 2 + Math.sqrt(discriminant), 1 / 3) - b / 3,
  17004. ];
  17005. }
  17006. const r = Math.sqrt(Math.pow(-(p / 3), 3));
  17007. const phi = Math.acos(-(q / (2 * Math.sqrt(Math.pow(-(p / 3), 3)))));
  17008. const s = 2 * Math.pow(r, 1 / 3);
  17009. return [
  17010. s * Math.cos(phi / 3) - b / 3,
  17011. s * Math.cos((phi + 2 * Math.PI) / 3) - b / 3,
  17012. s * Math.cos((phi + 4 * Math.PI) / 3) - b / 3,
  17013. ];
  17014. };
  17015. /**
  17016. * baseAnimation
  17017. * Base class which is extended by the various types. Each
  17018. * type will provide their own animations for open and close
  17019. * and registers itself with Menu.
  17020. */
  17021. const baseAnimation = (isIos) => {
  17022. // https://material.io/guidelines/motion/movement.html#movement-movement-in-out-of-screen-bounds
  17023. // https://material.io/guidelines/motion/duration-easing.html#duration-easing-natural-easing-curves
  17024. /**
  17025. * "Apply the sharp curve to items temporarily leaving the screen that may return
  17026. * from the same exit point. When they return, use the deceleration curve. On mobile,
  17027. * this transition typically occurs over 300ms" -- MD Motion Guide
  17028. */
  17029. return createAnimation().duration(isIos ? 400 : 300);
  17030. };
  17031. /**
  17032. * Menu Overlay Type
  17033. * The menu slides over the content. The content
  17034. * itself, which is under the menu, does not move.
  17035. */
  17036. const menuOverlayAnimation = (menu) => {
  17037. let closedX;
  17038. let openedX;
  17039. const width = menu.width + 8;
  17040. const menuAnimation = createAnimation();
  17041. const backdropAnimation = createAnimation();
  17042. if (menu.isEndSide) {
  17043. // right side
  17044. closedX = width + 'px';
  17045. openedX = '0px';
  17046. }
  17047. else {
  17048. // left side
  17049. closedX = -width + 'px';
  17050. openedX = '0px';
  17051. }
  17052. menuAnimation.addElement(menu.menuInnerEl).fromTo('transform', `translateX(${closedX})`, `translateX(${openedX})`);
  17053. const mode = getIonMode$1(menu);
  17054. const isIos = mode === 'ios';
  17055. const opacity = isIos ? 0.2 : 0.25;
  17056. backdropAnimation.addElement(menu.backdropEl).fromTo('opacity', 0.01, opacity);
  17057. return baseAnimation(isIos).addAnimation([menuAnimation, backdropAnimation]);
  17058. };
  17059. /**
  17060. * Menu Push Type
  17061. * The content slides over to reveal the menu underneath.
  17062. * The menu itself also slides over to reveal its bad self.
  17063. */
  17064. const menuPushAnimation = (menu) => {
  17065. let contentOpenedX;
  17066. let menuClosedX;
  17067. const mode = getIonMode$1(menu);
  17068. const width = menu.width;
  17069. if (menu.isEndSide) {
  17070. contentOpenedX = -width + 'px';
  17071. menuClosedX = width + 'px';
  17072. }
  17073. else {
  17074. contentOpenedX = width + 'px';
  17075. menuClosedX = -width + 'px';
  17076. }
  17077. const menuAnimation = createAnimation()
  17078. .addElement(menu.menuInnerEl)
  17079. .fromTo('transform', `translateX(${menuClosedX})`, 'translateX(0px)');
  17080. const contentAnimation = createAnimation()
  17081. .addElement(menu.contentEl)
  17082. .fromTo('transform', 'translateX(0px)', `translateX(${contentOpenedX})`);
  17083. const backdropAnimation = createAnimation().addElement(menu.backdropEl).fromTo('opacity', 0.01, 0.32);
  17084. return baseAnimation(mode === 'ios').addAnimation([menuAnimation, contentAnimation, backdropAnimation]);
  17085. };
  17086. /**
  17087. * Menu Reveal Type
  17088. * The content slides over to reveal the menu underneath.
  17089. * The menu itself, which is under the content, does not move.
  17090. */
  17091. const menuRevealAnimation = (menu) => {
  17092. const mode = getIonMode$1(menu);
  17093. const openedX = menu.width * (menu.isEndSide ? -1 : 1) + 'px';
  17094. const contentOpen = createAnimation()
  17095. .addElement(menu.contentEl) // REVIEW
  17096. .fromTo('transform', 'translateX(0px)', `translateX(${openedX})`);
  17097. return baseAnimation(mode === 'ios').addAnimation(contentOpen);
  17098. };
  17099. const createMenuController = () => {
  17100. const menuAnimations = new Map();
  17101. const menus = [];
  17102. const open = async (menu) => {
  17103. const menuEl = await get(menu, true);
  17104. if (menuEl) {
  17105. return menuEl.open();
  17106. }
  17107. return false;
  17108. };
  17109. const close = async (menu) => {
  17110. const menuEl = await (menu !== undefined ? get(menu, true) : getOpen());
  17111. if (menuEl !== undefined) {
  17112. return menuEl.close();
  17113. }
  17114. return false;
  17115. };
  17116. const toggle = async (menu) => {
  17117. const menuEl = await get(menu, true);
  17118. if (menuEl) {
  17119. return menuEl.toggle();
  17120. }
  17121. return false;
  17122. };
  17123. const enable = async (shouldEnable, menu) => {
  17124. const menuEl = await get(menu);
  17125. if (menuEl) {
  17126. menuEl.disabled = !shouldEnable;
  17127. }
  17128. return menuEl;
  17129. };
  17130. const swipeGesture = async (shouldEnable, menu) => {
  17131. const menuEl = await get(menu);
  17132. if (menuEl) {
  17133. menuEl.swipeGesture = shouldEnable;
  17134. }
  17135. return menuEl;
  17136. };
  17137. const isOpen = async (menu) => {
  17138. if (menu != null) {
  17139. const menuEl = await get(menu);
  17140. // eslint-disable-next-line @typescript-eslint/prefer-optional-chain
  17141. return menuEl !== undefined && menuEl.isOpen();
  17142. }
  17143. else {
  17144. const menuEl = await getOpen();
  17145. return menuEl !== undefined;
  17146. }
  17147. };
  17148. const isEnabled = async (menu) => {
  17149. const menuEl = await get(menu);
  17150. if (menuEl) {
  17151. return !menuEl.disabled;
  17152. }
  17153. return false;
  17154. };
  17155. /**
  17156. * Finds and returns the menu specified by "menu" if registered.
  17157. * @param menu - The side or ID of the desired menu
  17158. * @param logOnMultipleSideMenus - If true, this function will log a warning
  17159. * if "menu" is a side but multiple menus on the same side were found. Since this function
  17160. * is used in multiple places, we default this log to false so that the calling
  17161. * functions can choose whether or not it is appropriate to log this warning.
  17162. */
  17163. const get = async (menu, logOnMultipleSideMenus = false) => {
  17164. await waitUntilReady();
  17165. if (menu === 'start' || menu === 'end') {
  17166. // there could be more than one menu on the same side
  17167. // so first try to get the enabled one
  17168. const menuRefs = menus.filter((m) => m.side === menu && !m.disabled);
  17169. if (menuRefs.length >= 1) {
  17170. if (menuRefs.length > 1 && logOnMultipleSideMenus) {
  17171. 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));
  17172. }
  17173. return menuRefs[0].el;
  17174. }
  17175. // didn't find a menu side that is enabled
  17176. // so try to get the first menu side found
  17177. const sideMenuRefs = menus.filter((m) => m.side === menu);
  17178. if (sideMenuRefs.length >= 1) {
  17179. if (sideMenuRefs.length > 1 && logOnMultipleSideMenus) {
  17180. 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));
  17181. }
  17182. return sideMenuRefs[0].el;
  17183. }
  17184. }
  17185. else if (menu != null) {
  17186. // the menuId was not left or right
  17187. // so try to get the menu by its "id"
  17188. return find((m) => m.menuId === menu);
  17189. }
  17190. // return the first enabled menu
  17191. const menuEl = find((m) => !m.disabled);
  17192. if (menuEl) {
  17193. return menuEl;
  17194. }
  17195. // get the first menu in the array, if one exists
  17196. return menus.length > 0 ? menus[0].el : undefined;
  17197. };
  17198. /**
  17199. * Get the instance of the opened menu. Returns `null` if a menu is not found.
  17200. */
  17201. const getOpen = async () => {
  17202. await waitUntilReady();
  17203. return _getOpenSync();
  17204. };
  17205. /**
  17206. * Get all menu instances.
  17207. */
  17208. const getMenus = async () => {
  17209. await waitUntilReady();
  17210. return getMenusSync();
  17211. };
  17212. /**
  17213. * Get whether or not a menu is animating. Returns `true` if any
  17214. * menu is currently animating.
  17215. */
  17216. const isAnimating = async () => {
  17217. await waitUntilReady();
  17218. return isAnimatingSync();
  17219. };
  17220. const registerAnimation = (name, animation) => {
  17221. menuAnimations.set(name, animation);
  17222. };
  17223. const _register = (menu) => {
  17224. if (menus.indexOf(menu) < 0) {
  17225. menus.push(menu);
  17226. }
  17227. };
  17228. const _unregister = (menu) => {
  17229. const index = menus.indexOf(menu);
  17230. if (index > -1) {
  17231. menus.splice(index, 1);
  17232. }
  17233. };
  17234. const _setOpen = async (menu, shouldOpen, animated, role) => {
  17235. if (isAnimatingSync()) {
  17236. return false;
  17237. }
  17238. if (shouldOpen) {
  17239. const openedMenu = await getOpen();
  17240. if (openedMenu && menu.el !== openedMenu) {
  17241. await openedMenu.setOpen(false, false);
  17242. }
  17243. }
  17244. return menu._setOpen(shouldOpen, animated, role);
  17245. };
  17246. const _createAnimation = (type, menuCmp) => {
  17247. const animationBuilder = menuAnimations.get(type); // TODO(FW-2832): type
  17248. if (!animationBuilder) {
  17249. throw new Error('animation not registered');
  17250. }
  17251. const animation = animationBuilder(menuCmp);
  17252. return animation;
  17253. };
  17254. const _getOpenSync = () => {
  17255. return find((m) => m._isOpen);
  17256. };
  17257. const getMenusSync = () => {
  17258. return menus.map((menu) => menu.el);
  17259. };
  17260. const isAnimatingSync = () => {
  17261. return menus.some((menu) => menu.isAnimating);
  17262. };
  17263. const find = (predicate) => {
  17264. const instance = menus.find(predicate);
  17265. if (instance !== undefined) {
  17266. return instance.el;
  17267. }
  17268. return undefined;
  17269. };
  17270. const waitUntilReady = () => {
  17271. return Promise.all(Array.from(document.querySelectorAll('ion-menu')).map((menu) => new Promise((resolve) => componentOnReady(menu, resolve))));
  17272. };
  17273. registerAnimation('reveal', menuRevealAnimation);
  17274. registerAnimation('push', menuPushAnimation);
  17275. registerAnimation('overlay', menuOverlayAnimation);
  17276. doc === null || doc === void 0 ? void 0 : doc.addEventListener('ionBackButton', (ev) => {
  17277. const openMenu = _getOpenSync();
  17278. if (openMenu) {
  17279. ev.detail.register(MENU_BACK_BUTTON_PRIORITY, () => {
  17280. return openMenu.close();
  17281. });
  17282. }
  17283. });
  17284. return {
  17285. registerAnimation,
  17286. get,
  17287. getMenus,
  17288. getOpen,
  17289. isEnabled,
  17290. swipeGesture,
  17291. isAnimating,
  17292. isOpen,
  17293. enable,
  17294. toggle,
  17295. close,
  17296. open,
  17297. _getOpenSync,
  17298. _createAnimation,
  17299. _register,
  17300. _unregister,
  17301. _setOpen,
  17302. };
  17303. };
  17304. const menuController = /*@__PURE__*/ createMenuController();
  17305. 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}";
  17306. var IonMenuIosStyle0 = menuIosCss;
  17307. 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)}";
  17308. var IonMenuMdStyle0 = menuMdCss;
  17309. const iosEasing = 'cubic-bezier(0.32,0.72,0,1)';
  17310. const mdEasing = 'cubic-bezier(0.0,0.0,0.2,1)';
  17311. const iosEasingReverse = 'cubic-bezier(1, 0, 0.68, 0.28)';
  17312. const mdEasingReverse = 'cubic-bezier(0.4, 0, 0.6, 1)';
  17313. /**
  17314. * @part container - The container for the menu content.
  17315. * @part backdrop - The backdrop that appears over the main content when the menu is open.
  17316. */
  17317. class Menu {
  17318. constructor(hostRef) {
  17319. registerInstance(this, hostRef);
  17320. this.ionWillOpen = createEvent(this, "ionWillOpen", 7);
  17321. this.ionWillClose = createEvent(this, "ionWillClose", 7);
  17322. this.ionDidOpen = createEvent(this, "ionDidOpen", 7);
  17323. this.ionDidClose = createEvent(this, "ionDidClose", 7);
  17324. this.ionMenuChange = createEvent(this, "ionMenuChange", 7);
  17325. this.lastOnEnd = 0;
  17326. this.blocker = GESTURE_CONTROLLER.createBlocker({ disableScroll: true });
  17327. this.didLoad = false;
  17328. /**
  17329. * Flag used to determine if an open/close
  17330. * operation was cancelled. For example, if
  17331. * an app calls "menu.open" then disables the menu
  17332. * part way through the animation, then this would
  17333. * be considered a cancelled operation.
  17334. */
  17335. this.operationCancelled = false;
  17336. this.isAnimating = false;
  17337. this._isOpen = false;
  17338. this.inheritedAttributes = {};
  17339. this.handleFocus = (ev) => {
  17340. /**
  17341. * Overlays have their own focus trapping listener
  17342. * so we do not want the two listeners to conflict
  17343. * with each other. If the top-most overlay that is
  17344. * open does not contain this ion-menu, then ion-menu's
  17345. * focus trapping should not run.
  17346. */
  17347. const lastOverlay = getPresentedOverlay(document);
  17348. if (lastOverlay && !lastOverlay.contains(this.el)) {
  17349. return;
  17350. }
  17351. this.trapKeyboardFocus(ev, document);
  17352. };
  17353. this.isPaneVisible = false;
  17354. this.isEndSide = false;
  17355. this.contentId = undefined;
  17356. this.menuId = undefined;
  17357. this.type = undefined;
  17358. this.disabled = false;
  17359. this.side = 'start';
  17360. this.swipeGesture = true;
  17361. this.maxEdgeStart = 50;
  17362. }
  17363. typeChanged(type, oldType) {
  17364. const contentEl = this.contentEl;
  17365. if (contentEl) {
  17366. if (oldType !== undefined) {
  17367. contentEl.classList.remove(`menu-content-${oldType}`);
  17368. }
  17369. contentEl.classList.add(`menu-content-${type}`);
  17370. contentEl.removeAttribute('style');
  17371. }
  17372. if (this.menuInnerEl) {
  17373. // Remove effects of previous animations
  17374. this.menuInnerEl.removeAttribute('style');
  17375. }
  17376. this.animation = undefined;
  17377. }
  17378. disabledChanged() {
  17379. this.updateState();
  17380. this.ionMenuChange.emit({
  17381. disabled: this.disabled,
  17382. open: this._isOpen,
  17383. });
  17384. }
  17385. sideChanged() {
  17386. this.isEndSide = isEndSide(this.side);
  17387. /**
  17388. * Menu direction animation is calculated based on the document direction.
  17389. * If the document direction changes, we need to create a new animation.
  17390. */
  17391. this.animation = undefined;
  17392. }
  17393. swipeGestureChanged() {
  17394. this.updateState();
  17395. }
  17396. async connectedCallback() {
  17397. // TODO: connectedCallback is fired in CE build
  17398. // before WC is defined. This needs to be fixed in Stencil.
  17399. if (typeof customElements !== 'undefined' && customElements != null) {
  17400. await customElements.whenDefined('ion-menu');
  17401. }
  17402. if (this.type === undefined) {
  17403. this.type = config.get('menuType', 'overlay');
  17404. }
  17405. {
  17406. return;
  17407. }
  17408. }
  17409. componentWillLoad() {
  17410. this.inheritedAttributes = inheritAriaAttributes(this.el);
  17411. }
  17412. async componentDidLoad() {
  17413. this.didLoad = true;
  17414. /**
  17415. * A menu inside of a split pane is assumed
  17416. * to be a side pane.
  17417. *
  17418. * When the menu is loaded it needs to
  17419. * see if it should be considered visible inside
  17420. * of the split pane. If the split pane is
  17421. * hidden then the menu should be too.
  17422. */
  17423. const splitPane = this.el.closest('ion-split-pane');
  17424. if (splitPane !== null) {
  17425. this.isPaneVisible = await splitPane.isVisible();
  17426. }
  17427. this.menuChanged();
  17428. this.updateState();
  17429. }
  17430. menuChanged() {
  17431. /**
  17432. * Inform dependent components such as ion-menu-button
  17433. * that the menu is ready. Note that we only want to do this
  17434. * once the menu has been rendered which is why we check for didLoad.
  17435. */
  17436. if (this.didLoad) {
  17437. this.ionMenuChange.emit({ disabled: this.disabled, open: this._isOpen });
  17438. }
  17439. }
  17440. async disconnectedCallback() {
  17441. /**
  17442. * The menu should be closed when it is
  17443. * unmounted from the DOM.
  17444. * This is an async call, so we need to wait for
  17445. * this to finish otherwise contentEl
  17446. * will not have MENU_CONTENT_OPEN removed.
  17447. */
  17448. await this.close(false);
  17449. this.blocker.destroy();
  17450. menuController._unregister(this);
  17451. if (this.animation) {
  17452. this.animation.destroy();
  17453. }
  17454. if (this.gesture) {
  17455. this.gesture.destroy();
  17456. this.gesture = undefined;
  17457. }
  17458. this.animation = undefined;
  17459. this.contentEl = undefined;
  17460. }
  17461. onSplitPaneChanged(ev) {
  17462. const closestSplitPane = this.el.closest('ion-split-pane');
  17463. if (closestSplitPane !== null && closestSplitPane === ev.target) {
  17464. this.isPaneVisible = ev.detail.visible;
  17465. this.updateState();
  17466. }
  17467. }
  17468. onBackdropClick(ev) {
  17469. // TODO(FW-2832): type (CustomEvent triggers errors which should be sorted)
  17470. if (this._isOpen && this.lastOnEnd < ev.timeStamp - 100) {
  17471. const shouldClose = ev.composedPath ? !ev.composedPath().includes(this.menuInnerEl) : false;
  17472. if (shouldClose) {
  17473. ev.preventDefault();
  17474. ev.stopPropagation();
  17475. this.close(undefined, BACKDROP);
  17476. }
  17477. }
  17478. }
  17479. onKeydown(ev) {
  17480. if (ev.key === 'Escape') {
  17481. this.close(undefined, BACKDROP);
  17482. }
  17483. }
  17484. /**
  17485. * Returns `true` is the menu is open.
  17486. */
  17487. isOpen() {
  17488. return Promise.resolve(this._isOpen);
  17489. }
  17490. /**
  17491. * Returns `true` is the menu is active.
  17492. *
  17493. * A menu is active when it can be opened or closed, meaning it's enabled
  17494. * and it's not part of a `ion-split-pane`.
  17495. */
  17496. isActive() {
  17497. return Promise.resolve(this._isActive());
  17498. }
  17499. /**
  17500. * Opens the menu. If the menu is already open or it can't be opened,
  17501. * it returns `false`.
  17502. */
  17503. open(animated = true) {
  17504. return this.setOpen(true, animated);
  17505. }
  17506. /**
  17507. * Closes the menu. If the menu is already closed or it can't be closed,
  17508. * it returns `false`.
  17509. */
  17510. close(animated = true, role) {
  17511. return this.setOpen(false, animated, role);
  17512. }
  17513. /**
  17514. * Toggles the menu. If the menu is already open, it will try to close, otherwise it will try to open it.
  17515. * If the operation can't be completed successfully, it returns `false`.
  17516. */
  17517. toggle(animated = true) {
  17518. return this.setOpen(!this._isOpen, animated);
  17519. }
  17520. /**
  17521. * Opens or closes the button.
  17522. * If the operation can't be completed successfully, it returns `false`.
  17523. */
  17524. setOpen(shouldOpen, animated = true, role) {
  17525. return menuController._setOpen(this, shouldOpen, animated, role);
  17526. }
  17527. trapKeyboardFocus(ev, doc) {
  17528. const target = ev.target;
  17529. if (!target) {
  17530. return;
  17531. }
  17532. /**
  17533. * If the target is inside the menu contents, let the browser
  17534. * focus as normal and keep a log of the last focused element.
  17535. */
  17536. if (this.el.contains(target)) {
  17537. this.lastFocus = target;
  17538. }
  17539. else {
  17540. /**
  17541. * Otherwise, we are about to have focus go out of the menu.
  17542. * Wrap the focus to either the first or last element.
  17543. */
  17544. const { el } = this;
  17545. /**
  17546. * Once we call `focusFirstDescendant`, another focus event
  17547. * will fire, which will cause `lastFocus` to be updated
  17548. * before we can run the code after that. We cache the value
  17549. * here to avoid that.
  17550. */
  17551. focusFirstDescendant(el);
  17552. /**
  17553. * If the cached last focused element is the same as the now-
  17554. * active element, that means the user was on the first element
  17555. * already and pressed Shift + Tab, so we need to wrap to the
  17556. * last descendant.
  17557. */
  17558. if (this.lastFocus === doc.activeElement) {
  17559. focusLastDescendant(el);
  17560. }
  17561. }
  17562. }
  17563. async _setOpen(shouldOpen, animated = true, role) {
  17564. // If the menu is disabled or it is currently being animated, let's do nothing
  17565. if (!this._isActive() || this.isAnimating || shouldOpen === this._isOpen) {
  17566. return false;
  17567. }
  17568. this.beforeAnimation(shouldOpen, role);
  17569. await this.loadAnimation();
  17570. await this.startAnimation(shouldOpen, animated);
  17571. /**
  17572. * If the animation was cancelled then
  17573. * return false because the operation
  17574. * did not succeed.
  17575. */
  17576. if (this.operationCancelled) {
  17577. this.operationCancelled = false;
  17578. return false;
  17579. }
  17580. this.afterAnimation(shouldOpen, role);
  17581. return true;
  17582. }
  17583. async loadAnimation() {
  17584. // Menu swipe animation takes the menu's inner width as parameter,
  17585. // If `offsetWidth` changes, we need to create a new animation.
  17586. const width = this.menuInnerEl.offsetWidth;
  17587. /**
  17588. * Menu direction animation is calculated based on the document direction.
  17589. * If the document direction changes, we need to create a new animation.
  17590. */
  17591. const isEndSide$1 = isEndSide(this.side);
  17592. if (width === this.width && this.animation !== undefined && isEndSide$1 === this.isEndSide) {
  17593. return;
  17594. }
  17595. this.width = width;
  17596. this.isEndSide = isEndSide$1;
  17597. // Destroy existing animation
  17598. if (this.animation) {
  17599. this.animation.destroy();
  17600. this.animation = undefined;
  17601. }
  17602. // Create new animation
  17603. const animation = (this.animation = await menuController._createAnimation(this.type, this));
  17604. if (!config.getBoolean('animated', true)) {
  17605. animation.duration(0);
  17606. }
  17607. animation.fill('both');
  17608. }
  17609. async startAnimation(shouldOpen, animated) {
  17610. const isReversed = !shouldOpen;
  17611. const mode = getIonMode$1(this);
  17612. const easing = mode === 'ios' ? iosEasing : mdEasing;
  17613. const easingReverse = mode === 'ios' ? iosEasingReverse : mdEasingReverse;
  17614. const ani = this.animation
  17615. .direction(isReversed ? 'reverse' : 'normal')
  17616. .easing(isReversed ? easingReverse : easing);
  17617. if (animated) {
  17618. await ani.play();
  17619. }
  17620. else {
  17621. ani.play({ sync: true });
  17622. }
  17623. /**
  17624. * We run this after the play invocation
  17625. * instead of using ani.onFinish so that
  17626. * multiple onFinish callbacks do not get
  17627. * run if an animation is played, stopped,
  17628. * and then played again.
  17629. */
  17630. if (ani.getDirection() === 'reverse') {
  17631. ani.direction('normal');
  17632. }
  17633. }
  17634. _isActive() {
  17635. return !this.disabled && !this.isPaneVisible;
  17636. }
  17637. canSwipe() {
  17638. return this.swipeGesture && !this.isAnimating && this._isActive();
  17639. }
  17640. canStart(detail) {
  17641. // Do not allow swipe gesture if a modal is open
  17642. const isModalPresented = !!document.querySelector('ion-modal.show-modal');
  17643. if (isModalPresented || !this.canSwipe()) {
  17644. return false;
  17645. }
  17646. if (this._isOpen) {
  17647. return true;
  17648. }
  17649. else if (menuController._getOpenSync()) {
  17650. return false;
  17651. }
  17652. return checkEdgeSide(window, detail.currentX, this.isEndSide, this.maxEdgeStart);
  17653. }
  17654. onWillStart() {
  17655. this.beforeAnimation(!this._isOpen, GESTURE);
  17656. return this.loadAnimation();
  17657. }
  17658. onStart() {
  17659. if (!this.isAnimating || !this.animation) {
  17660. assert(false, 'isAnimating has to be true');
  17661. return;
  17662. }
  17663. // the cloned animation should not use an easing curve during seek
  17664. this.animation.progressStart(true, this._isOpen ? 1 : 0);
  17665. }
  17666. onMove(detail) {
  17667. if (!this.isAnimating || !this.animation) {
  17668. assert(false, 'isAnimating has to be true');
  17669. return;
  17670. }
  17671. const delta = computeDelta(detail.deltaX, this._isOpen, this.isEndSide);
  17672. const stepValue = delta / this.width;
  17673. this.animation.progressStep(this._isOpen ? 1 - stepValue : stepValue);
  17674. }
  17675. onEnd(detail) {
  17676. if (!this.isAnimating || !this.animation) {
  17677. assert(false, 'isAnimating has to be true');
  17678. return;
  17679. }
  17680. const isOpen = this._isOpen;
  17681. const isEndSide = this.isEndSide;
  17682. const delta = computeDelta(detail.deltaX, isOpen, isEndSide);
  17683. const width = this.width;
  17684. const stepValue = delta / width;
  17685. const velocity = detail.velocityX;
  17686. const z = width / 2.0;
  17687. const shouldCompleteRight = velocity >= 0 && (velocity > 0.2 || detail.deltaX > z);
  17688. const shouldCompleteLeft = velocity <= 0 && (velocity < -0.2 || detail.deltaX < -z);
  17689. const shouldComplete = isOpen
  17690. ? isEndSide
  17691. ? shouldCompleteRight
  17692. : shouldCompleteLeft
  17693. : isEndSide
  17694. ? shouldCompleteLeft
  17695. : shouldCompleteRight;
  17696. let shouldOpen = !isOpen && shouldComplete;
  17697. if (isOpen && !shouldComplete) {
  17698. shouldOpen = true;
  17699. }
  17700. this.lastOnEnd = detail.currentTime;
  17701. // Account for rounding errors in JS
  17702. let newStepValue = shouldComplete ? 0.001 : -0.001;
  17703. /**
  17704. * stepValue can sometimes return a negative
  17705. * value, but you can't have a negative time value
  17706. * for the cubic bezier curve (at least with web animations)
  17707. */
  17708. const adjustedStepValue = stepValue < 0 ? 0.01 : stepValue;
  17709. /**
  17710. * Animation will be reversed here, so need to
  17711. * reverse the easing curve as well
  17712. *
  17713. * Additionally, we need to account for the time relative
  17714. * to the new easing curve, as `stepValue` is going to be given
  17715. * in terms of a linear curve.
  17716. */
  17717. newStepValue +=
  17718. getTimeGivenProgression([0, 0], [0.4, 0], [0.6, 1], [1, 1], clamp(0, adjustedStepValue, 0.9999))[0] || 0;
  17719. const playTo = this._isOpen ? !shouldComplete : shouldComplete;
  17720. this.animation
  17721. .easing('cubic-bezier(0.4, 0.0, 0.6, 1)')
  17722. .onFinish(() => this.afterAnimation(shouldOpen, GESTURE), { oneTimeCallback: true })
  17723. .progressEnd(playTo ? 1 : 0, this._isOpen ? 1 - newStepValue : newStepValue, 300);
  17724. }
  17725. beforeAnimation(shouldOpen, role) {
  17726. assert(!this.isAnimating, '_before() should not be called while animating');
  17727. /**
  17728. * When the menu is presented on an Android device, TalkBack's focus rings
  17729. * may appear in the wrong position due to the transition (specifically
  17730. * `transform` styles). This occurs because the focus rings are initially
  17731. * displayed at the starting position of the elements before the transition
  17732. * begins. This workaround ensures the focus rings do not appear in the
  17733. * incorrect location.
  17734. *
  17735. * If this solution is applied to iOS devices, then it leads to a bug where
  17736. * the overlays cannot be accessed by screen readers. This is due to
  17737. * VoiceOver not being able to update the accessibility tree when the
  17738. * `aria-hidden` is removed.
  17739. */
  17740. if (isPlatform('android')) {
  17741. this.el.setAttribute('aria-hidden', 'true');
  17742. }
  17743. // this places the menu into the correct location before it animates in
  17744. // this css class doesn't actually kick off any animations
  17745. this.el.classList.add(SHOW_MENU);
  17746. /**
  17747. * We add a tabindex here so that focus trapping
  17748. * still works even if the menu does not have
  17749. * any focusable elements slotted inside. The
  17750. * focus trapping utility will fallback to focusing
  17751. * the menu so focus does not leave when the menu
  17752. * is open.
  17753. */
  17754. this.el.setAttribute('tabindex', '0');
  17755. if (this.backdropEl) {
  17756. this.backdropEl.classList.add(SHOW_BACKDROP);
  17757. }
  17758. // add css class and hide content behind menu from screen readers
  17759. if (this.contentEl) {
  17760. this.contentEl.classList.add(MENU_CONTENT_OPEN);
  17761. /**
  17762. * When the menu is open and overlaying the main
  17763. * content, the main content should not be announced
  17764. * by the screenreader as the menu is the main
  17765. * focus. This is useful with screenreaders that have
  17766. * "read from top" gestures that read the entire
  17767. * page from top to bottom when activated.
  17768. * This should be done before the animation starts
  17769. * so that users cannot accidentally scroll
  17770. * the content while dragging a menu open.
  17771. */
  17772. this.contentEl.setAttribute('aria-hidden', 'true');
  17773. }
  17774. this.blocker.block();
  17775. this.isAnimating = true;
  17776. if (shouldOpen) {
  17777. this.ionWillOpen.emit();
  17778. }
  17779. else {
  17780. this.ionWillClose.emit({ role });
  17781. }
  17782. }
  17783. afterAnimation(isOpen, role) {
  17784. var _a;
  17785. // keep opening/closing the menu disabled for a touch more yet
  17786. // only add listeners/css if it's enabled and isOpen
  17787. // and only remove listeners/css if it's not open
  17788. // emit opened/closed events
  17789. this._isOpen = isOpen;
  17790. this.isAnimating = false;
  17791. if (!this._isOpen) {
  17792. this.blocker.unblock();
  17793. }
  17794. if (isOpen) {
  17795. /**
  17796. * When the menu is presented on an Android device, TalkBack's focus rings
  17797. * may appear in the wrong position due to the transition (specifically
  17798. * `transform` styles). The menu is hidden from screen readers during the
  17799. * transition to prevent this. Once the transition is complete, the menu
  17800. * is shown again.
  17801. */
  17802. if (isPlatform('android')) {
  17803. this.el.removeAttribute('aria-hidden');
  17804. }
  17805. // emit open event
  17806. this.ionDidOpen.emit();
  17807. /**
  17808. * Move focus to the menu to prepare focus trapping, as long as
  17809. * it isn't already focused. Use the host element instead of the
  17810. * first descendant to avoid the scroll position jumping around.
  17811. */
  17812. const focusedMenu = (_a = document.activeElement) === null || _a === void 0 ? void 0 : _a.closest('ion-menu');
  17813. if (focusedMenu !== this.el) {
  17814. this.el.focus();
  17815. }
  17816. // start focus trapping
  17817. document.addEventListener('focus', this.handleFocus, true);
  17818. }
  17819. else {
  17820. this.el.removeAttribute('aria-hidden');
  17821. // remove css classes and unhide content from screen readers
  17822. this.el.classList.remove(SHOW_MENU);
  17823. /**
  17824. * Remove tabindex from the menu component
  17825. * so that is cannot be tabbed to.
  17826. */
  17827. this.el.removeAttribute('tabindex');
  17828. if (this.contentEl) {
  17829. this.contentEl.classList.remove(MENU_CONTENT_OPEN);
  17830. /**
  17831. * Remove aria-hidden so screen readers
  17832. * can announce the main content again
  17833. * now that the menu is not the main focus.
  17834. */
  17835. this.contentEl.removeAttribute('aria-hidden');
  17836. }
  17837. if (this.backdropEl) {
  17838. this.backdropEl.classList.remove(SHOW_BACKDROP);
  17839. }
  17840. if (this.animation) {
  17841. this.animation.stop();
  17842. }
  17843. // emit close event
  17844. this.ionDidClose.emit({ role });
  17845. // undo focus trapping so multiple menus don't collide
  17846. document.removeEventListener('focus', this.handleFocus, true);
  17847. }
  17848. }
  17849. updateState() {
  17850. const isActive = this._isActive();
  17851. if (this.gesture) {
  17852. this.gesture.enable(isActive && this.swipeGesture);
  17853. }
  17854. /**
  17855. * If the menu is disabled but it is still open
  17856. * then we should close the menu immediately.
  17857. * Additionally, if the menu is in the process
  17858. * of animating {open, close} and the menu is disabled
  17859. * then it should still be closed immediately.
  17860. */
  17861. if (!isActive) {
  17862. /**
  17863. * It is possible to disable the menu while
  17864. * it is mid-animation. When this happens, we
  17865. * need to set the operationCancelled flag
  17866. * so that this._setOpen knows to return false
  17867. * and not run the "afterAnimation" callback.
  17868. */
  17869. if (this.isAnimating) {
  17870. this.operationCancelled = true;
  17871. }
  17872. /**
  17873. * If the menu is disabled then we should
  17874. * forcibly close the menu even if it is open.
  17875. */
  17876. this.afterAnimation(false, GESTURE);
  17877. }
  17878. }
  17879. render() {
  17880. const { type, disabled, el, isPaneVisible, inheritedAttributes, side } = this;
  17881. const mode = getIonMode$1(this);
  17882. /**
  17883. * If the Close Watcher is enabled then
  17884. * the ionBackButton listener in the menu controller
  17885. * will handle closing the menu when Escape is pressed.
  17886. */
  17887. return (hAsync(Host, { key: '0a2ba4ff5600b80b54d1b5b45124779c6aa0d2f2', onKeyDown: shouldUseCloseWatcher() ? null : this.onKeydown, role: "navigation", "aria-label": inheritedAttributes['aria-label'] || 'menu', class: {
  17888. [mode]: true,
  17889. [`menu-type-${type}`]: true,
  17890. 'menu-enabled': !disabled,
  17891. [`menu-side-${side}`]: true,
  17892. 'menu-pane-visible': isPaneVisible,
  17893. 'split-pane-side': hostContext('ion-split-pane', el),
  17894. } }, 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" })));
  17895. }
  17896. get el() { return getElement(this); }
  17897. static get watchers() { return {
  17898. "type": ["typeChanged"],
  17899. "disabled": ["disabledChanged"],
  17900. "side": ["sideChanged"],
  17901. "swipeGesture": ["swipeGestureChanged"]
  17902. }; }
  17903. static get style() { return {
  17904. ios: IonMenuIosStyle0,
  17905. md: IonMenuMdStyle0
  17906. }; }
  17907. static get cmpMeta() { return {
  17908. "$flags$": 41,
  17909. "$tagName$": "ion-menu",
  17910. "$members$": {
  17911. "contentId": [513, "content-id"],
  17912. "menuId": [513, "menu-id"],
  17913. "type": [1025],
  17914. "disabled": [1028],
  17915. "side": [513],
  17916. "swipeGesture": [4, "swipe-gesture"],
  17917. "maxEdgeStart": [2, "max-edge-start"],
  17918. "isPaneVisible": [32],
  17919. "isEndSide": [32],
  17920. "isOpen": [64],
  17921. "isActive": [64],
  17922. "open": [64],
  17923. "close": [64],
  17924. "toggle": [64],
  17925. "setOpen": [64]
  17926. },
  17927. "$listeners$": [[16, "ionSplitPaneVisible", "onSplitPaneChanged"], [2, "click", "onBackdropClick"]],
  17928. "$lazyBundleId$": "-",
  17929. "$attrsToReflect$": [["contentId", "content-id"], ["menuId", "menu-id"], ["side", "side"]]
  17930. }; }
  17931. }
  17932. const computeDelta = (deltaX, isOpen, isEndSide) => {
  17933. return Math.max(0, isOpen !== isEndSide ? -deltaX : deltaX);
  17934. };
  17935. const checkEdgeSide = (win, posX, isEndSide, maxEdgeStart) => {
  17936. if (isEndSide) {
  17937. return posX >= win.innerWidth - maxEdgeStart;
  17938. }
  17939. else {
  17940. return posX <= maxEdgeStart;
  17941. }
  17942. };
  17943. const SHOW_MENU = 'show-menu';
  17944. const SHOW_BACKDROP = 'show-backdrop';
  17945. const MENU_CONTENT_OPEN = 'menu-content-open';
  17946. // Given a menu, return whether or not the menu toggle should be visible
  17947. const updateVisibility = async (menu) => {
  17948. const menuEl = await menuController.get(menu);
  17949. return !!(menuEl && (await menuEl.isActive()));
  17950. };
  17951. 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}}";
  17952. var IonMenuButtonIosStyle0 = menuButtonIosCss;
  17953. 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)}}";
  17954. var IonMenuButtonMdStyle0 = menuButtonMdCss;
  17955. /**
  17956. * @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
  17957. *
  17958. * @part native - The native HTML button element that wraps all child elements.
  17959. * @part icon - The menu button icon (uses ion-icon).
  17960. */
  17961. class MenuButton {
  17962. constructor(hostRef) {
  17963. registerInstance(this, hostRef);
  17964. this.inheritedAttributes = {};
  17965. this.onClick = async () => {
  17966. return menuController.toggle(this.menu);
  17967. };
  17968. this.visible = false;
  17969. this.color = undefined;
  17970. this.disabled = false;
  17971. this.menu = undefined;
  17972. this.autoHide = true;
  17973. this.type = 'button';
  17974. }
  17975. componentWillLoad() {
  17976. this.inheritedAttributes = inheritAriaAttributes(this.el);
  17977. }
  17978. componentDidLoad() {
  17979. this.visibilityChanged();
  17980. }
  17981. async visibilityChanged() {
  17982. this.visible = await updateVisibility(this.menu);
  17983. }
  17984. render() {
  17985. const { color, disabled, inheritedAttributes } = this;
  17986. const mode = getIonMode$1(this);
  17987. const menuIcon = config.get('menuIcon', mode === 'ios' ? menuOutline : menuSharp);
  17988. const hidden = this.autoHide && !this.visible;
  17989. const attrs = {
  17990. type: this.type,
  17991. };
  17992. const ariaLabel = inheritedAttributes['aria-label'] || 'menu';
  17993. return (hAsync(Host, { key: '3cde3704f28eb275f4a5ff2985bbb68c1024e79c', onClick: this.onClick, "aria-disabled": disabled ? 'true' : null, "aria-hidden": hidden ? 'true' : null, class: createColorClasses$1(color, {
  17994. [mode]: true,
  17995. button: true, // ion-buttons target .button
  17996. 'menu-button-hidden': hidden,
  17997. 'menu-button-disabled': disabled,
  17998. 'in-toolbar': hostContext('ion-toolbar', this.el),
  17999. 'in-toolbar-color': hostContext('ion-toolbar[color]', this.el),
  18000. 'ion-activatable': true,
  18001. 'ion-focusable': true,
  18002. }) }, 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" }))));
  18003. }
  18004. get el() { return getElement(this); }
  18005. static get style() { return {
  18006. ios: IonMenuButtonIosStyle0,
  18007. md: IonMenuButtonMdStyle0
  18008. }; }
  18009. static get cmpMeta() { return {
  18010. "$flags$": 41,
  18011. "$tagName$": "ion-menu-button",
  18012. "$members$": {
  18013. "color": [513],
  18014. "disabled": [4],
  18015. "menu": [1],
  18016. "autoHide": [4, "auto-hide"],
  18017. "type": [1],
  18018. "visible": [32]
  18019. },
  18020. "$listeners$": [[16, "ionMenuChange", "visibilityChanged"], [16, "ionSplitPaneVisible", "visibilityChanged"]],
  18021. "$lazyBundleId$": "-",
  18022. "$attrsToReflect$": [["color", "color"]]
  18023. }; }
  18024. }
  18025. const menuToggleCss = ":host(.menu-toggle-hidden){display:none}";
  18026. var IonMenuToggleStyle0 = menuToggleCss;
  18027. /**
  18028. * @slot - Content is placed inside the toggle to act as the click target.
  18029. */
  18030. class MenuToggle {
  18031. constructor(hostRef) {
  18032. registerInstance(this, hostRef);
  18033. this.onClick = () => {
  18034. return menuController.toggle(this.menu);
  18035. };
  18036. this.visible = false;
  18037. this.menu = undefined;
  18038. this.autoHide = true;
  18039. }
  18040. connectedCallback() {
  18041. this.visibilityChanged();
  18042. }
  18043. async visibilityChanged() {
  18044. this.visible = await updateVisibility(this.menu);
  18045. }
  18046. render() {
  18047. const mode = getIonMode$1(this);
  18048. const hidden = this.autoHide && !this.visible;
  18049. return (hAsync(Host, { key: '88e88fa13ac7f10ba3acfe378bd11cda0c7e2749', onClick: this.onClick, "aria-hidden": hidden ? 'true' : null, class: {
  18050. [mode]: true,
  18051. 'menu-toggle-hidden': hidden,
  18052. } }, hAsync("slot", { key: '0a14c7b63eda64702d2fd1b4bc7db4809892842d' })));
  18053. }
  18054. static get style() { return IonMenuToggleStyle0; }
  18055. static get cmpMeta() { return {
  18056. "$flags$": 9,
  18057. "$tagName$": "ion-menu-toggle",
  18058. "$members$": {
  18059. "menu": [1],
  18060. "autoHide": [4, "auto-hide"],
  18061. "visible": [32]
  18062. },
  18063. "$listeners$": [[16, "ionMenuChange", "visibilityChanged"], [16, "ionSplitPaneVisible", "visibilityChanged"]],
  18064. "$lazyBundleId$": "-",
  18065. "$attrsToReflect$": []
  18066. }; }
  18067. }
  18068. var Style;
  18069. (function (Style) {
  18070. Style["Dark"] = "DARK";
  18071. Style["Light"] = "LIGHT";
  18072. Style["Default"] = "DEFAULT";
  18073. })(Style || (Style = {}));
  18074. const StatusBar = {
  18075. getEngine() {
  18076. const capacitor = getCapacitor();
  18077. if (capacitor === null || capacitor === void 0 ? void 0 : capacitor.isPluginAvailable('StatusBar')) {
  18078. return capacitor.Plugins.StatusBar;
  18079. }
  18080. return undefined;
  18081. },
  18082. setStyle(options) {
  18083. const engine = this.getEngine();
  18084. if (!engine) {
  18085. return;
  18086. }
  18087. engine.setStyle(options);
  18088. },
  18089. getStyle: async function () {
  18090. const engine = this.getEngine();
  18091. if (!engine) {
  18092. return Style.Default;
  18093. }
  18094. const { style } = await engine.getInfo();
  18095. return style;
  18096. },
  18097. };
  18098. const LIFECYCLE_WILL_ENTER = 'ionViewWillEnter';
  18099. const LIFECYCLE_DID_ENTER = 'ionViewDidEnter';
  18100. const LIFECYCLE_WILL_LEAVE = 'ionViewWillLeave';
  18101. const LIFECYCLE_DID_LEAVE = 'ionViewDidLeave';
  18102. const LIFECYCLE_WILL_UNLOAD = 'ionViewWillUnload';
  18103. /**
  18104. * Moves focus to a specified element. Note that we do not remove the tabindex
  18105. * because that can result in an unintentional blur. Non-focusables can't be
  18106. * focused, so the body will get focused again.
  18107. */
  18108. const moveFocus = (el) => {
  18109. el.tabIndex = -1;
  18110. el.focus();
  18111. };
  18112. /**
  18113. * Elements that are hidden using `display: none` should not be focused even if
  18114. * they are present in the DOM.
  18115. */
  18116. const isVisible = (el) => {
  18117. return el.offsetParent !== null;
  18118. };
  18119. /**
  18120. * The focus controller allows us to manage focus within a view so assistive
  18121. * technologies can inform users of changes to the navigation state. Traditional
  18122. * native apps have a way of informing assistive technology about a navigation
  18123. * state change. Mobile browsers have this too, but only when doing a full page
  18124. * load. In a single page app we do not do that, so we need to build this
  18125. * integration ourselves.
  18126. */
  18127. const createFocusController = () => {
  18128. const saveViewFocus = (referenceEl) => {
  18129. const focusManagerEnabled = config.get('focusManagerPriority', false);
  18130. /**
  18131. * When going back to a previously visited page focus should typically be moved
  18132. * back to the element that was last focused when the user was on this view.
  18133. */
  18134. if (focusManagerEnabled) {
  18135. const activeEl = document.activeElement;
  18136. if (activeEl !== null && (referenceEl === null || referenceEl === void 0 ? void 0 : referenceEl.contains(activeEl))) {
  18137. activeEl.setAttribute(LAST_FOCUS, 'true');
  18138. }
  18139. }
  18140. };
  18141. const setViewFocus = (referenceEl) => {
  18142. const focusManagerPriorities = config.get('focusManagerPriority', false);
  18143. /**
  18144. * If the focused element is a descendant of the referenceEl then it's possible
  18145. * that the app developer manually moved focus, so we do not want to override that.
  18146. * This can happen with inputs the are focused when a view transitions in.
  18147. */
  18148. if (Array.isArray(focusManagerPriorities) && !referenceEl.contains(document.activeElement)) {
  18149. /**
  18150. * When going back to a previously visited view focus should always be moved back
  18151. * to the element that the user was last focused on when they were on this view.
  18152. */
  18153. const lastFocus = referenceEl.querySelector(`[${LAST_FOCUS}]`);
  18154. if (lastFocus && isVisible(lastFocus)) {
  18155. moveFocus(lastFocus);
  18156. return;
  18157. }
  18158. for (const priority of focusManagerPriorities) {
  18159. /**
  18160. * For each recognized case (excluding the default case) make sure to return
  18161. * so that the fallback focus behavior does not run.
  18162. *
  18163. * We intentionally query for specific roles/semantic elements so that the
  18164. * transition manager can work with both Ionic and non-Ionic UI components.
  18165. *
  18166. * If new selectors are added, be sure to remove the outline ring by adding
  18167. * new selectors to rule in core.scss.
  18168. */
  18169. switch (priority) {
  18170. case 'content':
  18171. const content = referenceEl.querySelector('main, [role="main"]');
  18172. if (content && isVisible(content)) {
  18173. moveFocus(content);
  18174. return;
  18175. }
  18176. break;
  18177. case 'heading':
  18178. const headingOne = referenceEl.querySelector('h1, [role="heading"][aria-level="1"]');
  18179. if (headingOne && isVisible(headingOne)) {
  18180. moveFocus(headingOne);
  18181. return;
  18182. }
  18183. break;
  18184. case 'banner':
  18185. const header = referenceEl.querySelector('header, [role="banner"]');
  18186. if (header && isVisible(header)) {
  18187. moveFocus(header);
  18188. return;
  18189. }
  18190. break;
  18191. default:
  18192. printIonWarning(`Unrecognized focus manager priority value ${priority}`);
  18193. break;
  18194. }
  18195. }
  18196. /**
  18197. * If there is nothing to focus then focus the page so focus at least moves to
  18198. * the correct view. The browser will then determine where within the page to
  18199. * move focus to.
  18200. */
  18201. moveFocus(referenceEl);
  18202. }
  18203. };
  18204. return {
  18205. saveViewFocus,
  18206. setViewFocus,
  18207. };
  18208. };
  18209. const LAST_FOCUS = 'ion-last-focus';
  18210. const iosTransitionAnimation$1 = () => Promise.resolve().then(function () { return ios_transition; });
  18211. const mdTransitionAnimation$1 = () => Promise.resolve().then(function () { return md_transition; });
  18212. const focusController = createFocusController();
  18213. // TODO(FW-2832): types
  18214. const transition = (opts) => {
  18215. return new Promise((resolve, reject) => {
  18216. writeTask(() => {
  18217. beforeTransition(opts);
  18218. runTransition(opts).then((result) => {
  18219. if (result.animation) {
  18220. result.animation.destroy();
  18221. }
  18222. afterTransition(opts);
  18223. resolve(result);
  18224. }, (error) => {
  18225. afterTransition(opts);
  18226. reject(error);
  18227. });
  18228. });
  18229. });
  18230. };
  18231. const beforeTransition = (opts) => {
  18232. const enteringEl = opts.enteringEl;
  18233. const leavingEl = opts.leavingEl;
  18234. focusController.saveViewFocus(leavingEl);
  18235. setZIndex(enteringEl, leavingEl, opts.direction);
  18236. if (opts.showGoBack) {
  18237. enteringEl.classList.add('can-go-back');
  18238. }
  18239. else {
  18240. enteringEl.classList.remove('can-go-back');
  18241. }
  18242. setPageHidden(enteringEl, false);
  18243. /**
  18244. * When transitioning, the page should not
  18245. * respond to click events. This resolves small
  18246. * issues like users double tapping the ion-back-button.
  18247. * These pointer events are removed in `afterTransition`.
  18248. */
  18249. enteringEl.style.setProperty('pointer-events', 'none');
  18250. if (leavingEl) {
  18251. setPageHidden(leavingEl, false);
  18252. leavingEl.style.setProperty('pointer-events', 'none');
  18253. }
  18254. };
  18255. const runTransition = async (opts) => {
  18256. const animationBuilder = await getAnimationBuilder(opts);
  18257. const ani = animationBuilder && Build.isBrowser ? animation(animationBuilder, opts) : noAnimation(opts); // fast path for no animation
  18258. return ani;
  18259. };
  18260. const afterTransition = (opts) => {
  18261. const enteringEl = opts.enteringEl;
  18262. const leavingEl = opts.leavingEl;
  18263. enteringEl.classList.remove('ion-page-invisible');
  18264. enteringEl.style.removeProperty('pointer-events');
  18265. if (leavingEl !== undefined) {
  18266. leavingEl.classList.remove('ion-page-invisible');
  18267. leavingEl.style.removeProperty('pointer-events');
  18268. }
  18269. focusController.setViewFocus(enteringEl);
  18270. };
  18271. const getAnimationBuilder = async (opts) => {
  18272. if (!opts.leavingEl || !opts.animated || opts.duration === 0) {
  18273. return undefined;
  18274. }
  18275. if (opts.animationBuilder) {
  18276. return opts.animationBuilder;
  18277. }
  18278. const getAnimation = opts.mode === 'ios'
  18279. ? (await iosTransitionAnimation$1()).iosTransitionAnimation
  18280. : (await mdTransitionAnimation$1()).mdTransitionAnimation;
  18281. return getAnimation;
  18282. };
  18283. const animation = async (animationBuilder, opts) => {
  18284. await waitForReady(opts, true);
  18285. const trans = animationBuilder(opts.baseEl, opts);
  18286. fireWillEvents(opts.enteringEl, opts.leavingEl);
  18287. const didComplete = await playTransition(trans, opts);
  18288. if (opts.progressCallback) {
  18289. opts.progressCallback(undefined);
  18290. }
  18291. if (didComplete) {
  18292. fireDidEvents(opts.enteringEl, opts.leavingEl);
  18293. }
  18294. return {
  18295. hasCompleted: didComplete,
  18296. animation: trans,
  18297. };
  18298. };
  18299. const noAnimation = async (opts) => {
  18300. const enteringEl = opts.enteringEl;
  18301. const leavingEl = opts.leavingEl;
  18302. const focusManagerEnabled = config.get('focusManagerPriority', false);
  18303. /**
  18304. * If the focus manager is enabled then we need to wait for Ionic components to be
  18305. * rendered otherwise the component to focus may not be focused because it is hidden.
  18306. */
  18307. await waitForReady(opts, focusManagerEnabled);
  18308. fireWillEvents(enteringEl, leavingEl);
  18309. fireDidEvents(enteringEl, leavingEl);
  18310. return {
  18311. hasCompleted: true,
  18312. };
  18313. };
  18314. const waitForReady = async (opts, defaultDeep) => {
  18315. const deep = opts.deepWait !== undefined ? opts.deepWait : defaultDeep;
  18316. if (deep) {
  18317. await Promise.all([deepReady(opts.enteringEl), deepReady(opts.leavingEl)]);
  18318. }
  18319. await notifyViewReady(opts.viewIsReady, opts.enteringEl);
  18320. };
  18321. const notifyViewReady = async (viewIsReady, enteringEl) => {
  18322. if (viewIsReady) {
  18323. await viewIsReady(enteringEl);
  18324. }
  18325. };
  18326. const playTransition = (trans, opts) => {
  18327. const progressCallback = opts.progressCallback;
  18328. const promise = new Promise((resolve) => {
  18329. trans.onFinish((currentStep) => resolve(currentStep === 1));
  18330. });
  18331. // cool, let's do this, start the transition
  18332. if (progressCallback) {
  18333. // this is a swipe to go back, just get the transition progress ready
  18334. // kick off the swipe animation start
  18335. trans.progressStart(true);
  18336. progressCallback(trans);
  18337. }
  18338. else {
  18339. // only the top level transition should actually start "play"
  18340. // kick it off and let it play through
  18341. // ******** DOM WRITE ****************
  18342. trans.play();
  18343. }
  18344. // create a callback for when the animation is done
  18345. return promise;
  18346. };
  18347. const fireWillEvents = (enteringEl, leavingEl) => {
  18348. lifecycle(leavingEl, LIFECYCLE_WILL_LEAVE);
  18349. lifecycle(enteringEl, LIFECYCLE_WILL_ENTER);
  18350. };
  18351. const fireDidEvents = (enteringEl, leavingEl) => {
  18352. lifecycle(enteringEl, LIFECYCLE_DID_ENTER);
  18353. lifecycle(leavingEl, LIFECYCLE_DID_LEAVE);
  18354. };
  18355. const lifecycle = (el, eventName) => {
  18356. if (el) {
  18357. const ev = new CustomEvent(eventName, {
  18358. bubbles: false,
  18359. cancelable: false,
  18360. });
  18361. el.dispatchEvent(ev);
  18362. }
  18363. };
  18364. /**
  18365. * Wait two request animation frame loops.
  18366. * This allows the framework implementations enough time to mount
  18367. * the user-defined contents. This is often needed when using inline
  18368. * modals and popovers that accept user components. For popover,
  18369. * the contents must be mounted for the popover to be sized correctly.
  18370. * For modals, the contents must be mounted for iOS to run the
  18371. * transition correctly.
  18372. *
  18373. * On Angular and React, a single raf is enough time, but for Vue
  18374. * we need to wait two rafs. As a result we are using two rafs for
  18375. * all frameworks to ensure contents are mounted.
  18376. */
  18377. const waitForMount = () => {
  18378. return new Promise((resolve) => raf(() => raf(() => resolve())));
  18379. };
  18380. const deepReady = async (el) => {
  18381. const element = el;
  18382. if (element) {
  18383. if (element.componentOnReady != null) {
  18384. // eslint-disable-next-line custom-rules/no-component-on-ready-method
  18385. const stencilEl = await element.componentOnReady();
  18386. if (stencilEl != null) {
  18387. return;
  18388. }
  18389. /**
  18390. * Custom elements in Stencil will have __registerHost.
  18391. */
  18392. }
  18393. else if (element.__registerHost != null) {
  18394. /**
  18395. * Non-lazy loaded custom elements need to wait
  18396. * one frame for component to be loaded.
  18397. */
  18398. const waitForCustomElement = new Promise((resolve) => raf(resolve));
  18399. await waitForCustomElement;
  18400. return;
  18401. }
  18402. await Promise.all(Array.from(element.children).map(deepReady));
  18403. }
  18404. };
  18405. const setPageHidden = (el, hidden) => {
  18406. if (hidden) {
  18407. el.setAttribute('aria-hidden', 'true');
  18408. el.classList.add('ion-page-hidden');
  18409. }
  18410. else {
  18411. el.hidden = false;
  18412. el.removeAttribute('aria-hidden');
  18413. el.classList.remove('ion-page-hidden');
  18414. }
  18415. };
  18416. const setZIndex = (enteringEl, leavingEl, direction) => {
  18417. if (enteringEl !== undefined) {
  18418. enteringEl.style.zIndex = direction === 'back' ? '99' : '101';
  18419. }
  18420. if (leavingEl !== undefined) {
  18421. leavingEl.style.zIndex = '100';
  18422. }
  18423. };
  18424. const getIonPageElement = (element) => {
  18425. if (element.classList.contains('ion-page')) {
  18426. return element;
  18427. }
  18428. const ionPage = element.querySelector(':scope > .ion-page, :scope > ion-nav, :scope > ion-tabs');
  18429. if (ionPage) {
  18430. return ionPage;
  18431. }
  18432. // idk, return the original element so at least something animates and we don't have a null pointer
  18433. return element;
  18434. };
  18435. const KEYBOARD_DID_OPEN = 'ionKeyboardDidShow';
  18436. /**
  18437. * Use y = mx + b to
  18438. * figure out the backdrop value
  18439. * at a particular x coordinate. This
  18440. * is useful when the backdrop does
  18441. * not begin to fade in until after
  18442. * the 0 breakpoint.
  18443. */
  18444. const getBackdropValueForSheet = (x, backdropBreakpoint) => {
  18445. /**
  18446. * We will use these points:
  18447. * (backdropBreakpoint, 0)
  18448. * (maxBreakpoint, 1)
  18449. * We know that at the beginning breakpoint,
  18450. * the backdrop will be hidden. We also
  18451. * know that at the maxBreakpoint, the backdrop
  18452. * must be fully visible. maxBreakpoint should
  18453. * always be 1 even if the maximum value
  18454. * of the breakpoints array is not 1 since
  18455. * the animation runs from a progress of 0
  18456. * to a progress of 1.
  18457. * m = (y2 - y1) / (x2 - x1)
  18458. *
  18459. * This is simplified from:
  18460. * m = (1 - 0) / (maxBreakpoint - backdropBreakpoint)
  18461. *
  18462. * If the backdropBreakpoint is 1, we return 0 as the
  18463. * backdrop is completely hidden.
  18464. *
  18465. */
  18466. if (backdropBreakpoint === 1) {
  18467. return 0;
  18468. }
  18469. const slope = 1 / (1 - backdropBreakpoint);
  18470. /**
  18471. * From here, compute b which is
  18472. * the backdrop opacity if the offset
  18473. * is 0. If the backdrop does not
  18474. * begin to fade in until after the
  18475. * 0 breakpoint, this b value will be
  18476. * negative. This is fine as we never pass
  18477. * b directly into the animation keyframes.
  18478. * b = y - mx
  18479. * Use a known point: (backdropBreakpoint, 0)
  18480. * This is simplified from:
  18481. * b = 0 - (backdropBreakpoint * slope)
  18482. */
  18483. const b = -(backdropBreakpoint * slope);
  18484. /**
  18485. * Finally, we can now determine the
  18486. * backdrop offset given an arbitrary
  18487. * gesture offset.
  18488. */
  18489. return x * slope + b;
  18490. };
  18491. /**
  18492. * The tablet/desktop card modal activates
  18493. * when the window width is >= 768.
  18494. * At that point, the presenting element
  18495. * is not transformed, so we do not need to
  18496. * adjust the status bar color.
  18497. *
  18498. */
  18499. const setCardStatusBarDark = () => {
  18500. if (!win$1 || win$1.innerWidth >= 768) {
  18501. return;
  18502. }
  18503. StatusBar.setStyle({ style: Style.Dark });
  18504. };
  18505. const setCardStatusBarDefault = (defaultStyle = Style.Default) => {
  18506. if (!win$1 || win$1.innerWidth >= 768) {
  18507. return;
  18508. }
  18509. StatusBar.setStyle({ style: defaultStyle });
  18510. };
  18511. const handleCanDismiss = async (el, animation) => {
  18512. /**
  18513. * If canDismiss is not a function
  18514. * then we can return early. If canDismiss is `true`,
  18515. * then canDismissBlocksGesture is `false` as canDismiss
  18516. * will never interrupt the gesture. As a result,
  18517. * this code block is never reached. If canDismiss is `false`,
  18518. * then we never dismiss.
  18519. */
  18520. if (typeof el.canDismiss !== 'function') {
  18521. return;
  18522. }
  18523. /**
  18524. * Run the canDismiss callback.
  18525. * If the function returns `true`,
  18526. * then we can proceed with dismiss.
  18527. */
  18528. const shouldDismiss = await el.canDismiss(undefined, GESTURE);
  18529. if (!shouldDismiss) {
  18530. return;
  18531. }
  18532. /**
  18533. * If canDismiss resolved after the snap
  18534. * back animation finished, we can
  18535. * dismiss immediately.
  18536. *
  18537. * If canDismiss resolved before the snap
  18538. * back animation finished, we need to
  18539. * wait until the snap back animation is
  18540. * done before dismissing.
  18541. */
  18542. if (animation.isRunning()) {
  18543. animation.onFinish(() => {
  18544. el.dismiss(undefined, 'handler');
  18545. }, { oneTimeCallback: true });
  18546. }
  18547. else {
  18548. el.dismiss(undefined, 'handler');
  18549. }
  18550. };
  18551. /**
  18552. * This function lets us simulate a realistic spring-like animation
  18553. * when swiping down on the modal.
  18554. * There are two forces that we need to use to compute the spring physics:
  18555. *
  18556. * 1. Stiffness, k: This is a measure of resistance applied a spring.
  18557. * 2. Dampening, c: This value has the effect of reducing or preventing oscillation.
  18558. *
  18559. * Using these two values, we can calculate the Spring Force and the Dampening Force
  18560. * to compute the total force applied to a spring.
  18561. *
  18562. * Spring Force: This force pulls a spring back into its equilibrium position.
  18563. * Hooke's Law tells us that that spring force (FS) = kX.
  18564. * k is the stiffness of a spring, and X is the displacement of the spring from its
  18565. * equilibrium position. In this case, it is the amount by which the free end
  18566. * of a spring was displaced (stretched/pushed) from its "relaxed" position.
  18567. *
  18568. * Dampening Force: This force slows down motion. Without it, a spring would oscillate forever.
  18569. * The dampening force, FD, can be found via this formula: FD = -cv
  18570. * where c the dampening value and v is velocity.
  18571. *
  18572. * Therefore, the resulting force that is exerted on the block is:
  18573. * F = FS + FD = -kX - cv
  18574. *
  18575. * Newton's 2nd Law tells us that F = ma:
  18576. * ma = -kX - cv.
  18577. *
  18578. * For Ionic's purposes, we can assume that m = 1:
  18579. * a = -kX - cv
  18580. *
  18581. * Imagine a block attached to the end of a spring. At equilibrium
  18582. * the block is at position x = 1.
  18583. * Pressing on the block moves it to position x = 0;
  18584. * So, to calculate the displacement, we need to take the
  18585. * current position and subtract the previous position from it.
  18586. * X = x - x0 = 0 - 1 = -1.
  18587. *
  18588. * For Ionic's purposes, we are only pushing on the spring modal
  18589. * so we have a max position of 1.
  18590. * As a result, we can expand displacement to this formula:
  18591. * X = x - 1
  18592. *
  18593. * a = -k(x - 1) - cv
  18594. *
  18595. * We can represent the motion of something as a function of time: f(t) = x.
  18596. * The derivative of position gives us the velocity: f'(t)
  18597. * The derivative of the velocity gives us the acceleration: f''(t)
  18598. *
  18599. * We can substitute the formula above with these values:
  18600. *
  18601. * f"(t) = -k * (f(t) - 1) - c * f'(t)
  18602. *
  18603. * This is called a differential equation.
  18604. *
  18605. * We know that at t = 0, we are at x = 0 because the modal does not move: f(0) = 0
  18606. * This means our velocity is also zero: f'(0) = 0.
  18607. *
  18608. * We can cheat a bit and plug the formula into Wolfram Alpha.
  18609. * However, we need to pick stiffness and dampening values:
  18610. * k = 0.57
  18611. * c = 15
  18612. *
  18613. * I picked these as they are fairly close to native iOS's spring effect
  18614. * with the modal.
  18615. *
  18616. * What we plug in is this: f(0) = 0; f'(0) = 0; f''(t) = -0.57(f(t) - 1) - 15f'(t)
  18617. *
  18618. * The result is a formula that lets us calculate the acceleration
  18619. * for a given time t.
  18620. * Note: This is the approximate form of the solution. Wolfram Alpha will
  18621. * give you a complex differential equation too.
  18622. */
  18623. const calculateSpringStep = (t) => {
  18624. return 0.00255275 * 2.71828 ** (-14.9619 * t) - 1.00255 * 2.71828 ** (-0.0380968 * t) + 1;
  18625. };
  18626. // Defaults for the card swipe animation
  18627. const SwipeToCloseDefaults = {
  18628. MIN_PRESENTING_SCALE: 0.915,
  18629. };
  18630. const createSwipeToCloseGesture = (el, animation, statusBarStyle, onDismiss) => {
  18631. /**
  18632. * The step value at which a card modal
  18633. * is eligible for dismissing via gesture.
  18634. */
  18635. const DISMISS_THRESHOLD = 0.5;
  18636. const height = el.offsetHeight;
  18637. let isOpen = false;
  18638. let canDismissBlocksGesture = false;
  18639. let contentEl = null;
  18640. let scrollEl = null;
  18641. const canDismissMaxStep = 0.2;
  18642. let initialScrollY = true;
  18643. let lastStep = 0;
  18644. const getScrollY = () => {
  18645. if (contentEl && isIonContent(contentEl)) {
  18646. return contentEl.scrollY;
  18647. /**
  18648. * Custom scroll containers are intended to be
  18649. * used with virtual scrolling, so we assume
  18650. * there is scrolling in this case.
  18651. */
  18652. }
  18653. else {
  18654. return true;
  18655. }
  18656. };
  18657. const canStart = (detail) => {
  18658. const target = detail.event.target;
  18659. if (target === null || !target.closest) {
  18660. return true;
  18661. }
  18662. /**
  18663. * If we are swiping on the content,
  18664. * swiping should only be possible if
  18665. * the content is scrolled all the way
  18666. * to the top so that we do not interfere
  18667. * with scrolling.
  18668. *
  18669. * We cannot assume that the `ion-content`
  18670. * target will remain consistent between
  18671. * swipes. For example, when using
  18672. * ion-nav within a card modal it is
  18673. * possible to swipe, push a view, and then
  18674. * swipe again. The target content will not
  18675. * be the same between swipes.
  18676. */
  18677. contentEl = findClosestIonContent(target);
  18678. if (contentEl) {
  18679. /**
  18680. * The card should never swipe to close
  18681. * on the content with a refresher.
  18682. * Note: We cannot solve this by making the
  18683. * swipeToClose gesture have a higher priority
  18684. * than the refresher gesture as the iOS native
  18685. * refresh gesture uses a scroll listener in
  18686. * addition to a gesture.
  18687. *
  18688. * Note: Do not use getScrollElement here
  18689. * because we need this to be a synchronous
  18690. * operation, and getScrollElement is
  18691. * asynchronous.
  18692. */
  18693. if (isIonContent(contentEl)) {
  18694. const root = getElementRoot(contentEl);
  18695. scrollEl = root.querySelector('.inner-scroll');
  18696. }
  18697. else {
  18698. scrollEl = contentEl;
  18699. }
  18700. const hasRefresherInContent = !!contentEl.querySelector('ion-refresher');
  18701. return !hasRefresherInContent && scrollEl.scrollTop === 0;
  18702. }
  18703. /**
  18704. * Card should be swipeable on all
  18705. * parts of the modal except for the footer.
  18706. */
  18707. const footer = target.closest('ion-footer');
  18708. if (footer === null) {
  18709. return true;
  18710. }
  18711. return false;
  18712. };
  18713. const onStart = (detail) => {
  18714. const { deltaY } = detail;
  18715. /**
  18716. * Get the initial scrollY value so
  18717. * that we can correctly reset the scrollY
  18718. * prop when the gesture ends.
  18719. */
  18720. initialScrollY = getScrollY();
  18721. /**
  18722. * If canDismiss is anything other than `true`
  18723. * then users should be able to swipe down
  18724. * until a threshold is hit. At that point,
  18725. * the card modal should not proceed any further.
  18726. * TODO (FW-937)
  18727. * Remove undefined check
  18728. */
  18729. canDismissBlocksGesture = el.canDismiss !== undefined && el.canDismiss !== true;
  18730. /**
  18731. * If we are pulling down, then
  18732. * it is possible we are pulling on the
  18733. * content. We do not want scrolling to
  18734. * happen at the same time as the gesture.
  18735. */
  18736. if (deltaY > 0 && contentEl) {
  18737. disableContentScrollY(contentEl);
  18738. }
  18739. animation.progressStart(true, isOpen ? 1 : 0);
  18740. };
  18741. const onMove = (detail) => {
  18742. const { deltaY } = detail;
  18743. /**
  18744. * If we are pulling down, then
  18745. * it is possible we are pulling on the
  18746. * content. We do not want scrolling to
  18747. * happen at the same time as the gesture.
  18748. */
  18749. if (deltaY > 0 && contentEl) {
  18750. disableContentScrollY(contentEl);
  18751. }
  18752. /**
  18753. * If we are swiping on the content
  18754. * then the swipe gesture should only
  18755. * happen if we are pulling down.
  18756. *
  18757. * However, if we pull up and
  18758. * then down such that the scroll position
  18759. * returns to 0, we should be able to swipe
  18760. * the card.
  18761. */
  18762. const step = detail.deltaY / height;
  18763. /**
  18764. * Check if user is swiping down and
  18765. * if we have a canDismiss value that
  18766. * should block the gesture from
  18767. * proceeding,
  18768. */
  18769. const isAttemptingDismissWithCanDismiss = step >= 0 && canDismissBlocksGesture;
  18770. /**
  18771. * If we are blocking the gesture from dismissing,
  18772. * set the max step value so that the sheet cannot be
  18773. * completely hidden.
  18774. */
  18775. const maxStep = isAttemptingDismissWithCanDismiss ? canDismissMaxStep : 0.9999;
  18776. /**
  18777. * If we are blocking the gesture from
  18778. * dismissing, calculate the spring modifier value
  18779. * this will be added to the starting breakpoint
  18780. * value to give the gesture a spring-like feeling.
  18781. * Note that the starting breakpoint is always 0,
  18782. * so we omit adding 0 to the result.
  18783. */
  18784. const processedStep = isAttemptingDismissWithCanDismiss ? calculateSpringStep(step / maxStep) : step;
  18785. const clampedStep = clamp(0.0001, processedStep, maxStep);
  18786. animation.progressStep(clampedStep);
  18787. /**
  18788. * When swiping down half way, the status bar style
  18789. * should be reset to its default value.
  18790. *
  18791. * We track lastStep so that we do not fire these
  18792. * functions on every onMove, only when the user has
  18793. * crossed a certain threshold.
  18794. */
  18795. if (clampedStep >= DISMISS_THRESHOLD && lastStep < DISMISS_THRESHOLD) {
  18796. setCardStatusBarDefault(statusBarStyle);
  18797. /**
  18798. * However, if we swipe back up, then the
  18799. * status bar style should be set to have light
  18800. * text on a dark background.
  18801. */
  18802. }
  18803. else if (clampedStep < DISMISS_THRESHOLD && lastStep >= DISMISS_THRESHOLD) {
  18804. setCardStatusBarDark();
  18805. }
  18806. lastStep = clampedStep;
  18807. };
  18808. const onEnd = (detail) => {
  18809. const velocity = detail.velocityY;
  18810. const step = detail.deltaY / height;
  18811. const isAttemptingDismissWithCanDismiss = step >= 0 && canDismissBlocksGesture;
  18812. const maxStep = isAttemptingDismissWithCanDismiss ? canDismissMaxStep : 0.9999;
  18813. const processedStep = isAttemptingDismissWithCanDismiss ? calculateSpringStep(step / maxStep) : step;
  18814. const clampedStep = clamp(0.0001, processedStep, maxStep);
  18815. const threshold = (detail.deltaY + velocity * 1000) / height;
  18816. /**
  18817. * If canDismiss blocks
  18818. * the swipe gesture, then the
  18819. * animation can never complete until
  18820. * canDismiss is checked.
  18821. */
  18822. const shouldComplete = !isAttemptingDismissWithCanDismiss && threshold >= DISMISS_THRESHOLD;
  18823. let newStepValue = shouldComplete ? -0.001 : 0.001;
  18824. if (!shouldComplete) {
  18825. animation.easing('cubic-bezier(1, 0, 0.68, 0.28)');
  18826. newStepValue += getTimeGivenProgression([0, 0], [1, 0], [0.68, 0.28], [1, 1], clampedStep)[0];
  18827. }
  18828. else {
  18829. animation.easing('cubic-bezier(0.32, 0.72, 0, 1)');
  18830. newStepValue += getTimeGivenProgression([0, 0], [0.32, 0.72], [0, 1], [1, 1], clampedStep)[0];
  18831. }
  18832. const duration = shouldComplete
  18833. ? computeDuration(step * height, velocity)
  18834. : computeDuration((1 - clampedStep) * height, velocity);
  18835. isOpen = shouldComplete;
  18836. gesture.enable(false);
  18837. if (contentEl) {
  18838. resetContentScrollY(contentEl, initialScrollY);
  18839. }
  18840. animation
  18841. .onFinish(() => {
  18842. if (!shouldComplete) {
  18843. gesture.enable(true);
  18844. }
  18845. })
  18846. .progressEnd(shouldComplete ? 1 : 0, newStepValue, duration);
  18847. /**
  18848. * If the canDismiss value blocked the gesture
  18849. * from proceeding, then we should ignore whatever
  18850. * shouldComplete is. Whether or not the modal
  18851. * animation should complete is now determined by
  18852. * canDismiss.
  18853. *
  18854. * If the user swiped >25% of the way
  18855. * to the max step, then we should
  18856. * check canDismiss. 25% was chosen
  18857. * to avoid accidental swipes.
  18858. */
  18859. if (isAttemptingDismissWithCanDismiss && clampedStep > maxStep / 4) {
  18860. handleCanDismiss(el, animation);
  18861. }
  18862. else if (shouldComplete) {
  18863. onDismiss();
  18864. }
  18865. };
  18866. const gesture = createGesture({
  18867. el,
  18868. gestureName: 'modalSwipeToClose',
  18869. gesturePriority: OVERLAY_GESTURE_PRIORITY,
  18870. direction: 'y',
  18871. threshold: 10,
  18872. canStart,
  18873. onStart,
  18874. onMove,
  18875. onEnd,
  18876. });
  18877. return gesture;
  18878. };
  18879. const computeDuration = (remaining, velocity) => {
  18880. return clamp(400, remaining / Math.abs(velocity * 1.1), 500);
  18881. };
  18882. const createSheetEnterAnimation = (opts) => {
  18883. const { currentBreakpoint, backdropBreakpoint, expandToScroll } = opts;
  18884. /**
  18885. * If the backdropBreakpoint is undefined, then the backdrop
  18886. * should always fade in. If the backdropBreakpoint came before the
  18887. * current breakpoint, then the backdrop should be fading in.
  18888. */
  18889. const shouldShowBackdrop = backdropBreakpoint === undefined || backdropBreakpoint < currentBreakpoint;
  18890. const initialBackdrop = shouldShowBackdrop ? `calc(var(--backdrop-opacity) * ${currentBreakpoint})` : '0';
  18891. const backdropAnimation = createAnimation('backdropAnimation').fromTo('opacity', 0, initialBackdrop);
  18892. if (shouldShowBackdrop) {
  18893. backdropAnimation
  18894. .beforeStyles({
  18895. 'pointer-events': 'none',
  18896. })
  18897. .afterClearStyles(['pointer-events']);
  18898. }
  18899. const wrapperAnimation = createAnimation('wrapperAnimation').keyframes([
  18900. { offset: 0, opacity: 1, transform: 'translateY(100%)' },
  18901. { offset: 1, opacity: 1, transform: `translateY(${100 - currentBreakpoint * 100}%)` },
  18902. ]);
  18903. /**
  18904. * This allows the content to be scrollable at any breakpoint.
  18905. */
  18906. const contentAnimation = !expandToScroll
  18907. ? createAnimation('contentAnimation').keyframes([
  18908. { offset: 0, opacity: 1, maxHeight: `${(1 - currentBreakpoint) * 100}%` },
  18909. { offset: 1, opacity: 1, maxHeight: `${currentBreakpoint * 100}%` },
  18910. ])
  18911. : undefined;
  18912. return { wrapperAnimation, backdropAnimation, contentAnimation };
  18913. };
  18914. const createSheetLeaveAnimation = (opts) => {
  18915. const { currentBreakpoint, backdropBreakpoint } = opts;
  18916. /**
  18917. * Backdrop does not always fade in from 0 to 1 if backdropBreakpoint
  18918. * is defined, so we need to account for that offset by figuring out
  18919. * what the current backdrop value should be.
  18920. */
  18921. const backdropValue = `calc(var(--backdrop-opacity) * ${getBackdropValueForSheet(currentBreakpoint, backdropBreakpoint)})`;
  18922. const defaultBackdrop = [
  18923. { offset: 0, opacity: backdropValue },
  18924. { offset: 1, opacity: 0 },
  18925. ];
  18926. const customBackdrop = [
  18927. { offset: 0, opacity: backdropValue },
  18928. { offset: backdropBreakpoint, opacity: 0 },
  18929. { offset: 1, opacity: 0 },
  18930. ];
  18931. const backdropAnimation = createAnimation('backdropAnimation').keyframes(backdropBreakpoint !== 0 ? customBackdrop : defaultBackdrop);
  18932. const wrapperAnimation = createAnimation('wrapperAnimation').keyframes([
  18933. { offset: 0, opacity: 1, transform: `translateY(${100 - currentBreakpoint * 100}%)` },
  18934. { offset: 1, opacity: 1, transform: `translateY(100%)` },
  18935. ]);
  18936. return { wrapperAnimation, backdropAnimation };
  18937. };
  18938. const createEnterAnimation$1 = () => {
  18939. const backdropAnimation = createAnimation()
  18940. .fromTo('opacity', 0.01, 'var(--backdrop-opacity)')
  18941. .beforeStyles({
  18942. 'pointer-events': 'none',
  18943. })
  18944. .afterClearStyles(['pointer-events']);
  18945. const wrapperAnimation = createAnimation().fromTo('transform', 'translateY(100vh)', 'translateY(0vh)');
  18946. return { backdropAnimation, wrapperAnimation, contentAnimation: undefined };
  18947. };
  18948. /**
  18949. * iOS Modal Enter Animation for the Card presentation style
  18950. */
  18951. const iosEnterAnimation$3 = (baseEl, opts) => {
  18952. const { presentingEl, currentBreakpoint, expandToScroll } = opts;
  18953. const root = getElementRoot(baseEl);
  18954. const { wrapperAnimation, backdropAnimation, contentAnimation } = currentBreakpoint !== undefined ? createSheetEnterAnimation(opts) : createEnterAnimation$1();
  18955. backdropAnimation.addElement(root.querySelector('ion-backdrop'));
  18956. wrapperAnimation.addElement(root.querySelectorAll('.modal-wrapper, .modal-shadow')).beforeStyles({ opacity: 1 });
  18957. // The content animation is only added if scrolling is enabled for
  18958. // all the breakpoints.
  18959. !expandToScroll && (contentAnimation === null || contentAnimation === void 0 ? void 0 : contentAnimation.addElement(baseEl.querySelector('.ion-page')));
  18960. const baseAnimation = createAnimation('entering-base')
  18961. .addElement(baseEl)
  18962. .easing('cubic-bezier(0.32,0.72,0,1)')
  18963. .duration(500)
  18964. .addAnimation([wrapperAnimation])
  18965. .beforeAddWrite(() => {
  18966. if (expandToScroll) {
  18967. // Scroll can only be done when the modal is fully expanded.
  18968. return;
  18969. }
  18970. /**
  18971. * There are some browsers that causes flickering when
  18972. * dragging the content when scroll is enabled at every
  18973. * breakpoint. This is due to the wrapper element being
  18974. * transformed off the screen and having a snap animation.
  18975. *
  18976. * A workaround is to clone the footer element and append
  18977. * it outside of the wrapper element. This way, the footer
  18978. * is still visible and the drag can be done without
  18979. * flickering. The original footer is hidden until the modal
  18980. * is dismissed. This maintains the animation of the footer
  18981. * when the modal is dismissed.
  18982. *
  18983. * The workaround needs to be done before the animation starts
  18984. * so there are no flickering issues.
  18985. */
  18986. const ionFooter = baseEl.querySelector('ion-footer');
  18987. /**
  18988. * This check is needed to prevent more than one footer
  18989. * from being appended to the shadow root.
  18990. * Otherwise, iOS and MD enter animations would append
  18991. * the footer twice.
  18992. */
  18993. const ionFooterAlreadyAppended = baseEl.shadowRoot.querySelector('ion-footer');
  18994. if (ionFooter && !ionFooterAlreadyAppended) {
  18995. const footerHeight = ionFooter.clientHeight;
  18996. const clonedFooter = ionFooter.cloneNode(true);
  18997. baseEl.shadowRoot.appendChild(clonedFooter);
  18998. ionFooter.style.setProperty('display', 'none');
  18999. ionFooter.setAttribute('aria-hidden', 'true');
  19000. // Padding is added to prevent some content from being hidden.
  19001. const page = baseEl.querySelector('.ion-page');
  19002. page.style.setProperty('padding-bottom', `${footerHeight}px`);
  19003. }
  19004. });
  19005. if (contentAnimation) {
  19006. baseAnimation.addAnimation(contentAnimation);
  19007. }
  19008. if (presentingEl) {
  19009. const isMobile = window.innerWidth < 768;
  19010. const hasCardModal = presentingEl.tagName === 'ION-MODAL' && presentingEl.presentingElement !== undefined;
  19011. const presentingElRoot = getElementRoot(presentingEl);
  19012. const presentingAnimation = createAnimation().beforeStyles({
  19013. transform: 'translateY(0)',
  19014. 'transform-origin': 'top center',
  19015. overflow: 'hidden',
  19016. });
  19017. const bodyEl = document.body;
  19018. if (isMobile) {
  19019. /**
  19020. * Fallback for browsers that does not support `max()` (ex: Firefox)
  19021. * No need to worry about statusbar padding since engines like Gecko
  19022. * are not used as the engine for standalone Cordova/Capacitor apps
  19023. */
  19024. const transformOffset = !CSS.supports('width', 'max(0px, 1px)') ? '30px' : 'max(30px, var(--ion-safe-area-top))';
  19025. const modalTransform = hasCardModal ? '-10px' : transformOffset;
  19026. const toPresentingScale = SwipeToCloseDefaults.MIN_PRESENTING_SCALE;
  19027. const finalTransform = `translateY(${modalTransform}) scale(${toPresentingScale})`;
  19028. presentingAnimation
  19029. .afterStyles({
  19030. transform: finalTransform,
  19031. })
  19032. .beforeAddWrite(() => bodyEl.style.setProperty('background-color', 'black'))
  19033. .addElement(presentingEl)
  19034. .keyframes([
  19035. { offset: 0, filter: 'contrast(1)', transform: 'translateY(0px) scale(1)', borderRadius: '0px' },
  19036. { offset: 1, filter: 'contrast(0.85)', transform: finalTransform, borderRadius: '10px 10px 0 0' },
  19037. ]);
  19038. baseAnimation.addAnimation(presentingAnimation);
  19039. }
  19040. else {
  19041. baseAnimation.addAnimation(backdropAnimation);
  19042. if (!hasCardModal) {
  19043. wrapperAnimation.fromTo('opacity', '0', '1');
  19044. }
  19045. else {
  19046. const toPresentingScale = hasCardModal ? SwipeToCloseDefaults.MIN_PRESENTING_SCALE : 1;
  19047. const finalTransform = `translateY(-10px) scale(${toPresentingScale})`;
  19048. presentingAnimation
  19049. .afterStyles({
  19050. transform: finalTransform,
  19051. })
  19052. .addElement(presentingElRoot.querySelector('.modal-wrapper'))
  19053. .keyframes([
  19054. { offset: 0, filter: 'contrast(1)', transform: 'translateY(0) scale(1)' },
  19055. { offset: 1, filter: 'contrast(0.85)', transform: finalTransform },
  19056. ]);
  19057. const shadowAnimation = createAnimation()
  19058. .afterStyles({
  19059. transform: finalTransform,
  19060. })
  19061. .addElement(presentingElRoot.querySelector('.modal-shadow'))
  19062. .keyframes([
  19063. { offset: 0, opacity: '1', transform: 'translateY(0) scale(1)' },
  19064. { offset: 1, opacity: '0', transform: finalTransform },
  19065. ]);
  19066. baseAnimation.addAnimation([presentingAnimation, shadowAnimation]);
  19067. }
  19068. }
  19069. }
  19070. else {
  19071. baseAnimation.addAnimation(backdropAnimation);
  19072. }
  19073. return baseAnimation;
  19074. };
  19075. const createLeaveAnimation$1 = () => {
  19076. const backdropAnimation = createAnimation().fromTo('opacity', 'var(--backdrop-opacity)', 0);
  19077. const wrapperAnimation = createAnimation().fromTo('transform', 'translateY(0vh)', 'translateY(100vh)');
  19078. return { backdropAnimation, wrapperAnimation };
  19079. };
  19080. /**
  19081. * iOS Modal Leave Animation
  19082. */
  19083. const iosLeaveAnimation$3 = (baseEl, opts, duration = 500) => {
  19084. const { presentingEl, currentBreakpoint, expandToScroll } = opts;
  19085. const root = getElementRoot(baseEl);
  19086. const { wrapperAnimation, backdropAnimation } = currentBreakpoint !== undefined ? createSheetLeaveAnimation(opts) : createLeaveAnimation$1();
  19087. backdropAnimation.addElement(root.querySelector('ion-backdrop'));
  19088. wrapperAnimation.addElement(root.querySelectorAll('.modal-wrapper, .modal-shadow')).beforeStyles({ opacity: 1 });
  19089. const baseAnimation = createAnimation('leaving-base')
  19090. .addElement(baseEl)
  19091. .easing('cubic-bezier(0.32,0.72,0,1)')
  19092. .duration(duration)
  19093. .addAnimation(wrapperAnimation)
  19094. .beforeAddWrite(() => {
  19095. if (expandToScroll) {
  19096. // Scroll can only be done when the modal is fully expanded.
  19097. return;
  19098. }
  19099. /**
  19100. * If expandToScroll is disabled, we need to swap
  19101. * the visibility to the original, so the footer
  19102. * dismisses with the modal and doesn't stay
  19103. * until the modal is removed from the DOM.
  19104. */
  19105. const ionFooter = baseEl.querySelector('ion-footer');
  19106. if (ionFooter) {
  19107. const clonedFooter = baseEl.shadowRoot.querySelector('ion-footer');
  19108. ionFooter.style.removeProperty('display');
  19109. ionFooter.removeAttribute('aria-hidden');
  19110. clonedFooter.style.setProperty('display', 'none');
  19111. clonedFooter.setAttribute('aria-hidden', 'true');
  19112. const page = baseEl.querySelector('.ion-page');
  19113. page.style.removeProperty('padding-bottom');
  19114. }
  19115. });
  19116. if (presentingEl) {
  19117. const isMobile = window.innerWidth < 768;
  19118. const hasCardModal = presentingEl.tagName === 'ION-MODAL' && presentingEl.presentingElement !== undefined;
  19119. const presentingElRoot = getElementRoot(presentingEl);
  19120. const presentingAnimation = createAnimation()
  19121. .beforeClearStyles(['transform'])
  19122. .afterClearStyles(['transform'])
  19123. .onFinish((currentStep) => {
  19124. // only reset background color if this is the last card-style modal
  19125. if (currentStep !== 1) {
  19126. return;
  19127. }
  19128. presentingEl.style.setProperty('overflow', '');
  19129. const numModals = Array.from(bodyEl.querySelectorAll('ion-modal:not(.overlay-hidden)')).filter((m) => m.presentingElement !== undefined).length;
  19130. if (numModals <= 1) {
  19131. bodyEl.style.setProperty('background-color', '');
  19132. }
  19133. });
  19134. const bodyEl = document.body;
  19135. if (isMobile) {
  19136. const transformOffset = !CSS.supports('width', 'max(0px, 1px)') ? '30px' : 'max(30px, var(--ion-safe-area-top))';
  19137. const modalTransform = hasCardModal ? '-10px' : transformOffset;
  19138. const toPresentingScale = SwipeToCloseDefaults.MIN_PRESENTING_SCALE;
  19139. const finalTransform = `translateY(${modalTransform}) scale(${toPresentingScale})`;
  19140. presentingAnimation.addElement(presentingEl).keyframes([
  19141. { offset: 0, filter: 'contrast(0.85)', transform: finalTransform, borderRadius: '10px 10px 0 0' },
  19142. { offset: 1, filter: 'contrast(1)', transform: 'translateY(0px) scale(1)', borderRadius: '0px' },
  19143. ]);
  19144. baseAnimation.addAnimation(presentingAnimation);
  19145. }
  19146. else {
  19147. baseAnimation.addAnimation(backdropAnimation);
  19148. if (!hasCardModal) {
  19149. wrapperAnimation.fromTo('opacity', '1', '0');
  19150. }
  19151. else {
  19152. const toPresentingScale = hasCardModal ? SwipeToCloseDefaults.MIN_PRESENTING_SCALE : 1;
  19153. const finalTransform = `translateY(-10px) scale(${toPresentingScale})`;
  19154. presentingAnimation
  19155. .addElement(presentingElRoot.querySelector('.modal-wrapper'))
  19156. .afterStyles({
  19157. transform: 'translate3d(0, 0, 0)',
  19158. })
  19159. .keyframes([
  19160. { offset: 0, filter: 'contrast(0.85)', transform: finalTransform },
  19161. { offset: 1, filter: 'contrast(1)', transform: 'translateY(0) scale(1)' },
  19162. ]);
  19163. const shadowAnimation = createAnimation()
  19164. .addElement(presentingElRoot.querySelector('.modal-shadow'))
  19165. .afterStyles({
  19166. transform: 'translateY(0) scale(1)',
  19167. })
  19168. .keyframes([
  19169. { offset: 0, opacity: '0', transform: finalTransform },
  19170. { offset: 1, opacity: '1', transform: 'translateY(0) scale(1)' },
  19171. ]);
  19172. baseAnimation.addAnimation([presentingAnimation, shadowAnimation]);
  19173. }
  19174. }
  19175. }
  19176. else {
  19177. baseAnimation.addAnimation(backdropAnimation);
  19178. }
  19179. return baseAnimation;
  19180. };
  19181. const createEnterAnimation = () => {
  19182. const backdropAnimation = createAnimation()
  19183. .fromTo('opacity', 0.01, 'var(--backdrop-opacity)')
  19184. .beforeStyles({
  19185. 'pointer-events': 'none',
  19186. })
  19187. .afterClearStyles(['pointer-events']);
  19188. const wrapperAnimation = createAnimation().keyframes([
  19189. { offset: 0, opacity: 0.01, transform: 'translateY(40px)' },
  19190. { offset: 1, opacity: 1, transform: `translateY(0px)` },
  19191. ]);
  19192. return { backdropAnimation, wrapperAnimation, contentAnimation: undefined };
  19193. };
  19194. /**
  19195. * Md Modal Enter Animation
  19196. */
  19197. const mdEnterAnimation$2 = (baseEl, opts) => {
  19198. const { currentBreakpoint, expandToScroll } = opts;
  19199. const root = getElementRoot(baseEl);
  19200. const { wrapperAnimation, backdropAnimation, contentAnimation } = currentBreakpoint !== undefined ? createSheetEnterAnimation(opts) : createEnterAnimation();
  19201. backdropAnimation.addElement(root.querySelector('ion-backdrop'));
  19202. wrapperAnimation.addElement(root.querySelector('.modal-wrapper'));
  19203. // The content animation is only added if scrolling is enabled for
  19204. // all the breakpoints.
  19205. expandToScroll && (contentAnimation === null || contentAnimation === void 0 ? void 0 : contentAnimation.addElement(baseEl.querySelector('.ion-page')));
  19206. const baseAnimation = createAnimation()
  19207. .addElement(baseEl)
  19208. .easing('cubic-bezier(0.36,0.66,0.04,1)')
  19209. .duration(280)
  19210. .addAnimation([backdropAnimation, wrapperAnimation])
  19211. .beforeAddWrite(() => {
  19212. if (expandToScroll) {
  19213. // Scroll can only be done when the modal is fully expanded.
  19214. return;
  19215. }
  19216. /**
  19217. * There are some browsers that causes flickering when
  19218. * dragging the content when scroll is enabled at every
  19219. * breakpoint. This is due to the wrapper element being
  19220. * transformed off the screen and having a snap animation.
  19221. *
  19222. * A workaround is to clone the footer element and append
  19223. * it outside of the wrapper element. This way, the footer
  19224. * is still visible and the drag can be done without
  19225. * flickering. The original footer is hidden until the modal
  19226. * is dismissed. This maintains the animation of the footer
  19227. * when the modal is dismissed.
  19228. *
  19229. * The workaround needs to be done before the animation starts
  19230. * so there are no flickering issues.
  19231. */
  19232. const ionFooter = baseEl.querySelector('ion-footer');
  19233. /**
  19234. * This check is needed to prevent more than one footer
  19235. * from being appended to the shadow root.
  19236. * Otherwise, iOS and MD enter animations would append
  19237. * the footer twice.
  19238. */
  19239. const ionFooterAlreadyAppended = baseEl.shadowRoot.querySelector('ion-footer');
  19240. if (ionFooter && !ionFooterAlreadyAppended) {
  19241. const footerHeight = ionFooter.clientHeight;
  19242. const clonedFooter = ionFooter.cloneNode(true);
  19243. baseEl.shadowRoot.appendChild(clonedFooter);
  19244. ionFooter.style.setProperty('display', 'none');
  19245. ionFooter.setAttribute('aria-hidden', 'true');
  19246. // Padding is added to prevent some content from being hidden.
  19247. const page = baseEl.querySelector('.ion-page');
  19248. page.style.setProperty('padding-bottom', `${footerHeight}px`);
  19249. }
  19250. });
  19251. if (contentAnimation) {
  19252. baseAnimation.addAnimation(contentAnimation);
  19253. }
  19254. return baseAnimation;
  19255. };
  19256. const createLeaveAnimation = () => {
  19257. const backdropAnimation = createAnimation().fromTo('opacity', 'var(--backdrop-opacity)', 0);
  19258. const wrapperAnimation = createAnimation().keyframes([
  19259. { offset: 0, opacity: 0.99, transform: `translateY(0px)` },
  19260. { offset: 1, opacity: 0, transform: 'translateY(40px)' },
  19261. ]);
  19262. return { backdropAnimation, wrapperAnimation };
  19263. };
  19264. /**
  19265. * Md Modal Leave Animation
  19266. */
  19267. const mdLeaveAnimation$2 = (baseEl, opts) => {
  19268. const { currentBreakpoint, expandToScroll } = opts;
  19269. const root = getElementRoot(baseEl);
  19270. const { wrapperAnimation, backdropAnimation } = currentBreakpoint !== undefined ? createSheetLeaveAnimation(opts) : createLeaveAnimation();
  19271. backdropAnimation.addElement(root.querySelector('ion-backdrop'));
  19272. wrapperAnimation.addElement(root.querySelector('.modal-wrapper'));
  19273. const baseAnimation = createAnimation()
  19274. .easing('cubic-bezier(0.47,0,0.745,0.715)')
  19275. .duration(200)
  19276. .addAnimation([backdropAnimation, wrapperAnimation])
  19277. .beforeAddWrite(() => {
  19278. if (expandToScroll) {
  19279. // Scroll can only be done when the modal is fully expanded.
  19280. return;
  19281. }
  19282. /**
  19283. * If expandToScroll is disabled, we need to swap
  19284. * the visibility to the original, so the footer
  19285. * dismisses with the modal and doesn't stay
  19286. * until the modal is removed from the DOM.
  19287. */
  19288. const ionFooter = baseEl.querySelector('ion-footer');
  19289. if (ionFooter) {
  19290. const clonedFooter = baseEl.shadowRoot.querySelector('ion-footer');
  19291. ionFooter.style.removeProperty('display');
  19292. ionFooter.removeAttribute('aria-hidden');
  19293. clonedFooter.style.setProperty('display', 'none');
  19294. clonedFooter.setAttribute('aria-hidden', 'true');
  19295. const page = baseEl.querySelector('.ion-page');
  19296. page.style.removeProperty('padding-bottom');
  19297. }
  19298. });
  19299. return baseAnimation;
  19300. };
  19301. const createSheetGesture = (baseEl, backdropEl, wrapperEl, initialBreakpoint, backdropBreakpoint, animation, breakpoints = [], expandToScroll, getCurrentBreakpoint, onDismiss, onBreakpointChange) => {
  19302. // Defaults for the sheet swipe animation
  19303. const defaultBackdrop = [
  19304. { offset: 0, opacity: 'var(--backdrop-opacity)' },
  19305. { offset: 1, opacity: 0.01 },
  19306. ];
  19307. const customBackdrop = [
  19308. { offset: 0, opacity: 'var(--backdrop-opacity)' },
  19309. { offset: 1 - backdropBreakpoint, opacity: 0 },
  19310. { offset: 1, opacity: 0 },
  19311. ];
  19312. const SheetDefaults = {
  19313. WRAPPER_KEYFRAMES: [
  19314. { offset: 0, transform: 'translateY(0%)' },
  19315. { offset: 1, transform: 'translateY(100%)' },
  19316. ],
  19317. BACKDROP_KEYFRAMES: backdropBreakpoint !== 0 ? customBackdrop : defaultBackdrop,
  19318. CONTENT_KEYFRAMES: [
  19319. { offset: 0, maxHeight: '100%' },
  19320. { offset: 1, maxHeight: '0%' },
  19321. ],
  19322. };
  19323. const contentEl = baseEl.querySelector('ion-content');
  19324. const height = wrapperEl.clientHeight;
  19325. let currentBreakpoint = initialBreakpoint;
  19326. let offset = 0;
  19327. let canDismissBlocksGesture = false;
  19328. let cachedScrollEl = null;
  19329. const canDismissMaxStep = 0.95;
  19330. const maxBreakpoint = breakpoints[breakpoints.length - 1];
  19331. const minBreakpoint = breakpoints[0];
  19332. const wrapperAnimation = animation.childAnimations.find((ani) => ani.id === 'wrapperAnimation');
  19333. const backdropAnimation = animation.childAnimations.find((ani) => ani.id === 'backdropAnimation');
  19334. const contentAnimation = animation.childAnimations.find((ani) => ani.id === 'contentAnimation');
  19335. const enableBackdrop = () => {
  19336. baseEl.style.setProperty('pointer-events', 'auto');
  19337. backdropEl.style.setProperty('pointer-events', 'auto');
  19338. /**
  19339. * When the backdrop is enabled, elements such
  19340. * as inputs should not be focusable outside
  19341. * the sheet.
  19342. */
  19343. baseEl.classList.remove(FOCUS_TRAP_DISABLE_CLASS);
  19344. };
  19345. const disableBackdrop = () => {
  19346. baseEl.style.setProperty('pointer-events', 'none');
  19347. backdropEl.style.setProperty('pointer-events', 'none');
  19348. /**
  19349. * When the backdrop is enabled, elements such
  19350. * as inputs should not be focusable outside
  19351. * the sheet.
  19352. * Adding this class disables focus trapping
  19353. * for the sheet temporarily.
  19354. */
  19355. baseEl.classList.add(FOCUS_TRAP_DISABLE_CLASS);
  19356. };
  19357. /**
  19358. * Toggles the visible modal footer when `expandToScroll` is disabled.
  19359. * @param footer The footer to show.
  19360. */
  19361. const swapFooterVisibility = (footer) => {
  19362. const originalFooter = baseEl.querySelector('ion-footer');
  19363. if (!originalFooter) {
  19364. return;
  19365. }
  19366. const clonedFooter = wrapperEl.nextElementSibling;
  19367. const footerToHide = footer === 'original' ? clonedFooter : originalFooter;
  19368. const footerToShow = footer === 'original' ? originalFooter : clonedFooter;
  19369. footerToShow.style.removeProperty('display');
  19370. footerToShow.removeAttribute('aria-hidden');
  19371. const page = baseEl.querySelector('.ion-page');
  19372. if (footer === 'original') {
  19373. page.style.removeProperty('padding-bottom');
  19374. }
  19375. else {
  19376. const pagePadding = footerToShow.clientHeight;
  19377. page.style.setProperty('padding-bottom', `${pagePadding}px`);
  19378. }
  19379. footerToHide.style.setProperty('display', 'none');
  19380. footerToHide.setAttribute('aria-hidden', 'true');
  19381. };
  19382. /**
  19383. * After the entering animation completes,
  19384. * we need to set the animation to go from
  19385. * offset 0 to offset 1 so that users can
  19386. * swipe in any direction. We then set the
  19387. * animation offset to the current breakpoint
  19388. * so there is no flickering.
  19389. */
  19390. if (wrapperAnimation && backdropAnimation) {
  19391. wrapperAnimation.keyframes([...SheetDefaults.WRAPPER_KEYFRAMES]);
  19392. backdropAnimation.keyframes([...SheetDefaults.BACKDROP_KEYFRAMES]);
  19393. contentAnimation === null || contentAnimation === void 0 ? void 0 : contentAnimation.keyframes([...SheetDefaults.CONTENT_KEYFRAMES]);
  19394. animation.progressStart(true, 1 - currentBreakpoint);
  19395. /**
  19396. * If backdrop is not enabled, then content
  19397. * behind modal should be clickable. To do this, we need
  19398. * to remove pointer-events from ion-modal as a whole.
  19399. * ion-backdrop and .modal-wrapper always have pointer-events: auto
  19400. * applied, so the modal content can still be interacted with.
  19401. */
  19402. const shouldEnableBackdrop = currentBreakpoint > backdropBreakpoint;
  19403. if (shouldEnableBackdrop) {
  19404. enableBackdrop();
  19405. }
  19406. else {
  19407. disableBackdrop();
  19408. }
  19409. }
  19410. if (contentEl && currentBreakpoint !== maxBreakpoint && expandToScroll) {
  19411. contentEl.scrollY = false;
  19412. }
  19413. const canStart = (detail) => {
  19414. /**
  19415. * If we are swiping on the content, swiping should only be possible if the content
  19416. * is scrolled all the way to the top so that we do not interfere with scrolling.
  19417. *
  19418. * We cannot assume that the `ion-content` target will remain consistent between swipes.
  19419. * For example, when using ion-nav within a modal it is possible to swipe, push a view,
  19420. * and then swipe again. The target content will not be the same between swipes.
  19421. */
  19422. const contentEl = findClosestIonContent(detail.event.target);
  19423. currentBreakpoint = getCurrentBreakpoint();
  19424. /**
  19425. * If `expandToScroll` is disabled, we should not allow the swipe gesture
  19426. * to start if the content is not scrolled to the top.
  19427. */
  19428. if (!expandToScroll && contentEl) {
  19429. const scrollEl = isIonContent(contentEl) ? getElementRoot(contentEl).querySelector('.inner-scroll') : contentEl;
  19430. return scrollEl.scrollTop === 0;
  19431. }
  19432. if (currentBreakpoint === 1 && contentEl) {
  19433. /**
  19434. * The modal should never swipe to close on the content with a refresher.
  19435. * Note 1: We cannot solve this by making this gesture have a higher priority than
  19436. * the refresher gesture as the iOS native refresh gesture uses a scroll listener in
  19437. * addition to a gesture.
  19438. *
  19439. * Note 2: Do not use getScrollElement here because we need this to be a synchronous
  19440. * operation, and getScrollElement is asynchronous.
  19441. */
  19442. const scrollEl = isIonContent(contentEl) ? getElementRoot(contentEl).querySelector('.inner-scroll') : contentEl;
  19443. const hasRefresherInContent = !!contentEl.querySelector('ion-refresher');
  19444. return !hasRefresherInContent && scrollEl.scrollTop === 0;
  19445. }
  19446. return true;
  19447. };
  19448. const onStart = (detail) => {
  19449. /**
  19450. * If canDismiss is anything other than `true`
  19451. * then users should be able to swipe down
  19452. * until a threshold is hit. At that point,
  19453. * the card modal should not proceed any further.
  19454. *
  19455. * canDismiss is never fired via gesture if there is
  19456. * no 0 breakpoint. However, it can be fired if the user
  19457. * presses Esc or the hardware back button.
  19458. * TODO (FW-937)
  19459. * Remove undefined check
  19460. */
  19461. canDismissBlocksGesture = baseEl.canDismiss !== undefined && baseEl.canDismiss !== true && minBreakpoint === 0;
  19462. /**
  19463. * Cache the scroll element reference when the gesture starts,
  19464. * this allows us to avoid querying the DOM for the target in onMove,
  19465. * which would impact performance significantly.
  19466. */
  19467. if (!expandToScroll) {
  19468. const targetEl = findClosestIonContent(detail.event.target);
  19469. cachedScrollEl =
  19470. targetEl && isIonContent(targetEl) ? getElementRoot(targetEl).querySelector('.inner-scroll') : targetEl;
  19471. }
  19472. /**
  19473. * If expandToScroll is disabled, we need to swap
  19474. * the footer visibility to the original, so if the modal
  19475. * is dismissed, the footer dismisses with the modal
  19476. * and doesn't stay on the screen after the modal is gone.
  19477. */
  19478. if (!expandToScroll) {
  19479. swapFooterVisibility('original');
  19480. }
  19481. /**
  19482. * If we are pulling down, then it is possible we are pulling on the content.
  19483. * We do not want scrolling to happen at the same time as the gesture.
  19484. */
  19485. if (detail.deltaY > 0 && contentEl) {
  19486. contentEl.scrollY = false;
  19487. }
  19488. raf(() => {
  19489. /**
  19490. * Dismisses the open keyboard when the sheet drag gesture is started.
  19491. * Sets the focus onto the modal element.
  19492. */
  19493. baseEl.focus();
  19494. });
  19495. animation.progressStart(true, 1 - currentBreakpoint);
  19496. };
  19497. const onMove = (detail) => {
  19498. /**
  19499. * If `expandToScroll` is disabled, and an upwards swipe gesture is done within
  19500. * the scrollable content, we should not allow the swipe gesture to continue.
  19501. */
  19502. if (!expandToScroll && detail.deltaY <= 0 && cachedScrollEl) {
  19503. return;
  19504. }
  19505. /**
  19506. * If we are pulling down, then it is possible we are pulling on the content.
  19507. * We do not want scrolling to happen at the same time as the gesture.
  19508. * This accounts for when the user scrolls down, scrolls all the way up, and then
  19509. * pulls down again such that the modal should start to move.
  19510. */
  19511. if (detail.deltaY > 0 && contentEl) {
  19512. contentEl.scrollY = false;
  19513. }
  19514. /**
  19515. * Given the change in gesture position on the Y axis,
  19516. * compute where the offset of the animation should be
  19517. * relative to where the user dragged.
  19518. */
  19519. const initialStep = 1 - currentBreakpoint;
  19520. const secondToLastBreakpoint = breakpoints.length > 1 ? 1 - breakpoints[1] : undefined;
  19521. const step = initialStep + detail.deltaY / height;
  19522. const isAttemptingDismissWithCanDismiss = secondToLastBreakpoint !== undefined && step >= secondToLastBreakpoint && canDismissBlocksGesture;
  19523. /**
  19524. * If we are blocking the gesture from dismissing,
  19525. * set the max step value so that the sheet cannot be
  19526. * completely hidden.
  19527. */
  19528. const maxStep = isAttemptingDismissWithCanDismiss ? canDismissMaxStep : 0.9999;
  19529. /**
  19530. * If we are blocking the gesture from
  19531. * dismissing, calculate the spring modifier value
  19532. * this will be added to the starting breakpoint
  19533. * value to give the gesture a spring-like feeling.
  19534. * Note that when isAttemptingDismissWithCanDismiss is true,
  19535. * the modifier is always added to the breakpoint that
  19536. * appears right after the 0 breakpoint.
  19537. *
  19538. * Note that this modifier is essentially the progression
  19539. * between secondToLastBreakpoint and maxStep which is
  19540. * why we subtract secondToLastBreakpoint. This lets us get
  19541. * the result as a value from 0 to 1.
  19542. */
  19543. const processedStep = isAttemptingDismissWithCanDismiss && secondToLastBreakpoint !== undefined
  19544. ? secondToLastBreakpoint +
  19545. calculateSpringStep((step - secondToLastBreakpoint) / (maxStep - secondToLastBreakpoint))
  19546. : step;
  19547. offset = clamp(0.0001, processedStep, maxStep);
  19548. animation.progressStep(offset);
  19549. };
  19550. const onEnd = (detail) => {
  19551. /**
  19552. * If expandToScroll is disabled, we should not allow the moveSheetToBreakpoint
  19553. * function to be called if the user is trying to swipe content upwards and the content
  19554. * is not scrolled to the top.
  19555. */
  19556. if (!expandToScroll && detail.deltaY <= 0 && cachedScrollEl && cachedScrollEl.scrollTop > 0) {
  19557. return;
  19558. }
  19559. /**
  19560. * When the gesture releases, we need to determine
  19561. * the closest breakpoint to snap to.
  19562. */
  19563. const velocity = detail.velocityY;
  19564. const threshold = (detail.deltaY + velocity * 350) / height;
  19565. const diff = currentBreakpoint - threshold;
  19566. const closest = breakpoints.reduce((a, b) => {
  19567. return Math.abs(b - diff) < Math.abs(a - diff) ? b : a;
  19568. });
  19569. moveSheetToBreakpoint({
  19570. breakpoint: closest,
  19571. breakpointOffset: offset,
  19572. canDismiss: canDismissBlocksGesture,
  19573. /**
  19574. * The swipe is user-driven, so we should
  19575. * always animate when the gesture ends.
  19576. */
  19577. animated: true,
  19578. });
  19579. };
  19580. const moveSheetToBreakpoint = (options) => {
  19581. const { breakpoint, canDismiss, breakpointOffset, animated } = options;
  19582. /**
  19583. * canDismiss should only prevent snapping
  19584. * when users are trying to dismiss. If canDismiss
  19585. * is present but the user is trying to swipe upwards,
  19586. * we should allow that to happen,
  19587. */
  19588. const shouldPreventDismiss = canDismiss && breakpoint === 0;
  19589. const snapToBreakpoint = shouldPreventDismiss ? currentBreakpoint : breakpoint;
  19590. const shouldRemainOpen = snapToBreakpoint !== 0;
  19591. currentBreakpoint = 0;
  19592. /**
  19593. * Update the animation so that it plays from
  19594. * the last offset to the closest snap point.
  19595. */
  19596. if (wrapperAnimation && backdropAnimation) {
  19597. wrapperAnimation.keyframes([
  19598. { offset: 0, transform: `translateY(${breakpointOffset * 100}%)` },
  19599. { offset: 1, transform: `translateY(${(1 - snapToBreakpoint) * 100}%)` },
  19600. ]);
  19601. backdropAnimation.keyframes([
  19602. {
  19603. offset: 0,
  19604. opacity: `calc(var(--backdrop-opacity) * ${getBackdropValueForSheet(1 - breakpointOffset, backdropBreakpoint)})`,
  19605. },
  19606. {
  19607. offset: 1,
  19608. opacity: `calc(var(--backdrop-opacity) * ${getBackdropValueForSheet(snapToBreakpoint, backdropBreakpoint)})`,
  19609. },
  19610. ]);
  19611. if (contentAnimation) {
  19612. /**
  19613. * The modal content should scroll at any breakpoint when expandToScroll
  19614. * is disabled. In order to do this, the content needs to be completely
  19615. * viewable so scrolling can access everything. Otherwise, the default
  19616. * behavior would show the content off the screen and only allow
  19617. * scrolling when the sheet is fully expanded.
  19618. */
  19619. contentAnimation.keyframes([
  19620. { offset: 0, maxHeight: `${(1 - breakpointOffset) * 100}%` },
  19621. { offset: 1, maxHeight: `${snapToBreakpoint * 100}%` },
  19622. ]);
  19623. }
  19624. animation.progressStep(0);
  19625. }
  19626. /**
  19627. * Gesture should remain disabled until the
  19628. * snapping animation completes.
  19629. */
  19630. gesture.enable(false);
  19631. /**
  19632. * If expandToScroll is disabled, we need to swap
  19633. * the footer visibility to the cloned one so the footer
  19634. * doesn't flicker when the sheet's height is animated.
  19635. */
  19636. if (!expandToScroll && shouldRemainOpen) {
  19637. swapFooterVisibility('cloned');
  19638. }
  19639. if (shouldPreventDismiss) {
  19640. handleCanDismiss(baseEl, animation);
  19641. }
  19642. else if (!shouldRemainOpen) {
  19643. onDismiss();
  19644. }
  19645. /**
  19646. * Enables scrolling immediately if the sheet is about to fully expand
  19647. * or if it allows scrolling at any breakpoint. Without this, there would
  19648. * be a ~500ms delay while the modal animation completes, causing a
  19649. * noticeable lag. Native iOS allows scrolling as soon as the gesture is
  19650. * released, so we align with that behavior.
  19651. */
  19652. if (contentEl && (snapToBreakpoint === breakpoints[breakpoints.length - 1] || !expandToScroll)) {
  19653. contentEl.scrollY = true;
  19654. }
  19655. return new Promise((resolve) => {
  19656. animation
  19657. .onFinish(() => {
  19658. if (shouldRemainOpen) {
  19659. /**
  19660. * Once the snapping animation completes,
  19661. * we need to reset the animation to go
  19662. * from 0 to 1 so users can swipe in any direction.
  19663. * We then set the animation offset to the current
  19664. * breakpoint so that it starts at the snapped position.
  19665. */
  19666. if (wrapperAnimation && backdropAnimation) {
  19667. raf(() => {
  19668. wrapperAnimation.keyframes([...SheetDefaults.WRAPPER_KEYFRAMES]);
  19669. backdropAnimation.keyframes([...SheetDefaults.BACKDROP_KEYFRAMES]);
  19670. contentAnimation === null || contentAnimation === void 0 ? void 0 : contentAnimation.keyframes([...SheetDefaults.CONTENT_KEYFRAMES]);
  19671. animation.progressStart(true, 1 - snapToBreakpoint);
  19672. currentBreakpoint = snapToBreakpoint;
  19673. onBreakpointChange(currentBreakpoint);
  19674. /**
  19675. * Backdrop should become enabled
  19676. * after the backdropBreakpoint value
  19677. */
  19678. const shouldEnableBackdrop = currentBreakpoint > backdropBreakpoint;
  19679. if (shouldEnableBackdrop) {
  19680. enableBackdrop();
  19681. }
  19682. else {
  19683. disableBackdrop();
  19684. }
  19685. gesture.enable(true);
  19686. resolve();
  19687. });
  19688. }
  19689. else {
  19690. gesture.enable(true);
  19691. resolve();
  19692. }
  19693. }
  19694. else {
  19695. resolve();
  19696. }
  19697. /**
  19698. * This must be a one time callback
  19699. * otherwise a new callback will
  19700. * be added every time onEnd runs.
  19701. */
  19702. }, { oneTimeCallback: true })
  19703. .progressEnd(1, 0, animated ? 500 : 0);
  19704. });
  19705. };
  19706. const gesture = createGesture({
  19707. el: wrapperEl,
  19708. gestureName: 'modalSheet',
  19709. gesturePriority: 40,
  19710. direction: 'y',
  19711. threshold: 10,
  19712. canStart,
  19713. onStart,
  19714. onMove,
  19715. onEnd,
  19716. });
  19717. return {
  19718. gesture,
  19719. moveSheetToBreakpoint,
  19720. };
  19721. };
  19722. 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}";
  19723. var IonModalIosStyle0 = modalIosCss;
  19724. 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}";
  19725. var IonModalMdStyle0 = modalMdCss;
  19726. // TODO(FW-2832): types
  19727. /**
  19728. * @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
  19729. *
  19730. * @slot - Content is placed inside of the `.modal-content` element.
  19731. *
  19732. * @part backdrop - The `ion-backdrop` element.
  19733. * @part content - The wrapper element for the default slot.
  19734. * @part handle - The handle that is displayed at the top of the sheet modal when `handle="true"`.
  19735. */
  19736. class Modal {
  19737. constructor(hostRef) {
  19738. registerInstance(this, hostRef);
  19739. this.didPresent = createEvent(this, "ionModalDidPresent", 7);
  19740. this.willPresent = createEvent(this, "ionModalWillPresent", 7);
  19741. this.willDismiss = createEvent(this, "ionModalWillDismiss", 7);
  19742. this.didDismiss = createEvent(this, "ionModalDidDismiss", 7);
  19743. this.ionBreakpointDidChange = createEvent(this, "ionBreakpointDidChange", 7);
  19744. this.didPresentShorthand = createEvent(this, "didPresent", 7);
  19745. this.willPresentShorthand = createEvent(this, "willPresent", 7);
  19746. this.willDismissShorthand = createEvent(this, "willDismiss", 7);
  19747. this.didDismissShorthand = createEvent(this, "didDismiss", 7);
  19748. this.ionMount = createEvent(this, "ionMount", 7);
  19749. this.lockController = createLockController();
  19750. this.triggerController = createTriggerController();
  19751. this.coreDelegate = CoreDelegate();
  19752. this.isSheetModal = false;
  19753. this.inheritedAttributes = {};
  19754. this.inline = false;
  19755. // Whether or not modal is being dismissed via gesture
  19756. this.gestureAnimationDismissing = false;
  19757. this.onHandleClick = () => {
  19758. const { sheetTransition, handleBehavior } = this;
  19759. if (handleBehavior !== 'cycle' || sheetTransition !== undefined) {
  19760. /**
  19761. * The sheet modal should not advance to the next breakpoint
  19762. * if the handle behavior is not `cycle` or if the handle
  19763. * is clicked while the sheet is moving to a breakpoint.
  19764. */
  19765. return;
  19766. }
  19767. this.moveToNextBreakpoint();
  19768. };
  19769. this.onBackdropTap = () => {
  19770. const { sheetTransition } = this;
  19771. if (sheetTransition !== undefined) {
  19772. /**
  19773. * When the handle is double clicked at the largest breakpoint,
  19774. * it will start to move to the first breakpoint. While transitioning,
  19775. * the backdrop will often receive the second click. We prevent the
  19776. * backdrop from dismissing the modal while moving between breakpoints.
  19777. */
  19778. return;
  19779. }
  19780. this.dismiss(undefined, BACKDROP);
  19781. };
  19782. this.onLifecycle = (modalEvent) => {
  19783. const el = this.usersElement;
  19784. const name = LIFECYCLE_MAP$1[modalEvent.type];
  19785. if (el && name) {
  19786. const ev = new CustomEvent(name, {
  19787. bubbles: false,
  19788. cancelable: false,
  19789. detail: modalEvent.detail,
  19790. });
  19791. el.dispatchEvent(ev);
  19792. }
  19793. };
  19794. this.presented = false;
  19795. this.hasController = false;
  19796. this.overlayIndex = undefined;
  19797. this.delegate = undefined;
  19798. this.keyboardClose = true;
  19799. this.enterAnimation = undefined;
  19800. this.leaveAnimation = undefined;
  19801. this.breakpoints = undefined;
  19802. this.expandToScroll = true;
  19803. this.initialBreakpoint = undefined;
  19804. this.backdropBreakpoint = 0;
  19805. this.handle = undefined;
  19806. this.handleBehavior = 'none';
  19807. this.component = undefined;
  19808. this.componentProps = undefined;
  19809. this.cssClass = undefined;
  19810. this.backdropDismiss = true;
  19811. this.showBackdrop = true;
  19812. this.animated = true;
  19813. this.presentingElement = undefined;
  19814. this.htmlAttributes = undefined;
  19815. this.isOpen = false;
  19816. this.trigger = undefined;
  19817. this.keepContentsMounted = false;
  19818. this.focusTrap = true;
  19819. this.canDismiss = true;
  19820. }
  19821. onIsOpenChange(newValue, oldValue) {
  19822. if (newValue === true && oldValue === false) {
  19823. this.present();
  19824. }
  19825. else if (newValue === false && oldValue === true) {
  19826. this.dismiss();
  19827. }
  19828. }
  19829. triggerChanged() {
  19830. const { trigger, el, triggerController } = this;
  19831. if (trigger) {
  19832. triggerController.addClickListener(el, trigger);
  19833. }
  19834. }
  19835. breakpointsChanged(breakpoints) {
  19836. if (breakpoints !== undefined) {
  19837. this.sortedBreakpoints = breakpoints.sort((a, b) => a - b);
  19838. }
  19839. }
  19840. connectedCallback() {
  19841. const { el } = this;
  19842. prepareOverlay(el);
  19843. this.triggerChanged();
  19844. }
  19845. disconnectedCallback() {
  19846. this.triggerController.removeClickListener();
  19847. }
  19848. componentWillLoad() {
  19849. var _a;
  19850. const { breakpoints, initialBreakpoint, el, htmlAttributes } = this;
  19851. const isSheetModal = (this.isSheetModal = breakpoints !== undefined && initialBreakpoint !== undefined);
  19852. const attributesToInherit = ['aria-label', 'role'];
  19853. this.inheritedAttributes = inheritAttributes$1(el, attributesToInherit);
  19854. /**
  19855. * When using a controller modal you can set attributes
  19856. * using the htmlAttributes property. Since the above attributes
  19857. * need to be inherited inside of the modal, we need to look
  19858. * and see if these attributes are being set via htmlAttributes.
  19859. *
  19860. * We could alternatively move this to componentDidLoad to simplify the work
  19861. * here, but we'd then need to make inheritedAttributes a State variable,
  19862. * thus causing another render to always happen after the first render.
  19863. */
  19864. if (htmlAttributes !== undefined) {
  19865. attributesToInherit.forEach((attribute) => {
  19866. const attributeValue = htmlAttributes[attribute];
  19867. if (attributeValue) {
  19868. /**
  19869. * If an attribute we need to inherit was
  19870. * set using htmlAttributes then add it to
  19871. * inheritedAttributes and remove it from htmlAttributes.
  19872. * This ensures the attribute is inherited and not
  19873. * set on the host.
  19874. *
  19875. * In this case, if an inherited attribute is set
  19876. * on the host element and using htmlAttributes then
  19877. * htmlAttributes wins, but that's not a pattern that we recommend.
  19878. * The only time you'd need htmlAttributes is when using modalController.
  19879. */
  19880. this.inheritedAttributes = Object.assign(Object.assign({}, this.inheritedAttributes), { [attribute]: htmlAttributes[attribute] });
  19881. delete htmlAttributes[attribute];
  19882. }
  19883. });
  19884. }
  19885. if (isSheetModal) {
  19886. this.currentBreakpoint = this.initialBreakpoint;
  19887. }
  19888. if (breakpoints !== undefined && initialBreakpoint !== undefined && !breakpoints.includes(initialBreakpoint)) {
  19889. printIonWarning('[ion-modal] - Your breakpoints array must include the initialBreakpoint value.');
  19890. }
  19891. if (!((_a = this.htmlAttributes) === null || _a === void 0 ? void 0 : _a.id)) {
  19892. setOverlayId(this.el);
  19893. }
  19894. }
  19895. componentDidLoad() {
  19896. /**
  19897. * If modal was rendered with isOpen="true"
  19898. * then we should open modal immediately.
  19899. */
  19900. if (this.isOpen === true) {
  19901. raf(() => this.present());
  19902. }
  19903. this.breakpointsChanged(this.breakpoints);
  19904. /**
  19905. * When binding values in frameworks such as Angular
  19906. * it is possible for the value to be set after the Web Component
  19907. * initializes but before the value watcher is set up in Stencil.
  19908. * As a result, the watcher callback may not be fired.
  19909. * We work around this by manually calling the watcher
  19910. * callback when the component has loaded and the watcher
  19911. * is configured.
  19912. */
  19913. this.triggerChanged();
  19914. }
  19915. /**
  19916. * Determines whether or not an overlay
  19917. * is being used inline or via a controller/JS
  19918. * and returns the correct delegate.
  19919. * By default, subsequent calls to getDelegate
  19920. * will use a cached version of the delegate.
  19921. * This is useful for calling dismiss after
  19922. * present so that the correct delegate is given.
  19923. */
  19924. getDelegate(force = false) {
  19925. if (this.workingDelegate && !force) {
  19926. return {
  19927. delegate: this.workingDelegate,
  19928. inline: this.inline,
  19929. };
  19930. }
  19931. /**
  19932. * If using overlay inline
  19933. * we potentially need to use the coreDelegate
  19934. * so that this works in vanilla JS apps.
  19935. * If a developer has presented this component
  19936. * via a controller, then we can assume
  19937. * the component is already in the
  19938. * correct place.
  19939. */
  19940. const parentEl = this.el.parentNode;
  19941. const inline = (this.inline = parentEl !== null && !this.hasController);
  19942. const delegate = (this.workingDelegate = inline ? this.delegate || this.coreDelegate : this.delegate);
  19943. return { inline, delegate };
  19944. }
  19945. /**
  19946. * Determines whether or not the
  19947. * modal is allowed to dismiss based
  19948. * on the state of the canDismiss prop.
  19949. */
  19950. async checkCanDismiss(data, role) {
  19951. const { canDismiss } = this;
  19952. if (typeof canDismiss === 'function') {
  19953. return canDismiss(data, role);
  19954. }
  19955. return canDismiss;
  19956. }
  19957. /**
  19958. * Present the modal overlay after it has been created.
  19959. */
  19960. async present() {
  19961. const unlock = await this.lockController.lock();
  19962. if (this.presented) {
  19963. unlock();
  19964. return;
  19965. }
  19966. const { presentingElement, el } = this;
  19967. /**
  19968. * If the modal is presented multiple times (inline modals), we
  19969. * need to reset the current breakpoint to the initial breakpoint.
  19970. */
  19971. this.currentBreakpoint = this.initialBreakpoint;
  19972. const { inline, delegate } = this.getDelegate(true);
  19973. /**
  19974. * Emit ionMount so JS Frameworks have an opportunity
  19975. * to add the child component to the DOM. The child
  19976. * component will be assigned to this.usersElement below.
  19977. */
  19978. this.ionMount.emit();
  19979. this.usersElement = await attachComponent(delegate, el, this.component, ['ion-page'], this.componentProps, inline);
  19980. /**
  19981. * When using the lazy loaded build of Stencil, we need to wait
  19982. * for every Stencil component instance to be ready before presenting
  19983. * otherwise there can be a flash of unstyled content. With the
  19984. * custom elements bundle we need to wait for the JS framework
  19985. * mount the inner contents of the overlay otherwise WebKit may
  19986. * get the transition incorrect.
  19987. */
  19988. if (hasLazyBuild(el)) {
  19989. await deepReady(this.usersElement);
  19990. /**
  19991. * If keepContentsMounted="true" then the
  19992. * JS Framework has already mounted the inner
  19993. * contents so there is no need to wait.
  19994. * Otherwise, we need to wait for the JS
  19995. * Framework to mount the inner contents
  19996. * of this component.
  19997. */
  19998. }
  19999. else if (!this.keepContentsMounted) {
  20000. await waitForMount();
  20001. }
  20002. writeTask(() => this.el.classList.add('show-modal'));
  20003. const hasCardModal = presentingElement !== undefined;
  20004. /**
  20005. * We need to change the status bar at the
  20006. * start of the animation so that it completes
  20007. * by the time the card animation is done.
  20008. */
  20009. if (hasCardModal && getIonMode$1(this) === 'ios') {
  20010. // Cache the original status bar color before the modal is presented
  20011. this.statusBarStyle = await StatusBar.getStyle();
  20012. setCardStatusBarDark();
  20013. }
  20014. await present(this, 'modalEnter', iosEnterAnimation$3, mdEnterAnimation$2, {
  20015. presentingEl: presentingElement,
  20016. currentBreakpoint: this.initialBreakpoint,
  20017. backdropBreakpoint: this.backdropBreakpoint,
  20018. expandToScroll: this.expandToScroll,
  20019. });
  20020. /* tslint:disable-next-line */
  20021. if (typeof window !== 'undefined') {
  20022. /**
  20023. * This needs to be setup before any
  20024. * non-transition async work so it can be dereferenced
  20025. * in the dismiss method. The dismiss method
  20026. * only waits for the entering transition
  20027. * to finish. It does not wait for all of the `present`
  20028. * method to resolve.
  20029. */
  20030. this.keyboardOpenCallback = () => {
  20031. if (this.gesture) {
  20032. /**
  20033. * When the native keyboard is opened and the webview
  20034. * is resized, the gesture implementation will become unresponsive
  20035. * and enter a free-scroll mode.
  20036. *
  20037. * When the keyboard is opened, we disable the gesture for
  20038. * a single frame and re-enable once the contents have repositioned
  20039. * from the keyboard placement.
  20040. */
  20041. this.gesture.enable(false);
  20042. raf(() => {
  20043. if (this.gesture) {
  20044. this.gesture.enable(true);
  20045. }
  20046. });
  20047. }
  20048. };
  20049. window.addEventListener(KEYBOARD_DID_OPEN, this.keyboardOpenCallback);
  20050. }
  20051. if (this.isSheetModal) {
  20052. this.initSheetGesture();
  20053. }
  20054. else if (hasCardModal) {
  20055. this.initSwipeToClose();
  20056. }
  20057. unlock();
  20058. }
  20059. initSwipeToClose() {
  20060. var _a;
  20061. if (getIonMode$1(this) !== 'ios') {
  20062. return;
  20063. }
  20064. const { el } = this;
  20065. // All of the elements needed for the swipe gesture
  20066. // should be in the DOM and referenced by now, except
  20067. // for the presenting el
  20068. const animationBuilder = this.leaveAnimation || config.get('modalLeave', iosLeaveAnimation$3);
  20069. const ani = (this.animation = animationBuilder(el, {
  20070. presentingEl: this.presentingElement,
  20071. expandToScroll: this.expandToScroll,
  20072. }));
  20073. const contentEl = findIonContent(el);
  20074. if (!contentEl) {
  20075. printIonContentErrorMsg(el);
  20076. return;
  20077. }
  20078. const statusBarStyle = (_a = this.statusBarStyle) !== null && _a !== void 0 ? _a : Style.Default;
  20079. this.gesture = createSwipeToCloseGesture(el, ani, statusBarStyle, () => {
  20080. /**
  20081. * While the gesture animation is finishing
  20082. * it is possible for a user to tap the backdrop.
  20083. * This would result in the dismiss animation
  20084. * being played again. Typically this is avoided
  20085. * by setting `presented = false` on the overlay
  20086. * component; however, we cannot do that here as
  20087. * that would prevent the element from being
  20088. * removed from the DOM.
  20089. */
  20090. this.gestureAnimationDismissing = true;
  20091. /**
  20092. * Reset the status bar style as the dismiss animation
  20093. * starts otherwise the status bar will be the wrong
  20094. * color for the duration of the dismiss animation.
  20095. * The dismiss method does this as well, but
  20096. * in this case it's only called once the animation
  20097. * has finished.
  20098. */
  20099. setCardStatusBarDefault(this.statusBarStyle);
  20100. this.animation.onFinish(async () => {
  20101. await this.dismiss(undefined, GESTURE);
  20102. this.gestureAnimationDismissing = false;
  20103. });
  20104. });
  20105. this.gesture.enable(true);
  20106. }
  20107. initSheetGesture() {
  20108. const { wrapperEl, initialBreakpoint, backdropBreakpoint } = this;
  20109. if (!wrapperEl || initialBreakpoint === undefined) {
  20110. return;
  20111. }
  20112. const animationBuilder = this.enterAnimation || config.get('modalEnter', iosEnterAnimation$3);
  20113. const ani = (this.animation = animationBuilder(this.el, {
  20114. presentingEl: this.presentingElement,
  20115. currentBreakpoint: initialBreakpoint,
  20116. backdropBreakpoint,
  20117. expandToScroll: this.expandToScroll,
  20118. }));
  20119. ani.progressStart(true, 1);
  20120. 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) => {
  20121. if (this.currentBreakpoint !== breakpoint) {
  20122. this.currentBreakpoint = breakpoint;
  20123. this.ionBreakpointDidChange.emit({ breakpoint });
  20124. }
  20125. });
  20126. this.gesture = gesture;
  20127. this.moveSheetToBreakpoint = moveSheetToBreakpoint;
  20128. this.gesture.enable(true);
  20129. }
  20130. sheetOnDismiss() {
  20131. /**
  20132. * While the gesture animation is finishing
  20133. * it is possible for a user to tap the backdrop.
  20134. * This would result in the dismiss animation
  20135. * being played again. Typically this is avoided
  20136. * by setting `presented = false` on the overlay
  20137. * component; however, we cannot do that here as
  20138. * that would prevent the element from being
  20139. * removed from the DOM.
  20140. */
  20141. this.gestureAnimationDismissing = true;
  20142. this.animation.onFinish(async () => {
  20143. this.currentBreakpoint = 0;
  20144. this.ionBreakpointDidChange.emit({ breakpoint: this.currentBreakpoint });
  20145. await this.dismiss(undefined, GESTURE);
  20146. this.gestureAnimationDismissing = false;
  20147. });
  20148. }
  20149. /**
  20150. * Dismiss the modal overlay after it has been presented.
  20151. *
  20152. * @param data Any data to emit in the dismiss events.
  20153. * @param role The role of the element that is dismissing the modal. For example, 'cancel' or 'backdrop'.
  20154. *
  20155. * This is a no-op if the overlay has not been presented yet. If you want
  20156. * to remove an overlay from the DOM that was never presented, use the
  20157. * [remove](https://developer.mozilla.org/en-US/docs/Web/API/Element/remove) method.
  20158. */
  20159. async dismiss(data, role) {
  20160. var _a;
  20161. if (this.gestureAnimationDismissing && role !== GESTURE) {
  20162. return false;
  20163. }
  20164. /**
  20165. * Because the canDismiss check below is async,
  20166. * we need to claim a lock before the check happens,
  20167. * in case the dismiss transition does run.
  20168. */
  20169. const unlock = await this.lockController.lock();
  20170. /**
  20171. * If a canDismiss handler is responsible
  20172. * for calling the dismiss method, we should
  20173. * not run the canDismiss check again.
  20174. */
  20175. if (role !== 'handler' && !(await this.checkCanDismiss(data, role))) {
  20176. unlock();
  20177. return false;
  20178. }
  20179. const { presentingElement } = this;
  20180. /**
  20181. * We need to start the status bar change
  20182. * before the animation so that the change
  20183. * finishes when the dismiss animation does.
  20184. */
  20185. const hasCardModal = presentingElement !== undefined;
  20186. if (hasCardModal && getIonMode$1(this) === 'ios') {
  20187. setCardStatusBarDefault(this.statusBarStyle);
  20188. }
  20189. /* tslint:disable-next-line */
  20190. if (typeof window !== 'undefined' && this.keyboardOpenCallback) {
  20191. window.removeEventListener(KEYBOARD_DID_OPEN, this.keyboardOpenCallback);
  20192. this.keyboardOpenCallback = undefined;
  20193. }
  20194. const dismissed = await dismiss(this, data, role, 'modalLeave', iosLeaveAnimation$3, mdLeaveAnimation$2, {
  20195. presentingEl: presentingElement,
  20196. currentBreakpoint: (_a = this.currentBreakpoint) !== null && _a !== void 0 ? _a : this.initialBreakpoint,
  20197. backdropBreakpoint: this.backdropBreakpoint,
  20198. expandToScroll: this.expandToScroll,
  20199. });
  20200. if (dismissed) {
  20201. const { delegate } = this.getDelegate();
  20202. await detachComponent(delegate, this.usersElement);
  20203. writeTask(() => this.el.classList.remove('show-modal'));
  20204. if (this.animation) {
  20205. this.animation.destroy();
  20206. }
  20207. if (this.gesture) {
  20208. this.gesture.destroy();
  20209. }
  20210. }
  20211. this.currentBreakpoint = undefined;
  20212. this.animation = undefined;
  20213. unlock();
  20214. return dismissed;
  20215. }
  20216. /**
  20217. * Returns a promise that resolves when the modal did dismiss.
  20218. */
  20219. onDidDismiss() {
  20220. return eventMethod(this.el, 'ionModalDidDismiss');
  20221. }
  20222. /**
  20223. * Returns a promise that resolves when the modal will dismiss.
  20224. */
  20225. onWillDismiss() {
  20226. return eventMethod(this.el, 'ionModalWillDismiss');
  20227. }
  20228. /**
  20229. * Move a sheet style modal to a specific breakpoint. The breakpoint value must
  20230. * be a value defined in your `breakpoints` array.
  20231. */
  20232. async setCurrentBreakpoint(breakpoint) {
  20233. if (!this.isSheetModal) {
  20234. printIonWarning('[ion-modal] - setCurrentBreakpoint is only supported on sheet modals.');
  20235. return;
  20236. }
  20237. if (!this.breakpoints.includes(breakpoint)) {
  20238. printIonWarning(`[ion-modal] - Attempted to set invalid breakpoint value ${breakpoint}. Please double check that the breakpoint value is part of your defined breakpoints.`);
  20239. return;
  20240. }
  20241. const { currentBreakpoint, moveSheetToBreakpoint, canDismiss, breakpoints, animated } = this;
  20242. if (currentBreakpoint === breakpoint) {
  20243. return;
  20244. }
  20245. if (moveSheetToBreakpoint) {
  20246. this.sheetTransition = moveSheetToBreakpoint({
  20247. breakpoint,
  20248. breakpointOffset: 1 - currentBreakpoint,
  20249. canDismiss: canDismiss !== undefined && canDismiss !== true && breakpoints[0] === 0,
  20250. animated,
  20251. });
  20252. await this.sheetTransition;
  20253. this.sheetTransition = undefined;
  20254. }
  20255. }
  20256. /**
  20257. * Returns the current breakpoint of a sheet style modal
  20258. */
  20259. async getCurrentBreakpoint() {
  20260. return this.currentBreakpoint;
  20261. }
  20262. async moveToNextBreakpoint() {
  20263. const { breakpoints, currentBreakpoint } = this;
  20264. if (!breakpoints || currentBreakpoint == null) {
  20265. /**
  20266. * If the modal does not have breakpoints and/or the current
  20267. * breakpoint is not set, we can't move to the next breakpoint.
  20268. */
  20269. return false;
  20270. }
  20271. const allowedBreakpoints = breakpoints.filter((b) => b !== 0);
  20272. const currentBreakpointIndex = allowedBreakpoints.indexOf(currentBreakpoint);
  20273. const nextBreakpointIndex = (currentBreakpointIndex + 1) % allowedBreakpoints.length;
  20274. const nextBreakpoint = allowedBreakpoints[nextBreakpointIndex];
  20275. /**
  20276. * Sets the current breakpoint to the next available breakpoint.
  20277. * If the current breakpoint is the last breakpoint, we set the current
  20278. * breakpoint to the first non-zero breakpoint to avoid dismissing the sheet.
  20279. */
  20280. await this.setCurrentBreakpoint(nextBreakpoint);
  20281. return true;
  20282. }
  20283. render() {
  20284. const { handle, isSheetModal, presentingElement, htmlAttributes, handleBehavior, inheritedAttributes, focusTrap, expandToScroll, } = this;
  20285. const showHandle = handle !== false && isSheetModal;
  20286. const mode = getIonMode$1(this);
  20287. const isCardModal = presentingElement !== undefined && mode === 'ios';
  20288. const isHandleCycle = handleBehavior === 'cycle';
  20289. return (hAsync(Host, Object.assign({ key: '0991b2e4e32da511e59fb1463b47e4ac1b86d1ca', "no-router": true, tabindex: "-1" }, htmlAttributes, { style: {
  20290. zIndex: `${20000 + this.overlayIndex}`,
  20291. }, 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',
  20292. /*
  20293. role and aria-modal must be used on the
  20294. same element. They must also be set inside the
  20295. shadow DOM otherwise ion-button will not be highlighted
  20296. when using VoiceOver: https://bugs.webkit.org/show_bug.cgi?id=247134
  20297. */
  20298. 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",
  20299. // Prevents the handle from receiving keyboard focus when it does not cycle
  20300. 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' }))));
  20301. }
  20302. get el() { return getElement(this); }
  20303. static get watchers() { return {
  20304. "isOpen": ["onIsOpenChange"],
  20305. "trigger": ["triggerChanged"]
  20306. }; }
  20307. static get style() { return {
  20308. ios: IonModalIosStyle0,
  20309. md: IonModalMdStyle0
  20310. }; }
  20311. static get cmpMeta() { return {
  20312. "$flags$": 41,
  20313. "$tagName$": "ion-modal",
  20314. "$members$": {
  20315. "hasController": [4, "has-controller"],
  20316. "overlayIndex": [2, "overlay-index"],
  20317. "delegate": [16],
  20318. "keyboardClose": [4, "keyboard-close"],
  20319. "enterAnimation": [16],
  20320. "leaveAnimation": [16],
  20321. "breakpoints": [16],
  20322. "expandToScroll": [4, "expand-to-scroll"],
  20323. "initialBreakpoint": [2, "initial-breakpoint"],
  20324. "backdropBreakpoint": [2, "backdrop-breakpoint"],
  20325. "handle": [4],
  20326. "handleBehavior": [1, "handle-behavior"],
  20327. "component": [1],
  20328. "componentProps": [16],
  20329. "cssClass": [1, "css-class"],
  20330. "backdropDismiss": [4, "backdrop-dismiss"],
  20331. "showBackdrop": [4, "show-backdrop"],
  20332. "animated": [4],
  20333. "presentingElement": [16],
  20334. "htmlAttributes": [16],
  20335. "isOpen": [4, "is-open"],
  20336. "trigger": [1],
  20337. "keepContentsMounted": [4, "keep-contents-mounted"],
  20338. "focusTrap": [4, "focus-trap"],
  20339. "canDismiss": [4, "can-dismiss"],
  20340. "presented": [32],
  20341. "present": [64],
  20342. "dismiss": [64],
  20343. "onDidDismiss": [64],
  20344. "onWillDismiss": [64],
  20345. "setCurrentBreakpoint": [64],
  20346. "getCurrentBreakpoint": [64]
  20347. },
  20348. "$listeners$": undefined,
  20349. "$lazyBundleId$": "-",
  20350. "$attrsToReflect$": []
  20351. }; }
  20352. }
  20353. const LIFECYCLE_MAP$1 = {
  20354. ionModalDidPresent: 'ionViewDidEnter',
  20355. ionModalWillPresent: 'ionViewWillEnter',
  20356. ionModalWillDismiss: 'ionViewWillLeave',
  20357. ionModalDidDismiss: 'ionViewDidLeave',
  20358. };
  20359. const VIEW_STATE_NEW = 1;
  20360. const VIEW_STATE_ATTACHED = 2;
  20361. const VIEW_STATE_DESTROYED = 3;
  20362. // TODO(FW-2832): types
  20363. class ViewController {
  20364. constructor(component, params) {
  20365. this.component = component;
  20366. this.params = params;
  20367. this.state = VIEW_STATE_NEW;
  20368. }
  20369. async init(container) {
  20370. this.state = VIEW_STATE_ATTACHED;
  20371. if (!this.element) {
  20372. const component = this.component;
  20373. this.element = await attachComponent(this.delegate, container, component, ['ion-page', 'ion-page-invisible'], this.params);
  20374. }
  20375. }
  20376. /**
  20377. * DOM WRITE
  20378. */
  20379. _destroy() {
  20380. assert(this.state !== VIEW_STATE_DESTROYED, 'view state must be ATTACHED');
  20381. const element = this.element;
  20382. if (element) {
  20383. if (this.delegate) {
  20384. this.delegate.removeViewFromDom(element.parentElement, element);
  20385. }
  20386. else {
  20387. element.remove();
  20388. }
  20389. }
  20390. this.nav = undefined;
  20391. this.state = VIEW_STATE_DESTROYED;
  20392. }
  20393. }
  20394. const matches = (view, id, params) => {
  20395. if (!view) {
  20396. return false;
  20397. }
  20398. if (view.component !== id) {
  20399. return false;
  20400. }
  20401. return shallowEqualStringMap(view.params, params);
  20402. };
  20403. const convertToView = (page, params) => {
  20404. if (!page) {
  20405. return null;
  20406. }
  20407. if (page instanceof ViewController) {
  20408. return page;
  20409. }
  20410. return new ViewController(page, params);
  20411. };
  20412. const convertToViews = (pages) => {
  20413. return pages
  20414. .map((page) => {
  20415. if (page instanceof ViewController) {
  20416. return page;
  20417. }
  20418. if ('component' in page) {
  20419. return convertToView(page.component, page.componentProps === null ? undefined : page.componentProps);
  20420. }
  20421. return convertToView(page, undefined);
  20422. })
  20423. .filter((v) => v !== null);
  20424. };
  20425. const navCss = ":host{left:0;right:0;top:0;bottom:0;position:absolute;contain:layout size style;z-index:0}";
  20426. var IonNavStyle0 = navCss;
  20427. class Nav {
  20428. constructor(hostRef) {
  20429. registerInstance(this, hostRef);
  20430. this.ionNavWillLoad = createEvent(this, "ionNavWillLoad", 7);
  20431. this.ionNavWillChange = createEvent(this, "ionNavWillChange", 3);
  20432. this.ionNavDidChange = createEvent(this, "ionNavDidChange", 3);
  20433. this.transInstr = [];
  20434. this.gestureOrAnimationInProgress = false;
  20435. this.useRouter = false;
  20436. this.isTransitioning = false;
  20437. this.destroyed = false;
  20438. this.views = [];
  20439. this.didLoad = false;
  20440. this.delegate = undefined;
  20441. this.swipeGesture = undefined;
  20442. this.animated = true;
  20443. this.animation = undefined;
  20444. this.rootParams = undefined;
  20445. this.root = undefined;
  20446. }
  20447. swipeGestureChanged() {
  20448. if (this.gesture) {
  20449. this.gesture.enable(this.swipeGesture === true);
  20450. }
  20451. }
  20452. rootChanged() {
  20453. if (this.root === undefined) {
  20454. return;
  20455. }
  20456. if (this.didLoad === false) {
  20457. /**
  20458. * If the component has not loaded yet, we can skip setting up the root component.
  20459. * It will be called when `componentDidLoad` fires.
  20460. */
  20461. return;
  20462. }
  20463. if (!this.useRouter) {
  20464. if (this.root !== undefined) {
  20465. this.setRoot(this.root, this.rootParams);
  20466. }
  20467. }
  20468. }
  20469. componentWillLoad() {
  20470. this.useRouter = document.querySelector('ion-router') !== null && this.el.closest('[no-router]') === null;
  20471. if (this.swipeGesture === undefined) {
  20472. const mode = getIonMode$1(this);
  20473. this.swipeGesture = config.getBoolean('swipeBackEnabled', mode === 'ios');
  20474. }
  20475. this.ionNavWillLoad.emit();
  20476. }
  20477. async componentDidLoad() {
  20478. // We want to set this flag before any watch callbacks are manually called
  20479. this.didLoad = true;
  20480. this.rootChanged();
  20481. 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));
  20482. this.swipeGestureChanged();
  20483. }
  20484. connectedCallback() {
  20485. this.destroyed = false;
  20486. }
  20487. disconnectedCallback() {
  20488. for (const view of this.views) {
  20489. lifecycle(view.element, LIFECYCLE_WILL_UNLOAD);
  20490. view._destroy();
  20491. }
  20492. // Release swipe back gesture and transition.
  20493. if (this.gesture) {
  20494. this.gesture.destroy();
  20495. this.gesture = undefined;
  20496. }
  20497. this.transInstr.length = 0;
  20498. this.views.length = 0;
  20499. this.destroyed = true;
  20500. }
  20501. /**
  20502. * Push a new component onto the current navigation stack. Pass any additional
  20503. * information along as an object. This additional information is accessible
  20504. * through NavParams.
  20505. *
  20506. * @param component The component to push onto the navigation stack.
  20507. * @param componentProps Any properties of the component.
  20508. * @param opts The navigation options.
  20509. * @param done The transition complete function.
  20510. */
  20511. push(component, componentProps, opts, done) {
  20512. return this.insert(-1, component, componentProps, opts, done);
  20513. }
  20514. /**
  20515. * Inserts a component into the navigation stack at the specified index.
  20516. * This is useful to add a component at any point in the navigation stack.
  20517. *
  20518. * @param insertIndex The index to insert the component at in the stack.
  20519. * @param component The component to insert into the navigation stack.
  20520. * @param componentProps Any properties of the component.
  20521. * @param opts The navigation options.
  20522. * @param done The transition complete function.
  20523. */
  20524. insert(insertIndex, component, componentProps, opts, done) {
  20525. return this.insertPages(insertIndex, [{ component, componentProps }], opts, done);
  20526. }
  20527. /**
  20528. * Inserts an array of components into the navigation stack at the specified index.
  20529. * The last component in the array will become instantiated as a view, and animate
  20530. * in to become the active view.
  20531. *
  20532. * @param insertIndex The index to insert the components at in the stack.
  20533. * @param insertComponents The components to insert into the navigation stack.
  20534. * @param opts The navigation options.
  20535. * @param done The transition complete function.
  20536. */
  20537. insertPages(insertIndex, insertComponents, opts, done) {
  20538. return this.queueTrns({
  20539. insertStart: insertIndex,
  20540. insertViews: insertComponents,
  20541. opts,
  20542. }, done);
  20543. }
  20544. /**
  20545. * Pop a component off of the navigation stack. Navigates back from the current
  20546. * component.
  20547. *
  20548. * @param opts The navigation options.
  20549. * @param done The transition complete function.
  20550. */
  20551. pop(opts, done) {
  20552. return this.removeIndex(-1, 1, opts, done);
  20553. }
  20554. /**
  20555. * Pop to a specific index in the navigation stack.
  20556. *
  20557. * @param indexOrViewCtrl The index or view controller to pop to.
  20558. * @param opts The navigation options.
  20559. * @param done The transition complete function.
  20560. */
  20561. popTo(indexOrViewCtrl, opts, done) {
  20562. const ti = {
  20563. removeStart: -1,
  20564. removeCount: -1,
  20565. opts,
  20566. };
  20567. if (typeof indexOrViewCtrl === 'object' && indexOrViewCtrl.component) {
  20568. ti.removeView = indexOrViewCtrl;
  20569. ti.removeStart = 1;
  20570. }
  20571. else if (typeof indexOrViewCtrl === 'number') {
  20572. ti.removeStart = indexOrViewCtrl + 1;
  20573. }
  20574. return this.queueTrns(ti, done);
  20575. }
  20576. /**
  20577. * Navigate back to the root of the stack, no matter how far back that is.
  20578. *
  20579. * @param opts The navigation options.
  20580. * @param done The transition complete function.
  20581. */
  20582. popToRoot(opts, done) {
  20583. return this.removeIndex(1, -1, opts, done);
  20584. }
  20585. /**
  20586. * Removes a component from the navigation stack at the specified index.
  20587. *
  20588. * @param startIndex The number to begin removal at.
  20589. * @param removeCount The number of components to remove.
  20590. * @param opts The navigation options.
  20591. * @param done The transition complete function.
  20592. */
  20593. removeIndex(startIndex, removeCount = 1, opts, done) {
  20594. return this.queueTrns({
  20595. removeStart: startIndex,
  20596. removeCount,
  20597. opts,
  20598. }, done);
  20599. }
  20600. /**
  20601. * Set the root for the current navigation stack to a component.
  20602. *
  20603. * @param component The component to set as the root of the navigation stack.
  20604. * @param componentProps Any properties of the component.
  20605. * @param opts The navigation options.
  20606. * @param done The transition complete function.
  20607. */
  20608. setRoot(component, componentProps, opts, done) {
  20609. return this.setPages([{ component, componentProps }], opts, done);
  20610. }
  20611. /**
  20612. * Set the views of the current navigation stack and navigate to the last view.
  20613. * By default animations are disabled, but they can be enabled by passing options
  20614. * to the navigation controller. Navigation parameters can also be passed to the
  20615. * individual pages in the array.
  20616. *
  20617. * @param views The list of views to set as the navigation stack.
  20618. * @param opts The navigation options.
  20619. * @param done The transition complete function.
  20620. */
  20621. setPages(views, opts, done) {
  20622. opts !== null && opts !== void 0 ? opts : (opts = {});
  20623. // if animation wasn't set to true then default it to NOT animate
  20624. if (opts.animated !== true) {
  20625. opts.animated = false;
  20626. }
  20627. return this.queueTrns({
  20628. insertStart: 0,
  20629. insertViews: views,
  20630. removeStart: 0,
  20631. removeCount: -1,
  20632. opts,
  20633. }, done);
  20634. }
  20635. /**
  20636. * Called by the router to update the view.
  20637. *
  20638. * @param id The component tag.
  20639. * @param params The component params.
  20640. * @param direction A direction hint.
  20641. * @param animation an AnimationBuilder.
  20642. *
  20643. * @return the status.
  20644. * @internal
  20645. */
  20646. setRouteId(id, params, direction, animation) {
  20647. const active = this.getActiveSync();
  20648. if (matches(active, id, params)) {
  20649. return Promise.resolve({
  20650. changed: false,
  20651. element: active.element,
  20652. });
  20653. }
  20654. let resolve;
  20655. const promise = new Promise((r) => (resolve = r));
  20656. let finish;
  20657. const commonOpts = {
  20658. updateURL: false,
  20659. viewIsReady: (enteringEl) => {
  20660. let mark;
  20661. const p = new Promise((r) => (mark = r));
  20662. resolve({
  20663. changed: true,
  20664. element: enteringEl,
  20665. markVisible: async () => {
  20666. mark();
  20667. await finish;
  20668. },
  20669. });
  20670. return p;
  20671. },
  20672. };
  20673. if (direction === 'root') {
  20674. finish = this.setRoot(id, params, commonOpts);
  20675. }
  20676. else {
  20677. // Look for a view matching the target in the view stack.
  20678. const viewController = this.views.find((v) => matches(v, id, params));
  20679. if (viewController) {
  20680. finish = this.popTo(viewController, Object.assign(Object.assign({}, commonOpts), { direction: 'back', animationBuilder: animation }));
  20681. }
  20682. else if (direction === 'forward') {
  20683. finish = this.push(id, params, Object.assign(Object.assign({}, commonOpts), { animationBuilder: animation }));
  20684. }
  20685. else if (direction === 'back') {
  20686. finish = this.setRoot(id, params, Object.assign(Object.assign({}, commonOpts), { direction: 'back', animated: true, animationBuilder: animation }));
  20687. }
  20688. }
  20689. return promise;
  20690. }
  20691. /**
  20692. * Called by <ion-router> to retrieve the current component.
  20693. *
  20694. * @internal
  20695. */
  20696. async getRouteId() {
  20697. const active = this.getActiveSync();
  20698. if (active) {
  20699. return {
  20700. id: active.element.tagName,
  20701. params: active.params,
  20702. element: active.element,
  20703. };
  20704. }
  20705. return undefined;
  20706. }
  20707. /**
  20708. * Get the active view.
  20709. */
  20710. async getActive() {
  20711. return this.getActiveSync();
  20712. }
  20713. /**
  20714. * Get the view at the specified index.
  20715. *
  20716. * @param index The index of the view.
  20717. */
  20718. async getByIndex(index) {
  20719. return this.views[index];
  20720. }
  20721. /**
  20722. * Returns `true` if the current view can go back.
  20723. *
  20724. * @param view The view to check.
  20725. */
  20726. async canGoBack(view) {
  20727. return this.canGoBackSync(view);
  20728. }
  20729. /**
  20730. * Get the previous view.
  20731. *
  20732. * @param view The view to get.
  20733. */
  20734. async getPrevious(view) {
  20735. return this.getPreviousSync(view);
  20736. }
  20737. /**
  20738. * Returns the number of views in the stack.
  20739. */
  20740. async getLength() {
  20741. return Promise.resolve(this.views.length);
  20742. }
  20743. getActiveSync() {
  20744. return this.views[this.views.length - 1];
  20745. }
  20746. canGoBackSync(view = this.getActiveSync()) {
  20747. return !!(view && this.getPreviousSync(view));
  20748. }
  20749. getPreviousSync(view = this.getActiveSync()) {
  20750. if (!view) {
  20751. return undefined;
  20752. }
  20753. const views = this.views;
  20754. const index = views.indexOf(view);
  20755. return index > 0 ? views[index - 1] : undefined;
  20756. }
  20757. /**
  20758. * Adds a navigation stack change to the queue and schedules it to run.
  20759. *
  20760. * @returns Whether the transition succeeds.
  20761. */
  20762. async queueTrns(ti, done) {
  20763. var _a, _b;
  20764. if (this.isTransitioning && ((_a = ti.opts) === null || _a === void 0 ? void 0 : _a.skipIfBusy)) {
  20765. return false;
  20766. }
  20767. const promise = new Promise((resolve, reject) => {
  20768. ti.resolve = resolve;
  20769. ti.reject = reject;
  20770. });
  20771. ti.done = done;
  20772. /**
  20773. * If using router, check to see if navigation hooks
  20774. * will allow us to perform this transition. This
  20775. * is required in order for hooks to work with
  20776. * the ion-back-button or swipe to go back.
  20777. */
  20778. if (ti.opts && ti.opts.updateURL !== false && this.useRouter) {
  20779. const router = document.querySelector('ion-router');
  20780. if (router) {
  20781. const canTransition = await router.canTransition();
  20782. if (canTransition === false) {
  20783. return false;
  20784. }
  20785. if (typeof canTransition === 'string') {
  20786. router.push(canTransition, ti.opts.direction || 'back');
  20787. return false;
  20788. }
  20789. }
  20790. }
  20791. // Normalize empty
  20792. if (((_b = ti.insertViews) === null || _b === void 0 ? void 0 : _b.length) === 0) {
  20793. ti.insertViews = undefined;
  20794. }
  20795. // Enqueue transition instruction
  20796. this.transInstr.push(ti);
  20797. // if there isn't a transition already happening
  20798. // then this will kick off this transition
  20799. this.nextTrns();
  20800. return promise;
  20801. }
  20802. success(result, ti) {
  20803. if (this.destroyed) {
  20804. this.fireError('nav controller was destroyed', ti);
  20805. return;
  20806. }
  20807. if (ti.done) {
  20808. ti.done(result.hasCompleted, result.requiresTransition, result.enteringView, result.leavingView, result.direction);
  20809. }
  20810. ti.resolve(result.hasCompleted);
  20811. if (ti.opts.updateURL !== false && this.useRouter) {
  20812. const router = document.querySelector('ion-router');
  20813. if (router) {
  20814. const direction = result.direction === 'back' ? 'back' : 'forward';
  20815. router.navChanged(direction);
  20816. }
  20817. }
  20818. }
  20819. failed(rejectReason, ti) {
  20820. if (this.destroyed) {
  20821. this.fireError('nav controller was destroyed', ti);
  20822. return;
  20823. }
  20824. this.transInstr.length = 0;
  20825. this.fireError(rejectReason, ti);
  20826. }
  20827. fireError(rejectReason, ti) {
  20828. if (ti.done) {
  20829. ti.done(false, false, rejectReason);
  20830. }
  20831. if (ti.reject && !this.destroyed) {
  20832. ti.reject(rejectReason);
  20833. }
  20834. else {
  20835. ti.resolve(false);
  20836. }
  20837. }
  20838. /**
  20839. * Consumes the next transition in the queue.
  20840. *
  20841. * @returns whether the transition is executed.
  20842. */
  20843. nextTrns() {
  20844. // this is the framework's bread 'n butta function
  20845. // only one transition is allowed at any given time
  20846. if (this.isTransitioning) {
  20847. return false;
  20848. }
  20849. // there is no transition happening right now, executes the next instructions.
  20850. const ti = this.transInstr.shift();
  20851. if (!ti) {
  20852. return false;
  20853. }
  20854. this.runTransition(ti);
  20855. return true;
  20856. }
  20857. /** Executes all the transition instruction from the queue. */
  20858. async runTransition(ti) {
  20859. try {
  20860. // set that this nav is actively transitioning
  20861. this.ionNavWillChange.emit();
  20862. this.isTransitioning = true;
  20863. this.prepareTI(ti);
  20864. const leavingView = this.getActiveSync();
  20865. const enteringView = this.getEnteringView(ti, leavingView);
  20866. if (!leavingView && !enteringView) {
  20867. throw new Error('no views in the stack to be removed');
  20868. }
  20869. if (enteringView && enteringView.state === VIEW_STATE_NEW) {
  20870. await enteringView.init(this.el);
  20871. }
  20872. this.postViewInit(enteringView, leavingView, ti);
  20873. // Needs transition?
  20874. const requiresTransition = (ti.enteringRequiresTransition || ti.leavingRequiresTransition) && enteringView !== leavingView;
  20875. if (requiresTransition && ti.opts && leavingView) {
  20876. const isBackDirection = ti.opts.direction === 'back';
  20877. /**
  20878. * If heading back, use the entering page's animation
  20879. * unless otherwise specified by the developer.
  20880. */
  20881. if (isBackDirection) {
  20882. ti.opts.animationBuilder = ti.opts.animationBuilder || (enteringView === null || enteringView === void 0 ? void 0 : enteringView.animationBuilder);
  20883. }
  20884. leavingView.animationBuilder = ti.opts.animationBuilder;
  20885. }
  20886. let result;
  20887. if (requiresTransition) {
  20888. result = await this.transition(enteringView, leavingView, ti);
  20889. }
  20890. else {
  20891. // transition is not required, so we are already done!
  20892. // they're inserting/removing the views somewhere in the middle or
  20893. // beginning, so visually nothing needs to animate/transition
  20894. // resolve immediately because there's no animation that's happening
  20895. result = {
  20896. hasCompleted: true,
  20897. requiresTransition: false,
  20898. };
  20899. }
  20900. this.success(result, ti);
  20901. this.ionNavDidChange.emit();
  20902. }
  20903. catch (rejectReason) {
  20904. this.failed(rejectReason, ti);
  20905. }
  20906. this.isTransitioning = false;
  20907. this.nextTrns();
  20908. }
  20909. prepareTI(ti) {
  20910. var _a, _b;
  20911. var _c;
  20912. const viewsLength = this.views.length;
  20913. (_a = ti.opts) !== null && _a !== void 0 ? _a : (ti.opts = {});
  20914. (_b = (_c = ti.opts).delegate) !== null && _b !== void 0 ? _b : (_c.delegate = this.delegate);
  20915. if (ti.removeView !== undefined) {
  20916. assert(ti.removeStart !== undefined, 'removeView needs removeStart');
  20917. assert(ti.removeCount !== undefined, 'removeView needs removeCount');
  20918. const index = this.views.indexOf(ti.removeView);
  20919. if (index < 0) {
  20920. throw new Error('removeView was not found');
  20921. }
  20922. ti.removeStart += index;
  20923. }
  20924. if (ti.removeStart !== undefined) {
  20925. if (ti.removeStart < 0) {
  20926. ti.removeStart = viewsLength - 1;
  20927. }
  20928. if (ti.removeCount < 0) {
  20929. ti.removeCount = viewsLength - ti.removeStart;
  20930. }
  20931. ti.leavingRequiresTransition = ti.removeCount > 0 && ti.removeStart + ti.removeCount === viewsLength;
  20932. }
  20933. if (ti.insertViews) {
  20934. // allow -1 to be passed in to auto push it on the end
  20935. // and clean up the index if it's larger then the size of the stack
  20936. if (ti.insertStart < 0 || ti.insertStart > viewsLength) {
  20937. ti.insertStart = viewsLength;
  20938. }
  20939. ti.enteringRequiresTransition = ti.insertStart === viewsLength;
  20940. }
  20941. const insertViews = ti.insertViews;
  20942. if (!insertViews) {
  20943. return;
  20944. }
  20945. assert(insertViews.length > 0, 'length can not be zero');
  20946. const viewControllers = convertToViews(insertViews);
  20947. if (viewControllers.length === 0) {
  20948. throw new Error('invalid views to insert');
  20949. }
  20950. // Check all the inserted view are correct
  20951. for (const view of viewControllers) {
  20952. view.delegate = ti.opts.delegate;
  20953. const nav = view.nav;
  20954. if (nav && nav !== this) {
  20955. throw new Error('inserted view was already inserted');
  20956. }
  20957. if (view.state === VIEW_STATE_DESTROYED) {
  20958. throw new Error('inserted view was already destroyed');
  20959. }
  20960. }
  20961. ti.insertViews = viewControllers;
  20962. }
  20963. /**
  20964. * Returns the view that will be entered considering the transition instructions.
  20965. *
  20966. * @param ti The instructions.
  20967. * @param leavingView The view being left or undefined if none.
  20968. *
  20969. * @returns The view that will be entered, undefined if none.
  20970. */
  20971. getEnteringView(ti, leavingView) {
  20972. // The last inserted view will be entered when view are inserted.
  20973. const insertViews = ti.insertViews;
  20974. if (insertViews !== undefined) {
  20975. return insertViews[insertViews.length - 1];
  20976. }
  20977. // When views are deleted, we will enter the last view that is not removed and not the view being left.
  20978. const removeStart = ti.removeStart;
  20979. if (removeStart !== undefined) {
  20980. const views = this.views;
  20981. const removeEnd = removeStart + ti.removeCount;
  20982. for (let i = views.length - 1; i >= 0; i--) {
  20983. const view = views[i];
  20984. if ((i < removeStart || i >= removeEnd) && view !== leavingView) {
  20985. return view;
  20986. }
  20987. }
  20988. }
  20989. return undefined;
  20990. }
  20991. /**
  20992. * Adds and Removes the views from the navigation stack.
  20993. *
  20994. * @param enteringView The view being entered.
  20995. * @param leavingView The view being left.
  20996. * @param ti The instructions.
  20997. */
  20998. postViewInit(enteringView, leavingView, ti) {
  20999. var _a, _b, _c;
  21000. assert(leavingView || enteringView, 'Both leavingView and enteringView are null');
  21001. assert(ti.resolve, 'resolve must be valid');
  21002. assert(ti.reject, 'reject must be valid');
  21003. // Compute the views to remove.
  21004. const opts = ti.opts;
  21005. const { insertViews, removeStart, removeCount } = ti;
  21006. /** Records the view to destroy */
  21007. let destroyQueue;
  21008. // there are views to remove
  21009. if (removeStart !== undefined && removeCount !== undefined) {
  21010. assert(removeStart >= 0, 'removeStart can not be negative');
  21011. assert(removeCount >= 0, 'removeCount can not be negative');
  21012. destroyQueue = [];
  21013. for (let i = removeStart; i < removeStart + removeCount; i++) {
  21014. const view = this.views[i];
  21015. if (view !== undefined && view !== enteringView && view !== leavingView) {
  21016. destroyQueue.push(view);
  21017. }
  21018. }
  21019. // default the direction to "back"
  21020. (_a = opts.direction) !== null && _a !== void 0 ? _a : (opts.direction = 'back');
  21021. }
  21022. 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);
  21023. assert(finalNumViews >= 0, 'final balance can not be negative');
  21024. if (finalNumViews === 0) {
  21025. 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);
  21026. throw new Error('navigation stack needs at least one root page');
  21027. }
  21028. // At this point the transition can not be rejected, any throw should be an error
  21029. // Insert the new views in the stack.
  21030. if (insertViews) {
  21031. // add the views to the
  21032. let insertIndex = ti.insertStart;
  21033. for (const view of insertViews) {
  21034. this.insertViewAt(view, insertIndex);
  21035. insertIndex++;
  21036. }
  21037. if (ti.enteringRequiresTransition) {
  21038. // default to forward if not already set
  21039. (_c = opts.direction) !== null && _c !== void 0 ? _c : (opts.direction = 'forward');
  21040. }
  21041. }
  21042. // if the views to be removed are in the beginning or middle
  21043. // and there is not a view that needs to visually transition out
  21044. // then just destroy them and don't transition anything
  21045. // batch all of lifecycles together
  21046. // let's make sure, callbacks are zoned
  21047. if (destroyQueue && destroyQueue.length > 0) {
  21048. for (const view of destroyQueue) {
  21049. lifecycle(view.element, LIFECYCLE_WILL_LEAVE);
  21050. lifecycle(view.element, LIFECYCLE_DID_LEAVE);
  21051. lifecycle(view.element, LIFECYCLE_WILL_UNLOAD);
  21052. }
  21053. // once all lifecycle events has been delivered, we can safely detroy the views
  21054. for (const view of destroyQueue) {
  21055. this.destroyView(view);
  21056. }
  21057. }
  21058. }
  21059. async transition(enteringView, leavingView, ti) {
  21060. // we should animate (duration > 0) if the pushed page is not the first one (startup)
  21061. // or if it is a portal (modal, actionsheet, etc.)
  21062. const opts = ti.opts;
  21063. const progressCallback = opts.progressAnimation
  21064. ? (ani) => {
  21065. /**
  21066. * Because this progress callback is called asynchronously
  21067. * it is possible for the gesture to start and end before
  21068. * the animation is ever set. In that scenario, we should
  21069. * immediately call progressEnd so that the transition promise
  21070. * resolves and the gesture does not get locked up.
  21071. */
  21072. if (ani !== undefined && !this.gestureOrAnimationInProgress) {
  21073. this.gestureOrAnimationInProgress = true;
  21074. ani.onFinish(() => {
  21075. this.gestureOrAnimationInProgress = false;
  21076. }, { oneTimeCallback: true });
  21077. /**
  21078. * Playing animation to beginning
  21079. * with a duration of 0 prevents
  21080. * any flickering when the animation
  21081. * is later cleaned up.
  21082. */
  21083. ani.progressEnd(0, 0, 0);
  21084. }
  21085. else {
  21086. this.sbAni = ani;
  21087. }
  21088. }
  21089. : undefined;
  21090. const mode = getIonMode$1(this);
  21091. const enteringEl = enteringView.element;
  21092. // eslint-disable-next-line @typescript-eslint/prefer-optional-chain
  21093. const leavingEl = leavingView && leavingView.element;
  21094. const animationOpts = Object.assign(Object.assign({ mode, showGoBack: this.canGoBackSync(enteringView), baseEl: this.el, progressCallback, animated: this.animated && config.getBoolean('animated', true), enteringEl,
  21095. leavingEl }, opts), { animationBuilder: opts.animationBuilder || this.animation || config.get('navAnimation') });
  21096. const { hasCompleted } = await transition(animationOpts);
  21097. return this.transitionFinish(hasCompleted, enteringView, leavingView, opts);
  21098. }
  21099. transitionFinish(hasCompleted, enteringView, leavingView, opts) {
  21100. /**
  21101. * If the transition did not complete, the leavingView will still be the active
  21102. * view on the stack. Otherwise unmount all the views after the enteringView.
  21103. */
  21104. const activeView = hasCompleted ? enteringView : leavingView;
  21105. if (activeView) {
  21106. this.unmountInactiveViews(activeView);
  21107. }
  21108. return {
  21109. hasCompleted,
  21110. requiresTransition: true,
  21111. enteringView,
  21112. leavingView,
  21113. direction: opts.direction,
  21114. };
  21115. }
  21116. /**
  21117. * Inserts a view at the specified index.
  21118. *
  21119. * When the view already is in the stack it will be moved to the new position.
  21120. *
  21121. * @param view The view to insert.
  21122. * @param index The index where to insert the view.
  21123. */
  21124. insertViewAt(view, index) {
  21125. const views = this.views;
  21126. const existingIndex = views.indexOf(view);
  21127. if (existingIndex > -1) {
  21128. assert(view.nav === this, 'view is not part of the nav');
  21129. // The view already in the stack, removes it.
  21130. views.splice(existingIndex, 1);
  21131. // and add it back at the requested index.
  21132. views.splice(index, 0, view);
  21133. }
  21134. else {
  21135. assert(!view.nav, 'nav is used');
  21136. // this is a new view to add to the stack
  21137. // create the new entering view
  21138. view.nav = this;
  21139. views.splice(index, 0, view);
  21140. }
  21141. }
  21142. /**
  21143. * Removes a view from the stack.
  21144. *
  21145. * @param view The view to remove.
  21146. */
  21147. removeView(view) {
  21148. assert(view.state === VIEW_STATE_ATTACHED || view.state === VIEW_STATE_DESTROYED, 'view state should be loaded or destroyed');
  21149. const views = this.views;
  21150. const index = views.indexOf(view);
  21151. assert(index > -1, 'view must be part of the stack');
  21152. if (index >= 0) {
  21153. views.splice(index, 1);
  21154. }
  21155. }
  21156. destroyView(view) {
  21157. view._destroy();
  21158. this.removeView(view);
  21159. }
  21160. /**
  21161. * Unmounts all inactive views after the specified active view.
  21162. *
  21163. * DOM WRITE
  21164. *
  21165. * @param activeView The view that is actively visible in the stack. Used to calculate which views to unmount.
  21166. */
  21167. unmountInactiveViews(activeView) {
  21168. // ok, cleanup time!! Destroy all of the views that are
  21169. // INACTIVE and come after the active view
  21170. // only do this if the views exist, though
  21171. if (this.destroyed) {
  21172. return;
  21173. }
  21174. const views = this.views;
  21175. const activeViewIndex = views.indexOf(activeView);
  21176. for (let i = views.length - 1; i >= 0; i--) {
  21177. const view = views[i];
  21178. /**
  21179. * When inserting multiple views via insertPages
  21180. * the last page will be transitioned to, but the
  21181. * others will not be. As a result, a DOM element
  21182. * will only be created for the last page inserted.
  21183. * As a result, it is possible to have views in the
  21184. * stack that do not have `view.element` yet.
  21185. */
  21186. const element = view.element;
  21187. if (element) {
  21188. if (i > activeViewIndex) {
  21189. // this view comes after the active view
  21190. // let's unload it
  21191. lifecycle(element, LIFECYCLE_WILL_UNLOAD);
  21192. this.destroyView(view);
  21193. }
  21194. else if (i < activeViewIndex) {
  21195. // this view comes before the active view
  21196. // and it is not a portal then ensure it is hidden
  21197. setPageHidden(element, true);
  21198. }
  21199. }
  21200. }
  21201. }
  21202. canStart() {
  21203. return (!this.gestureOrAnimationInProgress &&
  21204. !!this.swipeGesture &&
  21205. !this.isTransitioning &&
  21206. this.transInstr.length === 0 &&
  21207. this.canGoBackSync());
  21208. }
  21209. onStart() {
  21210. this.gestureOrAnimationInProgress = true;
  21211. this.pop({ direction: 'back', progressAnimation: true });
  21212. }
  21213. onMove(stepValue) {
  21214. if (this.sbAni) {
  21215. this.sbAni.progressStep(stepValue);
  21216. }
  21217. }
  21218. onEnd(shouldComplete, stepValue, dur) {
  21219. if (this.sbAni) {
  21220. this.sbAni.onFinish(() => {
  21221. this.gestureOrAnimationInProgress = false;
  21222. }, { oneTimeCallback: true });
  21223. // Account for rounding errors in JS
  21224. let newStepValue = shouldComplete ? -0.001 : 0.001;
  21225. /**
  21226. * Animation will be reversed here, so need to
  21227. * reverse the easing curve as well
  21228. *
  21229. * Additionally, we need to account for the time relative
  21230. * to the new easing curve, as `stepValue` is going to be given
  21231. * in terms of a linear curve.
  21232. */
  21233. if (!shouldComplete) {
  21234. this.sbAni.easing('cubic-bezier(1, 0, 0.68, 0.28)');
  21235. newStepValue += getTimeGivenProgression([0, 0], [1, 0], [0.68, 0.28], [1, 1], stepValue)[0];
  21236. }
  21237. else {
  21238. newStepValue += getTimeGivenProgression([0, 0], [0.32, 0.72], [0, 1], [1, 1], stepValue)[0];
  21239. }
  21240. this.sbAni.progressEnd(shouldComplete ? 1 : 0, newStepValue, dur);
  21241. }
  21242. else {
  21243. this.gestureOrAnimationInProgress = false;
  21244. }
  21245. }
  21246. render() {
  21247. return hAsync("slot", { key: '188d0abd6c047d235380f07aac81223b757010e8' });
  21248. }
  21249. get el() { return getElement(this); }
  21250. static get watchers() { return {
  21251. "swipeGesture": ["swipeGestureChanged"],
  21252. "root": ["rootChanged"]
  21253. }; }
  21254. static get style() { return IonNavStyle0; }
  21255. static get cmpMeta() { return {
  21256. "$flags$": 9,
  21257. "$tagName$": "ion-nav",
  21258. "$members$": {
  21259. "delegate": [16],
  21260. "swipeGesture": [1028, "swipe-gesture"],
  21261. "animated": [4],
  21262. "animation": [16],
  21263. "rootParams": [16],
  21264. "root": [1],
  21265. "push": [64],
  21266. "insert": [64],
  21267. "insertPages": [64],
  21268. "pop": [64],
  21269. "popTo": [64],
  21270. "popToRoot": [64],
  21271. "removeIndex": [64],
  21272. "setRoot": [64],
  21273. "setPages": [64],
  21274. "setRouteId": [64],
  21275. "getRouteId": [64],
  21276. "getActive": [64],
  21277. "getByIndex": [64],
  21278. "canGoBack": [64],
  21279. "getPrevious": [64],
  21280. "getLength": [64]
  21281. },
  21282. "$listeners$": undefined,
  21283. "$lazyBundleId$": "-",
  21284. "$attrsToReflect$": []
  21285. }; }
  21286. }
  21287. const navLink = (el, routerDirection, component, componentProps, routerAnimation) => {
  21288. const nav = el.closest('ion-nav');
  21289. if (nav) {
  21290. if (routerDirection === 'forward') {
  21291. if (component !== undefined) {
  21292. return nav.push(component, componentProps, { skipIfBusy: true, animationBuilder: routerAnimation });
  21293. }
  21294. }
  21295. else if (routerDirection === 'root') {
  21296. if (component !== undefined) {
  21297. return nav.setRoot(component, componentProps, { skipIfBusy: true, animationBuilder: routerAnimation });
  21298. }
  21299. }
  21300. else if (routerDirection === 'back') {
  21301. return nav.pop({ skipIfBusy: true, animationBuilder: routerAnimation });
  21302. }
  21303. }
  21304. return Promise.resolve(false);
  21305. };
  21306. class NavLink {
  21307. constructor(hostRef) {
  21308. registerInstance(this, hostRef);
  21309. this.onClick = () => {
  21310. return navLink(this.el, this.routerDirection, this.component, this.componentProps, this.routerAnimation);
  21311. };
  21312. this.component = undefined;
  21313. this.componentProps = undefined;
  21314. this.routerDirection = 'forward';
  21315. this.routerAnimation = undefined;
  21316. }
  21317. render() {
  21318. return hAsync(Host, { key: '9ba170d1b10e08e8a6b5e6a30d363871d455a0a9', onClick: this.onClick });
  21319. }
  21320. get el() { return getElement(this); }
  21321. static get cmpMeta() { return {
  21322. "$flags$": 0,
  21323. "$tagName$": "ion-nav-link",
  21324. "$members$": {
  21325. "component": [1],
  21326. "componentProps": [16],
  21327. "routerDirection": [1, "router-direction"],
  21328. "routerAnimation": [16]
  21329. },
  21330. "$listeners$": undefined,
  21331. "$lazyBundleId$": "-",
  21332. "$attrsToReflect$": []
  21333. }; }
  21334. }
  21335. 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)}";
  21336. var IonNoteIosStyle0 = noteIosCss;
  21337. 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}";
  21338. var IonNoteMdStyle0 = noteMdCss;
  21339. /**
  21340. * @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
  21341. */
  21342. class Note {
  21343. constructor(hostRef) {
  21344. registerInstance(this, hostRef);
  21345. this.color = undefined;
  21346. }
  21347. render() {
  21348. const mode = getIonMode$1(this);
  21349. return (hAsync(Host, { key: '3c3d9b2aa805c0bc1fdc6270a2bbf4dcc1b96c5b', class: createColorClasses$1(this.color, {
  21350. [mode]: true,
  21351. }) }, hAsync("slot", { key: '39e34682009fcb705ecafe51825162734bdf14d3' })));
  21352. }
  21353. static get style() { return {
  21354. ios: IonNoteIosStyle0,
  21355. md: IonNoteMdStyle0
  21356. }; }
  21357. static get cmpMeta() { return {
  21358. "$flags$": 41,
  21359. "$tagName$": "ion-note",
  21360. "$members$": {
  21361. "color": [513]
  21362. },
  21363. "$listeners$": undefined,
  21364. "$lazyBundleId$": "-",
  21365. "$attrsToReflect$": [["color", "color"]]
  21366. }; }
  21367. }
  21368. 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)))}";
  21369. var IonPickerIosStyle0 = pickerIosCss$1;
  21370. 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%)}";
  21371. var IonPickerMdStyle0 = pickerMdCss$1;
  21372. /**
  21373. * @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
  21374. */
  21375. class Picker$1 {
  21376. constructor(hostRef) {
  21377. registerInstance(this, hostRef);
  21378. this.ionInputModeChange = createEvent(this, "ionInputModeChange", 7);
  21379. this.useInputMode = false;
  21380. this.isInHighlightBounds = (ev) => {
  21381. const { highlightEl } = this;
  21382. if (!highlightEl) {
  21383. return false;
  21384. }
  21385. const bbox = highlightEl.getBoundingClientRect();
  21386. /**
  21387. * Check to see if the user clicked
  21388. * outside the bounds of the highlight.
  21389. */
  21390. const outsideX = ev.clientX < bbox.left || ev.clientX > bbox.right;
  21391. const outsideY = ev.clientY < bbox.top || ev.clientY > bbox.bottom;
  21392. if (outsideX || outsideY) {
  21393. return false;
  21394. }
  21395. return true;
  21396. };
  21397. /**
  21398. * If we are no longer focused
  21399. * on a picker column, then we should
  21400. * exit input mode. An exception is made
  21401. * for the input in the picker since having
  21402. * that focused means we are still in input mode.
  21403. */
  21404. this.onFocusOut = (ev) => {
  21405. // TODO(FW-2832): type
  21406. const { relatedTarget } = ev;
  21407. if (!relatedTarget || (relatedTarget.tagName !== 'ION-PICKER-COLUMN' && relatedTarget !== this.inputEl)) {
  21408. this.exitInputMode();
  21409. }
  21410. };
  21411. /**
  21412. * When picker columns receive focus
  21413. * the parent picker needs to determine
  21414. * whether to enter/exit input mode.
  21415. */
  21416. this.onFocusIn = (ev) => {
  21417. // TODO(FW-2832): type
  21418. const { target } = ev;
  21419. /**
  21420. * Due to browser differences in how/when focus
  21421. * is dispatched on certain elements, we need to
  21422. * make sure that this function only ever runs when
  21423. * focusing a picker column.
  21424. */
  21425. if (target.tagName !== 'ION-PICKER-COLUMN') {
  21426. return;
  21427. }
  21428. /**
  21429. * If we have actionOnClick
  21430. * then this means the user focused
  21431. * a picker column via mouse or
  21432. * touch (i.e. a PointerEvent). As a result,
  21433. * we should not enter/exit input mode
  21434. * until the click event has fired, which happens
  21435. * after the `focusin` event.
  21436. *
  21437. * Otherwise, the user likely focused
  21438. * the column using their keyboard and
  21439. * we should enter/exit input mode automatically.
  21440. */
  21441. if (!this.actionOnClick) {
  21442. const columnEl = target;
  21443. const allowInput = columnEl.numericInput;
  21444. if (allowInput) {
  21445. this.enterInputMode(columnEl, false);
  21446. }
  21447. else {
  21448. this.exitInputMode();
  21449. }
  21450. }
  21451. };
  21452. /**
  21453. * On click we need to run an actionOnClick
  21454. * function that has been set in onPointerDown
  21455. * so that we enter/exit input mode correctly.
  21456. */
  21457. this.onClick = () => {
  21458. const { actionOnClick } = this;
  21459. if (actionOnClick) {
  21460. actionOnClick();
  21461. this.actionOnClick = undefined;
  21462. }
  21463. };
  21464. /**
  21465. * Clicking a column also focuses the column on
  21466. * certain browsers, so we use onPointerDown
  21467. * to tell the onFocusIn function that users
  21468. * are trying to click the column rather than
  21469. * focus the column using the keyboard. When the
  21470. * user completes the click, the onClick function
  21471. * runs and runs the actionOnClick callback.
  21472. */
  21473. this.onPointerDown = (ev) => {
  21474. const { useInputMode, inputModeColumn, el } = this;
  21475. if (this.isInHighlightBounds(ev)) {
  21476. /**
  21477. * If we were already in
  21478. * input mode, then we should determine
  21479. * if we tapped a particular column and
  21480. * should switch to input mode for
  21481. * that specific column.
  21482. */
  21483. if (useInputMode) {
  21484. /**
  21485. * If we tapped a picker column
  21486. * then we should either switch to input
  21487. * mode for that column or all columns.
  21488. * Otherwise we should exit input mode
  21489. * since we just tapped the highlight and
  21490. * not a column.
  21491. */
  21492. if (ev.target.tagName === 'ION-PICKER-COLUMN') {
  21493. /**
  21494. * If user taps 2 different columns
  21495. * then we should just switch to input mode
  21496. * for the new column rather than switching to
  21497. * input mode for all columns.
  21498. */
  21499. if (inputModeColumn && inputModeColumn === ev.target) {
  21500. this.actionOnClick = () => {
  21501. this.enterInputMode();
  21502. };
  21503. }
  21504. else {
  21505. this.actionOnClick = () => {
  21506. this.enterInputMode(ev.target);
  21507. };
  21508. }
  21509. }
  21510. else {
  21511. this.actionOnClick = () => {
  21512. this.exitInputMode();
  21513. };
  21514. }
  21515. /**
  21516. * If we were not already in
  21517. * input mode, then we should
  21518. * enter input mode for all columns.
  21519. */
  21520. }
  21521. else {
  21522. /**
  21523. * If there is only 1 numeric input column
  21524. * then we should skip multi column input.
  21525. */
  21526. const columns = el.querySelectorAll('ion-picker-column.picker-column-numeric-input');
  21527. const columnEl = columns.length === 1 ? ev.target : undefined;
  21528. this.actionOnClick = () => {
  21529. this.enterInputMode(columnEl);
  21530. };
  21531. }
  21532. return;
  21533. }
  21534. this.actionOnClick = () => {
  21535. this.exitInputMode();
  21536. };
  21537. };
  21538. /**
  21539. * Enters input mode to allow
  21540. * for text entry of numeric values.
  21541. * If on mobile, we focus a hidden input
  21542. * field so that the on screen keyboard
  21543. * is brought up. When tabbing using a
  21544. * keyboard, picker columns receive an outline
  21545. * to indicate they are focused. As a result,
  21546. * we should not focus the hidden input as it
  21547. * would cause the outline to go away, preventing
  21548. * users from having any visual indication of which
  21549. * column is focused.
  21550. */
  21551. this.enterInputMode = (columnEl, focusInput = true) => {
  21552. const { inputEl, el } = this;
  21553. if (!inputEl) {
  21554. return;
  21555. }
  21556. /**
  21557. * Only active input mode if there is at
  21558. * least one column that accepts numeric input.
  21559. */
  21560. const hasInputColumn = el.querySelector('ion-picker-column.picker-column-numeric-input');
  21561. if (!hasInputColumn) {
  21562. return;
  21563. }
  21564. /**
  21565. * If columnEl is undefined then
  21566. * it is assumed that all numeric pickers
  21567. * are eligible for text entry.
  21568. * (i.e. hour and minute columns)
  21569. */
  21570. this.useInputMode = true;
  21571. this.inputModeColumn = columnEl;
  21572. /**
  21573. * Users with a keyboard and mouse can
  21574. * activate input mode where the input is
  21575. * focused as well as when it is not focused,
  21576. * so we need to make sure we clean up any
  21577. * old listeners.
  21578. */
  21579. if (focusInput) {
  21580. if (this.destroyKeypressListener) {
  21581. this.destroyKeypressListener();
  21582. this.destroyKeypressListener = undefined;
  21583. }
  21584. inputEl.focus();
  21585. }
  21586. else {
  21587. // TODO FW-5900 Use keydown instead
  21588. el.addEventListener('keypress', this.onKeyPress);
  21589. this.destroyKeypressListener = () => {
  21590. el.removeEventListener('keypress', this.onKeyPress);
  21591. };
  21592. }
  21593. this.emitInputModeChange();
  21594. };
  21595. this.onKeyPress = (ev) => {
  21596. const { inputEl } = this;
  21597. if (!inputEl) {
  21598. return;
  21599. }
  21600. const parsedValue = parseInt(ev.key, 10);
  21601. /**
  21602. * Only numbers should be allowed
  21603. */
  21604. if (!Number.isNaN(parsedValue)) {
  21605. inputEl.value += ev.key;
  21606. this.onInputChange();
  21607. }
  21608. };
  21609. this.selectSingleColumn = () => {
  21610. const { inputEl, inputModeColumn, singleColumnSearchTimeout } = this;
  21611. if (!inputEl || !inputModeColumn) {
  21612. return;
  21613. }
  21614. const options = Array.from(inputModeColumn.querySelectorAll('ion-picker-column-option')).filter((el) => el.disabled !== true);
  21615. /**
  21616. * If users pause for a bit, the search
  21617. * value should be reset similar to how a
  21618. * <select> behaves. So typing "34", waiting,
  21619. * then typing "5" should select "05".
  21620. */
  21621. if (singleColumnSearchTimeout) {
  21622. clearTimeout(singleColumnSearchTimeout);
  21623. }
  21624. this.singleColumnSearchTimeout = setTimeout(() => {
  21625. inputEl.value = '';
  21626. this.singleColumnSearchTimeout = undefined;
  21627. }, 1000);
  21628. /**
  21629. * For values that are longer than 2 digits long
  21630. * we should shift the value over 1 character
  21631. * to the left. So typing "456" would result in "56".
  21632. * TODO: If we want to support more than just
  21633. * time entry, we should update this value to be
  21634. * the max length of all of the picker items.
  21635. */
  21636. if (inputEl.value.length >= 3) {
  21637. const startIndex = inputEl.value.length - 2;
  21638. const newString = inputEl.value.substring(startIndex);
  21639. inputEl.value = newString;
  21640. this.selectSingleColumn();
  21641. return;
  21642. }
  21643. /**
  21644. * Checking the value of the input gets priority
  21645. * first. For example, if the value of the input
  21646. * is "1" and we entered "2", then the complete value
  21647. * is "12" and we should select hour 12.
  21648. *
  21649. * Regex removes any leading zeros from values like "02",
  21650. * but it keeps a single zero if there are only zeros in the string.
  21651. * 0+(?=[1-9]) --> Match 1 or more zeros that are followed by 1-9
  21652. * 0+(?=0$) --> Match 1 or more zeros that must be followed by one 0 and end.
  21653. */
  21654. const findItemFromCompleteValue = options.find(({ textContent }) => {
  21655. /**
  21656. * Keyboard entry is currently only used inside of Datetime
  21657. * where we guarantee textContent is set.
  21658. * If we end up exposing this feature publicly we should revisit this assumption.
  21659. */
  21660. const parsedText = textContent.replace(/^0+(?=[1-9])|0+(?=0$)/, '');
  21661. return parsedText === inputEl.value;
  21662. });
  21663. if (findItemFromCompleteValue) {
  21664. inputModeColumn.setValue(findItemFromCompleteValue.value);
  21665. return;
  21666. }
  21667. /**
  21668. * If we typed "56" to get minute 56, then typed "7",
  21669. * we should select "07" as "567" is not a valid minute.
  21670. */
  21671. if (inputEl.value.length === 2) {
  21672. const changedCharacter = inputEl.value.substring(inputEl.value.length - 1);
  21673. inputEl.value = changedCharacter;
  21674. this.selectSingleColumn();
  21675. }
  21676. };
  21677. /**
  21678. * Searches a list of column items for a particular
  21679. * value. This is currently used for numeric values.
  21680. * The zeroBehavior can be set to account for leading
  21681. * or trailing zeros when looking at the item text.
  21682. */
  21683. this.searchColumn = (colEl, value, zeroBehavior = 'start') => {
  21684. if (!value) {
  21685. return false;
  21686. }
  21687. const behavior = zeroBehavior === 'start' ? /^0+/ : /0$/;
  21688. value = value.replace(behavior, '');
  21689. const option = Array.from(colEl.querySelectorAll('ion-picker-column-option')).find((el) => {
  21690. return el.disabled !== true && el.textContent.replace(behavior, '') === value;
  21691. });
  21692. if (option) {
  21693. colEl.setValue(option.value);
  21694. }
  21695. return !!option;
  21696. };
  21697. /**
  21698. * Attempts to intelligently search the first and second
  21699. * column as if they're number columns for the provided numbers
  21700. * where the first two numbers are the first column
  21701. * and the last 2 are the last column. Tries to allow for the first
  21702. * number to be ignored for situations where typos occurred.
  21703. */
  21704. this.multiColumnSearch = (firstColumn, secondColumn, input) => {
  21705. if (input.length === 0) {
  21706. return;
  21707. }
  21708. const inputArray = input.split('');
  21709. const hourValue = inputArray.slice(0, 2).join('');
  21710. // Try to find a match for the first two digits in the first column
  21711. const foundHour = this.searchColumn(firstColumn, hourValue);
  21712. // If we have more than 2 digits and found a match for hours,
  21713. // use the remaining digits for the second column (minutes)
  21714. if (inputArray.length > 2 && foundHour) {
  21715. const minuteValue = inputArray.slice(2, 4).join('');
  21716. this.searchColumn(secondColumn, minuteValue);
  21717. }
  21718. // If we couldn't find a match for the two-digit hour, try single digit approaches
  21719. else if (!foundHour && inputArray.length >= 1) {
  21720. // First try the first digit as a single-digit hour
  21721. let singleDigitHour = inputArray[0];
  21722. let singleDigitFound = this.searchColumn(firstColumn, singleDigitHour);
  21723. // If that didn't work, try the second digit as a single-digit hour
  21724. // (handles case where user made a typo in the first digit, or they typed over themselves)
  21725. if (!singleDigitFound) {
  21726. inputArray.shift();
  21727. singleDigitHour = inputArray[0];
  21728. singleDigitFound = this.searchColumn(firstColumn, singleDigitHour);
  21729. }
  21730. // If we found a single-digit hour and have remaining digits,
  21731. // use up to 2 of the remaining digits for the second column
  21732. if (singleDigitFound && inputArray.length > 1) {
  21733. const remainingDigits = inputArray.slice(1, 3).join('');
  21734. this.searchColumn(secondColumn, remainingDigits);
  21735. }
  21736. }
  21737. };
  21738. this.selectMultiColumn = () => {
  21739. const { inputEl, el } = this;
  21740. if (!inputEl) {
  21741. return;
  21742. }
  21743. const numericPickers = Array.from(el.querySelectorAll('ion-picker-column')).filter((col) => col.numericInput);
  21744. const firstColumn = numericPickers[0];
  21745. const lastColumn = numericPickers[1];
  21746. let value = inputEl.value;
  21747. if (value.length > 4) {
  21748. const startIndex = inputEl.value.length - 4;
  21749. const newString = inputEl.value.substring(startIndex);
  21750. inputEl.value = newString;
  21751. value = newString;
  21752. }
  21753. this.multiColumnSearch(firstColumn, lastColumn, value);
  21754. };
  21755. /**
  21756. * Searches the value of the active column
  21757. * to determine which value users are trying
  21758. * to select
  21759. */
  21760. this.onInputChange = () => {
  21761. const { useInputMode, inputEl, inputModeColumn } = this;
  21762. if (!useInputMode || !inputEl) {
  21763. return;
  21764. }
  21765. if (inputModeColumn) {
  21766. this.selectSingleColumn();
  21767. }
  21768. else {
  21769. this.selectMultiColumn();
  21770. }
  21771. };
  21772. /**
  21773. * Emit ionInputModeChange. Picker columns
  21774. * listen for this event to determine whether
  21775. * or not their column is "active" for text input.
  21776. */
  21777. this.emitInputModeChange = () => {
  21778. const { useInputMode, inputModeColumn } = this;
  21779. this.ionInputModeChange.emit({
  21780. useInputMode,
  21781. inputModeColumn,
  21782. });
  21783. };
  21784. }
  21785. /**
  21786. * When the picker is interacted with
  21787. * we need to prevent touchstart so other
  21788. * gestures do not fire. For example,
  21789. * scrolling on the wheel picker
  21790. * in ion-datetime should not cause
  21791. * a card modal to swipe to close.
  21792. */
  21793. preventTouchStartPropagation(ev) {
  21794. ev.stopPropagation();
  21795. }
  21796. componentWillLoad() {
  21797. getElementRoot(this.el).addEventListener('focusin', this.onFocusIn);
  21798. getElementRoot(this.el).addEventListener('focusout', this.onFocusOut);
  21799. }
  21800. /**
  21801. * @internal
  21802. * Exits text entry mode for the picker
  21803. * This method blurs the hidden input
  21804. * and cause the keyboard to dismiss.
  21805. */
  21806. async exitInputMode() {
  21807. const { inputEl, useInputMode } = this;
  21808. if (!useInputMode || !inputEl) {
  21809. return;
  21810. }
  21811. this.useInputMode = false;
  21812. this.inputModeColumn = undefined;
  21813. inputEl.blur();
  21814. inputEl.value = '';
  21815. if (this.destroyKeypressListener) {
  21816. this.destroyKeypressListener();
  21817. this.destroyKeypressListener = undefined;
  21818. }
  21819. this.emitInputModeChange();
  21820. }
  21821. render() {
  21822. 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) => {
  21823. var _a;
  21824. /**
  21825. * The "Enter" key represents
  21826. * the user submitting their time
  21827. * selection, so we should blur the
  21828. * input (and therefore close the keyboard)
  21829. *
  21830. * Updating the picker's state to no longer
  21831. * be in input mode is handled in the onBlur
  21832. * callback below.
  21833. */
  21834. if (ev.key === 'Enter') {
  21835. (_a = this.inputEl) === null || _a === void 0 ? void 0 : _a.blur();
  21836. }
  21837. }, 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' })));
  21838. }
  21839. get el() { return getElement(this); }
  21840. static get style() { return {
  21841. ios: IonPickerIosStyle0,
  21842. md: IonPickerMdStyle0
  21843. }; }
  21844. static get cmpMeta() { return {
  21845. "$flags$": 41,
  21846. "$tagName$": "ion-picker",
  21847. "$members$": {
  21848. "exitInputMode": [64]
  21849. },
  21850. "$listeners$": [[1, "touchstart", "preventTouchStartPropagation"]],
  21851. "$lazyBundleId$": "-",
  21852. "$attrsToReflect$": []
  21853. }; }
  21854. }
  21855. /**
  21856. * iOS Picker Enter Animation
  21857. */
  21858. const iosEnterAnimation$2 = (baseEl) => {
  21859. const baseAnimation = createAnimation();
  21860. const backdropAnimation = createAnimation();
  21861. const wrapperAnimation = createAnimation();
  21862. backdropAnimation
  21863. .addElement(baseEl.querySelector('ion-backdrop'))
  21864. .fromTo('opacity', 0.01, 'var(--backdrop-opacity)')
  21865. .beforeStyles({
  21866. 'pointer-events': 'none',
  21867. })
  21868. .afterClearStyles(['pointer-events']);
  21869. wrapperAnimation
  21870. .addElement(baseEl.querySelector('.picker-wrapper'))
  21871. .fromTo('transform', 'translateY(100%)', 'translateY(0%)');
  21872. return baseAnimation
  21873. .addElement(baseEl)
  21874. .easing('cubic-bezier(.36,.66,.04,1)')
  21875. .duration(400)
  21876. .addAnimation([backdropAnimation, wrapperAnimation]);
  21877. };
  21878. /**
  21879. * iOS Picker Leave Animation
  21880. */
  21881. const iosLeaveAnimation$2 = (baseEl) => {
  21882. const baseAnimation = createAnimation();
  21883. const backdropAnimation = createAnimation();
  21884. const wrapperAnimation = createAnimation();
  21885. backdropAnimation
  21886. .addElement(baseEl.querySelector('ion-backdrop'))
  21887. .fromTo('opacity', 'var(--backdrop-opacity)', 0.01);
  21888. wrapperAnimation
  21889. .addElement(baseEl.querySelector('.picker-wrapper'))
  21890. .fromTo('transform', 'translateY(0%)', 'translateY(100%)');
  21891. return baseAnimation
  21892. .addElement(baseEl)
  21893. .easing('cubic-bezier(.36,.66,.04,1)')
  21894. .duration(400)
  21895. .addAnimation([backdropAnimation, wrapperAnimation]);
  21896. };
  21897. 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}";
  21898. var IonPickerLegacyIosStyle0 = pickerIosCss;
  21899. 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}";
  21900. var IonPickerLegacyMdStyle0 = pickerMdCss;
  21901. // TODO(FW-2832): types
  21902. /**
  21903. * @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
  21904. */
  21905. class Picker {
  21906. constructor(hostRef) {
  21907. registerInstance(this, hostRef);
  21908. this.didPresent = createEvent(this, "ionPickerDidPresent", 7);
  21909. this.willPresent = createEvent(this, "ionPickerWillPresent", 7);
  21910. this.willDismiss = createEvent(this, "ionPickerWillDismiss", 7);
  21911. this.didDismiss = createEvent(this, "ionPickerDidDismiss", 7);
  21912. this.didPresentShorthand = createEvent(this, "didPresent", 7);
  21913. this.willPresentShorthand = createEvent(this, "willPresent", 7);
  21914. this.willDismissShorthand = createEvent(this, "willDismiss", 7);
  21915. this.didDismissShorthand = createEvent(this, "didDismiss", 7);
  21916. this.delegateController = createDelegateController(this);
  21917. this.lockController = createLockController();
  21918. this.triggerController = createTriggerController();
  21919. this.onBackdropTap = () => {
  21920. this.dismiss(undefined, BACKDROP);
  21921. };
  21922. this.dispatchCancelHandler = (ev) => {
  21923. const role = ev.detail.role;
  21924. if (isCancel(role)) {
  21925. const cancelButton = this.buttons.find((b) => b.role === 'cancel');
  21926. this.callButtonHandler(cancelButton);
  21927. }
  21928. };
  21929. this.presented = false;
  21930. this.overlayIndex = undefined;
  21931. this.delegate = undefined;
  21932. this.hasController = false;
  21933. this.keyboardClose = true;
  21934. this.enterAnimation = undefined;
  21935. this.leaveAnimation = undefined;
  21936. this.buttons = [];
  21937. this.columns = [];
  21938. this.cssClass = undefined;
  21939. this.duration = 0;
  21940. this.showBackdrop = true;
  21941. this.backdropDismiss = true;
  21942. this.animated = true;
  21943. this.htmlAttributes = undefined;
  21944. this.isOpen = false;
  21945. this.trigger = undefined;
  21946. }
  21947. onIsOpenChange(newValue, oldValue) {
  21948. if (newValue === true && oldValue === false) {
  21949. this.present();
  21950. }
  21951. else if (newValue === false && oldValue === true) {
  21952. this.dismiss();
  21953. }
  21954. }
  21955. triggerChanged() {
  21956. const { trigger, el, triggerController } = this;
  21957. if (trigger) {
  21958. triggerController.addClickListener(el, trigger);
  21959. }
  21960. }
  21961. connectedCallback() {
  21962. prepareOverlay(this.el);
  21963. this.triggerChanged();
  21964. }
  21965. disconnectedCallback() {
  21966. this.triggerController.removeClickListener();
  21967. }
  21968. componentWillLoad() {
  21969. var _a;
  21970. if (!((_a = this.htmlAttributes) === null || _a === void 0 ? void 0 : _a.id)) {
  21971. setOverlayId(this.el);
  21972. }
  21973. }
  21974. componentDidLoad() {
  21975. 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);
  21976. /**
  21977. * If picker was rendered with isOpen="true"
  21978. * then we should open picker immediately.
  21979. */
  21980. if (this.isOpen === true) {
  21981. raf(() => this.present());
  21982. }
  21983. /**
  21984. * When binding values in frameworks such as Angular
  21985. * it is possible for the value to be set after the Web Component
  21986. * initializes but before the value watcher is set up in Stencil.
  21987. * As a result, the watcher callback may not be fired.
  21988. * We work around this by manually calling the watcher
  21989. * callback when the component has loaded and the watcher
  21990. * is configured.
  21991. */
  21992. this.triggerChanged();
  21993. }
  21994. /**
  21995. * Present the picker overlay after it has been created.
  21996. */
  21997. async present() {
  21998. const unlock = await this.lockController.lock();
  21999. await this.delegateController.attachViewToDom();
  22000. await present(this, 'pickerEnter', iosEnterAnimation$2, iosEnterAnimation$2, undefined);
  22001. if (this.duration > 0) {
  22002. this.durationTimeout = setTimeout(() => this.dismiss(), this.duration);
  22003. }
  22004. unlock();
  22005. }
  22006. /**
  22007. * Dismiss the picker overlay after it has been presented.
  22008. *
  22009. * @param data Any data to emit in the dismiss events.
  22010. * @param role The role of the element that is dismissing the picker.
  22011. * This can be useful in a button handler for determining which button was
  22012. * clicked to dismiss the picker.
  22013. * Some examples include: ``"cancel"`, `"destructive"`, "selected"`, and `"backdrop"`.
  22014. */
  22015. async dismiss(data, role) {
  22016. const unlock = await this.lockController.lock();
  22017. if (this.durationTimeout) {
  22018. clearTimeout(this.durationTimeout);
  22019. }
  22020. const dismissed = await dismiss(this, data, role, 'pickerLeave', iosLeaveAnimation$2, iosLeaveAnimation$2);
  22021. if (dismissed) {
  22022. this.delegateController.removeViewFromDom();
  22023. }
  22024. unlock();
  22025. return dismissed;
  22026. }
  22027. /**
  22028. * Returns a promise that resolves when the picker did dismiss.
  22029. */
  22030. onDidDismiss() {
  22031. return eventMethod(this.el, 'ionPickerDidDismiss');
  22032. }
  22033. /**
  22034. * Returns a promise that resolves when the picker will dismiss.
  22035. */
  22036. onWillDismiss() {
  22037. return eventMethod(this.el, 'ionPickerWillDismiss');
  22038. }
  22039. /**
  22040. * Get the column that matches the specified name.
  22041. *
  22042. * @param name The name of the column.
  22043. */
  22044. getColumn(name) {
  22045. return Promise.resolve(this.columns.find((column) => column.name === name));
  22046. }
  22047. async buttonClick(button) {
  22048. const role = button.role;
  22049. if (isCancel(role)) {
  22050. return this.dismiss(undefined, role);
  22051. }
  22052. const shouldDismiss = await this.callButtonHandler(button);
  22053. if (shouldDismiss) {
  22054. return this.dismiss(this.getSelected(), button.role);
  22055. }
  22056. return Promise.resolve();
  22057. }
  22058. async callButtonHandler(button) {
  22059. if (button) {
  22060. // a handler has been provided, execute it
  22061. // pass the handler the values from the inputs
  22062. const rtn = await safeCall(button.handler, this.getSelected());
  22063. if (rtn === false) {
  22064. // if the return value of the handler is false then do not dismiss
  22065. return false;
  22066. }
  22067. }
  22068. return true;
  22069. }
  22070. getSelected() {
  22071. const selected = {};
  22072. this.columns.forEach((col, index) => {
  22073. const selectedColumn = col.selectedIndex !== undefined ? col.options[col.selectedIndex] : undefined;
  22074. selected[col.name] = {
  22075. text: selectedColumn ? selectedColumn.text : undefined,
  22076. value: selectedColumn ? selectedColumn.value : undefined,
  22077. columnIndex: index,
  22078. };
  22079. });
  22080. return selected;
  22081. }
  22082. render() {
  22083. const { htmlAttributes } = this;
  22084. const mode = getIonMode$1(this);
  22085. return (hAsync(Host, Object.assign({ key: 'b6b6ca6f9aa74681e6d67f64b366f5965fec2a6d', "aria-modal": "true", tabindex: "-1" }, htmlAttributes, { style: {
  22086. zIndex: `${20000 + this.overlayIndex}`,
  22087. }, class: Object.assign({ [mode]: true,
  22088. // Used internally for styling
  22089. [`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" })));
  22090. }
  22091. get el() { return getElement(this); }
  22092. static get watchers() { return {
  22093. "isOpen": ["onIsOpenChange"],
  22094. "trigger": ["triggerChanged"]
  22095. }; }
  22096. static get style() { return {
  22097. ios: IonPickerLegacyIosStyle0,
  22098. md: IonPickerLegacyMdStyle0
  22099. }; }
  22100. static get cmpMeta() { return {
  22101. "$flags$": 34,
  22102. "$tagName$": "ion-picker-legacy",
  22103. "$members$": {
  22104. "overlayIndex": [2, "overlay-index"],
  22105. "delegate": [16],
  22106. "hasController": [4, "has-controller"],
  22107. "keyboardClose": [4, "keyboard-close"],
  22108. "enterAnimation": [16],
  22109. "leaveAnimation": [16],
  22110. "buttons": [16],
  22111. "columns": [16],
  22112. "cssClass": [1, "css-class"],
  22113. "duration": [2],
  22114. "showBackdrop": [4, "show-backdrop"],
  22115. "backdropDismiss": [4, "backdrop-dismiss"],
  22116. "animated": [4],
  22117. "htmlAttributes": [16],
  22118. "isOpen": [4, "is-open"],
  22119. "trigger": [1],
  22120. "presented": [32],
  22121. "present": [64],
  22122. "dismiss": [64],
  22123. "onDidDismiss": [64],
  22124. "onWillDismiss": [64],
  22125. "getColumn": [64]
  22126. },
  22127. "$listeners$": undefined,
  22128. "$lazyBundleId$": "-",
  22129. "$attrsToReflect$": []
  22130. }; }
  22131. }
  22132. const buttonWrapperClass = (button) => {
  22133. return {
  22134. [`picker-toolbar-${button.role}`]: button.role !== undefined,
  22135. 'picker-toolbar-button': true,
  22136. };
  22137. };
  22138. const buttonClass$1 = (button) => {
  22139. return Object.assign({ 'picker-button': true, 'ion-activatable': true }, getClassMap(button.cssClass));
  22140. };
  22141. 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)}}";
  22142. var IonPickerColumnStyle0 = pickerColumnCss;
  22143. /**
  22144. * @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
  22145. *
  22146. * @slot prefix - Content to show on the left side of the picker options.
  22147. * @slot suffix - Content to show on the right side of the picker options.
  22148. */
  22149. class PickerColumn {
  22150. constructor(hostRef) {
  22151. registerInstance(this, hostRef);
  22152. this.ionChange = createEvent(this, "ionChange", 7);
  22153. this.isScrolling = false;
  22154. this.isColumnVisible = false;
  22155. this.canExitInputMode = true;
  22156. this.updateValueTextOnScroll = false;
  22157. this.centerPickerItemInView = (target, smooth = true, canExitInputMode = true) => {
  22158. const { isColumnVisible, scrollEl } = this;
  22159. if (isColumnVisible && scrollEl) {
  22160. // (Vertical offset from parent) - (three empty picker rows) + (half the height of the target to ensure the scroll triggers)
  22161. const top = target.offsetTop - 3 * target.clientHeight + target.clientHeight / 2;
  22162. if (scrollEl.scrollTop !== top) {
  22163. /**
  22164. * Setting this flag prevents input
  22165. * mode from exiting in the picker column's
  22166. * scroll callback. This is useful when the user manually
  22167. * taps an item or types on the keyboard as both
  22168. * of these can cause a scroll to occur.
  22169. */
  22170. this.canExitInputMode = canExitInputMode;
  22171. this.updateValueTextOnScroll = false;
  22172. scrollEl.scroll({
  22173. top,
  22174. left: 0,
  22175. behavior: smooth ? 'smooth' : undefined,
  22176. });
  22177. }
  22178. }
  22179. };
  22180. this.setPickerItemActiveState = (item, isActive) => {
  22181. if (isActive) {
  22182. item.classList.add(PICKER_ITEM_ACTIVE_CLASS);
  22183. }
  22184. else {
  22185. item.classList.remove(PICKER_ITEM_ACTIVE_CLASS);
  22186. }
  22187. };
  22188. /**
  22189. * When ionInputModeChange is emitted, each column
  22190. * needs to check if it is the one being made available
  22191. * for text entry.
  22192. */
  22193. this.inputModeChange = (ev) => {
  22194. if (!this.numericInput) {
  22195. return;
  22196. }
  22197. const { useInputMode, inputModeColumn } = ev.detail;
  22198. /**
  22199. * If inputModeColumn is undefined then this means
  22200. * all numericInput columns are being selected.
  22201. */
  22202. const isColumnActive = inputModeColumn === undefined || inputModeColumn === this.el;
  22203. if (!useInputMode || !isColumnActive) {
  22204. this.setInputModeActive(false);
  22205. return;
  22206. }
  22207. this.setInputModeActive(true);
  22208. };
  22209. /**
  22210. * Setting isActive will cause a re-render.
  22211. * As a result, we do not want to cause the
  22212. * re-render mid scroll as this will cause
  22213. * the picker column to jump back to
  22214. * whatever value was selected at the
  22215. * start of the scroll interaction.
  22216. */
  22217. this.setInputModeActive = (state) => {
  22218. if (this.isScrolling) {
  22219. this.scrollEndCallback = () => {
  22220. this.isActive = state;
  22221. };
  22222. return;
  22223. }
  22224. this.isActive = state;
  22225. };
  22226. /**
  22227. * When the column scrolls, the component
  22228. * needs to determine which item is centered
  22229. * in the view and will emit an ionChange with
  22230. * the item object.
  22231. */
  22232. this.initializeScrollListener = () => {
  22233. /**
  22234. * The haptics for the wheel picker are
  22235. * an iOS-only feature. As a result, they should
  22236. * be disabled on Android.
  22237. */
  22238. const enableHaptics = isPlatform('ios');
  22239. const { el, scrollEl } = this;
  22240. let timeout;
  22241. let activeEl = this.activeItem;
  22242. const scrollCallback = () => {
  22243. raf(() => {
  22244. var _a;
  22245. if (!scrollEl)
  22246. return;
  22247. if (timeout) {
  22248. clearTimeout(timeout);
  22249. timeout = undefined;
  22250. }
  22251. if (!this.isScrolling) {
  22252. enableHaptics && hapticSelectionStart();
  22253. this.isScrolling = true;
  22254. }
  22255. /**
  22256. * Select item in the center of the column
  22257. * which is the month/year that we want to select
  22258. */
  22259. const bbox = scrollEl.getBoundingClientRect();
  22260. const centerX = bbox.x + bbox.width / 2;
  22261. const centerY = bbox.y + bbox.height / 2;
  22262. /**
  22263. * elementFromPoint returns the top-most element.
  22264. * This means that if an ion-backdrop is overlaying the
  22265. * picker then the appropriate picker column option will
  22266. * not be selected. To account for this, we use elementsFromPoint
  22267. * and use an Array.find to find the appropriate column option
  22268. * at that point.
  22269. *
  22270. * Additionally, the picker column could be used in the
  22271. * Shadow DOM (i.e. in ion-datetime) so we need to make
  22272. * sure we are choosing the correct host otherwise
  22273. * the elements returns by elementsFromPoint will be
  22274. * retargeted. To account for this, we check to see
  22275. * if the picker column has a parent shadow root. If
  22276. * so, we use that shadow root when doing elementsFromPoint.
  22277. * Otherwise, we just use the document.
  22278. */
  22279. const rootNode = el.getRootNode();
  22280. const hasParentShadow = rootNode instanceof ShadowRoot;
  22281. const referenceNode = hasParentShadow ? rootNode : doc;
  22282. /**
  22283. * If the reference node is undefined
  22284. * then it's likely that doc is undefined
  22285. * due to being in an SSR environment.
  22286. */
  22287. if (referenceNode === undefined) {
  22288. return;
  22289. }
  22290. const elementsAtPoint = referenceNode.elementsFromPoint(centerX, centerY);
  22291. /**
  22292. * elementsFromPoint can returns multiple elements
  22293. * so find the relevant picker column option if one exists.
  22294. */
  22295. const newActiveElement = elementsAtPoint.find((el) => el.tagName === 'ION-PICKER-COLUMN-OPTION');
  22296. if (activeEl !== undefined) {
  22297. this.setPickerItemActiveState(activeEl, false);
  22298. }
  22299. if (newActiveElement === undefined || newActiveElement.disabled) {
  22300. return;
  22301. }
  22302. /**
  22303. * If we are selecting a new value,
  22304. * we need to run haptics again.
  22305. */
  22306. if (newActiveElement !== activeEl) {
  22307. enableHaptics && hapticSelectionChanged();
  22308. if (this.canExitInputMode) {
  22309. /**
  22310. * The native iOS wheel picker
  22311. * only dismisses the keyboard
  22312. * once the selected item has changed
  22313. * as a result of a swipe
  22314. * from the user. If `canExitInputMode` is
  22315. * `false` then this means that the
  22316. * scroll is happening as a result of
  22317. * the `value` property programmatically changing
  22318. * either by an application or by the user via the keyboard.
  22319. */
  22320. this.exitInputMode();
  22321. }
  22322. }
  22323. activeEl = newActiveElement;
  22324. this.setPickerItemActiveState(newActiveElement, true);
  22325. /**
  22326. * Set the aria-valuetext even though the value prop has not been updated yet.
  22327. * This enables some screen readers to announce the value as the users drag
  22328. * as opposed to when their release their pointer from the screen.
  22329. *
  22330. * When the value is programmatically updated, we will smoothly scroll
  22331. * to the new option. However, we do not want to update aria-valuetext mid-scroll
  22332. * as that can cause the old value to be briefly set before being set to the
  22333. * correct option. This will cause some screen readers to announce the old value
  22334. * again before announcing the new value. The correct valuetext will be set on render.
  22335. */
  22336. if (this.updateValueTextOnScroll) {
  22337. (_a = this.assistiveFocusable) === null || _a === void 0 ? void 0 : _a.setAttribute('aria-valuetext', this.getOptionValueText(newActiveElement));
  22338. }
  22339. timeout = setTimeout(() => {
  22340. this.isScrolling = false;
  22341. this.updateValueTextOnScroll = true;
  22342. enableHaptics && hapticSelectionEnd();
  22343. /**
  22344. * Certain tasks (such as those that
  22345. * cause re-renders) should only be done
  22346. * once scrolling has finished, otherwise
  22347. * flickering may occur.
  22348. */
  22349. const { scrollEndCallback } = this;
  22350. if (scrollEndCallback) {
  22351. scrollEndCallback();
  22352. this.scrollEndCallback = undefined;
  22353. }
  22354. /**
  22355. * Reset this flag as the
  22356. * next scroll interaction could
  22357. * be a scroll from the user. In this
  22358. * case, we should exit input mode.
  22359. */
  22360. this.canExitInputMode = true;
  22361. this.setValue(newActiveElement.value);
  22362. }, 250);
  22363. });
  22364. };
  22365. /**
  22366. * Wrap this in an raf so that the scroll callback
  22367. * does not fire when component is initially shown.
  22368. */
  22369. raf(() => {
  22370. if (!scrollEl)
  22371. return;
  22372. scrollEl.addEventListener('scroll', scrollCallback);
  22373. this.destroyScrollListener = () => {
  22374. scrollEl.removeEventListener('scroll', scrollCallback);
  22375. };
  22376. });
  22377. };
  22378. /**
  22379. * Tells the parent picker to
  22380. * exit text entry mode. This is only called
  22381. * when the selected item changes during scroll, so
  22382. * we know that the user likely wants to scroll
  22383. * instead of type.
  22384. */
  22385. this.exitInputMode = () => {
  22386. const { parentEl } = this;
  22387. if (parentEl == null)
  22388. return;
  22389. parentEl.exitInputMode();
  22390. /**
  22391. * setInputModeActive only takes
  22392. * effect once scrolling stops to avoid
  22393. * a component re-render while scrolling.
  22394. * However, we want the visual active
  22395. * indicator to go away immediately, so
  22396. * we call classList.remove here.
  22397. */
  22398. this.el.classList.remove('picker-column-active');
  22399. };
  22400. /**
  22401. * Find the next enabled option after the active option.
  22402. * @param stride - How many options to "jump" over in order to select the next option.
  22403. * This can be used to implement PageUp/PageDown behaviors where pressing these keys
  22404. * scrolls the picker by more than 1 option. For example, a stride of 5 means select
  22405. * the enabled option 5 options after the active one. Note that the actual option selected
  22406. * may be past the stride if the option at the stride is disabled.
  22407. */
  22408. this.findNextOption = (stride = 1) => {
  22409. const { activeItem } = this;
  22410. if (!activeItem)
  22411. return null;
  22412. let prevNode = activeItem;
  22413. let node = activeItem.nextElementSibling;
  22414. while (node != null) {
  22415. if (stride > 0) {
  22416. stride--;
  22417. }
  22418. if (node.tagName === 'ION-PICKER-COLUMN-OPTION' && !node.disabled && stride === 0) {
  22419. return node;
  22420. }
  22421. prevNode = node;
  22422. // Use nextElementSibling instead of nextSibling to avoid text/comment nodes
  22423. node = node.nextElementSibling;
  22424. }
  22425. return prevNode;
  22426. };
  22427. /**
  22428. * Find the next enabled option after the active option.
  22429. * @param stride - How many options to "jump" over in order to select the next option.
  22430. * This can be used to implement PageUp/PageDown behaviors where pressing these keys
  22431. * scrolls the picker by more than 1 option. For example, a stride of 5 means select
  22432. * the enabled option 5 options before the active one. Note that the actual option selected
  22433. * may be past the stride if the option at the stride is disabled.
  22434. */
  22435. this.findPreviousOption = (stride = 1) => {
  22436. const { activeItem } = this;
  22437. if (!activeItem)
  22438. return null;
  22439. let nextNode = activeItem;
  22440. let node = activeItem.previousElementSibling;
  22441. while (node != null) {
  22442. if (stride > 0) {
  22443. stride--;
  22444. }
  22445. if (node.tagName === 'ION-PICKER-COLUMN-OPTION' && !node.disabled && stride === 0) {
  22446. return node;
  22447. }
  22448. nextNode = node;
  22449. // Use previousElementSibling instead of previousSibling to avoid text/comment nodes
  22450. node = node.previousElementSibling;
  22451. }
  22452. return nextNode;
  22453. };
  22454. this.onKeyDown = (ev) => {
  22455. /**
  22456. * The below operations should be inverted when running on a mobile device.
  22457. * For example, swiping up will dispatch an "ArrowUp" event. On desktop,
  22458. * this should cause the previous option to be selected. On mobile, swiping
  22459. * up causes a view to scroll down. As a result, swiping up on mobile should
  22460. * cause the next option to be selected. The Home/End operations remain
  22461. * unchanged because those always represent the first/last options, respectively.
  22462. */
  22463. const mobile = isPlatform('mobile');
  22464. let newOption = null;
  22465. switch (ev.key) {
  22466. case 'ArrowDown':
  22467. newOption = mobile ? this.findPreviousOption() : this.findNextOption();
  22468. break;
  22469. case 'ArrowUp':
  22470. newOption = mobile ? this.findNextOption() : this.findPreviousOption();
  22471. break;
  22472. case 'PageUp':
  22473. newOption = mobile ? this.findNextOption(5) : this.findPreviousOption(5);
  22474. break;
  22475. case 'PageDown':
  22476. newOption = mobile ? this.findPreviousOption(5) : this.findNextOption(5);
  22477. break;
  22478. case 'Home':
  22479. /**
  22480. * There is no guarantee that the first child will be an ion-picker-column-option,
  22481. * so we do not use firstElementChild.
  22482. */
  22483. newOption = this.el.querySelector('ion-picker-column-option:first-of-type');
  22484. break;
  22485. case 'End':
  22486. /**
  22487. * There is no guarantee that the last child will be an ion-picker-column-option,
  22488. * so we do not use lastElementChild.
  22489. */
  22490. newOption = this.el.querySelector('ion-picker-column-option:last-of-type');
  22491. break;
  22492. }
  22493. if (newOption !== null) {
  22494. this.setValue(newOption.value);
  22495. // This stops any default browser behavior such as scrolling
  22496. ev.preventDefault();
  22497. }
  22498. };
  22499. /**
  22500. * Utility to generate the correct text for aria-valuetext.
  22501. */
  22502. this.getOptionValueText = (el) => {
  22503. var _a;
  22504. return el ? (_a = el.getAttribute('aria-label')) !== null && _a !== void 0 ? _a : el.innerText : '';
  22505. };
  22506. /**
  22507. * Render an element that overlays the column. This element is for assistive
  22508. * tech to allow users to navigate the column up/down. This element should receive
  22509. * focus as it listens for synthesized keyboard events as required by the
  22510. * slider role: https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/slider_role
  22511. */
  22512. this.renderAssistiveFocusable = () => {
  22513. const { activeItem } = this;
  22514. const valueText = this.getOptionValueText(activeItem);
  22515. /**
  22516. * When using the picker, the valuetext provides important context that valuenow
  22517. * does not. Additionally, using non-zero valuemin/valuemax values can cause
  22518. * WebKit to incorrectly announce numeric valuetext values (such as a year
  22519. * like "2024") as percentages: https://bugs.webkit.org/show_bug.cgi?id=273126
  22520. */
  22521. 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) }));
  22522. };
  22523. this.ariaLabel = null;
  22524. this.isActive = false;
  22525. this.disabled = false;
  22526. this.value = undefined;
  22527. this.color = 'primary';
  22528. this.numericInput = false;
  22529. }
  22530. ariaLabelChanged(newValue) {
  22531. this.ariaLabel = newValue;
  22532. }
  22533. valueChange() {
  22534. if (this.isColumnVisible) {
  22535. /**
  22536. * Only scroll the active item into view when the picker column
  22537. * is actively visible to the user.
  22538. */
  22539. this.scrollActiveItemIntoView(true);
  22540. }
  22541. }
  22542. /**
  22543. * Only setup scroll listeners
  22544. * when the picker is visible, otherwise
  22545. * the container will have a scroll
  22546. * height of 0px.
  22547. */
  22548. componentWillLoad() {
  22549. /**
  22550. * We cache parentEl in a local variable
  22551. * so we don't need to keep accessing
  22552. * the class variable (which comes with
  22553. * a small performance hit)
  22554. */
  22555. const parentEl = (this.parentEl = this.el.closest('ion-picker'));
  22556. const visibleCallback = (entries) => {
  22557. /**
  22558. * Browsers will sometimes group multiple IO events into a single callback.
  22559. * As a result, we want to grab the last/most recent event in case there are multiple events.
  22560. */
  22561. const ev = entries[entries.length - 1];
  22562. if (ev.isIntersecting) {
  22563. const { activeItem, el } = this;
  22564. this.isColumnVisible = true;
  22565. /**
  22566. * Because this initial call to scrollActiveItemIntoView has to fire before
  22567. * the scroll listener is set up, we need to manage the active class manually.
  22568. */
  22569. const oldActive = getElementRoot(el).querySelector(`.${PICKER_ITEM_ACTIVE_CLASS}`);
  22570. if (oldActive) {
  22571. this.setPickerItemActiveState(oldActive, false);
  22572. }
  22573. this.scrollActiveItemIntoView();
  22574. if (activeItem) {
  22575. this.setPickerItemActiveState(activeItem, true);
  22576. }
  22577. this.initializeScrollListener();
  22578. }
  22579. else {
  22580. this.isColumnVisible = false;
  22581. if (this.destroyScrollListener) {
  22582. this.destroyScrollListener();
  22583. this.destroyScrollListener = undefined;
  22584. }
  22585. }
  22586. };
  22587. /**
  22588. * Set the root to be the parent picker element
  22589. * This causes the IO callback
  22590. * to be fired in WebKit as soon as the element
  22591. * is visible. If we used the default root value
  22592. * then WebKit would only fire the IO callback
  22593. * after any animations (such as a modal transition)
  22594. * finished, and there would potentially be a flicker.
  22595. */
  22596. new IntersectionObserver(visibleCallback, { threshold: 0.001, root: this.parentEl }).observe(this.el);
  22597. if (parentEl !== null) {
  22598. // TODO(FW-2832): type
  22599. parentEl.addEventListener('ionInputModeChange', (ev) => this.inputModeChange(ev));
  22600. }
  22601. }
  22602. componentDidRender() {
  22603. const { el, activeItem, isColumnVisible, value } = this;
  22604. if (isColumnVisible && !activeItem) {
  22605. const firstOption = el.querySelector('ion-picker-column-option');
  22606. /**
  22607. * If the picker column does not have an active item and the current value
  22608. * does not match the first item in the picker column, that means
  22609. * the value is out of bounds. In this case, we assign the value to the
  22610. * first item to match the scroll position of the column.
  22611. *
  22612. */
  22613. if (firstOption !== null && firstOption.value !== value) {
  22614. this.setValue(firstOption.value);
  22615. }
  22616. }
  22617. }
  22618. /** @internal */
  22619. async scrollActiveItemIntoView(smooth = false) {
  22620. const activeEl = this.activeItem;
  22621. if (activeEl) {
  22622. this.centerPickerItemInView(activeEl, smooth, false);
  22623. }
  22624. }
  22625. /**
  22626. * Sets the value prop and fires the ionChange event.
  22627. * This is used when we need to fire ionChange from
  22628. * user-generated events that cannot be caught with normal
  22629. * input/change event listeners.
  22630. * @internal
  22631. */
  22632. async setValue(value) {
  22633. if (this.disabled === true || this.value === value) {
  22634. return;
  22635. }
  22636. this.value = value;
  22637. this.ionChange.emit({ value });
  22638. }
  22639. /**
  22640. * Sets focus on the scrollable container within the picker column.
  22641. * Use this method instead of the global `pickerColumn.focus()`.
  22642. */
  22643. async setFocus() {
  22644. if (this.assistiveFocusable) {
  22645. this.assistiveFocusable.focus();
  22646. }
  22647. }
  22648. connectedCallback() {
  22649. var _a;
  22650. this.ariaLabel = (_a = this.el.getAttribute('aria-label')) !== null && _a !== void 0 ? _a : 'Select a value';
  22651. }
  22652. get activeItem() {
  22653. const { value } = this;
  22654. const options = Array.from(this.el.querySelectorAll('ion-picker-column-option'));
  22655. return options.find((option) => {
  22656. /**
  22657. * If the whole picker column is disabled, the current value should appear active
  22658. * If the current value item is specifically disabled, it should not appear active
  22659. */
  22660. if (!this.disabled && option.disabled) {
  22661. return false;
  22662. }
  22663. return option.value === value;
  22664. });
  22665. }
  22666. render() {
  22667. const { color, disabled, isActive, numericInput } = this;
  22668. const mode = getIonMode$1(this);
  22669. return (hAsync(Host, { key: 'a221dc10f1eb7c41637a16d2c7167c16939822fd', class: createColorClasses$1(color, {
  22670. [mode]: true,
  22671. ['picker-column-active']: isActive,
  22672. ['picker-column-numeric-input']: numericInput,
  22673. ['picker-column-disabled']: disabled,
  22674. }) }, this.renderAssistiveFocusable(), hAsync("slot", { key: '81b0656f606856f3dc0a657bf167d81a5011405e', name: "prefix" }), hAsync("div", { key: '71b9de67c04150255dd66592601c9d926db0c31c', "aria-hidden": "true", class: "picker-opts", ref: (el) => {
  22675. this.scrollEl = el;
  22676. },
  22677. /**
  22678. * When an element has an overlay scroll style and
  22679. * a fixed height, Firefox will focus the scrollable
  22680. * container if the content exceeds the container's
  22681. * dimensions.
  22682. *
  22683. * This causes keyboard navigation to focus to this
  22684. * element instead of going to the next element in
  22685. * the tab order.
  22686. *
  22687. * The desired behavior is for the user to be able to
  22688. * focus the assistive focusable element and tab to
  22689. * the next element in the tab order. Instead of tabbing
  22690. * to this element.
  22691. *
  22692. * To prevent this, we set the tabIndex to -1. This
  22693. * will match the behavior of the other browsers.
  22694. */
  22695. 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" })));
  22696. }
  22697. get el() { return getElement(this); }
  22698. static get watchers() { return {
  22699. "aria-label": ["ariaLabelChanged"],
  22700. "value": ["valueChange"]
  22701. }; }
  22702. static get style() { return IonPickerColumnStyle0; }
  22703. static get cmpMeta() { return {
  22704. "$flags$": 9,
  22705. "$tagName$": "ion-picker-column",
  22706. "$members$": {
  22707. "disabled": [4],
  22708. "value": [1032],
  22709. "color": [513],
  22710. "numericInput": [4, "numeric-input"],
  22711. "ariaLabel": [32],
  22712. "isActive": [32],
  22713. "scrollActiveItemIntoView": [64],
  22714. "setValue": [64],
  22715. "setFocus": [64]
  22716. },
  22717. "$listeners$": undefined,
  22718. "$lazyBundleId$": "-",
  22719. "$attrsToReflect$": [["color", "color"]]
  22720. }; }
  22721. }
  22722. const PICKER_ITEM_ACTIVE_CLASS = 'option-active';
  22723. 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}}";
  22724. var IonPickerLegacyColumnIosStyle0 = pickerColumnIosCss;
  22725. 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)}";
  22726. var IonPickerLegacyColumnMdStyle0 = pickerColumnMdCss;
  22727. /**
  22728. * @internal
  22729. */
  22730. class PickerColumnCmp {
  22731. constructor(hostRef) {
  22732. registerInstance(this, hostRef);
  22733. this.ionPickerColChange = createEvent(this, "ionPickerColChange", 7);
  22734. this.optHeight = 0;
  22735. this.rotateFactor = 0;
  22736. this.scaleFactor = 1;
  22737. this.velocity = 0;
  22738. this.y = 0;
  22739. this.noAnimate = true;
  22740. // `colDidChange` is a flag that gets set when the column is changed
  22741. // dynamically. When this flag is set, the column will refresh
  22742. // after the component re-renders to incorporate the new column data.
  22743. // This is necessary because `this.refresh` queries for the option elements,
  22744. // so it needs to wait for the latest elements to be available in the DOM.
  22745. // Ex: column is created with 3 options. User updates the column data
  22746. // to have 5 options. The column will still think it only has 3 options.
  22747. this.colDidChange = false;
  22748. this.col = undefined;
  22749. }
  22750. colChanged() {
  22751. this.colDidChange = true;
  22752. }
  22753. async connectedCallback() {
  22754. let pickerRotateFactor = 0;
  22755. let pickerScaleFactor = 0.81;
  22756. const mode = getIonMode$1(this);
  22757. if (mode === 'ios') {
  22758. pickerRotateFactor = -0.46;
  22759. pickerScaleFactor = 1;
  22760. }
  22761. this.rotateFactor = pickerRotateFactor;
  22762. this.scaleFactor = pickerScaleFactor;
  22763. this.gesture = (await Promise.resolve().then(function () { return index; })).createGesture({
  22764. el: this.el,
  22765. gestureName: 'picker-swipe',
  22766. gesturePriority: 100,
  22767. threshold: 0,
  22768. passive: false,
  22769. onStart: (ev) => this.onStart(ev),
  22770. onMove: (ev) => this.onMove(ev),
  22771. onEnd: (ev) => this.onEnd(ev),
  22772. });
  22773. this.gesture.enable();
  22774. // Options have not been initialized yet
  22775. // Animation must be disabled through the `noAnimate` flag
  22776. // Otherwise, the options will render
  22777. // at the top of the column and transition down
  22778. this.tmrId = setTimeout(() => {
  22779. this.noAnimate = false;
  22780. // After initialization, `refresh()` will be called
  22781. // At this point, animation will be enabled. The options will
  22782. // animate as they are being selected.
  22783. this.refresh(true);
  22784. }, 250);
  22785. }
  22786. componentDidLoad() {
  22787. this.onDomChange();
  22788. }
  22789. componentDidUpdate() {
  22790. // Options may have changed since last update.
  22791. if (this.colDidChange) {
  22792. // Animation must be disabled through the `onDomChange` parameter.
  22793. // Otherwise, the recently added options will render
  22794. // at the top of the column and transition down
  22795. this.onDomChange(true, false);
  22796. this.colDidChange = false;
  22797. }
  22798. }
  22799. disconnectedCallback() {
  22800. if (this.rafId !== undefined)
  22801. cancelAnimationFrame(this.rafId);
  22802. if (this.tmrId)
  22803. clearTimeout(this.tmrId);
  22804. if (this.gesture) {
  22805. this.gesture.destroy();
  22806. this.gesture = undefined;
  22807. }
  22808. }
  22809. emitColChange() {
  22810. this.ionPickerColChange.emit(this.col);
  22811. }
  22812. setSelected(selectedIndex, duration) {
  22813. // if there is a selected index, then figure out it's y position
  22814. // if there isn't a selected index, then just use the top y position
  22815. const y = selectedIndex > -1 ? -(selectedIndex * this.optHeight) : 0;
  22816. this.velocity = 0;
  22817. // set what y position we're at
  22818. if (this.rafId !== undefined)
  22819. cancelAnimationFrame(this.rafId);
  22820. this.update(y, duration, true);
  22821. this.emitColChange();
  22822. }
  22823. update(y, duration, saveY) {
  22824. if (!this.optsEl) {
  22825. return;
  22826. }
  22827. // ensure we've got a good round number :)
  22828. let translateY = 0;
  22829. let translateZ = 0;
  22830. const { col, rotateFactor } = this;
  22831. const prevSelected = col.selectedIndex;
  22832. const selectedIndex = (col.selectedIndex = this.indexForY(-y));
  22833. const durationStr = duration === 0 ? '' : duration + 'ms';
  22834. const scaleStr = `scale(${this.scaleFactor})`;
  22835. const children = this.optsEl.children;
  22836. for (let i = 0; i < children.length; i++) {
  22837. const button = children[i];
  22838. const opt = col.options[i];
  22839. const optOffset = i * this.optHeight + y;
  22840. let transform = '';
  22841. if (rotateFactor !== 0) {
  22842. const rotateX = optOffset * rotateFactor;
  22843. if (Math.abs(rotateX) <= 90) {
  22844. translateY = 0;
  22845. translateZ = 90;
  22846. transform = `rotateX(${rotateX}deg) `;
  22847. }
  22848. else {
  22849. translateY = -9999;
  22850. }
  22851. }
  22852. else {
  22853. translateZ = 0;
  22854. translateY = optOffset;
  22855. }
  22856. const selected = selectedIndex === i;
  22857. transform += `translate3d(0px,${translateY}px,${translateZ}px) `;
  22858. if (this.scaleFactor !== 1 && !selected) {
  22859. transform += scaleStr;
  22860. }
  22861. // Update transition duration
  22862. if (this.noAnimate) {
  22863. opt.duration = 0;
  22864. button.style.transitionDuration = '';
  22865. }
  22866. else if (duration !== opt.duration) {
  22867. opt.duration = duration;
  22868. button.style.transitionDuration = durationStr;
  22869. }
  22870. // Update transform
  22871. if (transform !== opt.transform) {
  22872. opt.transform = transform;
  22873. }
  22874. button.style.transform = transform;
  22875. /**
  22876. * Ensure that the select column
  22877. * item has the selected class
  22878. */
  22879. opt.selected = selected;
  22880. if (selected) {
  22881. button.classList.add(PICKER_OPT_SELECTED);
  22882. }
  22883. else {
  22884. button.classList.remove(PICKER_OPT_SELECTED);
  22885. }
  22886. }
  22887. this.col.prevSelected = prevSelected;
  22888. if (saveY) {
  22889. this.y = y;
  22890. }
  22891. if (this.lastIndex !== selectedIndex) {
  22892. // have not set a last index yet
  22893. hapticSelectionChanged();
  22894. this.lastIndex = selectedIndex;
  22895. }
  22896. }
  22897. decelerate() {
  22898. if (this.velocity !== 0) {
  22899. // still decelerating
  22900. this.velocity *= DECELERATION_FRICTION;
  22901. // do not let it go slower than a velocity of 1
  22902. this.velocity = this.velocity > 0 ? Math.max(this.velocity, 1) : Math.min(this.velocity, -1);
  22903. let y = this.y + this.velocity;
  22904. if (y > this.minY) {
  22905. // whoops, it's trying to scroll up farther than the options we have!
  22906. y = this.minY;
  22907. this.velocity = 0;
  22908. }
  22909. else if (y < this.maxY) {
  22910. // gahh, it's trying to scroll down farther than we can!
  22911. y = this.maxY;
  22912. this.velocity = 0;
  22913. }
  22914. this.update(y, 0, true);
  22915. const notLockedIn = Math.round(y) % this.optHeight !== 0 || Math.abs(this.velocity) > 1;
  22916. if (notLockedIn) {
  22917. // isn't locked in yet, keep decelerating until it is
  22918. this.rafId = requestAnimationFrame(() => this.decelerate());
  22919. }
  22920. else {
  22921. this.velocity = 0;
  22922. this.emitColChange();
  22923. hapticSelectionEnd();
  22924. }
  22925. }
  22926. else if (this.y % this.optHeight !== 0) {
  22927. // needs to still get locked into a position so options line up
  22928. const currentPos = Math.abs(this.y % this.optHeight);
  22929. // create a velocity in the direction it needs to scroll
  22930. this.velocity = currentPos > this.optHeight / 2 ? 1 : -1;
  22931. this.decelerate();
  22932. }
  22933. }
  22934. indexForY(y) {
  22935. return Math.min(Math.max(Math.abs(Math.round(y / this.optHeight)), 0), this.col.options.length - 1);
  22936. }
  22937. onStart(detail) {
  22938. // We have to prevent default in order to block scrolling under the picker
  22939. // but we DO NOT have to stop propagation, since we still want
  22940. // some "click" events to capture
  22941. if (detail.event.cancelable) {
  22942. detail.event.preventDefault();
  22943. }
  22944. detail.event.stopPropagation();
  22945. hapticSelectionStart();
  22946. // reset everything
  22947. if (this.rafId !== undefined)
  22948. cancelAnimationFrame(this.rafId);
  22949. const options = this.col.options;
  22950. let minY = options.length - 1;
  22951. let maxY = 0;
  22952. for (let i = 0; i < options.length; i++) {
  22953. if (!options[i].disabled) {
  22954. minY = Math.min(minY, i);
  22955. maxY = Math.max(maxY, i);
  22956. }
  22957. }
  22958. this.minY = -(minY * this.optHeight);
  22959. this.maxY = -(maxY * this.optHeight);
  22960. }
  22961. onMove(detail) {
  22962. if (detail.event.cancelable) {
  22963. detail.event.preventDefault();
  22964. }
  22965. detail.event.stopPropagation();
  22966. // update the scroll position relative to pointer start position
  22967. let y = this.y + detail.deltaY;
  22968. if (y > this.minY) {
  22969. // scrolling up higher than scroll area
  22970. y = Math.pow(y, 0.8);
  22971. this.bounceFrom = y;
  22972. }
  22973. else if (y < this.maxY) {
  22974. // scrolling down below scroll area
  22975. y += Math.pow(this.maxY - y, 0.9);
  22976. this.bounceFrom = y;
  22977. }
  22978. else {
  22979. this.bounceFrom = 0;
  22980. }
  22981. this.update(y, 0, false);
  22982. }
  22983. onEnd(detail) {
  22984. if (this.bounceFrom > 0) {
  22985. // bounce back up
  22986. this.update(this.minY, 100, true);
  22987. this.emitColChange();
  22988. return;
  22989. }
  22990. else if (this.bounceFrom < 0) {
  22991. // bounce back down
  22992. this.update(this.maxY, 100, true);
  22993. this.emitColChange();
  22994. return;
  22995. }
  22996. this.velocity = clamp(-MAX_PICKER_SPEED, detail.velocityY * 23, MAX_PICKER_SPEED);
  22997. if (this.velocity === 0 && detail.deltaY === 0) {
  22998. const opt = detail.event.target.closest('.picker-opt');
  22999. if (opt === null || opt === void 0 ? void 0 : opt.hasAttribute('opt-index')) {
  23000. this.setSelected(parseInt(opt.getAttribute('opt-index'), 10), TRANSITION_DURATION);
  23001. }
  23002. }
  23003. else {
  23004. this.y += detail.deltaY;
  23005. if (Math.abs(detail.velocityY) < 0.05) {
  23006. const isScrollingUp = detail.deltaY > 0;
  23007. const optHeightFraction = (Math.abs(this.y) % this.optHeight) / this.optHeight;
  23008. if (isScrollingUp && optHeightFraction > 0.5) {
  23009. this.velocity = Math.abs(this.velocity) * -1;
  23010. }
  23011. else if (!isScrollingUp && optHeightFraction <= 0.5) {
  23012. this.velocity = Math.abs(this.velocity);
  23013. }
  23014. }
  23015. this.decelerate();
  23016. }
  23017. }
  23018. refresh(forceRefresh, animated) {
  23019. var _a;
  23020. let min = this.col.options.length - 1;
  23021. let max = 0;
  23022. const options = this.col.options;
  23023. for (let i = 0; i < options.length; i++) {
  23024. if (!options[i].disabled) {
  23025. min = Math.min(min, i);
  23026. max = Math.max(max, i);
  23027. }
  23028. }
  23029. /**
  23030. * Only update selected value if column has a
  23031. * velocity of 0. If it does not, then the
  23032. * column is animating might land on
  23033. * a value different than the value at
  23034. * selectedIndex
  23035. */
  23036. if (this.velocity !== 0) {
  23037. return;
  23038. }
  23039. const selectedIndex = clamp(min, (_a = this.col.selectedIndex) !== null && _a !== void 0 ? _a : 0, max);
  23040. if (this.col.prevSelected !== selectedIndex || forceRefresh) {
  23041. const y = selectedIndex * this.optHeight * -1;
  23042. const duration = animated ? TRANSITION_DURATION : 0;
  23043. this.velocity = 0;
  23044. this.update(y, duration, true);
  23045. }
  23046. }
  23047. onDomChange(forceRefresh, animated) {
  23048. const colEl = this.optsEl;
  23049. if (colEl) {
  23050. // DOM READ
  23051. // We perfom a DOM read over a rendered item, this needs to happen after the first render or after the the column has changed
  23052. this.optHeight = colEl.firstElementChild ? colEl.firstElementChild.clientHeight : 0;
  23053. }
  23054. this.refresh(forceRefresh, animated);
  23055. }
  23056. render() {
  23057. const col = this.col;
  23058. const mode = getIonMode$1(this);
  23059. 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: {
  23060. 'max-width': this.col.columnWidth,
  23061. } }, 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))));
  23062. }
  23063. get el() { return getElement(this); }
  23064. static get watchers() { return {
  23065. "col": ["colChanged"]
  23066. }; }
  23067. static get style() { return {
  23068. ios: IonPickerLegacyColumnIosStyle0,
  23069. md: IonPickerLegacyColumnMdStyle0
  23070. }; }
  23071. static get cmpMeta() { return {
  23072. "$flags$": 32,
  23073. "$tagName$": "ion-picker-legacy-column",
  23074. "$members$": {
  23075. "col": [16]
  23076. },
  23077. "$listeners$": undefined,
  23078. "$lazyBundleId$": "-",
  23079. "$attrsToReflect$": []
  23080. }; }
  23081. }
  23082. const PICKER_OPT_SELECTED = 'picker-opt-selected';
  23083. const DECELERATION_FRICTION = 0.97;
  23084. const MAX_PICKER_SPEED = 90;
  23085. const TRANSITION_DURATION = 150;
  23086. 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}";
  23087. var IonPickerColumnOptionIosStyle0 = pickerColumnOptionIosCss;
  23088. 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)}";
  23089. var IonPickerColumnOptionMdStyle0 = pickerColumnOptionMdCss;
  23090. class PickerColumnOption {
  23091. constructor(hostRef) {
  23092. registerInstance(this, hostRef);
  23093. /**
  23094. * We keep track of the parent picker column
  23095. * so we can update the value of it when
  23096. * clicking an enable option.
  23097. */
  23098. this.pickerColumn = null;
  23099. this.ariaLabel = null;
  23100. this.disabled = false;
  23101. this.value = undefined;
  23102. this.color = 'primary';
  23103. }
  23104. /**
  23105. * The aria-label of the option has changed after the
  23106. * first render and needs to be updated within the component.
  23107. *
  23108. * @param ariaLbl The new aria-label value.
  23109. */
  23110. onAriaLabelChange(ariaLbl) {
  23111. this.ariaLabel = ariaLbl;
  23112. }
  23113. componentWillLoad() {
  23114. const inheritedAttributes = inheritAttributes$1(this.el, ['aria-label']);
  23115. /**
  23116. * The initial value of `aria-label` needs to be set for
  23117. * the first render.
  23118. */
  23119. this.ariaLabel = inheritedAttributes['aria-label'] || null;
  23120. }
  23121. connectedCallback() {
  23122. this.pickerColumn = this.el.closest('ion-picker-column');
  23123. }
  23124. disconnectedCallback() {
  23125. this.pickerColumn = null;
  23126. }
  23127. /**
  23128. * The column options can load at any time
  23129. * so the options needs to tell the
  23130. * parent picker column when it is loaded
  23131. * so the picker column can ensure it is
  23132. * centered in the view.
  23133. *
  23134. * We intentionally run this for every
  23135. * option. If we only ran this from
  23136. * the selected option then if the newly
  23137. * loaded options were not selected then
  23138. * scrollActiveItemIntoView would not be called.
  23139. */
  23140. componentDidLoad() {
  23141. const { pickerColumn } = this;
  23142. if (pickerColumn !== null) {
  23143. pickerColumn.scrollActiveItemIntoView();
  23144. }
  23145. }
  23146. /**
  23147. * When an option is clicked, update the
  23148. * parent picker column value. This
  23149. * component will handle centering the option
  23150. * in the column view.
  23151. */
  23152. onClick() {
  23153. const { pickerColumn } = this;
  23154. if (pickerColumn !== null) {
  23155. pickerColumn.setValue(this.value);
  23156. }
  23157. }
  23158. render() {
  23159. const { color, disabled, ariaLabel } = this;
  23160. const mode = getIonMode$1(this);
  23161. return (hAsync(Host, { key: 'c1353e99c2aa19c0e3ddbe433557ed18e72e1c66', class: createColorClasses$1(color, {
  23162. [mode]: true,
  23163. ['option-disabled']: disabled,
  23164. }) }, hAsync("button", { key: 'b4ee62ecf7458a07a56e8aa494485766a87a3fcb', tabindex: "-1", "aria-label": ariaLabel, disabled: disabled, onClick: () => this.onClick() }, hAsync("slot", { key: '9ab1e4700c27103b676670a4b3521c183c6ab83d' }))));
  23165. }
  23166. get el() { return getElement(this); }
  23167. static get watchers() { return {
  23168. "aria-label": ["onAriaLabelChange"]
  23169. }; }
  23170. static get style() { return {
  23171. ios: IonPickerColumnOptionIosStyle0,
  23172. md: IonPickerColumnOptionMdStyle0
  23173. }; }
  23174. static get cmpMeta() { return {
  23175. "$flags$": 41,
  23176. "$tagName$": "ion-picker-column-option",
  23177. "$members$": {
  23178. "disabled": [4],
  23179. "value": [8],
  23180. "color": [513],
  23181. "ariaLabel": [32]
  23182. },
  23183. "$listeners$": undefined,
  23184. "$lazyBundleId$": "-",
  23185. "$attrsToReflect$": [["color", "color"]]
  23186. }; }
  23187. }
  23188. /**
  23189. * Returns the dimensions of the popover
  23190. * arrow on `ios` mode. If arrow is disabled
  23191. * returns (0, 0).
  23192. */
  23193. const getArrowDimensions = (arrowEl) => {
  23194. if (!arrowEl) {
  23195. return { arrowWidth: 0, arrowHeight: 0 };
  23196. }
  23197. const { width, height } = arrowEl.getBoundingClientRect();
  23198. return { arrowWidth: width, arrowHeight: height };
  23199. };
  23200. /**
  23201. * Returns the recommended dimensions of the popover
  23202. * that takes into account whether or not the width
  23203. * should match the trigger width.
  23204. */
  23205. const getPopoverDimensions = (size, contentEl, triggerEl) => {
  23206. const contentDimentions = contentEl.getBoundingClientRect();
  23207. const contentHeight = contentDimentions.height;
  23208. let contentWidth = contentDimentions.width;
  23209. if (size === 'cover' && triggerEl) {
  23210. const triggerDimensions = triggerEl.getBoundingClientRect();
  23211. contentWidth = triggerDimensions.width;
  23212. }
  23213. return {
  23214. contentWidth,
  23215. contentHeight,
  23216. };
  23217. };
  23218. const configureDismissInteraction = (triggerEl, triggerAction, popoverEl, parentPopoverEl) => {
  23219. let dismissCallbacks = [];
  23220. const root = getElementRoot(parentPopoverEl);
  23221. const parentContentEl = root.querySelector('.popover-content');
  23222. switch (triggerAction) {
  23223. case 'hover':
  23224. dismissCallbacks = [
  23225. {
  23226. /**
  23227. * Do not use mouseover here
  23228. * as this will causes the event to
  23229. * be dispatched on each underlying
  23230. * element rather than on the popover
  23231. * content as a whole.
  23232. */
  23233. eventName: 'mouseenter',
  23234. callback: (ev) => {
  23235. /**
  23236. * Do not dismiss the popover is we
  23237. * are hovering over its trigger.
  23238. * This would be easier if we used mouseover
  23239. * but this would cause the event to be dispatched
  23240. * more often than we would like, potentially
  23241. * causing performance issues.
  23242. */
  23243. const element = document.elementFromPoint(ev.clientX, ev.clientY);
  23244. if (element === triggerEl) {
  23245. return;
  23246. }
  23247. popoverEl.dismiss(undefined, undefined, false);
  23248. },
  23249. },
  23250. ];
  23251. break;
  23252. case 'context-menu':
  23253. case 'click':
  23254. default:
  23255. dismissCallbacks = [
  23256. {
  23257. eventName: 'click',
  23258. callback: (ev) => {
  23259. /**
  23260. * Do not dismiss the popover is we
  23261. * are hovering over its trigger.
  23262. */
  23263. const target = ev.target;
  23264. const closestTrigger = target.closest('[data-ion-popover-trigger]');
  23265. if (closestTrigger === triggerEl) {
  23266. /**
  23267. * stopPropagation here so if the
  23268. * popover has dismissOnSelect="true"
  23269. * the popover does not dismiss since
  23270. * we just clicked a trigger element.
  23271. */
  23272. ev.stopPropagation();
  23273. return;
  23274. }
  23275. popoverEl.dismiss(undefined, undefined, false);
  23276. },
  23277. },
  23278. ];
  23279. break;
  23280. }
  23281. dismissCallbacks.forEach(({ eventName, callback }) => parentContentEl.addEventListener(eventName, callback));
  23282. return () => {
  23283. dismissCallbacks.forEach(({ eventName, callback }) => parentContentEl.removeEventListener(eventName, callback));
  23284. };
  23285. };
  23286. /**
  23287. * Configures the triggerEl to respond
  23288. * to user interaction based upon the triggerAction
  23289. * prop that devs have defined.
  23290. */
  23291. const configureTriggerInteraction = (triggerEl, triggerAction, popoverEl) => {
  23292. let triggerCallbacks = [];
  23293. /**
  23294. * Based upon the kind of trigger interaction
  23295. * the user wants, we setup the correct event
  23296. * listeners.
  23297. */
  23298. switch (triggerAction) {
  23299. case 'hover':
  23300. let hoverTimeout;
  23301. triggerCallbacks = [
  23302. {
  23303. eventName: 'mouseenter',
  23304. callback: async (ev) => {
  23305. ev.stopPropagation();
  23306. if (hoverTimeout) {
  23307. clearTimeout(hoverTimeout);
  23308. }
  23309. /**
  23310. * Hovering over a trigger should not
  23311. * immediately open the next popover.
  23312. */
  23313. hoverTimeout = setTimeout(() => {
  23314. raf(() => {
  23315. popoverEl.presentFromTrigger(ev);
  23316. hoverTimeout = undefined;
  23317. });
  23318. }, 100);
  23319. },
  23320. },
  23321. {
  23322. eventName: 'mouseleave',
  23323. callback: (ev) => {
  23324. if (hoverTimeout) {
  23325. clearTimeout(hoverTimeout);
  23326. }
  23327. /**
  23328. * If mouse is over another popover
  23329. * that is not this popover then we should
  23330. * close this popover.
  23331. */
  23332. const target = ev.relatedTarget;
  23333. if (!target) {
  23334. return;
  23335. }
  23336. if (target.closest('ion-popover') !== popoverEl) {
  23337. popoverEl.dismiss(undefined, undefined, false);
  23338. }
  23339. },
  23340. },
  23341. {
  23342. /**
  23343. * stopPropagation here prevents the popover
  23344. * from dismissing when dismiss-on-select="true".
  23345. */
  23346. eventName: 'click',
  23347. callback: (ev) => ev.stopPropagation(),
  23348. },
  23349. {
  23350. eventName: 'ionPopoverActivateTrigger',
  23351. callback: (ev) => popoverEl.presentFromTrigger(ev, true),
  23352. },
  23353. ];
  23354. break;
  23355. case 'context-menu':
  23356. triggerCallbacks = [
  23357. {
  23358. eventName: 'contextmenu',
  23359. callback: (ev) => {
  23360. /**
  23361. * Prevents the platform context
  23362. * menu from appearing.
  23363. */
  23364. ev.preventDefault();
  23365. popoverEl.presentFromTrigger(ev);
  23366. },
  23367. },
  23368. {
  23369. eventName: 'click',
  23370. callback: (ev) => ev.stopPropagation(),
  23371. },
  23372. {
  23373. eventName: 'ionPopoverActivateTrigger',
  23374. callback: (ev) => popoverEl.presentFromTrigger(ev, true),
  23375. },
  23376. ];
  23377. break;
  23378. case 'click':
  23379. default:
  23380. triggerCallbacks = [
  23381. {
  23382. /**
  23383. * Do not do a stopPropagation() here
  23384. * because if you had two click triggers
  23385. * then clicking the first trigger and then
  23386. * clicking the second trigger would not cause
  23387. * the first popover to dismiss.
  23388. */
  23389. eventName: 'click',
  23390. callback: (ev) => popoverEl.presentFromTrigger(ev),
  23391. },
  23392. {
  23393. eventName: 'ionPopoverActivateTrigger',
  23394. callback: (ev) => popoverEl.presentFromTrigger(ev, true),
  23395. },
  23396. ];
  23397. break;
  23398. }
  23399. triggerCallbacks.forEach(({ eventName, callback }) => triggerEl.addEventListener(eventName, callback));
  23400. triggerEl.setAttribute('data-ion-popover-trigger', 'true');
  23401. return () => {
  23402. triggerCallbacks.forEach(({ eventName, callback }) => triggerEl.removeEventListener(eventName, callback));
  23403. triggerEl.removeAttribute('data-ion-popover-trigger');
  23404. };
  23405. };
  23406. /**
  23407. * Returns the index of an ion-item in an array of ion-items.
  23408. */
  23409. const getIndexOfItem = (items, item) => {
  23410. if (!item || item.tagName !== 'ION-ITEM') {
  23411. return -1;
  23412. }
  23413. return items.findIndex((el) => el === item);
  23414. };
  23415. /**
  23416. * Given an array of elements and a currently focused ion-item
  23417. * returns the next ion-item relative to the focused one or
  23418. * undefined.
  23419. */
  23420. const getNextItem = (items, currentItem) => {
  23421. const currentItemIndex = getIndexOfItem(items, currentItem);
  23422. return items[currentItemIndex + 1];
  23423. };
  23424. /**
  23425. * Given an array of elements and a currently focused ion-item
  23426. * returns the previous ion-item relative to the focused one or
  23427. * undefined.
  23428. */
  23429. const getPrevItem = (items, currentItem) => {
  23430. const currentItemIndex = getIndexOfItem(items, currentItem);
  23431. return items[currentItemIndex - 1];
  23432. };
  23433. /** Focus the internal button of the ion-item */
  23434. const focusItem = (item) => {
  23435. const root = getElementRoot(item);
  23436. const button = root.querySelector('button');
  23437. if (button) {
  23438. raf(() => button.focus());
  23439. }
  23440. };
  23441. /**
  23442. * Returns `true` if `el` has been designated
  23443. * as a trigger element for an ion-popover.
  23444. */
  23445. const isTriggerElement = (el) => el.hasAttribute('data-ion-popover-trigger');
  23446. const configureKeyboardInteraction = (popoverEl) => {
  23447. const callback = async (ev) => {
  23448. var _a;
  23449. const activeElement = document.activeElement;
  23450. let items = [];
  23451. const targetTagName = (_a = ev.target) === null || _a === void 0 ? void 0 : _a.tagName;
  23452. /**
  23453. * Only handle custom keyboard interactions for the host popover element
  23454. * and children ion-item elements.
  23455. */
  23456. if (targetTagName !== 'ION-POPOVER' && targetTagName !== 'ION-ITEM') {
  23457. return;
  23458. }
  23459. /**
  23460. * Complex selectors with :not() are :not supported
  23461. * in older versions of Chromium so we need to do a
  23462. * try/catch here so errors are not thrown.
  23463. */
  23464. try {
  23465. /**
  23466. * Select all ion-items that are not children of child popovers.
  23467. * i.e. only select ion-item elements that are part of this popover
  23468. */
  23469. items = Array.from(popoverEl.querySelectorAll('ion-item:not(ion-popover ion-popover *):not([disabled])'));
  23470. /* eslint-disable-next-line */
  23471. }
  23472. catch (_b) { }
  23473. switch (ev.key) {
  23474. /**
  23475. * If we are in a child popover
  23476. * then pressing the left arrow key
  23477. * should close this popover and move
  23478. * focus to the popover that presented
  23479. * this one.
  23480. */
  23481. case 'ArrowLeft':
  23482. const parentPopover = await popoverEl.getParentPopover();
  23483. if (parentPopover) {
  23484. popoverEl.dismiss(undefined, undefined, false);
  23485. }
  23486. break;
  23487. /**
  23488. * ArrowDown should move focus to the next focusable ion-item.
  23489. */
  23490. case 'ArrowDown':
  23491. // Disable movement/scroll with keyboard
  23492. ev.preventDefault();
  23493. const nextItem = getNextItem(items, activeElement);
  23494. if (nextItem !== undefined) {
  23495. focusItem(nextItem);
  23496. }
  23497. break;
  23498. /**
  23499. * ArrowUp should move focus to the previous focusable ion-item.
  23500. */
  23501. case 'ArrowUp':
  23502. // Disable movement/scroll with keyboard
  23503. ev.preventDefault();
  23504. const prevItem = getPrevItem(items, activeElement);
  23505. if (prevItem !== undefined) {
  23506. focusItem(prevItem);
  23507. }
  23508. break;
  23509. /**
  23510. * Home should move focus to the first focusable ion-item.
  23511. */
  23512. case 'Home':
  23513. ev.preventDefault();
  23514. const firstItem = items[0];
  23515. if (firstItem !== undefined) {
  23516. focusItem(firstItem);
  23517. }
  23518. break;
  23519. /**
  23520. * End should move focus to the last focusable ion-item.
  23521. */
  23522. case 'End':
  23523. ev.preventDefault();
  23524. const lastItem = items[items.length - 1];
  23525. if (lastItem !== undefined) {
  23526. focusItem(lastItem);
  23527. }
  23528. break;
  23529. /**
  23530. * ArrowRight, Spacebar, or Enter should activate
  23531. * the currently focused trigger item to open a
  23532. * popover if the element is a trigger item.
  23533. */
  23534. case 'ArrowRight':
  23535. case ' ':
  23536. case 'Enter':
  23537. if (activeElement && isTriggerElement(activeElement)) {
  23538. const rightEvent = new CustomEvent('ionPopoverActivateTrigger');
  23539. activeElement.dispatchEvent(rightEvent);
  23540. }
  23541. break;
  23542. }
  23543. };
  23544. popoverEl.addEventListener('keydown', callback);
  23545. return () => popoverEl.removeEventListener('keydown', callback);
  23546. };
  23547. /**
  23548. * Positions a popover by taking into account
  23549. * the reference point, preferred side, alignment
  23550. * and viewport dimensions.
  23551. */
  23552. const getPopoverPosition = (isRTL, contentWidth, contentHeight, arrowWidth, arrowHeight, reference, side, align, defaultPosition, triggerEl, event) => {
  23553. var _a;
  23554. let referenceCoordinates = {
  23555. top: 0,
  23556. left: 0,
  23557. width: 0,
  23558. height: 0,
  23559. };
  23560. /**
  23561. * Calculate position relative to the
  23562. * x-y coordinates in the event that
  23563. * was passed in
  23564. */
  23565. switch (reference) {
  23566. case 'event':
  23567. if (!event) {
  23568. return defaultPosition;
  23569. }
  23570. const mouseEv = event;
  23571. referenceCoordinates = {
  23572. top: mouseEv.clientY,
  23573. left: mouseEv.clientX,
  23574. width: 1,
  23575. height: 1,
  23576. };
  23577. break;
  23578. /**
  23579. * Calculate position relative to the bounding
  23580. * box on either the trigger element
  23581. * specified via the `trigger` prop or
  23582. * the target specified on the event
  23583. * that was passed in.
  23584. */
  23585. case 'trigger':
  23586. default:
  23587. const customEv = event;
  23588. /**
  23589. * ionShadowTarget is used when we need to align the
  23590. * popover with an element inside of the shadow root
  23591. * of an Ionic component. Ex: Presenting a popover
  23592. * by clicking on the collapsed indicator inside
  23593. * of `ion-breadcrumb` and centering it relative
  23594. * to the indicator rather than `ion-breadcrumb`
  23595. * as a whole.
  23596. */
  23597. const actualTriggerEl = (triggerEl ||
  23598. ((_a = customEv === null || customEv === void 0 ? void 0 : customEv.detail) === null || _a === void 0 ? void 0 : _a.ionShadowTarget) ||
  23599. (customEv === null || customEv === void 0 ? void 0 : customEv.target));
  23600. if (!actualTriggerEl) {
  23601. return defaultPosition;
  23602. }
  23603. const triggerBoundingBox = actualTriggerEl.getBoundingClientRect();
  23604. referenceCoordinates = {
  23605. top: triggerBoundingBox.top,
  23606. left: triggerBoundingBox.left,
  23607. width: triggerBoundingBox.width,
  23608. height: triggerBoundingBox.height,
  23609. };
  23610. break;
  23611. }
  23612. /**
  23613. * Get top/left offset that would allow
  23614. * popover to be positioned on the
  23615. * preferred side of the reference.
  23616. */
  23617. const coordinates = calculatePopoverSide(side, referenceCoordinates, contentWidth, contentHeight, arrowWidth, arrowHeight, isRTL);
  23618. /**
  23619. * Get the top/left adjustments that
  23620. * would allow the popover content
  23621. * to have the correct alignment.
  23622. */
  23623. const alignedCoordinates = calculatePopoverAlign(align, side, referenceCoordinates, contentWidth, contentHeight);
  23624. const top = coordinates.top + alignedCoordinates.top;
  23625. const left = coordinates.left + alignedCoordinates.left;
  23626. const { arrowTop, arrowLeft } = calculateArrowPosition(side, arrowWidth, arrowHeight, top, left, contentWidth, contentHeight, isRTL);
  23627. const { originX, originY } = calculatePopoverOrigin(side, align, isRTL);
  23628. return { top, left, referenceCoordinates, arrowTop, arrowLeft, originX, originY };
  23629. };
  23630. /**
  23631. * Determines the transform-origin
  23632. * of the popover animation so that it
  23633. * is in line with what the side and alignment
  23634. * prop values are. Currently only used
  23635. * with the MD animation.
  23636. */
  23637. const calculatePopoverOrigin = (side, align, isRTL) => {
  23638. switch (side) {
  23639. case 'top':
  23640. return { originX: getOriginXAlignment(align), originY: 'bottom' };
  23641. case 'bottom':
  23642. return { originX: getOriginXAlignment(align), originY: 'top' };
  23643. case 'left':
  23644. return { originX: 'right', originY: getOriginYAlignment(align) };
  23645. case 'right':
  23646. return { originX: 'left', originY: getOriginYAlignment(align) };
  23647. case 'start':
  23648. return { originX: isRTL ? 'left' : 'right', originY: getOriginYAlignment(align) };
  23649. case 'end':
  23650. return { originX: isRTL ? 'right' : 'left', originY: getOriginYAlignment(align) };
  23651. }
  23652. };
  23653. const getOriginXAlignment = (align) => {
  23654. switch (align) {
  23655. case 'start':
  23656. return 'left';
  23657. case 'center':
  23658. return 'center';
  23659. case 'end':
  23660. return 'right';
  23661. }
  23662. };
  23663. const getOriginYAlignment = (align) => {
  23664. switch (align) {
  23665. case 'start':
  23666. return 'top';
  23667. case 'center':
  23668. return 'center';
  23669. case 'end':
  23670. return 'bottom';
  23671. }
  23672. };
  23673. /**
  23674. * Calculates where the arrow positioning
  23675. * should be relative to the popover content.
  23676. */
  23677. const calculateArrowPosition = (side, arrowWidth, arrowHeight, top, left, contentWidth, contentHeight, isRTL) => {
  23678. /**
  23679. * Note: When side is left, right, start, or end, the arrow is
  23680. * been rotated using a `transform`, so to move the arrow up or down
  23681. * by its dimension, you need to use `arrowWidth`.
  23682. */
  23683. const leftPosition = {
  23684. arrowTop: top + contentHeight / 2 - arrowWidth / 2,
  23685. arrowLeft: left + contentWidth - arrowWidth / 2,
  23686. };
  23687. /**
  23688. * Move the arrow to the left by arrowWidth and then
  23689. * again by half of its width because we have rotated
  23690. * the arrow using a transform.
  23691. */
  23692. const rightPosition = { arrowTop: top + contentHeight / 2 - arrowWidth / 2, arrowLeft: left - arrowWidth * 1.5 };
  23693. switch (side) {
  23694. case 'top':
  23695. return { arrowTop: top + contentHeight, arrowLeft: left + contentWidth / 2 - arrowWidth / 2 };
  23696. case 'bottom':
  23697. return { arrowTop: top - arrowHeight, arrowLeft: left + contentWidth / 2 - arrowWidth / 2 };
  23698. case 'left':
  23699. return leftPosition;
  23700. case 'right':
  23701. return rightPosition;
  23702. case 'start':
  23703. return isRTL ? rightPosition : leftPosition;
  23704. case 'end':
  23705. return isRTL ? leftPosition : rightPosition;
  23706. default:
  23707. return { arrowTop: 0, arrowLeft: 0 };
  23708. }
  23709. };
  23710. /**
  23711. * Calculates the required top/left
  23712. * values needed to position the popover
  23713. * content on the side specified in the
  23714. * `side` prop.
  23715. */
  23716. const calculatePopoverSide = (side, triggerBoundingBox, contentWidth, contentHeight, arrowWidth, arrowHeight, isRTL) => {
  23717. const sideLeft = {
  23718. top: triggerBoundingBox.top,
  23719. left: triggerBoundingBox.left - contentWidth - arrowWidth,
  23720. };
  23721. const sideRight = {
  23722. top: triggerBoundingBox.top,
  23723. left: triggerBoundingBox.left + triggerBoundingBox.width + arrowWidth,
  23724. };
  23725. switch (side) {
  23726. case 'top':
  23727. return {
  23728. top: triggerBoundingBox.top - contentHeight - arrowHeight,
  23729. left: triggerBoundingBox.left,
  23730. };
  23731. case 'right':
  23732. return sideRight;
  23733. case 'bottom':
  23734. return {
  23735. top: triggerBoundingBox.top + triggerBoundingBox.height + arrowHeight,
  23736. left: triggerBoundingBox.left,
  23737. };
  23738. case 'left':
  23739. return sideLeft;
  23740. case 'start':
  23741. return isRTL ? sideRight : sideLeft;
  23742. case 'end':
  23743. return isRTL ? sideLeft : sideRight;
  23744. }
  23745. };
  23746. /**
  23747. * Calculates the required top/left
  23748. * offset values needed to provide the
  23749. * correct alignment regardless while taking
  23750. * into account the side the popover is on.
  23751. */
  23752. const calculatePopoverAlign = (align, side, triggerBoundingBox, contentWidth, contentHeight) => {
  23753. switch (align) {
  23754. case 'center':
  23755. return calculatePopoverCenterAlign(side, triggerBoundingBox, contentWidth, contentHeight);
  23756. case 'end':
  23757. return calculatePopoverEndAlign(side, triggerBoundingBox, contentWidth, contentHeight);
  23758. case 'start':
  23759. default:
  23760. return { top: 0, left: 0 };
  23761. }
  23762. };
  23763. /**
  23764. * Calculate the end alignment for
  23765. * the popover. If side is on the x-axis
  23766. * then the align values refer to the top
  23767. * and bottom margins of the content.
  23768. * If side is on the y-axis then the
  23769. * align values refer to the left and right
  23770. * margins of the content.
  23771. */
  23772. const calculatePopoverEndAlign = (side, triggerBoundingBox, contentWidth, contentHeight) => {
  23773. switch (side) {
  23774. case 'start':
  23775. case 'end':
  23776. case 'left':
  23777. case 'right':
  23778. return {
  23779. top: -(contentHeight - triggerBoundingBox.height),
  23780. left: 0,
  23781. };
  23782. case 'top':
  23783. case 'bottom':
  23784. default:
  23785. return {
  23786. top: 0,
  23787. left: -(contentWidth - triggerBoundingBox.width),
  23788. };
  23789. }
  23790. };
  23791. /**
  23792. * Calculate the center alignment for
  23793. * the popover. If side is on the x-axis
  23794. * then the align values refer to the top
  23795. * and bottom margins of the content.
  23796. * If side is on the y-axis then the
  23797. * align values refer to the left and right
  23798. * margins of the content.
  23799. */
  23800. const calculatePopoverCenterAlign = (side, triggerBoundingBox, contentWidth, contentHeight) => {
  23801. switch (side) {
  23802. case 'start':
  23803. case 'end':
  23804. case 'left':
  23805. case 'right':
  23806. return {
  23807. top: -(contentHeight / 2 - triggerBoundingBox.height / 2),
  23808. left: 0,
  23809. };
  23810. case 'top':
  23811. case 'bottom':
  23812. default:
  23813. return {
  23814. top: 0,
  23815. left: -(contentWidth / 2 - triggerBoundingBox.width / 2),
  23816. };
  23817. }
  23818. };
  23819. /**
  23820. * Adjusts popover positioning coordinates
  23821. * such that popover does not appear offscreen
  23822. * or overlapping safe area bounds.
  23823. */
  23824. const calculateWindowAdjustment = (side, coordTop, coordLeft, bodyPadding, bodyWidth, bodyHeight, contentWidth, contentHeight, safeAreaMargin, contentOriginX, contentOriginY, triggerCoordinates, coordArrowTop = 0, coordArrowLeft = 0, arrowHeight = 0) => {
  23825. let arrowTop = coordArrowTop;
  23826. const arrowLeft = coordArrowLeft;
  23827. let left = coordLeft;
  23828. let top = coordTop;
  23829. let bottom;
  23830. let originX = contentOriginX;
  23831. let originY = contentOriginY;
  23832. let checkSafeAreaLeft = false;
  23833. let checkSafeAreaRight = false;
  23834. const triggerTop = triggerCoordinates
  23835. ? triggerCoordinates.top + triggerCoordinates.height
  23836. : bodyHeight / 2 - contentHeight / 2;
  23837. const triggerHeight = triggerCoordinates ? triggerCoordinates.height : 0;
  23838. let addPopoverBottomClass = false;
  23839. /**
  23840. * Adjust popover so it does not
  23841. * go off the left of the screen.
  23842. */
  23843. if (left < bodyPadding + safeAreaMargin) {
  23844. left = bodyPadding;
  23845. checkSafeAreaLeft = true;
  23846. originX = 'left';
  23847. /**
  23848. * Adjust popover so it does not
  23849. * go off the right of the screen.
  23850. */
  23851. }
  23852. else if (contentWidth + bodyPadding + left + safeAreaMargin > bodyWidth) {
  23853. checkSafeAreaRight = true;
  23854. left = bodyWidth - contentWidth - bodyPadding;
  23855. originX = 'right';
  23856. }
  23857. /**
  23858. * Adjust popover so it does not
  23859. * go off the top of the screen.
  23860. * If popover is on the left or the right of
  23861. * the trigger, then we should not adjust top
  23862. * margins.
  23863. */
  23864. if (triggerTop + triggerHeight + contentHeight > bodyHeight && (side === 'top' || side === 'bottom')) {
  23865. if (triggerTop - contentHeight > 0) {
  23866. /**
  23867. * While we strive to align the popover with the trigger
  23868. * on smaller screens this is not always possible. As a result,
  23869. * we adjust the popover up so that it does not hang
  23870. * off the bottom of the screen. However, we do not want to move
  23871. * the popover up so much that it goes off the top of the screen.
  23872. *
  23873. * We chose 12 here so that the popover position looks a bit nicer as
  23874. * it is not right up against the edge of the screen.
  23875. */
  23876. top = Math.max(12, triggerTop - contentHeight - triggerHeight - (arrowHeight - 1));
  23877. arrowTop = top + contentHeight;
  23878. originY = 'bottom';
  23879. addPopoverBottomClass = true;
  23880. /**
  23881. * If not enough room for popover to appear
  23882. * above trigger, then cut it off.
  23883. */
  23884. }
  23885. else {
  23886. bottom = bodyPadding;
  23887. }
  23888. }
  23889. return {
  23890. top,
  23891. left,
  23892. bottom,
  23893. originX,
  23894. originY,
  23895. checkSafeAreaLeft,
  23896. checkSafeAreaRight,
  23897. arrowTop,
  23898. arrowLeft,
  23899. addPopoverBottomClass,
  23900. };
  23901. };
  23902. const shouldShowArrow = (side, didAdjustBounds = false, ev, trigger) => {
  23903. /**
  23904. * If no event provided and
  23905. * we do not have a trigger,
  23906. * then this popover was likely
  23907. * presented via the popoverController
  23908. * or users called `present` manually.
  23909. * In this case, the arrow should not be
  23910. * shown as we do not have a reference.
  23911. */
  23912. if (!ev && !trigger) {
  23913. return false;
  23914. }
  23915. /**
  23916. * If popover is on the left or the right
  23917. * of a trigger, but we needed to adjust the
  23918. * popover due to screen bounds, then we should
  23919. * hide the arrow as it will never be pointing
  23920. * at the trigger.
  23921. */
  23922. if (side !== 'top' && side !== 'bottom' && didAdjustBounds) {
  23923. return false;
  23924. }
  23925. return true;
  23926. };
  23927. const POPOVER_IOS_BODY_PADDING = 5;
  23928. /**
  23929. * iOS Popover Enter Animation
  23930. */
  23931. // TODO(FW-2832): types
  23932. const iosEnterAnimation$1 = (baseEl, opts) => {
  23933. var _a;
  23934. const { event: ev, size, trigger, reference, side, align } = opts;
  23935. const doc = baseEl.ownerDocument;
  23936. const isRTL = doc.dir === 'rtl';
  23937. const bodyWidth = doc.defaultView.innerWidth;
  23938. const bodyHeight = doc.defaultView.innerHeight;
  23939. const root = getElementRoot(baseEl);
  23940. const contentEl = root.querySelector('.popover-content');
  23941. const arrowEl = root.querySelector('.popover-arrow');
  23942. 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);
  23943. const { contentWidth, contentHeight } = getPopoverDimensions(size, contentEl, referenceSizeEl);
  23944. const { arrowWidth, arrowHeight } = getArrowDimensions(arrowEl);
  23945. const defaultPosition = {
  23946. top: bodyHeight / 2 - contentHeight / 2,
  23947. left: bodyWidth / 2 - contentWidth / 2,
  23948. originX: isRTL ? 'right' : 'left',
  23949. originY: 'top',
  23950. };
  23951. const results = getPopoverPosition(isRTL, contentWidth, contentHeight, arrowWidth, arrowHeight, reference, side, align, defaultPosition, trigger, ev);
  23952. const padding = size === 'cover' ? 0 : POPOVER_IOS_BODY_PADDING;
  23953. const margin = size === 'cover' ? 0 : 25;
  23954. 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);
  23955. const baseAnimation = createAnimation();
  23956. const backdropAnimation = createAnimation();
  23957. const contentAnimation = createAnimation();
  23958. backdropAnimation
  23959. .addElement(root.querySelector('ion-backdrop'))
  23960. .fromTo('opacity', 0.01, 'var(--backdrop-opacity)')
  23961. .beforeStyles({
  23962. 'pointer-events': 'none',
  23963. })
  23964. .afterClearStyles(['pointer-events']);
  23965. // In Chromium, if the wrapper animates, the backdrop filter doesn't work.
  23966. // 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.
  23967. // To get around this, instead of animating the wrapper, animate both the arrow and content.
  23968. // https://bugs.chromium.org/p/chromium/issues/detail?id=1148826
  23969. contentAnimation
  23970. .addElement(root.querySelector('.popover-arrow'))
  23971. .addElement(root.querySelector('.popover-content'))
  23972. .fromTo('opacity', 0.01, 1);
  23973. // TODO(FW-4376) Ensure that arrow also blurs when translucent
  23974. return baseAnimation
  23975. .easing('ease')
  23976. .duration(100)
  23977. .beforeAddWrite(() => {
  23978. if (size === 'cover') {
  23979. baseEl.style.setProperty('--width', `${contentWidth}px`);
  23980. }
  23981. if (addPopoverBottomClass) {
  23982. baseEl.classList.add('popover-bottom');
  23983. }
  23984. if (bottom !== undefined) {
  23985. contentEl.style.setProperty('bottom', `${bottom}px`);
  23986. }
  23987. const safeAreaLeft = ' + var(--ion-safe-area-left, 0)';
  23988. const safeAreaRight = ' - var(--ion-safe-area-right, 0)';
  23989. let leftValue = `${left}px`;
  23990. if (checkSafeAreaLeft) {
  23991. leftValue = `${left}px${safeAreaLeft}`;
  23992. }
  23993. if (checkSafeAreaRight) {
  23994. leftValue = `${left}px${safeAreaRight}`;
  23995. }
  23996. contentEl.style.setProperty('top', `calc(${top}px + var(--offset-y, 0))`);
  23997. contentEl.style.setProperty('left', `calc(${leftValue} + var(--offset-x, 0))`);
  23998. contentEl.style.setProperty('transform-origin', `${originY} ${originX}`);
  23999. if (arrowEl !== null) {
  24000. const didAdjustBounds = results.top !== top || results.left !== left;
  24001. const showArrow = shouldShowArrow(side, didAdjustBounds, ev, trigger);
  24002. if (showArrow) {
  24003. arrowEl.style.setProperty('top', `calc(${arrowTop}px + var(--offset-y, 0))`);
  24004. arrowEl.style.setProperty('left', `calc(${arrowLeft}px + var(--offset-x, 0))`);
  24005. }
  24006. else {
  24007. arrowEl.style.setProperty('display', 'none');
  24008. }
  24009. }
  24010. })
  24011. .addAnimation([backdropAnimation, contentAnimation]);
  24012. };
  24013. /**
  24014. * iOS Popover Leave Animation
  24015. */
  24016. const iosLeaveAnimation$1 = (baseEl) => {
  24017. const root = getElementRoot(baseEl);
  24018. const contentEl = root.querySelector('.popover-content');
  24019. const arrowEl = root.querySelector('.popover-arrow');
  24020. const baseAnimation = createAnimation();
  24021. const backdropAnimation = createAnimation();
  24022. const contentAnimation = createAnimation();
  24023. backdropAnimation.addElement(root.querySelector('ion-backdrop')).fromTo('opacity', 'var(--backdrop-opacity)', 0);
  24024. contentAnimation
  24025. .addElement(root.querySelector('.popover-arrow'))
  24026. .addElement(root.querySelector('.popover-content'))
  24027. .fromTo('opacity', 0.99, 0);
  24028. return baseAnimation
  24029. .easing('ease')
  24030. .afterAddWrite(() => {
  24031. baseEl.style.removeProperty('--width');
  24032. baseEl.classList.remove('popover-bottom');
  24033. contentEl.style.removeProperty('top');
  24034. contentEl.style.removeProperty('left');
  24035. contentEl.style.removeProperty('bottom');
  24036. contentEl.style.removeProperty('transform-origin');
  24037. if (arrowEl) {
  24038. arrowEl.style.removeProperty('top');
  24039. arrowEl.style.removeProperty('left');
  24040. arrowEl.style.removeProperty('display');
  24041. }
  24042. })
  24043. .duration(300)
  24044. .addAnimation([backdropAnimation, contentAnimation]);
  24045. };
  24046. const POPOVER_MD_BODY_PADDING = 12;
  24047. /**
  24048. * Md Popover Enter Animation
  24049. */
  24050. // TODO(FW-2832): types
  24051. const mdEnterAnimation$1 = (baseEl, opts) => {
  24052. var _a;
  24053. const { event: ev, size, trigger, reference, side, align } = opts;
  24054. const doc = baseEl.ownerDocument;
  24055. const isRTL = doc.dir === 'rtl';
  24056. const bodyWidth = doc.defaultView.innerWidth;
  24057. const bodyHeight = doc.defaultView.innerHeight;
  24058. const root = getElementRoot(baseEl);
  24059. const contentEl = root.querySelector('.popover-content');
  24060. 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);
  24061. const { contentWidth, contentHeight } = getPopoverDimensions(size, contentEl, referenceSizeEl);
  24062. const defaultPosition = {
  24063. top: bodyHeight / 2 - contentHeight / 2,
  24064. left: bodyWidth / 2 - contentWidth / 2,
  24065. originX: isRTL ? 'right' : 'left',
  24066. originY: 'top',
  24067. };
  24068. const results = getPopoverPosition(isRTL, contentWidth, contentHeight, 0, 0, reference, side, align, defaultPosition, trigger, ev);
  24069. const padding = size === 'cover' ? 0 : POPOVER_MD_BODY_PADDING;
  24070. const { originX, originY, top, left, bottom } = calculateWindowAdjustment(side, results.top, results.left, padding, bodyWidth, bodyHeight, contentWidth, contentHeight, 0, results.originX, results.originY, results.referenceCoordinates);
  24071. const baseAnimation = createAnimation();
  24072. const backdropAnimation = createAnimation();
  24073. const wrapperAnimation = createAnimation();
  24074. const contentAnimation = createAnimation();
  24075. const viewportAnimation = createAnimation();
  24076. backdropAnimation
  24077. .addElement(root.querySelector('ion-backdrop'))
  24078. .fromTo('opacity', 0.01, 'var(--backdrop-opacity)')
  24079. .beforeStyles({
  24080. 'pointer-events': 'none',
  24081. })
  24082. .afterClearStyles(['pointer-events']);
  24083. wrapperAnimation.addElement(root.querySelector('.popover-wrapper')).duration(150).fromTo('opacity', 0.01, 1);
  24084. contentAnimation
  24085. .addElement(contentEl)
  24086. .beforeStyles({
  24087. top: `calc(${top}px + var(--offset-y, 0px))`,
  24088. left: `calc(${left}px + var(--offset-x, 0px))`,
  24089. 'transform-origin': `${originY} ${originX}`,
  24090. })
  24091. .beforeAddWrite(() => {
  24092. if (bottom !== undefined) {
  24093. contentEl.style.setProperty('bottom', `${bottom}px`);
  24094. }
  24095. })
  24096. .fromTo('transform', 'scale(0.8)', 'scale(1)');
  24097. viewportAnimation.addElement(root.querySelector('.popover-viewport')).fromTo('opacity', 0.01, 1);
  24098. return baseAnimation
  24099. .easing('cubic-bezier(0.36,0.66,0.04,1)')
  24100. .duration(300)
  24101. .beforeAddWrite(() => {
  24102. if (size === 'cover') {
  24103. baseEl.style.setProperty('--width', `${contentWidth}px`);
  24104. }
  24105. if (originY === 'bottom') {
  24106. baseEl.classList.add('popover-bottom');
  24107. }
  24108. })
  24109. .addAnimation([backdropAnimation, wrapperAnimation, contentAnimation, viewportAnimation]);
  24110. };
  24111. /**
  24112. * Md Popover Leave Animation
  24113. */
  24114. const mdLeaveAnimation$1 = (baseEl) => {
  24115. const root = getElementRoot(baseEl);
  24116. const contentEl = root.querySelector('.popover-content');
  24117. const baseAnimation = createAnimation();
  24118. const backdropAnimation = createAnimation();
  24119. const wrapperAnimation = createAnimation();
  24120. backdropAnimation.addElement(root.querySelector('ion-backdrop')).fromTo('opacity', 'var(--backdrop-opacity)', 0);
  24121. wrapperAnimation.addElement(root.querySelector('.popover-wrapper')).fromTo('opacity', 0.99, 0);
  24122. return baseAnimation
  24123. .easing('ease')
  24124. .afterAddWrite(() => {
  24125. baseEl.style.removeProperty('--width');
  24126. baseEl.classList.remove('popover-bottom');
  24127. contentEl.style.removeProperty('top');
  24128. contentEl.style.removeProperty('left');
  24129. contentEl.style.removeProperty('bottom');
  24130. contentEl.style.removeProperty('transform-origin');
  24131. })
  24132. .duration(150)
  24133. .addAnimation([backdropAnimation, wrapperAnimation]);
  24134. };
  24135. 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)}}";
  24136. var IonPopoverIosStyle0 = popoverIosCss;
  24137. 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}";
  24138. var IonPopoverMdStyle0 = popoverMdCss;
  24139. // TODO(FW-2832): types
  24140. /**
  24141. * @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
  24142. *
  24143. * @slot - Content is placed inside of the `.popover-content` element.
  24144. *
  24145. * @part backdrop - The `ion-backdrop` element.
  24146. * @part arrow - The arrow that points to the reference element. Only applies on `ios` mode.
  24147. * @part content - The wrapper element for the default slot.
  24148. */
  24149. class Popover {
  24150. constructor(hostRef) {
  24151. registerInstance(this, hostRef);
  24152. this.didPresent = createEvent(this, "ionPopoverDidPresent", 7);
  24153. this.willPresent = createEvent(this, "ionPopoverWillPresent", 7);
  24154. this.willDismiss = createEvent(this, "ionPopoverWillDismiss", 7);
  24155. this.didDismiss = createEvent(this, "ionPopoverDidDismiss", 7);
  24156. this.didPresentShorthand = createEvent(this, "didPresent", 7);
  24157. this.willPresentShorthand = createEvent(this, "willPresent", 7);
  24158. this.willDismissShorthand = createEvent(this, "willDismiss", 7);
  24159. this.didDismissShorthand = createEvent(this, "didDismiss", 7);
  24160. this.ionMount = createEvent(this, "ionMount", 7);
  24161. this.parentPopover = null;
  24162. this.coreDelegate = CoreDelegate();
  24163. this.lockController = createLockController();
  24164. this.inline = false;
  24165. this.focusDescendantOnPresent = false;
  24166. this.onBackdropTap = () => {
  24167. this.dismiss(undefined, BACKDROP);
  24168. };
  24169. this.onLifecycle = (modalEvent) => {
  24170. const el = this.usersElement;
  24171. const name = LIFECYCLE_MAP[modalEvent.type];
  24172. if (el && name) {
  24173. const event = new CustomEvent(name, {
  24174. bubbles: false,
  24175. cancelable: false,
  24176. detail: modalEvent.detail,
  24177. });
  24178. el.dispatchEvent(event);
  24179. }
  24180. };
  24181. this.configureTriggerInteraction = () => {
  24182. const { trigger, triggerAction, el, destroyTriggerInteraction } = this;
  24183. if (destroyTriggerInteraction) {
  24184. destroyTriggerInteraction();
  24185. }
  24186. if (trigger === undefined) {
  24187. return;
  24188. }
  24189. const triggerEl = (this.triggerEl = trigger !== undefined ? document.getElementById(trigger) : null);
  24190. if (!triggerEl) {
  24191. 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);
  24192. return;
  24193. }
  24194. this.destroyTriggerInteraction = configureTriggerInteraction(triggerEl, triggerAction, el);
  24195. };
  24196. this.configureKeyboardInteraction = () => {
  24197. const { destroyKeyboardInteraction, el } = this;
  24198. if (destroyKeyboardInteraction) {
  24199. destroyKeyboardInteraction();
  24200. }
  24201. this.destroyKeyboardInteraction = configureKeyboardInteraction(el);
  24202. };
  24203. this.configureDismissInteraction = () => {
  24204. const { destroyDismissInteraction, parentPopover, triggerAction, triggerEl, el } = this;
  24205. if (!parentPopover || !triggerEl) {
  24206. return;
  24207. }
  24208. if (destroyDismissInteraction) {
  24209. destroyDismissInteraction();
  24210. }
  24211. this.destroyDismissInteraction = configureDismissInteraction(triggerEl, triggerAction, el, parentPopover);
  24212. };
  24213. this.presented = false;
  24214. this.hasController = false;
  24215. this.delegate = undefined;
  24216. this.overlayIndex = undefined;
  24217. this.enterAnimation = undefined;
  24218. this.leaveAnimation = undefined;
  24219. this.component = undefined;
  24220. this.componentProps = undefined;
  24221. this.keyboardClose = true;
  24222. this.cssClass = undefined;
  24223. this.backdropDismiss = true;
  24224. this.event = undefined;
  24225. this.showBackdrop = true;
  24226. this.translucent = false;
  24227. this.animated = true;
  24228. this.htmlAttributes = undefined;
  24229. this.triggerAction = 'click';
  24230. this.trigger = undefined;
  24231. this.size = 'auto';
  24232. this.dismissOnSelect = false;
  24233. this.reference = 'trigger';
  24234. this.side = 'bottom';
  24235. this.alignment = undefined;
  24236. this.arrow = true;
  24237. this.isOpen = false;
  24238. this.keyboardEvents = false;
  24239. this.focusTrap = true;
  24240. this.keepContentsMounted = false;
  24241. }
  24242. onTriggerChange() {
  24243. this.configureTriggerInteraction();
  24244. }
  24245. onIsOpenChange(newValue, oldValue) {
  24246. if (newValue === true && oldValue === false) {
  24247. this.present();
  24248. }
  24249. else if (newValue === false && oldValue === true) {
  24250. this.dismiss();
  24251. }
  24252. }
  24253. connectedCallback() {
  24254. const { configureTriggerInteraction, el } = this;
  24255. prepareOverlay(el);
  24256. configureTriggerInteraction();
  24257. }
  24258. disconnectedCallback() {
  24259. const { destroyTriggerInteraction } = this;
  24260. if (destroyTriggerInteraction) {
  24261. destroyTriggerInteraction();
  24262. }
  24263. }
  24264. componentWillLoad() {
  24265. var _a, _b;
  24266. const { el } = this;
  24267. const popoverId = (_b = (_a = this.htmlAttributes) === null || _a === void 0 ? void 0 : _a.id) !== null && _b !== void 0 ? _b : setOverlayId(el);
  24268. this.parentPopover = el.closest(`ion-popover:not(#${popoverId})`);
  24269. if (this.alignment === undefined) {
  24270. this.alignment = getIonMode$1(this) === 'ios' ? 'center' : 'start';
  24271. }
  24272. }
  24273. componentDidLoad() {
  24274. const { parentPopover, isOpen } = this;
  24275. /**
  24276. * If popover was rendered with isOpen="true"
  24277. * then we should open popover immediately.
  24278. */
  24279. if (isOpen === true) {
  24280. raf(() => this.present());
  24281. }
  24282. if (parentPopover) {
  24283. addEventListener$1(parentPopover, 'ionPopoverWillDismiss', () => {
  24284. this.dismiss(undefined, undefined, false);
  24285. });
  24286. }
  24287. /**
  24288. * When binding values in frameworks such as Angular
  24289. * it is possible for the value to be set after the Web Component
  24290. * initializes but before the value watcher is set up in Stencil.
  24291. * As a result, the watcher callback may not be fired.
  24292. * We work around this by manually calling the watcher
  24293. * callback when the component has loaded and the watcher
  24294. * is configured.
  24295. */
  24296. this.configureTriggerInteraction();
  24297. }
  24298. /**
  24299. * When opening a popover from a trigger, we should not be
  24300. * modifying the `event` prop from inside the component.
  24301. * Additionally, when pressing the "Right" arrow key, we need
  24302. * to shift focus to the first descendant in the newly presented
  24303. * popover.
  24304. *
  24305. * @internal
  24306. */
  24307. async presentFromTrigger(event, focusDescendant = false) {
  24308. this.focusDescendantOnPresent = focusDescendant;
  24309. await this.present(event);
  24310. this.focusDescendantOnPresent = false;
  24311. }
  24312. /**
  24313. * Determines whether or not an overlay
  24314. * is being used inline or via a controller/JS
  24315. * and returns the correct delegate.
  24316. * By default, subsequent calls to getDelegate
  24317. * will use a cached version of the delegate.
  24318. * This is useful for calling dismiss after
  24319. * present so that the correct delegate is given.
  24320. */
  24321. getDelegate(force = false) {
  24322. if (this.workingDelegate && !force) {
  24323. return {
  24324. delegate: this.workingDelegate,
  24325. inline: this.inline,
  24326. };
  24327. }
  24328. /**
  24329. * If using overlay inline
  24330. * we potentially need to use the coreDelegate
  24331. * so that this works in vanilla JS apps.
  24332. * If a developer has presented this component
  24333. * via a controller, then we can assume
  24334. * the component is already in the
  24335. * correct place.
  24336. */
  24337. const parentEl = this.el.parentNode;
  24338. const inline = (this.inline = parentEl !== null && !this.hasController);
  24339. const delegate = (this.workingDelegate = inline ? this.delegate || this.coreDelegate : this.delegate);
  24340. return { inline, delegate };
  24341. }
  24342. /**
  24343. * Present the popover overlay after it has been created.
  24344. * Developers can pass a mouse, touch, or pointer event
  24345. * to position the popover relative to where that event
  24346. * was dispatched.
  24347. */
  24348. async present(event) {
  24349. const unlock = await this.lockController.lock();
  24350. if (this.presented) {
  24351. unlock();
  24352. return;
  24353. }
  24354. const { el } = this;
  24355. const { inline, delegate } = this.getDelegate(true);
  24356. /**
  24357. * Emit ionMount so JS Frameworks have an opportunity
  24358. * to add the child component to the DOM. The child
  24359. * component will be assigned to this.usersElement below.
  24360. */
  24361. this.ionMount.emit();
  24362. this.usersElement = await attachComponent(delegate, el, this.component, ['popover-viewport'], this.componentProps, inline);
  24363. if (!this.keyboardEvents) {
  24364. this.configureKeyboardInteraction();
  24365. }
  24366. this.configureDismissInteraction();
  24367. /**
  24368. * When using the lazy loaded build of Stencil, we need to wait
  24369. * for every Stencil component instance to be ready before presenting
  24370. * otherwise there can be a flash of unstyled content. With the
  24371. * custom elements bundle we need to wait for the JS framework
  24372. * mount the inner contents of the overlay otherwise WebKit may
  24373. * get the transition incorrect.
  24374. */
  24375. if (hasLazyBuild(el)) {
  24376. await deepReady(this.usersElement);
  24377. /**
  24378. * If keepContentsMounted="true" then the
  24379. * JS Framework has already mounted the inner
  24380. * contents so there is no need to wait.
  24381. * Otherwise, we need to wait for the JS
  24382. * Framework to mount the inner contents
  24383. * of this component.
  24384. */
  24385. }
  24386. else if (!this.keepContentsMounted) {
  24387. await waitForMount();
  24388. }
  24389. await present(this, 'popoverEnter', iosEnterAnimation$1, mdEnterAnimation$1, {
  24390. event: event || this.event,
  24391. size: this.size,
  24392. trigger: this.triggerEl,
  24393. reference: this.reference,
  24394. side: this.side,
  24395. align: this.alignment,
  24396. });
  24397. /**
  24398. * If popover is nested and was
  24399. * presented using the "Right" arrow key,
  24400. * we need to move focus to the first
  24401. * descendant inside of the popover.
  24402. */
  24403. if (this.focusDescendantOnPresent) {
  24404. focusFirstDescendant(el);
  24405. }
  24406. unlock();
  24407. }
  24408. /**
  24409. * Dismiss the popover overlay after it has been presented.
  24410. *
  24411. * @param data Any data to emit in the dismiss events.
  24412. * @param role The role of the element that is dismissing the popover. For example, 'cancel' or 'backdrop'.
  24413. * @param dismissParentPopover If `true`, dismissing this popover will also dismiss
  24414. * a parent popover if this popover is nested. Defaults to `true`.
  24415. *
  24416. * This is a no-op if the overlay has not been presented yet. If you want
  24417. * to remove an overlay from the DOM that was never presented, use the
  24418. * [remove](https://developer.mozilla.org/en-US/docs/Web/API/Element/remove) method.
  24419. */
  24420. async dismiss(data, role, dismissParentPopover = true) {
  24421. const unlock = await this.lockController.lock();
  24422. const { destroyKeyboardInteraction, destroyDismissInteraction } = this;
  24423. if (dismissParentPopover && this.parentPopover) {
  24424. this.parentPopover.dismiss(data, role, dismissParentPopover);
  24425. }
  24426. const shouldDismiss = await dismiss(this, data, role, 'popoverLeave', iosLeaveAnimation$1, mdLeaveAnimation$1, this.event);
  24427. if (shouldDismiss) {
  24428. if (destroyKeyboardInteraction) {
  24429. destroyKeyboardInteraction();
  24430. this.destroyKeyboardInteraction = undefined;
  24431. }
  24432. if (destroyDismissInteraction) {
  24433. destroyDismissInteraction();
  24434. this.destroyDismissInteraction = undefined;
  24435. }
  24436. /**
  24437. * If using popover inline
  24438. * we potentially need to use the coreDelegate
  24439. * so that this works in vanilla JS apps
  24440. */
  24441. const { delegate } = this.getDelegate();
  24442. await detachComponent(delegate, this.usersElement);
  24443. }
  24444. unlock();
  24445. return shouldDismiss;
  24446. }
  24447. /**
  24448. * @internal
  24449. */
  24450. async getParentPopover() {
  24451. return this.parentPopover;
  24452. }
  24453. /**
  24454. * Returns a promise that resolves when the popover did dismiss.
  24455. */
  24456. onDidDismiss() {
  24457. return eventMethod(this.el, 'ionPopoverDidDismiss');
  24458. }
  24459. /**
  24460. * Returns a promise that resolves when the popover will dismiss.
  24461. */
  24462. onWillDismiss() {
  24463. return eventMethod(this.el, 'ionPopoverWillDismiss');
  24464. }
  24465. render() {
  24466. const mode = getIonMode$1(this);
  24467. const { onLifecycle, parentPopover, dismissOnSelect, side, arrow, htmlAttributes, focusTrap } = this;
  24468. const desktop = isPlatform('desktop');
  24469. const enableArrow = arrow && !parentPopover;
  24470. return (hAsync(Host, Object.assign({ key: 'ff24e8d9677711248a36994cce568e74ba151499', "aria-modal": "true", "no-router": true, tabindex: "-1" }, htmlAttributes, { style: {
  24471. zIndex: `${20000 + this.overlayIndex}`,
  24472. }, 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' })))));
  24473. }
  24474. get el() { return getElement(this); }
  24475. static get watchers() { return {
  24476. "trigger": ["onTriggerChange"],
  24477. "triggerAction": ["onTriggerChange"],
  24478. "isOpen": ["onIsOpenChange"]
  24479. }; }
  24480. static get style() { return {
  24481. ios: IonPopoverIosStyle0,
  24482. md: IonPopoverMdStyle0
  24483. }; }
  24484. static get cmpMeta() { return {
  24485. "$flags$": 41,
  24486. "$tagName$": "ion-popover",
  24487. "$members$": {
  24488. "hasController": [4, "has-controller"],
  24489. "delegate": [16],
  24490. "overlayIndex": [2, "overlay-index"],
  24491. "enterAnimation": [16],
  24492. "leaveAnimation": [16],
  24493. "component": [1],
  24494. "componentProps": [16],
  24495. "keyboardClose": [4, "keyboard-close"],
  24496. "cssClass": [1, "css-class"],
  24497. "backdropDismiss": [4, "backdrop-dismiss"],
  24498. "event": [8],
  24499. "showBackdrop": [4, "show-backdrop"],
  24500. "translucent": [4],
  24501. "animated": [4],
  24502. "htmlAttributes": [16],
  24503. "triggerAction": [1, "trigger-action"],
  24504. "trigger": [1],
  24505. "size": [1],
  24506. "dismissOnSelect": [4, "dismiss-on-select"],
  24507. "reference": [1],
  24508. "side": [1],
  24509. "alignment": [1025],
  24510. "arrow": [4],
  24511. "isOpen": [4, "is-open"],
  24512. "keyboardEvents": [4, "keyboard-events"],
  24513. "focusTrap": [4, "focus-trap"],
  24514. "keepContentsMounted": [4, "keep-contents-mounted"],
  24515. "presented": [32],
  24516. "presentFromTrigger": [64],
  24517. "present": [64],
  24518. "dismiss": [64],
  24519. "getParentPopover": [64],
  24520. "onDidDismiss": [64],
  24521. "onWillDismiss": [64]
  24522. },
  24523. "$listeners$": undefined,
  24524. "$lazyBundleId$": "-",
  24525. "$attrsToReflect$": []
  24526. }; }
  24527. }
  24528. const LIFECYCLE_MAP = {
  24529. ionPopoverDidPresent: 'ionViewDidEnter',
  24530. ionPopoverWillPresent: 'ionViewWillEnter',
  24531. ionPopoverWillDismiss: 'ionViewWillLeave',
  24532. ionPopoverDidDismiss: 'ionViewDidLeave',
  24533. };
  24534. 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))}";
  24535. var IonProgressBarIosStyle0 = progressBarIosCss;
  24536. 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)}";
  24537. var IonProgressBarMdStyle0 = progressBarMdCss;
  24538. /**
  24539. * @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
  24540. *
  24541. * @part progress - The progress bar that shows the current value when `type` is `"determinate"` and slides back and forth when `type` is `"indeterminate"`.
  24542. * @part stream - The animated circles that appear while buffering. This only shows when `buffer` is set and `type` is `"determinate"`.
  24543. * @part track - The track bar behind the progress bar. If the `buffer` property is set and `type` is `"determinate"` the track will be the
  24544. * width of the `buffer` value.
  24545. */
  24546. class ProgressBar {
  24547. constructor(hostRef) {
  24548. registerInstance(this, hostRef);
  24549. this.type = 'determinate';
  24550. this.reversed = false;
  24551. this.value = 0;
  24552. this.buffer = 1;
  24553. this.color = undefined;
  24554. }
  24555. render() {
  24556. const { color, type, reversed, value, buffer } = this;
  24557. const paused = config.getBoolean('_testing');
  24558. const mode = getIonMode$1(this);
  24559. // If the progress is displayed as a solid bar.
  24560. const progressSolid = buffer === 1;
  24561. return (hAsync(Host, { key: 'd60eeaa18aaee607e083c0ef9d0de8178d47c4cd', role: "progressbar", "aria-valuenow": type === 'determinate' ? value : null, "aria-valuemin": "0", "aria-valuemax": "1", class: createColorClasses$1(color, {
  24562. [mode]: true,
  24563. [`progress-bar-${type}`]: true,
  24564. 'progress-paused': paused,
  24565. 'progress-bar-reversed': document.dir === 'rtl' ? !reversed : reversed,
  24566. 'progress-bar-solid': progressSolid,
  24567. }) }, type === 'indeterminate' ? renderIndeterminate() : renderProgress(value, buffer)));
  24568. }
  24569. static get style() { return {
  24570. ios: IonProgressBarIosStyle0,
  24571. md: IonProgressBarMdStyle0
  24572. }; }
  24573. static get cmpMeta() { return {
  24574. "$flags$": 41,
  24575. "$tagName$": "ion-progress-bar",
  24576. "$members$": {
  24577. "type": [1],
  24578. "reversed": [4],
  24579. "value": [2],
  24580. "buffer": [2],
  24581. "color": [513]
  24582. },
  24583. "$listeners$": undefined,
  24584. "$lazyBundleId$": "-",
  24585. "$attrsToReflect$": [["color", "color"]]
  24586. }; }
  24587. }
  24588. const renderIndeterminate = () => {
  24589. 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" }))));
  24590. };
  24591. const renderProgress = (value, buffer) => {
  24592. const finalValue = clamp(0, value, 1);
  24593. const finalBuffer = clamp(0, buffer, 1);
  24594. return [
  24595. hAsync("div", { part: "progress", class: "progress", style: { transform: `scaleX(${finalValue})` } }),
  24596. /**
  24597. * Buffer circles with two container to move
  24598. * the circles behind the buffer progress
  24599. * with respecting the animation.
  24600. * When finalBuffer === 1, we use display: none
  24601. * instead of removing the element to avoid flickering.
  24602. */
  24603. 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" }))),
  24604. hAsync("div", { part: "track", class: "progress-buffer-bar", style: { transform: `scaleX(${finalBuffer})` } }),
  24605. ];
  24606. };
  24607. 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}";
  24608. var IonRadioIosStyle0 = radioIosCss;
  24609. 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}";
  24610. var IonRadioMdStyle0 = radioMdCss;
  24611. /**
  24612. * @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
  24613. *
  24614. * @slot - The label text to associate with the radio. Use the "labelPlacement" property to control where the label is placed relative to the radio.
  24615. *
  24616. * @part container - The container for the radio mark.
  24617. * @part label - The label text describing the radio.
  24618. * @part mark - The checkmark or dot used to indicate the checked state.
  24619. */
  24620. class Radio {
  24621. constructor(hostRef) {
  24622. registerInstance(this, hostRef);
  24623. this.ionFocus = createEvent(this, "ionFocus", 7);
  24624. this.ionBlur = createEvent(this, "ionBlur", 7);
  24625. this.inputId = `ion-rb-${radioButtonIds++}`;
  24626. this.radioGroup = null;
  24627. this.updateState = () => {
  24628. if (this.radioGroup) {
  24629. const { compareWith, value: radioGroupValue } = this.radioGroup;
  24630. this.checked = isOptionSelected(radioGroupValue, this.value, compareWith);
  24631. }
  24632. };
  24633. this.onClick = () => {
  24634. const { radioGroup, checked, disabled } = this;
  24635. if (disabled) {
  24636. return;
  24637. }
  24638. /**
  24639. * The modern control does not use a native input
  24640. * inside of the radio host, so we cannot rely on the
  24641. * ev.preventDefault() behavior above. If the radio
  24642. * is checked and the parent radio group allows for empty
  24643. * selection, then we can set the checked state to false.
  24644. * Otherwise, the checked state should always be set
  24645. * to true because the checked state cannot be toggled.
  24646. */
  24647. if (checked && (radioGroup === null || radioGroup === void 0 ? void 0 : radioGroup.allowEmptySelection)) {
  24648. this.checked = false;
  24649. }
  24650. else {
  24651. this.checked = true;
  24652. }
  24653. };
  24654. this.onFocus = () => {
  24655. this.ionFocus.emit();
  24656. };
  24657. this.onBlur = () => {
  24658. this.ionBlur.emit();
  24659. };
  24660. this.checked = false;
  24661. this.buttonTabindex = -1;
  24662. this.color = undefined;
  24663. this.name = this.inputId;
  24664. this.disabled = false;
  24665. this.value = undefined;
  24666. this.labelPlacement = 'start';
  24667. this.justify = undefined;
  24668. this.alignment = undefined;
  24669. }
  24670. valueChanged() {
  24671. /**
  24672. * The new value of the radio may
  24673. * match the radio group's value,
  24674. * so we see if it should be checked.
  24675. */
  24676. this.updateState();
  24677. }
  24678. componentDidLoad() {
  24679. /**
  24680. * The value may be `undefined` if it
  24681. * gets set before the radio is
  24682. * rendered. This ensures that the radio
  24683. * is checked if the value matches. This
  24684. * happens most often when Angular is
  24685. * rendering the radio.
  24686. */
  24687. this.updateState();
  24688. }
  24689. /** @internal */
  24690. async setFocus(ev) {
  24691. if (ev !== undefined) {
  24692. ev.stopPropagation();
  24693. ev.preventDefault();
  24694. }
  24695. this.el.focus();
  24696. }
  24697. /** @internal */
  24698. async setButtonTabindex(value) {
  24699. this.buttonTabindex = value;
  24700. }
  24701. connectedCallback() {
  24702. if (this.value === undefined) {
  24703. this.value = this.inputId;
  24704. }
  24705. const radioGroup = (this.radioGroup = this.el.closest('ion-radio-group'));
  24706. if (radioGroup) {
  24707. this.updateState();
  24708. addEventListener$1(radioGroup, 'ionValueChange', this.updateState);
  24709. }
  24710. }
  24711. disconnectedCallback() {
  24712. const radioGroup = this.radioGroup;
  24713. if (radioGroup) {
  24714. removeEventListener(radioGroup, 'ionValueChange', this.updateState);
  24715. this.radioGroup = null;
  24716. }
  24717. }
  24718. get hasLabel() {
  24719. return this.el.textContent !== '';
  24720. }
  24721. renderRadioControl() {
  24722. return (hAsync("div", { class: "radio-icon", part: "container" }, hAsync("div", { class: "radio-inner", part: "mark" }), hAsync("div", { class: "radio-ripple" })));
  24723. }
  24724. render() {
  24725. const { checked, disabled, color, el, justify, labelPlacement, hasLabel, buttonTabindex, alignment } = this;
  24726. const mode = getIonMode$1(this);
  24727. const inItem = hostContext('ion-item', el);
  24728. return (hAsync(Host, { key: '8badd4aec277addc0793e14df21f73bb345e99b7', onFocus: this.onFocus, onBlur: this.onBlur, onClick: this.onClick, class: createColorClasses$1(color, {
  24729. [mode]: true,
  24730. 'in-item': inItem,
  24731. 'radio-checked': checked,
  24732. 'radio-disabled': disabled,
  24733. [`radio-justify-${justify}`]: justify !== undefined,
  24734. [`radio-alignment-${alignment}`]: alignment !== undefined,
  24735. [`radio-label-placement-${labelPlacement}`]: true,
  24736. // Focus and active styling should not apply when the radio is in an item
  24737. 'ion-activatable': !inItem,
  24738. 'ion-focusable': !inItem,
  24739. }), 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: {
  24740. 'label-text-wrapper': true,
  24741. 'label-text-wrapper-hidden': !hasLabel,
  24742. }, part: "label" }, hAsync("slot", { key: '331f3dc2ce5f6ed8f124fc4560f92e0f7c668a85' })), hAsync("div", { key: '473bd4aaf448753e385f2dda3fddc9f56379aa19', class: "native-wrapper" }, this.renderRadioControl()))));
  24743. }
  24744. get el() { return getElement(this); }
  24745. static get watchers() { return {
  24746. "value": ["valueChanged"]
  24747. }; }
  24748. static get style() { return {
  24749. ios: IonRadioIosStyle0,
  24750. md: IonRadioMdStyle0
  24751. }; }
  24752. static get cmpMeta() { return {
  24753. "$flags$": 41,
  24754. "$tagName$": "ion-radio",
  24755. "$members$": {
  24756. "color": [513],
  24757. "name": [1],
  24758. "disabled": [4],
  24759. "value": [8],
  24760. "labelPlacement": [1, "label-placement"],
  24761. "justify": [1],
  24762. "alignment": [1],
  24763. "checked": [32],
  24764. "buttonTabindex": [32],
  24765. "setFocus": [64],
  24766. "setButtonTabindex": [64]
  24767. },
  24768. "$listeners$": undefined,
  24769. "$lazyBundleId$": "-",
  24770. "$attrsToReflect$": [["color", "color"]]
  24771. }; }
  24772. }
  24773. let radioButtonIds = 0;
  24774. 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}";
  24775. var IonRadioGroupIosStyle0 = radioGroupIosCss;
  24776. 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}";
  24777. var IonRadioGroupMdStyle0 = radioGroupMdCss;
  24778. class RadioGroup {
  24779. constructor(hostRef) {
  24780. registerInstance(this, hostRef);
  24781. this.ionChange = createEvent(this, "ionChange", 7);
  24782. this.ionValueChange = createEvent(this, "ionValueChange", 7);
  24783. this.inputId = `ion-rg-${radioGroupIds++}`;
  24784. this.helperTextId = `${this.inputId}-helper-text`;
  24785. this.errorTextId = `${this.inputId}-error-text`;
  24786. this.labelId = `${this.inputId}-lbl`;
  24787. this.setRadioTabindex = (value) => {
  24788. const radios = this.getRadios();
  24789. // Get the first radio that is not disabled and the checked one
  24790. const first = radios.find((radio) => !radio.disabled);
  24791. const checked = radios.find((radio) => radio.value === value && !radio.disabled);
  24792. if (!first && !checked) {
  24793. return;
  24794. }
  24795. // If an enabled checked radio exists, set it to be the focusable radio
  24796. // otherwise we default to focus the first radio
  24797. const focusable = checked || first;
  24798. for (const radio of radios) {
  24799. const tabindex = radio === focusable ? 0 : -1;
  24800. radio.setButtonTabindex(tabindex);
  24801. }
  24802. };
  24803. this.onClick = (ev) => {
  24804. ev.preventDefault();
  24805. /**
  24806. * The Radio Group component mandates that only one radio button
  24807. * within the group can be selected at any given time. Since `ion-radio`
  24808. * is a shadow DOM component, it cannot natively perform this behavior
  24809. * using the `name` attribute.
  24810. */
  24811. const selectedRadio = ev.target && ev.target.closest('ion-radio');
  24812. /**
  24813. * Our current disabled prop definition causes Stencil to mark it
  24814. * as optional. While this is not desired, fixing this behavior
  24815. * in Stencil is a significant breaking change, so this effort is
  24816. * being de-risked in STENCIL-917. Until then, we compromise
  24817. * here by checking for falsy `disabled` values instead of strictly
  24818. * checking `disabled === false`.
  24819. */
  24820. if (selectedRadio && !selectedRadio.disabled) {
  24821. const currentValue = this.value;
  24822. const newValue = selectedRadio.value;
  24823. if (newValue !== currentValue) {
  24824. this.value = newValue;
  24825. this.emitValueChange(ev);
  24826. }
  24827. else if (this.allowEmptySelection) {
  24828. this.value = undefined;
  24829. this.emitValueChange(ev);
  24830. }
  24831. }
  24832. };
  24833. this.allowEmptySelection = false;
  24834. this.compareWith = undefined;
  24835. this.name = this.inputId;
  24836. this.value = undefined;
  24837. this.helperText = undefined;
  24838. this.errorText = undefined;
  24839. }
  24840. valueChanged(value) {
  24841. this.setRadioTabindex(value);
  24842. this.ionValueChange.emit({ value });
  24843. }
  24844. componentDidLoad() {
  24845. /**
  24846. * There's an issue when assigning a value to the radio group
  24847. * within the Angular primary content (rendering within the
  24848. * app component template). When the template is isolated to a route,
  24849. * the value is assigned correctly.
  24850. * To address this issue, we need to ensure that the watcher is
  24851. * called after the component has finished loading,
  24852. * allowing the emit to be dispatched correctly.
  24853. */
  24854. this.valueChanged(this.value);
  24855. }
  24856. async connectedCallback() {
  24857. // Get the list header if it exists and set the id
  24858. // this is used to set aria-labelledby
  24859. const header = this.el.querySelector('ion-list-header') || this.el.querySelector('ion-item-divider');
  24860. if (header) {
  24861. const label = (this.label = header.querySelector('ion-label'));
  24862. if (label) {
  24863. this.labelId = label.id = this.name + '-lbl';
  24864. }
  24865. }
  24866. }
  24867. getRadios() {
  24868. return Array.from(this.el.querySelectorAll('ion-radio'));
  24869. }
  24870. /**
  24871. * Emits an `ionChange` event.
  24872. *
  24873. * This API should be called for user committed changes.
  24874. * This API should not be used for external value changes.
  24875. */
  24876. emitValueChange(event) {
  24877. const { value } = this;
  24878. this.ionChange.emit({ value, event });
  24879. }
  24880. onKeydown(ev) {
  24881. // We don't want the value to automatically change/emit when the radio group is part of a select interface
  24882. // as this will cause the interface to close when navigating through the radio group options
  24883. const inSelectInterface = !!this.el.closest('ion-select-popover') || !!this.el.closest('ion-select-modal');
  24884. if (ev.target && !this.el.contains(ev.target)) {
  24885. return;
  24886. }
  24887. // Get all radios inside of the radio group and then
  24888. // filter out disabled radios since we need to skip those
  24889. const radios = this.getRadios().filter((radio) => !radio.disabled);
  24890. // Only move the radio if the current focus is in the radio group
  24891. if (ev.target && radios.includes(ev.target)) {
  24892. const index = radios.findIndex((radio) => radio === ev.target);
  24893. const current = radios[index];
  24894. let next;
  24895. // If hitting arrow down or arrow right, move to the next radio
  24896. // If we're on the last radio, move to the first radio
  24897. if (['ArrowDown', 'ArrowRight'].includes(ev.key)) {
  24898. next = index === radios.length - 1 ? radios[0] : radios[index + 1];
  24899. }
  24900. // If hitting arrow up or arrow left, move to the previous radio
  24901. // If we're on the first radio, move to the last radio
  24902. if (['ArrowUp', 'ArrowLeft'].includes(ev.key)) {
  24903. next = index === 0 ? radios[radios.length - 1] : radios[index - 1];
  24904. }
  24905. if (next && radios.includes(next)) {
  24906. next.setFocus(ev);
  24907. if (!inSelectInterface) {
  24908. this.value = next.value;
  24909. this.emitValueChange(ev);
  24910. }
  24911. }
  24912. // Update the radio group value when a user presses the
  24913. // space bar on top of a selected radio
  24914. if ([' '].includes(ev.key)) {
  24915. const previousValue = this.value;
  24916. this.value = this.allowEmptySelection && this.value !== undefined ? undefined : current.value;
  24917. if (previousValue !== this.value || this.allowEmptySelection) {
  24918. /**
  24919. * Value change should only be emitted if the value is different,
  24920. * such as selecting a new radio with the space bar or if
  24921. * the radio group allows for empty selection and the user
  24922. * is deselecting a checked radio.
  24923. */
  24924. this.emitValueChange(ev);
  24925. }
  24926. // Prevent browsers from jumping
  24927. // to the bottom of the screen
  24928. ev.preventDefault();
  24929. }
  24930. }
  24931. }
  24932. /** @internal */
  24933. async setFocus() {
  24934. const radioToFocus = this.getRadios().find((r) => r.tabIndex !== -1);
  24935. radioToFocus === null || radioToFocus === void 0 ? void 0 : radioToFocus.setFocus();
  24936. }
  24937. /**
  24938. * Renders the helper text or error text values
  24939. */
  24940. renderHintText() {
  24941. const { helperText, errorText, helperTextId, errorTextId } = this;
  24942. const hasHintText = !!helperText || !!errorText;
  24943. if (!hasHintText) {
  24944. return;
  24945. }
  24946. return (hAsync("div", { class: "radio-group-top" }, hAsync("div", { id: helperTextId, class: "helper-text" }, helperText), hAsync("div", { id: errorTextId, class: "error-text" }, errorText)));
  24947. }
  24948. getHintTextID() {
  24949. const { el, helperText, errorText, helperTextId, errorTextId } = this;
  24950. if (el.classList.contains('ion-touched') && el.classList.contains('ion-invalid') && errorText) {
  24951. return errorTextId;
  24952. }
  24953. if (helperText) {
  24954. return helperTextId;
  24955. }
  24956. return undefined;
  24957. }
  24958. render() {
  24959. const { label, labelId, el, name, value } = this;
  24960. const mode = getIonMode$1(this);
  24961. renderHiddenInput(true, el, name, value, false);
  24962. 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' }))));
  24963. }
  24964. get el() { return getElement(this); }
  24965. static get watchers() { return {
  24966. "value": ["valueChanged"]
  24967. }; }
  24968. static get style() { return {
  24969. ios: IonRadioGroupIosStyle0,
  24970. md: IonRadioGroupMdStyle0
  24971. }; }
  24972. static get cmpMeta() { return {
  24973. "$flags$": 36,
  24974. "$tagName$": "ion-radio-group",
  24975. "$members$": {
  24976. "allowEmptySelection": [4, "allow-empty-selection"],
  24977. "compareWith": [1, "compare-with"],
  24978. "name": [1],
  24979. "value": [1032],
  24980. "helperText": [1, "helper-text"],
  24981. "errorText": [1, "error-text"],
  24982. "setFocus": [64]
  24983. },
  24984. "$listeners$": [[4, "keydown", "onKeydown"]],
  24985. "$lazyBundleId$": "-",
  24986. "$attrsToReflect$": []
  24987. }; }
  24988. }
  24989. let radioGroupIds = 0;
  24990. function getDecimalPlaces(n) {
  24991. if (!isSafeNumber(n))
  24992. return 0;
  24993. if (n % 1 === 0)
  24994. return 0;
  24995. return n.toString().split('.')[1].length;
  24996. }
  24997. /**
  24998. * Fixes floating point rounding errors in a result by rounding
  24999. * to the same specificity, or number of decimal places (*not*
  25000. * significant figures) as provided reference numbers. If multiple
  25001. * references are provided, the highest number of decimal places
  25002. * between them will be used.
  25003. *
  25004. * The main use case is when numbers x and y are added to produce n,
  25005. * but x and y are floats, so n may have rounding errors (such as
  25006. * 3.1000000004 instead of 3.1). As long as only addition/subtraction
  25007. * occurs between x and y, the specificity of the result will never
  25008. * increase, so x and y should be passed in as the references.
  25009. *
  25010. * If multiplication, division, or other operations were used to
  25011. * calculate n, the rounded result may have less specificity than
  25012. * desired. For example, 1 / 3 = 0.33333(...), but
  25013. * roundToMaxDecimalPlaces((1 / 3), 1, 3) will return 0, since both
  25014. * 1 and 3 are whole numbers.
  25015. *
  25016. * Note that extremely precise reference numbers may lead to rounding
  25017. * errors not being trimmed, due to the error result having the same or
  25018. * fewer decimal places as the reference(s). This is acceptable as we
  25019. * would not be able to tell the difference between a rounding error
  25020. * and correct value in this case, but it does mean there is an implicit
  25021. * precision limit. If precision that high is needed, it is recommended
  25022. * to use a third party data type designed to handle floating point
  25023. * errors instead.
  25024. *
  25025. * @param n The number to round.
  25026. * @param references Number(s) used to calculate n, or that should otherwise
  25027. * be used as a reference for the desired specificity.
  25028. */
  25029. function roundToMaxDecimalPlaces(n, ...references) {
  25030. if (!isSafeNumber(n))
  25031. return 0;
  25032. const maxPlaces = Math.max(...references.map((r) => getDecimalPlaces(r)));
  25033. return Number(n.toFixed(maxPlaces));
  25034. }
  25035. 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}";
  25036. var IonRangeIosStyle0 = rangeIosCss;
  25037. 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}";
  25038. var IonRangeMdStyle0 = rangeMdCss;
  25039. // TODO(FW-2832): types
  25040. /**
  25041. * @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
  25042. *
  25043. * @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.
  25044. * @slot start - Content is placed to the left of the range slider in LTR, and to the right in RTL.
  25045. * @slot end - Content is placed to the right of the range slider in LTR, and to the left in RTL.
  25046. *
  25047. * @part tick - An inactive tick mark.
  25048. * @part tick-active - An active tick mark.
  25049. * @part pin - The counter that appears above a knob.
  25050. * @part knob - The handle that is used to drag the range.
  25051. * @part bar - The inactive part of the bar.
  25052. * @part bar-active - The active part of the bar.
  25053. * @part label - The label text describing the range.
  25054. */
  25055. class Range {
  25056. constructor(hostRef) {
  25057. registerInstance(this, hostRef);
  25058. this.ionChange = createEvent(this, "ionChange", 7);
  25059. this.ionInput = createEvent(this, "ionInput", 7);
  25060. this.ionFocus = createEvent(this, "ionFocus", 7);
  25061. this.ionBlur = createEvent(this, "ionBlur", 7);
  25062. this.ionKnobMoveStart = createEvent(this, "ionKnobMoveStart", 7);
  25063. this.ionKnobMoveEnd = createEvent(this, "ionKnobMoveEnd", 7);
  25064. this.rangeId = `ion-r-${rangeIds++}`;
  25065. this.didLoad = false;
  25066. this.noUpdate = false;
  25067. this.hasFocus = false;
  25068. this.inheritedAttributes = {};
  25069. this.contentEl = null;
  25070. this.initialContentScrollY = true;
  25071. /**
  25072. * Compares two RangeValue inputs to determine if they are different.
  25073. *
  25074. * @param newVal - The new value.
  25075. * @param oldVal - The old value.
  25076. * @returns `true` if the values are different, `false` otherwise.
  25077. */
  25078. this.compareValues = (newVal, oldVal) => {
  25079. if (typeof newVal === 'object' && typeof oldVal === 'object') {
  25080. return newVal.lower !== oldVal.lower || newVal.upper !== oldVal.upper;
  25081. }
  25082. return newVal !== oldVal;
  25083. };
  25084. this.clampBounds = (value) => {
  25085. return clamp(this.min, value, this.max);
  25086. };
  25087. this.ensureValueInBounds = (value) => {
  25088. if (this.dualKnobs) {
  25089. return {
  25090. lower: this.clampBounds(value.lower),
  25091. upper: this.clampBounds(value.upper),
  25092. };
  25093. }
  25094. else {
  25095. return this.clampBounds(value);
  25096. }
  25097. };
  25098. this.setupGesture = async () => {
  25099. const rangeSlider = this.rangeSlider;
  25100. if (rangeSlider) {
  25101. this.gesture = (await Promise.resolve().then(function () { return index; })).createGesture({
  25102. el: rangeSlider,
  25103. gestureName: 'range',
  25104. gesturePriority: 100,
  25105. /**
  25106. * Provide a threshold since the drag movement
  25107. * might be a user scrolling the view.
  25108. * If this is true, then the range
  25109. * should not move.
  25110. */
  25111. threshold: 10,
  25112. onStart: () => this.onStart(),
  25113. onMove: (ev) => this.onMove(ev),
  25114. onEnd: (ev) => this.onEnd(ev),
  25115. });
  25116. this.gesture.enable(!this.disabled);
  25117. }
  25118. };
  25119. this.handleKeyboard = (knob, isIncrease) => {
  25120. const { ensureValueInBounds } = this;
  25121. let step = this.step;
  25122. step = step > 0 ? step : 1;
  25123. step = step / (this.max - this.min);
  25124. if (!isIncrease) {
  25125. step *= -1;
  25126. }
  25127. if (knob === 'A') {
  25128. this.ratioA = clamp(0, this.ratioA + step, 1);
  25129. }
  25130. else {
  25131. this.ratioB = clamp(0, this.ratioB + step, 1);
  25132. }
  25133. this.ionKnobMoveStart.emit({ value: ensureValueInBounds(this.value) });
  25134. this.updateValue();
  25135. this.emitValueChange();
  25136. this.ionKnobMoveEnd.emit({ value: ensureValueInBounds(this.value) });
  25137. };
  25138. this.onBlur = () => {
  25139. if (this.hasFocus) {
  25140. this.hasFocus = false;
  25141. this.ionBlur.emit();
  25142. }
  25143. };
  25144. this.onFocus = () => {
  25145. if (!this.hasFocus) {
  25146. this.hasFocus = true;
  25147. this.ionFocus.emit();
  25148. }
  25149. };
  25150. this.ratioA = 0;
  25151. this.ratioB = 0;
  25152. this.pressedKnob = undefined;
  25153. this.color = undefined;
  25154. this.debounce = undefined;
  25155. this.name = this.rangeId;
  25156. this.label = undefined;
  25157. this.dualKnobs = false;
  25158. this.min = 0;
  25159. this.max = 100;
  25160. this.pin = false;
  25161. this.pinFormatter = (value) => Math.round(value);
  25162. this.snaps = false;
  25163. this.step = 1;
  25164. this.ticks = true;
  25165. this.activeBarStart = undefined;
  25166. this.disabled = false;
  25167. this.value = 0;
  25168. this.labelPlacement = 'start';
  25169. }
  25170. debounceChanged() {
  25171. const { ionInput, debounce, originalIonInput } = this;
  25172. /**
  25173. * If debounce is undefined, we have to manually revert the ionInput emitter in case
  25174. * debounce used to be set to a number. Otherwise, the event would stay debounced.
  25175. */
  25176. this.ionInput = debounce === undefined ? originalIonInput !== null && originalIonInput !== void 0 ? originalIonInput : ionInput : debounceEvent(ionInput, debounce);
  25177. }
  25178. minChanged(newValue) {
  25179. if (!isSafeNumber(newValue)) {
  25180. this.min = 0;
  25181. }
  25182. if (!this.noUpdate) {
  25183. this.updateRatio();
  25184. }
  25185. }
  25186. maxChanged(newValue) {
  25187. if (!isSafeNumber(newValue)) {
  25188. this.max = 100;
  25189. }
  25190. if (!this.noUpdate) {
  25191. this.updateRatio();
  25192. }
  25193. }
  25194. stepChanged(newValue) {
  25195. if (!isSafeNumber(newValue)) {
  25196. this.step = 1;
  25197. }
  25198. }
  25199. activeBarStartChanged() {
  25200. const { activeBarStart } = this;
  25201. if (activeBarStart !== undefined) {
  25202. if (activeBarStart > this.max) {
  25203. 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);
  25204. this.activeBarStart = this.max;
  25205. }
  25206. else if (activeBarStart < this.min) {
  25207. 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);
  25208. this.activeBarStart = this.min;
  25209. }
  25210. }
  25211. }
  25212. disabledChanged() {
  25213. if (this.gesture) {
  25214. this.gesture.enable(!this.disabled);
  25215. }
  25216. }
  25217. valueChanged(newValue, oldValue) {
  25218. const valuesChanged = this.compareValues(newValue, oldValue);
  25219. if (valuesChanged) {
  25220. this.ionInput.emit({ value: this.value });
  25221. }
  25222. if (!this.noUpdate) {
  25223. this.updateRatio();
  25224. }
  25225. }
  25226. componentWillLoad() {
  25227. /**
  25228. * If user has custom ID set then we should
  25229. * not assign the default incrementing ID.
  25230. */
  25231. if (this.el.hasAttribute('id')) {
  25232. this.rangeId = this.el.getAttribute('id');
  25233. }
  25234. this.inheritedAttributes = inheritAriaAttributes(this.el);
  25235. // If min, max, or step are not safe, set them to 0, 100, and 1, respectively.
  25236. // Each watch does this, but not before the initial load.
  25237. this.min = isSafeNumber(this.min) ? this.min : 0;
  25238. this.max = isSafeNumber(this.max) ? this.max : 100;
  25239. this.step = isSafeNumber(this.step) ? this.step : 1;
  25240. }
  25241. componentDidLoad() {
  25242. this.originalIonInput = this.ionInput;
  25243. this.setupGesture();
  25244. this.updateRatio();
  25245. this.didLoad = true;
  25246. }
  25247. connectedCallback() {
  25248. var _a;
  25249. this.updateRatio();
  25250. this.debounceChanged();
  25251. this.disabledChanged();
  25252. this.activeBarStartChanged();
  25253. /**
  25254. * If we have not yet rendered
  25255. * ion-range, then rangeSlider is not defined.
  25256. * But if we are moving ion-range via appendChild,
  25257. * then rangeSlider will be defined.
  25258. */
  25259. if (this.didLoad) {
  25260. this.setupGesture();
  25261. }
  25262. const ionContent = findClosestIonContent(this.el);
  25263. this.contentEl = (_a = ionContent === null || ionContent === void 0 ? void 0 : ionContent.querySelector('.ion-content-scroll-host')) !== null && _a !== void 0 ? _a : ionContent;
  25264. }
  25265. disconnectedCallback() {
  25266. if (this.gesture) {
  25267. this.gesture.destroy();
  25268. this.gesture = undefined;
  25269. }
  25270. }
  25271. getValue() {
  25272. var _a;
  25273. const value = (_a = this.value) !== null && _a !== void 0 ? _a : 0;
  25274. if (this.dualKnobs) {
  25275. if (typeof value === 'object') {
  25276. return value;
  25277. }
  25278. return {
  25279. lower: 0,
  25280. upper: value,
  25281. };
  25282. }
  25283. else {
  25284. if (typeof value === 'object') {
  25285. return value.upper;
  25286. }
  25287. return value;
  25288. }
  25289. }
  25290. /**
  25291. * Emits an `ionChange` event.
  25292. *
  25293. * This API should be called for user committed changes.
  25294. * This API should not be used for external value changes.
  25295. */
  25296. emitValueChange() {
  25297. this.value = this.ensureValueInBounds(this.value);
  25298. this.ionChange.emit({ value: this.value });
  25299. }
  25300. /**
  25301. * The value should be updated on touch end or
  25302. * when the component is being dragged.
  25303. * This follows the native behavior of mobile devices.
  25304. *
  25305. * For example: When the user lifts their finger from the
  25306. * screen after tapping the bar or dragging the bar or knob.
  25307. */
  25308. onStart() {
  25309. this.ionKnobMoveStart.emit({ value: this.ensureValueInBounds(this.value) });
  25310. }
  25311. /**
  25312. * The value should be updated while dragging the
  25313. * bar or knob.
  25314. *
  25315. * While the user is dragging, the view
  25316. * should not scroll. This is to prevent the user from
  25317. * feeling disoriented while dragging.
  25318. *
  25319. * The user can scroll on the view if the knob or
  25320. * bar is not being dragged.
  25321. *
  25322. * @param detail The details of the gesture event.
  25323. */
  25324. onMove(detail) {
  25325. const { contentEl, pressedKnob } = this;
  25326. const currentX = detail.currentX;
  25327. /**
  25328. * Since the user is dragging on the bar or knob, the view should not scroll.
  25329. *
  25330. * This only needs to be done once.
  25331. */
  25332. if (contentEl && this.pressedKnob === undefined) {
  25333. this.initialContentScrollY = disableContentScrollY(contentEl);
  25334. }
  25335. /**
  25336. * The `pressedKnob` can be undefined if the user just
  25337. * started dragging the knob.
  25338. *
  25339. * This is necessary to determine which knob the user is dragging,
  25340. * especially when it's a dual knob.
  25341. * Plus, it determines when to apply certain styles.
  25342. *
  25343. * This only needs to be done once since the knob won't change
  25344. * while the user is dragging.
  25345. */
  25346. if (pressedKnob === undefined) {
  25347. this.setPressedKnob(currentX);
  25348. }
  25349. this.update(currentX);
  25350. }
  25351. /**
  25352. * The value should be updated on touch end:
  25353. * - When the user lifts their finger from the screen after
  25354. * tapping the bar.
  25355. *
  25356. * @param detail The details of the gesture or mouse event.
  25357. */
  25358. onEnd(detail) {
  25359. var _a;
  25360. const { contentEl, initialContentScrollY } = this;
  25361. const currentX = (_a = detail.currentX) !== null && _a !== void 0 ? _a : detail.clientX;
  25362. /**
  25363. * The `pressedKnob` can be undefined if the user never
  25364. * dragged the knob. They just tapped on the bar.
  25365. *
  25366. * This is necessary to determine which knob the user is changing,
  25367. * especially when it's a dual knob.
  25368. * Plus, it determines when to apply certain styles.
  25369. */
  25370. if (this.pressedKnob === undefined) {
  25371. this.setPressedKnob(currentX);
  25372. }
  25373. /**
  25374. * The user is no longer dragging the bar or
  25375. * knob (if they were dragging it).
  25376. *
  25377. * The user can now scroll on the view in the next gesture event.
  25378. */
  25379. if (contentEl && this.pressedKnob !== undefined) {
  25380. resetContentScrollY(contentEl, initialContentScrollY);
  25381. }
  25382. // update the active knob's position
  25383. this.update(currentX);
  25384. /**
  25385. * Reset the pressed knob to undefined since the user
  25386. * may start dragging a different knob in the next gesture event.
  25387. */
  25388. this.pressedKnob = undefined;
  25389. this.emitValueChange();
  25390. this.ionKnobMoveEnd.emit({ value: this.ensureValueInBounds(this.value) });
  25391. }
  25392. update(currentX) {
  25393. // figure out where the pointer is currently at
  25394. // update the knob being interacted with
  25395. const rect = this.rect;
  25396. let ratio = clamp(0, (currentX - rect.left) / rect.width, 1);
  25397. if (isRTL$1(this.el)) {
  25398. ratio = 1 - ratio;
  25399. }
  25400. if (this.snaps) {
  25401. // snaps the ratio to the current value
  25402. ratio = valueToRatio(ratioToValue(ratio, this.min, this.max, this.step), this.min, this.max);
  25403. }
  25404. // update which knob is pressed
  25405. if (this.pressedKnob === 'A') {
  25406. this.ratioA = ratio;
  25407. }
  25408. else {
  25409. this.ratioB = ratio;
  25410. }
  25411. // Update input value
  25412. this.updateValue();
  25413. }
  25414. setPressedKnob(currentX) {
  25415. const rect = (this.rect = this.rangeSlider.getBoundingClientRect());
  25416. // figure out which knob they started closer to
  25417. let ratio = clamp(0, (currentX - rect.left) / rect.width, 1);
  25418. if (isRTL$1(this.el)) {
  25419. ratio = 1 - ratio;
  25420. }
  25421. this.pressedKnob = !this.dualKnobs || Math.abs(this.ratioA - ratio) < Math.abs(this.ratioB - ratio) ? 'A' : 'B';
  25422. this.setFocus(this.pressedKnob);
  25423. }
  25424. get valA() {
  25425. return ratioToValue(this.ratioA, this.min, this.max, this.step);
  25426. }
  25427. get valB() {
  25428. return ratioToValue(this.ratioB, this.min, this.max, this.step);
  25429. }
  25430. get ratioLower() {
  25431. if (this.dualKnobs) {
  25432. return Math.min(this.ratioA, this.ratioB);
  25433. }
  25434. const { activeBarStart } = this;
  25435. if (activeBarStart == null) {
  25436. return 0;
  25437. }
  25438. return valueToRatio(activeBarStart, this.min, this.max);
  25439. }
  25440. get ratioUpper() {
  25441. if (this.dualKnobs) {
  25442. return Math.max(this.ratioA, this.ratioB);
  25443. }
  25444. return this.ratioA;
  25445. }
  25446. updateRatio() {
  25447. const value = this.getValue();
  25448. const { min, max } = this;
  25449. if (this.dualKnobs) {
  25450. this.ratioA = valueToRatio(value.lower, min, max);
  25451. this.ratioB = valueToRatio(value.upper, min, max);
  25452. }
  25453. else {
  25454. this.ratioA = valueToRatio(value, min, max);
  25455. }
  25456. }
  25457. updateValue() {
  25458. this.noUpdate = true;
  25459. const { valA, valB } = this;
  25460. this.value = !this.dualKnobs
  25461. ? valA
  25462. : {
  25463. lower: Math.min(valA, valB),
  25464. upper: Math.max(valA, valB),
  25465. };
  25466. this.noUpdate = false;
  25467. }
  25468. setFocus(knob) {
  25469. if (this.el.shadowRoot) {
  25470. const knobEl = this.el.shadowRoot.querySelector(knob === 'A' ? '.range-knob-a' : '.range-knob-b');
  25471. if (knobEl) {
  25472. knobEl.focus();
  25473. }
  25474. }
  25475. }
  25476. /**
  25477. * Returns true if content was passed to the "start" slot
  25478. */
  25479. get hasStartSlotContent() {
  25480. return this.el.querySelector('[slot="start"]') !== null;
  25481. }
  25482. /**
  25483. * Returns true if content was passed to the "end" slot
  25484. */
  25485. get hasEndSlotContent() {
  25486. return this.el.querySelector('[slot="end"]') !== null;
  25487. }
  25488. get hasLabel() {
  25489. return this.label !== undefined || this.el.querySelector('[slot="label"]') !== null;
  25490. }
  25491. renderRangeSlider() {
  25492. var _a;
  25493. const { min, max, step, handleKeyboard, pressedKnob, disabled, pin, ratioLower, ratioUpper, pinFormatter, inheritedAttributes, } = this;
  25494. let barStart = `${ratioLower * 100}%`;
  25495. let barEnd = `${100 - ratioUpper * 100}%`;
  25496. const rtl = isRTL$1(this.el);
  25497. const start = rtl ? 'right' : 'left';
  25498. const end = rtl ? 'left' : 'right';
  25499. const tickStyle = (tick) => {
  25500. return {
  25501. [start]: tick[start],
  25502. };
  25503. };
  25504. if (this.dualKnobs === false) {
  25505. /**
  25506. * When the value is less than the activeBarStart or the min value,
  25507. * the knob will display at the start of the active bar.
  25508. */
  25509. if (this.valA < ((_a = this.activeBarStart) !== null && _a !== void 0 ? _a : this.min)) {
  25510. /**
  25511. * Sets the bar positions relative to the upper and lower limits.
  25512. * Converts the ratio values into percentages, used as offsets for left/right styles.
  25513. *
  25514. * The ratioUpper refers to the knob position on the bar.
  25515. * The ratioLower refers to the end position of the active bar (the value).
  25516. */
  25517. barStart = `${ratioUpper * 100}%`;
  25518. barEnd = `${100 - ratioLower * 100}%`;
  25519. }
  25520. else {
  25521. /**
  25522. * Otherwise, the knob will display at the end of the active bar.
  25523. *
  25524. * The ratioLower refers to the start position of the active bar (the value).
  25525. * The ratioUpper refers to the knob position on the bar.
  25526. */
  25527. barStart = `${ratioLower * 100}%`;
  25528. barEnd = `${100 - ratioUpper * 100}%`;
  25529. }
  25530. }
  25531. const barStyle = {
  25532. [start]: barStart,
  25533. [end]: barEnd,
  25534. };
  25535. const ticks = [];
  25536. if (this.snaps && this.ticks) {
  25537. for (let value = min; value <= max; value += step) {
  25538. const ratio = valueToRatio(value, min, max);
  25539. const ratioMin = Math.min(ratioLower, ratioUpper);
  25540. const ratioMax = Math.max(ratioLower, ratioUpper);
  25541. const tick = {
  25542. ratio,
  25543. /**
  25544. * Sets the tick mark as active when the tick is between the min bounds and the knob.
  25545. * When using activeBarStart, the tick mark will be active between the knob and activeBarStart.
  25546. */
  25547. active: ratio >= ratioMin && ratio <= ratioMax,
  25548. };
  25549. tick[start] = `${ratio * 100}%`;
  25550. ticks.push(tick);
  25551. }
  25552. }
  25553. return (hAsync("div", { class: "range-slider", ref: (rangeEl) => (this.rangeSlider = rangeEl),
  25554. /**
  25555. * Since the gesture has a threshold, the value
  25556. * won't change until the user has dragged past
  25557. * the threshold. This is to prevent the range
  25558. * from moving when the user is scrolling.
  25559. *
  25560. * This results in the value not being updated
  25561. * and the event emitters not being triggered
  25562. * if the user taps on the range. This is why
  25563. * we need to listen for the "pointerUp" event.
  25564. */
  25565. onPointerUp: (ev) => {
  25566. /**
  25567. * If the user drags the knob on the web
  25568. * version (does not occur on mobile),
  25569. * the "pointerUp" event will be triggered
  25570. * along with the gesture's events.
  25571. * This leads to duplicate events.
  25572. *
  25573. * By checking if the pressedKnob is undefined,
  25574. * we can determine if the "pointerUp" event was
  25575. * triggered by a tap or a drag. If it was
  25576. * dragged, the pressedKnob will be defined.
  25577. */
  25578. if (this.pressedKnob === undefined) {
  25579. this.onStart();
  25580. this.onEnd(ev);
  25581. }
  25582. } }, ticks.map((tick) => (hAsync("div", { style: tickStyle(tick), role: "presentation", class: {
  25583. 'range-tick': true,
  25584. 'range-tick-active': tick.active,
  25585. }, part: tick.active ? 'tick-active' : 'tick' }))), hAsync("div", { class: "range-bar-container" }, hAsync("div", { class: "range-bar", role: "presentation", part: "bar" }), hAsync("div", { class: {
  25586. 'range-bar': true,
  25587. 'range-bar-active': true,
  25588. 'has-ticks': ticks.length > 0,
  25589. }, role: "presentation", style: barStyle, part: "bar-active" })), renderKnob(rtl, {
  25590. knob: 'A',
  25591. pressed: pressedKnob === 'A',
  25592. value: this.valA,
  25593. ratio: this.ratioA,
  25594. pin,
  25595. pinFormatter,
  25596. disabled,
  25597. handleKeyboard,
  25598. min,
  25599. max,
  25600. inheritedAttributes,
  25601. }), this.dualKnobs &&
  25602. renderKnob(rtl, {
  25603. knob: 'B',
  25604. pressed: pressedKnob === 'B',
  25605. value: this.valB,
  25606. ratio: this.ratioB,
  25607. pin,
  25608. pinFormatter,
  25609. disabled,
  25610. handleKeyboard,
  25611. min,
  25612. max,
  25613. inheritedAttributes,
  25614. })));
  25615. }
  25616. render() {
  25617. const { disabled, el, hasLabel, rangeId, pin, pressedKnob, labelPlacement, label } = this;
  25618. const inItem = hostContext('ion-item', el);
  25619. /**
  25620. * If there is no start content then the knob at
  25621. * the min value will be cut off by the item margin.
  25622. */
  25623. const hasStartContent = (hasLabel && (labelPlacement === 'start' || labelPlacement === 'fixed')) || this.hasStartSlotContent;
  25624. const needsStartAdjustment = inItem && !hasStartContent;
  25625. /**
  25626. * If there is no end content then the knob at
  25627. * the max value will be cut off by the item margin.
  25628. */
  25629. const hasEndContent = (hasLabel && labelPlacement === 'end') || this.hasEndSlotContent;
  25630. const needsEndAdjustment = inItem && !hasEndContent;
  25631. const mode = getIonMode$1(this);
  25632. renderHiddenInput(true, el, this.name, JSON.stringify(this.getValue()), disabled);
  25633. return (hAsync(Host, { key: '3e065039ee048f1f70d97dba5dae98fa1315d867', onFocusin: this.onFocus, onFocusout: this.onBlur, id: rangeId, class: createColorClasses$1(this.color, {
  25634. [mode]: true,
  25635. 'in-item': inItem,
  25636. 'range-disabled': disabled,
  25637. 'range-pressed': pressedKnob !== undefined,
  25638. 'range-has-pin': pin,
  25639. [`range-label-placement-${labelPlacement}`]: true,
  25640. 'range-item-start-adjustment': needsStartAdjustment,
  25641. 'range-item-end-adjustment': needsEndAdjustment,
  25642. }) }, hAsync("label", { key: '27ff22842c9ea79a1b9495302b926f70c9080a95', class: "range-wrapper", id: "range-label" }, hAsync("div", { key: 'da1f9784be02dfe87d2fef34931d8b7f2148189e', class: {
  25643. 'label-text-wrapper': true,
  25644. 'label-text-wrapper-hidden': !hasLabel,
  25645. }, 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" })))));
  25646. }
  25647. get el() { return getElement(this); }
  25648. static get watchers() { return {
  25649. "debounce": ["debounceChanged"],
  25650. "min": ["minChanged"],
  25651. "max": ["maxChanged"],
  25652. "step": ["stepChanged"],
  25653. "activeBarStart": ["activeBarStartChanged"],
  25654. "disabled": ["disabledChanged"],
  25655. "value": ["valueChanged"]
  25656. }; }
  25657. static get style() { return {
  25658. ios: IonRangeIosStyle0,
  25659. md: IonRangeMdStyle0
  25660. }; }
  25661. static get cmpMeta() { return {
  25662. "$flags$": 41,
  25663. "$tagName$": "ion-range",
  25664. "$members$": {
  25665. "color": [513],
  25666. "debounce": [2],
  25667. "name": [1],
  25668. "label": [1],
  25669. "dualKnobs": [4, "dual-knobs"],
  25670. "min": [2],
  25671. "max": [2],
  25672. "pin": [4],
  25673. "pinFormatter": [16],
  25674. "snaps": [4],
  25675. "step": [2],
  25676. "ticks": [4],
  25677. "activeBarStart": [1026, "active-bar-start"],
  25678. "disabled": [4],
  25679. "value": [1026],
  25680. "labelPlacement": [1, "label-placement"],
  25681. "ratioA": [32],
  25682. "ratioB": [32],
  25683. "pressedKnob": [32]
  25684. },
  25685. "$listeners$": undefined,
  25686. "$lazyBundleId$": "-",
  25687. "$attrsToReflect$": [["color", "color"]]
  25688. }; }
  25689. }
  25690. const renderKnob = (rtl, { knob, value, ratio, min, max, disabled, pressed, pin, handleKeyboard, pinFormatter, inheritedAttributes }) => {
  25691. const start = rtl ? 'right' : 'left';
  25692. const knobStyle = () => {
  25693. const style = {};
  25694. style[start] = `${ratio * 100}%`;
  25695. return style;
  25696. };
  25697. // The aria label should be preferred over visible text if both are specified
  25698. const ariaLabel = inheritedAttributes['aria-label'];
  25699. return (hAsync("div", { onKeyDown: (ev) => {
  25700. const key = ev.key;
  25701. if (key === 'ArrowLeft' || key === 'ArrowDown') {
  25702. handleKeyboard(knob, false);
  25703. ev.preventDefault();
  25704. ev.stopPropagation();
  25705. }
  25706. else if (key === 'ArrowRight' || key === 'ArrowUp') {
  25707. handleKeyboard(knob, true);
  25708. ev.preventDefault();
  25709. ev.stopPropagation();
  25710. }
  25711. }, class: {
  25712. 'range-knob-handle': true,
  25713. 'range-knob-a': knob === 'A',
  25714. 'range-knob-b': knob === 'B',
  25715. 'range-knob-pressed': pressed,
  25716. 'range-knob-min': value === min,
  25717. 'range-knob-max': value === max,
  25718. 'ion-activatable': true,
  25719. 'ion-focusable': true,
  25720. }, 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" })));
  25721. };
  25722. const ratioToValue = (ratio, min, max, step) => {
  25723. let value = (max - min) * ratio;
  25724. if (step > 0) {
  25725. // round to nearest multiple of step, then add min
  25726. value = Math.round(value / step) * step + min;
  25727. }
  25728. const clampedValue = clamp(min, value, max);
  25729. return roundToMaxDecimalPlaces(clampedValue, min, max, step);
  25730. };
  25731. const valueToRatio = (value, min, max) => {
  25732. return clamp(0, (value - min) / (max - min), 1);
  25733. };
  25734. let rangeIds = 0;
  25735. const getRefresherAnimationType = (contentEl) => {
  25736. const previousSibling = contentEl.previousElementSibling;
  25737. const hasHeader = previousSibling !== null && previousSibling.tagName === 'ION-HEADER';
  25738. return hasHeader ? 'translate' : 'scale';
  25739. };
  25740. const createPullingAnimation = (type, pullingSpinner, refresherEl) => {
  25741. return type === 'scale'
  25742. ? createScaleAnimation(pullingSpinner, refresherEl)
  25743. : createTranslateAnimation(pullingSpinner, refresherEl);
  25744. };
  25745. const createBaseAnimation = (pullingRefresherIcon) => {
  25746. const spinner = pullingRefresherIcon.querySelector('ion-spinner');
  25747. const circle = spinner.shadowRoot.querySelector('circle');
  25748. const spinnerArrowContainer = pullingRefresherIcon.querySelector('.spinner-arrow-container');
  25749. const arrowContainer = pullingRefresherIcon.querySelector('.arrow-container');
  25750. const arrow = arrowContainer ? arrowContainer.querySelector('ion-icon') : null;
  25751. const baseAnimation = createAnimation().duration(1000).easing('ease-out');
  25752. const spinnerArrowContainerAnimation = createAnimation()
  25753. .addElement(spinnerArrowContainer)
  25754. .keyframes([
  25755. { offset: 0, opacity: '0.3' },
  25756. { offset: 0.45, opacity: '0.3' },
  25757. { offset: 0.55, opacity: '1' },
  25758. { offset: 1, opacity: '1' },
  25759. ]);
  25760. const circleInnerAnimation = createAnimation()
  25761. .addElement(circle)
  25762. .keyframes([
  25763. { offset: 0, strokeDasharray: '1px, 200px' },
  25764. { offset: 0.2, strokeDasharray: '1px, 200px' },
  25765. { offset: 0.55, strokeDasharray: '100px, 200px' },
  25766. { offset: 1, strokeDasharray: '100px, 200px' },
  25767. ]);
  25768. const circleOuterAnimation = createAnimation()
  25769. .addElement(spinner)
  25770. .keyframes([
  25771. { offset: 0, transform: 'rotate(-90deg)' },
  25772. { offset: 1, transform: 'rotate(210deg)' },
  25773. ]);
  25774. /**
  25775. * Only add arrow animation if present
  25776. * this allows users to customize the spinners
  25777. * without errors being thrown
  25778. */
  25779. if (arrowContainer && arrow) {
  25780. const arrowContainerAnimation = createAnimation()
  25781. .addElement(arrowContainer)
  25782. .keyframes([
  25783. { offset: 0, transform: 'rotate(0deg)' },
  25784. { offset: 0.3, transform: 'rotate(0deg)' },
  25785. { offset: 0.55, transform: 'rotate(280deg)' },
  25786. { offset: 1, transform: 'rotate(400deg)' },
  25787. ]);
  25788. const arrowAnimation = createAnimation()
  25789. .addElement(arrow)
  25790. .keyframes([
  25791. { offset: 0, transform: 'translateX(2px) scale(0)' },
  25792. { offset: 0.3, transform: 'translateX(2px) scale(0)' },
  25793. { offset: 0.55, transform: 'translateX(-1.5px) scale(1)' },
  25794. { offset: 1, transform: 'translateX(-1.5px) scale(1)' },
  25795. ]);
  25796. baseAnimation.addAnimation([arrowContainerAnimation, arrowAnimation]);
  25797. }
  25798. return baseAnimation.addAnimation([spinnerArrowContainerAnimation, circleInnerAnimation, circleOuterAnimation]);
  25799. };
  25800. const createScaleAnimation = (pullingRefresherIcon, refresherEl) => {
  25801. /**
  25802. * Do not take the height of the refresher icon
  25803. * because at this point the DOM has not updated,
  25804. * so the refresher icon is still hidden with
  25805. * display: none.
  25806. * The `ion-refresher` container height
  25807. * is roughly the amount we need to offset
  25808. * the icon by when pulling down.
  25809. */
  25810. const height = refresherEl.clientHeight;
  25811. const spinnerAnimation = createAnimation()
  25812. .addElement(pullingRefresherIcon)
  25813. .keyframes([
  25814. { offset: 0, transform: `scale(0) translateY(-${height}px)` },
  25815. { offset: 1, transform: 'scale(1) translateY(100px)' },
  25816. ]);
  25817. return createBaseAnimation(pullingRefresherIcon).addAnimation([spinnerAnimation]);
  25818. };
  25819. const createTranslateAnimation = (pullingRefresherIcon, refresherEl) => {
  25820. /**
  25821. * Do not take the height of the refresher icon
  25822. * because at this point the DOM has not updated,
  25823. * so the refresher icon is still hidden with
  25824. * display: none.
  25825. * The `ion-refresher` container height
  25826. * is roughly the amount we need to offset
  25827. * the icon by when pulling down.
  25828. */
  25829. const height = refresherEl.clientHeight;
  25830. const spinnerAnimation = createAnimation()
  25831. .addElement(pullingRefresherIcon)
  25832. .keyframes([
  25833. { offset: 0, transform: `translateY(-${height}px)` },
  25834. { offset: 1, transform: 'translateY(100px)' },
  25835. ]);
  25836. return createBaseAnimation(pullingRefresherIcon).addAnimation([spinnerAnimation]);
  25837. };
  25838. const createSnapBackAnimation = (pullingRefresherIcon) => {
  25839. return createAnimation()
  25840. .duration(125)
  25841. .addElement(pullingRefresherIcon)
  25842. .fromTo('transform', 'translateY(var(--ion-pulling-refresher-translate, 100px))', 'translateY(0px)');
  25843. };
  25844. // iOS Native Refresher
  25845. // -----------------------------
  25846. const setSpinnerOpacity = (spinner, opacity) => {
  25847. spinner.style.setProperty('opacity', opacity.toString());
  25848. };
  25849. const handleScrollWhilePulling = (ticks, numTicks, pullAmount) => {
  25850. const max = 1;
  25851. writeTask(() => {
  25852. ticks.forEach((el, i) => {
  25853. /**
  25854. * Compute the opacity of each tick
  25855. * mark as a percentage of the pullAmount
  25856. * offset by max / numTicks so
  25857. * the tick marks are shown staggered.
  25858. */
  25859. const min = i * (max / numTicks);
  25860. const range = max - min;
  25861. const start = pullAmount - min;
  25862. const progression = clamp(0, start / range, 1);
  25863. el.style.setProperty('opacity', progression.toString());
  25864. });
  25865. });
  25866. };
  25867. const handleScrollWhileRefreshing = (spinner, lastVelocityY) => {
  25868. writeTask(() => {
  25869. // If user pulls down quickly, the spinner should spin faster
  25870. spinner.style.setProperty('--refreshing-rotation-duration', lastVelocityY >= 1.0 ? '0.5s' : '2s');
  25871. spinner.style.setProperty('opacity', '1');
  25872. });
  25873. };
  25874. const translateElement = (el, value, duration = 200) => {
  25875. if (!el) {
  25876. return Promise.resolve();
  25877. }
  25878. const trans = transitionEndAsync(el, duration);
  25879. writeTask(() => {
  25880. el.style.setProperty('transition', `${duration}ms all ease-out`);
  25881. if (value === undefined) {
  25882. el.style.removeProperty('transform');
  25883. }
  25884. else {
  25885. el.style.setProperty('transform', `translate3d(0px, ${value}, 0px)`);
  25886. }
  25887. });
  25888. return trans;
  25889. };
  25890. // Utils
  25891. // -----------------------------
  25892. /**
  25893. * In order to use the native iOS refresher the device must support rubber band scrolling.
  25894. * 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.
  25895. *
  25896. * We also need to be careful not to include devices that spoof their user agent.
  25897. * For example, when using iOS emulation in Chrome the user agent will be spoofed such that
  25898. * navigator.maxTouchPointer > 0. To work around this,
  25899. * we check to see if the apple-pay-logo is supported as a named image which is only
  25900. * true on Apple devices.
  25901. *
  25902. * We previously checked referencEl.style.webkitOverflowScrolling to explicitly check
  25903. * for rubber band support. However, this property was removed on iPadOS and it's possible
  25904. * that this will be removed on iOS in the future too.
  25905. *
  25906. */
  25907. const supportsRubberBandScrolling = () => {
  25908. return navigator.maxTouchPoints > 0 && CSS.supports('background: -webkit-named-image(apple-pay-logo-black)');
  25909. };
  25910. const shouldUseNativeRefresher = async (referenceEl, mode) => {
  25911. const refresherContent = referenceEl.querySelector('ion-refresher-content');
  25912. if (!refresherContent) {
  25913. return Promise.resolve(false);
  25914. }
  25915. await new Promise((resolve) => componentOnReady(refresherContent, resolve));
  25916. const pullingSpinner = referenceEl.querySelector('ion-refresher-content .refresher-pulling ion-spinner');
  25917. const refreshingSpinner = referenceEl.querySelector('ion-refresher-content .refresher-refreshing ion-spinner');
  25918. return (pullingSpinner !== null &&
  25919. refreshingSpinner !== null &&
  25920. ((mode === 'ios' && supportsRubberBandScrolling()) || mode === 'md'));
  25921. };
  25922. 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)}}";
  25923. var IonRefresherIosStyle0 = refresherIosCss;
  25924. 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)}";
  25925. var IonRefresherMdStyle0 = refresherMdCss;
  25926. /**
  25927. * @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
  25928. */
  25929. class Refresher {
  25930. constructor(hostRef) {
  25931. registerInstance(this, hostRef);
  25932. this.ionRefresh = createEvent(this, "ionRefresh", 7);
  25933. this.ionPull = createEvent(this, "ionPull", 7);
  25934. this.ionStart = createEvent(this, "ionStart", 7);
  25935. this.appliedStyles = false;
  25936. this.didStart = false;
  25937. this.progress = 0;
  25938. this.pointerDown = false;
  25939. this.needsCompletion = false;
  25940. this.didRefresh = false;
  25941. this.contentFullscreen = false;
  25942. this.lastVelocityY = 0;
  25943. this.animations = [];
  25944. this.nativeRefresher = false;
  25945. this.state = 1 /* RefresherState.Inactive */;
  25946. this.pullMin = 60;
  25947. this.pullMax = this.pullMin + 60;
  25948. this.closeDuration = '280ms';
  25949. this.snapbackDuration = '280ms';
  25950. this.pullFactor = 1;
  25951. this.disabled = false;
  25952. }
  25953. disabledChanged() {
  25954. if (this.gesture) {
  25955. this.gesture.enable(!this.disabled);
  25956. }
  25957. }
  25958. async checkNativeRefresher() {
  25959. const useNativeRefresher = await shouldUseNativeRefresher(this.el, getIonMode$1(this));
  25960. if (useNativeRefresher && !this.nativeRefresher) {
  25961. const contentEl = this.el.closest('ion-content');
  25962. this.setupNativeRefresher(contentEl);
  25963. }
  25964. else if (!useNativeRefresher) {
  25965. this.destroyNativeRefresher();
  25966. }
  25967. }
  25968. destroyNativeRefresher() {
  25969. if (this.scrollEl && this.scrollListenerCallback) {
  25970. this.scrollEl.removeEventListener('scroll', this.scrollListenerCallback);
  25971. this.scrollListenerCallback = undefined;
  25972. }
  25973. this.nativeRefresher = false;
  25974. }
  25975. async resetNativeRefresher(el, state) {
  25976. this.state = state;
  25977. if (getIonMode$1(this) === 'ios') {
  25978. await translateElement(el, undefined, 300);
  25979. }
  25980. else {
  25981. await transitionEndAsync(this.el.querySelector('.refresher-refreshing-icon'), 200);
  25982. }
  25983. this.didRefresh = false;
  25984. this.needsCompletion = false;
  25985. this.pointerDown = false;
  25986. this.animations.forEach((ani) => ani.destroy());
  25987. this.animations = [];
  25988. this.progress = 0;
  25989. this.state = 1 /* RefresherState.Inactive */;
  25990. }
  25991. async setupiOSNativeRefresher(pullingSpinner, refreshingSpinner) {
  25992. this.elementToTransform = this.scrollEl;
  25993. const ticks = pullingSpinner.shadowRoot.querySelectorAll('svg');
  25994. let MAX_PULL = this.scrollEl.clientHeight * 0.16;
  25995. const NUM_TICKS = ticks.length;
  25996. writeTask(() => ticks.forEach((el) => el.style.setProperty('animation', 'none')));
  25997. this.scrollListenerCallback = () => {
  25998. // If pointer is not on screen or refresher is not active, ignore scroll
  25999. if (!this.pointerDown && this.state === 1 /* RefresherState.Inactive */) {
  26000. return;
  26001. }
  26002. readTask(() => {
  26003. // PTR should only be active when overflow scrolling at the top
  26004. const scrollTop = this.scrollEl.scrollTop;
  26005. const refresherHeight = this.el.clientHeight;
  26006. if (scrollTop > 0) {
  26007. /**
  26008. * If refresher is refreshing and user tries to scroll
  26009. * progressively fade refresher out/in
  26010. */
  26011. if (this.state === 8 /* RefresherState.Refreshing */) {
  26012. const ratio = clamp(0, scrollTop / (refresherHeight * 0.5), 1);
  26013. writeTask(() => setSpinnerOpacity(refreshingSpinner, 1 - ratio));
  26014. return;
  26015. }
  26016. return;
  26017. }
  26018. if (this.pointerDown) {
  26019. if (!this.didStart) {
  26020. this.didStart = true;
  26021. this.ionStart.emit();
  26022. }
  26023. // emit "pulling" on every move
  26024. if (this.pointerDown) {
  26025. this.ionPull.emit();
  26026. }
  26027. }
  26028. /**
  26029. * We want to delay the start of this gesture by ~30px
  26030. * when initially pulling down so the refresher does not
  26031. * overlap with the content. But when letting go of the
  26032. * gesture before the refresher completes, we want the
  26033. * refresher tick marks to quickly fade out.
  26034. */
  26035. const offset = this.didStart ? 30 : 0;
  26036. const pullAmount = (this.progress = clamp(0, (Math.abs(scrollTop) - offset) / MAX_PULL, 1));
  26037. const shouldShowRefreshingSpinner = this.state === 8 /* RefresherState.Refreshing */ || pullAmount === 1;
  26038. if (shouldShowRefreshingSpinner) {
  26039. if (this.pointerDown) {
  26040. handleScrollWhileRefreshing(refreshingSpinner, this.lastVelocityY);
  26041. }
  26042. if (!this.didRefresh) {
  26043. this.beginRefresh();
  26044. this.didRefresh = true;
  26045. hapticImpact({ style: ImpactStyle.Light });
  26046. /**
  26047. * Translate the content element otherwise when pointer is removed
  26048. * from screen the scroll content will bounce back over the refresher
  26049. */
  26050. if (!this.pointerDown) {
  26051. translateElement(this.elementToTransform, `${refresherHeight}px`);
  26052. }
  26053. }
  26054. }
  26055. else {
  26056. this.state = 2 /* RefresherState.Pulling */;
  26057. handleScrollWhilePulling(ticks, NUM_TICKS, pullAmount);
  26058. }
  26059. });
  26060. };
  26061. this.scrollEl.addEventListener('scroll', this.scrollListenerCallback);
  26062. this.gesture = (await Promise.resolve().then(function () { return index; })).createGesture({
  26063. el: this.scrollEl,
  26064. gestureName: 'refresher',
  26065. gesturePriority: 31,
  26066. direction: 'y',
  26067. threshold: 5,
  26068. onStart: () => {
  26069. this.pointerDown = true;
  26070. if (!this.didRefresh) {
  26071. translateElement(this.elementToTransform, '0px');
  26072. }
  26073. /**
  26074. * If the content had `display: none` when
  26075. * the refresher was initialized, its clientHeight
  26076. * will be 0. When the gesture starts, the content
  26077. * will be visible, so try to get the correct
  26078. * client height again. This is most common when
  26079. * using the refresher in an ion-menu.
  26080. */
  26081. if (MAX_PULL === 0) {
  26082. MAX_PULL = this.scrollEl.clientHeight * 0.16;
  26083. }
  26084. },
  26085. onMove: (ev) => {
  26086. this.lastVelocityY = ev.velocityY;
  26087. },
  26088. onEnd: () => {
  26089. this.pointerDown = false;
  26090. this.didStart = false;
  26091. if (this.needsCompletion) {
  26092. this.resetNativeRefresher(this.elementToTransform, 32 /* RefresherState.Completing */);
  26093. this.needsCompletion = false;
  26094. }
  26095. else if (this.didRefresh) {
  26096. readTask(() => translateElement(this.elementToTransform, `${this.el.clientHeight}px`));
  26097. }
  26098. },
  26099. });
  26100. this.disabledChanged();
  26101. }
  26102. async setupMDNativeRefresher(contentEl, pullingSpinner, refreshingSpinner) {
  26103. const circle = getElementRoot(pullingSpinner).querySelector('circle');
  26104. const pullingRefresherIcon = this.el.querySelector('ion-refresher-content .refresher-pulling-icon');
  26105. const refreshingCircle = getElementRoot(refreshingSpinner).querySelector('circle');
  26106. if (circle !== null && refreshingCircle !== null) {
  26107. writeTask(() => {
  26108. circle.style.setProperty('animation', 'none');
  26109. // This lines up the animation on the refreshing spinner with the pulling spinner
  26110. refreshingSpinner.style.setProperty('animation-delay', '-655ms');
  26111. refreshingCircle.style.setProperty('animation-delay', '-655ms');
  26112. });
  26113. }
  26114. this.gesture = (await Promise.resolve().then(function () { return index; })).createGesture({
  26115. el: this.scrollEl,
  26116. gestureName: 'refresher',
  26117. gesturePriority: 31,
  26118. direction: 'y',
  26119. threshold: 5,
  26120. canStart: () => this.state !== 8 /* RefresherState.Refreshing */ &&
  26121. this.state !== 32 /* RefresherState.Completing */ &&
  26122. this.scrollEl.scrollTop === 0,
  26123. onStart: (ev) => {
  26124. this.progress = 0;
  26125. ev.data = { animation: undefined, didStart: false, cancelled: false };
  26126. },
  26127. onMove: (ev) => {
  26128. if ((ev.velocityY < 0 && this.progress === 0 && !ev.data.didStart) || ev.data.cancelled) {
  26129. ev.data.cancelled = true;
  26130. return;
  26131. }
  26132. if (!ev.data.didStart) {
  26133. ev.data.didStart = true;
  26134. this.state = 2 /* RefresherState.Pulling */;
  26135. // 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
  26136. const { scrollEl } = this;
  26137. const overflowProperty = scrollEl.matches(ION_CONTENT_CLASS_SELECTOR) ? 'overflow' : '--overflow';
  26138. writeTask(() => scrollEl.style.setProperty(overflowProperty, 'hidden'));
  26139. const animationType = getRefresherAnimationType(contentEl);
  26140. const animation = createPullingAnimation(animationType, pullingRefresherIcon, this.el);
  26141. ev.data.animation = animation;
  26142. animation.progressStart(false, 0);
  26143. this.ionStart.emit();
  26144. this.animations.push(animation);
  26145. return;
  26146. }
  26147. // Since we are using an easing curve, slow the gesture tracking down a bit
  26148. this.progress = clamp(0, (ev.deltaY / 180) * 0.5, 1);
  26149. ev.data.animation.progressStep(this.progress);
  26150. this.ionPull.emit();
  26151. },
  26152. onEnd: (ev) => {
  26153. if (!ev.data.didStart) {
  26154. return;
  26155. }
  26156. this.gesture.enable(false);
  26157. const { scrollEl } = this;
  26158. const overflowProperty = scrollEl.matches(ION_CONTENT_CLASS_SELECTOR) ? 'overflow' : '--overflow';
  26159. writeTask(() => scrollEl.style.removeProperty(overflowProperty));
  26160. if (this.progress <= 0.4) {
  26161. ev.data.animation.progressEnd(0, this.progress, 500).onFinish(() => {
  26162. this.animations.forEach((ani) => ani.destroy());
  26163. this.animations = [];
  26164. this.gesture.enable(true);
  26165. this.state = 1 /* RefresherState.Inactive */;
  26166. });
  26167. return;
  26168. }
  26169. const progress = getTimeGivenProgression([0, 0], [0, 0], [1, 1], [1, 1], this.progress)[0];
  26170. const snapBackAnimation = createSnapBackAnimation(pullingRefresherIcon);
  26171. this.animations.push(snapBackAnimation);
  26172. writeTask(async () => {
  26173. pullingRefresherIcon.style.setProperty('--ion-pulling-refresher-translate', `${progress * 100}px`);
  26174. ev.data.animation.progressEnd();
  26175. await snapBackAnimation.play();
  26176. this.beginRefresh();
  26177. ev.data.animation.destroy();
  26178. this.gesture.enable(true);
  26179. });
  26180. },
  26181. });
  26182. this.disabledChanged();
  26183. }
  26184. async setupNativeRefresher(contentEl) {
  26185. if (this.scrollListenerCallback || !contentEl || this.nativeRefresher || !this.scrollEl) {
  26186. return;
  26187. }
  26188. /**
  26189. * If using non-native refresher before make sure
  26190. * we clean up any old CSS. This can happen when
  26191. * a user manually calls the refresh method in a
  26192. * component create callback before the native
  26193. * refresher is setup.
  26194. */
  26195. this.setCss(0, '', false, '');
  26196. this.nativeRefresher = true;
  26197. const pullingSpinner = this.el.querySelector('ion-refresher-content .refresher-pulling ion-spinner');
  26198. const refreshingSpinner = this.el.querySelector('ion-refresher-content .refresher-refreshing ion-spinner');
  26199. if (getIonMode$1(this) === 'ios') {
  26200. this.setupiOSNativeRefresher(pullingSpinner, refreshingSpinner);
  26201. }
  26202. else {
  26203. this.setupMDNativeRefresher(contentEl, pullingSpinner, refreshingSpinner);
  26204. }
  26205. }
  26206. componentDidUpdate() {
  26207. this.checkNativeRefresher();
  26208. }
  26209. async connectedCallback() {
  26210. if (this.el.getAttribute('slot') !== 'fixed') {
  26211. printIonError('[ion-refresher] - Make sure you use: <ion-refresher slot="fixed">');
  26212. return;
  26213. }
  26214. const contentEl = this.el.closest(ION_CONTENT_ELEMENT_SELECTOR);
  26215. if (!contentEl) {
  26216. printIonContentErrorMsg(this.el);
  26217. return;
  26218. }
  26219. /**
  26220. * Waits for the content to be ready before querying the scroll
  26221. * or the background content element.
  26222. */
  26223. componentOnReady(contentEl, async () => {
  26224. const customScrollTarget = contentEl.querySelector(ION_CONTENT_CLASS_SELECTOR);
  26225. /**
  26226. * Query the custom scroll target (if available), first. In refresher implementations,
  26227. * the ion-refresher element will always be a direct child of ion-content (slot="fixed"). By
  26228. * querying the custom scroll target first and falling back to the ion-content element,
  26229. * the correct scroll element will be returned by the implementation.
  26230. */
  26231. this.scrollEl = await getScrollElement(customScrollTarget !== null && customScrollTarget !== void 0 ? customScrollTarget : contentEl);
  26232. /**
  26233. * Query the background content element from the host ion-content element directly.
  26234. */
  26235. this.backgroundContentEl = await contentEl.getBackgroundElement();
  26236. /**
  26237. * Check if the content element is fullscreen to apply the correct styles
  26238. * when the refresher is refreshing. Otherwise, the refresher will be
  26239. * hidden because it is positioned behind the background content element.
  26240. */
  26241. this.contentFullscreen = contentEl.fullscreen;
  26242. if (await shouldUseNativeRefresher(this.el, getIonMode$1(this))) {
  26243. this.setupNativeRefresher(contentEl);
  26244. }
  26245. else {
  26246. this.gesture = (await Promise.resolve().then(function () { return index; })).createGesture({
  26247. el: contentEl,
  26248. gestureName: 'refresher',
  26249. gesturePriority: 31,
  26250. direction: 'y',
  26251. threshold: 20,
  26252. passive: false,
  26253. canStart: () => this.canStart(),
  26254. onStart: () => this.onStart(),
  26255. onMove: (ev) => this.onMove(ev),
  26256. onEnd: () => this.onEnd(),
  26257. });
  26258. this.disabledChanged();
  26259. }
  26260. });
  26261. }
  26262. disconnectedCallback() {
  26263. this.destroyNativeRefresher();
  26264. this.scrollEl = undefined;
  26265. if (this.gesture) {
  26266. this.gesture.destroy();
  26267. this.gesture = undefined;
  26268. }
  26269. }
  26270. /**
  26271. * Call `complete()` when your async operation has completed.
  26272. * For example, the `refreshing` state is while the app is performing
  26273. * an asynchronous operation, such as receiving more data from an
  26274. * AJAX request. Once the data has been received, you then call this
  26275. * method to signify that the refreshing has completed and to close
  26276. * the refresher. This method also changes the refresher's state from
  26277. * `refreshing` to `completing`.
  26278. */
  26279. async complete() {
  26280. if (this.nativeRefresher) {
  26281. this.needsCompletion = true;
  26282. // Do not reset scroll el until user removes pointer from screen
  26283. if (!this.pointerDown) {
  26284. raf(() => raf(() => this.resetNativeRefresher(this.elementToTransform, 32 /* RefresherState.Completing */)));
  26285. }
  26286. }
  26287. else {
  26288. this.close(32 /* RefresherState.Completing */, '120ms');
  26289. }
  26290. }
  26291. /**
  26292. * Changes the refresher's state from `refreshing` to `cancelling`.
  26293. */
  26294. async cancel() {
  26295. if (this.nativeRefresher) {
  26296. // Do not reset scroll el until user removes pointer from screen
  26297. if (!this.pointerDown) {
  26298. raf(() => raf(() => this.resetNativeRefresher(this.elementToTransform, 16 /* RefresherState.Cancelling */)));
  26299. }
  26300. }
  26301. else {
  26302. this.close(16 /* RefresherState.Cancelling */, '');
  26303. }
  26304. }
  26305. /**
  26306. * A number representing how far down the user has pulled.
  26307. * The number `0` represents the user hasn't pulled down at all. The
  26308. * number `1`, and anything greater than `1`, represents that the user
  26309. * has pulled far enough down that when they let go then the refresh will
  26310. * happen. If they let go and the number is less than `1`, then the
  26311. * refresh will not happen, and the content will return to it's original
  26312. * position.
  26313. */
  26314. getProgress() {
  26315. return Promise.resolve(this.progress);
  26316. }
  26317. canStart() {
  26318. if (!this.scrollEl) {
  26319. return false;
  26320. }
  26321. if (this.state !== 1 /* RefresherState.Inactive */) {
  26322. return false;
  26323. }
  26324. // if the scrollTop is greater than zero then it's
  26325. // not possible to pull the content down yet
  26326. if (this.scrollEl.scrollTop > 0) {
  26327. return false;
  26328. }
  26329. return true;
  26330. }
  26331. onStart() {
  26332. this.progress = 0;
  26333. this.state = 1 /* RefresherState.Inactive */;
  26334. this.memoizeOverflowStyle();
  26335. /**
  26336. * If the content is fullscreen, then we need to
  26337. * set the offset-top style on the background content
  26338. * element to ensure that the refresher is shown.
  26339. */
  26340. if (this.contentFullscreen && this.backgroundContentEl) {
  26341. this.backgroundContentEl.style.setProperty('--offset-top', '0px');
  26342. }
  26343. }
  26344. onMove(detail) {
  26345. if (!this.scrollEl) {
  26346. return;
  26347. }
  26348. // this method can get called like a bazillion times per second,
  26349. // so it's built to be as efficient as possible, and does its
  26350. // best to do any DOM read/writes only when absolutely necessary
  26351. // if multi-touch then get out immediately
  26352. const ev = detail.event;
  26353. if (ev.touches !== undefined && ev.touches.length > 1) {
  26354. return;
  26355. }
  26356. // do nothing if it's actively refreshing
  26357. // or it's in the way of closing
  26358. // or this was never a startY
  26359. if ((this.state & 56 /* RefresherState._BUSY_ */) !== 0) {
  26360. return;
  26361. }
  26362. const pullFactor = Number.isNaN(this.pullFactor) || this.pullFactor < 0 ? 1 : this.pullFactor;
  26363. const deltaY = detail.deltaY * pullFactor;
  26364. // don't bother if they're scrolling up
  26365. // and have not already started dragging
  26366. if (deltaY <= 0) {
  26367. // the current Y is higher than the starting Y
  26368. // so they scrolled up enough to be ignored
  26369. this.progress = 0;
  26370. this.state = 1 /* RefresherState.Inactive */;
  26371. if (this.appliedStyles) {
  26372. // reset the styles only if they were applied
  26373. this.setCss(0, '', false, '');
  26374. return;
  26375. }
  26376. return;
  26377. }
  26378. if (this.state === 1 /* RefresherState.Inactive */) {
  26379. // this refresh is not already actively pulling down
  26380. // get the content's scrollTop
  26381. const scrollHostScrollTop = this.scrollEl.scrollTop;
  26382. // if the scrollTop is greater than zero then it's
  26383. // not possible to pull the content down yet
  26384. if (scrollHostScrollTop > 0) {
  26385. this.progress = 0;
  26386. return;
  26387. }
  26388. // content scrolled all the way to the top, and dragging down
  26389. this.state = 2 /* RefresherState.Pulling */;
  26390. }
  26391. // prevent native scroll events
  26392. if (ev.cancelable) {
  26393. ev.preventDefault();
  26394. }
  26395. // the refresher is actively pulling at this point
  26396. // move the scroll element within the content element
  26397. this.setCss(deltaY, '0ms', true, '');
  26398. if (deltaY === 0) {
  26399. // don't continue if there's no delta yet
  26400. this.progress = 0;
  26401. return;
  26402. }
  26403. const pullMin = this.pullMin;
  26404. // set pull progress
  26405. this.progress = deltaY / pullMin;
  26406. // emit "start" if it hasn't started yet
  26407. if (!this.didStart) {
  26408. this.didStart = true;
  26409. this.ionStart.emit();
  26410. }
  26411. // emit "pulling" on every move
  26412. this.ionPull.emit();
  26413. // do nothing if the delta is less than the pull threshold
  26414. if (deltaY < pullMin) {
  26415. // ensure it stays in the pulling state, cuz its not ready yet
  26416. this.state = 2 /* RefresherState.Pulling */;
  26417. return;
  26418. }
  26419. if (deltaY > this.pullMax) {
  26420. // they pulled farther than the max, so kick off the refresh
  26421. this.beginRefresh();
  26422. return;
  26423. }
  26424. // pulled farther than the pull min!!
  26425. // it is now in the `ready` state!!
  26426. // if they let go then it'll refresh, kerpow!!
  26427. this.state = 4 /* RefresherState.Ready */;
  26428. return;
  26429. }
  26430. onEnd() {
  26431. // only run in a zone when absolutely necessary
  26432. if (this.state === 4 /* RefresherState.Ready */) {
  26433. // they pulled down far enough, so it's ready to refresh
  26434. this.beginRefresh();
  26435. }
  26436. else if (this.state === 2 /* RefresherState.Pulling */) {
  26437. // they were pulling down, but didn't pull down far enough
  26438. // set the content back to it's original location
  26439. // and close the refresher
  26440. // set that the refresh is actively cancelling
  26441. this.cancel();
  26442. }
  26443. else if (this.state === 1 /* RefresherState.Inactive */) {
  26444. /**
  26445. * The pull to refresh gesture was aborted
  26446. * so we should immediately restore any overflow styles
  26447. * that have been modified. Do not call this.cancel
  26448. * because the styles will only be reset after a timeout.
  26449. * If the gesture is aborted then scrolling should be
  26450. * available right away.
  26451. */
  26452. this.restoreOverflowStyle();
  26453. }
  26454. }
  26455. beginRefresh() {
  26456. // assumes we're already back in a zone
  26457. // they pulled down far enough, so it's ready to refresh
  26458. this.state = 8 /* RefresherState.Refreshing */;
  26459. // place the content in a hangout position while it thinks
  26460. this.setCss(this.pullMin, this.snapbackDuration, true, '');
  26461. // emit "refresh" because it was pulled down far enough
  26462. // and they let go to begin refreshing
  26463. this.ionRefresh.emit({
  26464. complete: this.complete.bind(this),
  26465. });
  26466. }
  26467. close(state, delay) {
  26468. // create fallback timer incase something goes wrong with transitionEnd event
  26469. setTimeout(() => {
  26470. var _a;
  26471. this.state = 1 /* RefresherState.Inactive */;
  26472. this.progress = 0;
  26473. this.didStart = false;
  26474. /**
  26475. * Reset any overflow styles so the
  26476. * user can scroll again.
  26477. */
  26478. this.setCss(0, '0ms', false, '', true);
  26479. /**
  26480. * Reset the offset-top style on the background content
  26481. * when the refresher is no longer refreshing and the
  26482. * content is fullscreen.
  26483. *
  26484. * This ensures that the behavior of background content
  26485. * does not change when refreshing is complete.
  26486. */
  26487. if (this.contentFullscreen && this.backgroundContentEl) {
  26488. (_a = this.backgroundContentEl) === null || _a === void 0 ? void 0 : _a.style.removeProperty('--offset-top');
  26489. }
  26490. }, 600);
  26491. // reset the styles on the scroll element
  26492. // set that the refresh is actively cancelling/completing
  26493. this.state = state;
  26494. this.setCss(0, this.closeDuration, true, delay);
  26495. }
  26496. setCss(y, duration, overflowVisible, delay, shouldRestoreOverflowStyle = false) {
  26497. if (this.nativeRefresher) {
  26498. return;
  26499. }
  26500. this.appliedStyles = y > 0;
  26501. writeTask(() => {
  26502. if (this.scrollEl && this.backgroundContentEl) {
  26503. const scrollStyle = this.scrollEl.style;
  26504. const backgroundStyle = this.backgroundContentEl.style;
  26505. scrollStyle.transform = backgroundStyle.transform = y > 0 ? `translateY(${y}px) translateZ(0px)` : '';
  26506. scrollStyle.transitionDuration = backgroundStyle.transitionDuration = duration;
  26507. scrollStyle.transitionDelay = backgroundStyle.transitionDelay = delay;
  26508. scrollStyle.overflow = overflowVisible ? 'hidden' : '';
  26509. }
  26510. /**
  26511. * Reset the overflow styles only once
  26512. * the pull to refresh effect has been closed.
  26513. * This ensures that the gesture is done
  26514. * and the refresh operation has either
  26515. * been aborted or has completed.
  26516. */
  26517. if (shouldRestoreOverflowStyle) {
  26518. this.restoreOverflowStyle();
  26519. }
  26520. });
  26521. }
  26522. memoizeOverflowStyle() {
  26523. if (this.scrollEl) {
  26524. const { overflow, overflowX, overflowY } = this.scrollEl.style;
  26525. this.overflowStyles = {
  26526. overflow: overflow !== null && overflow !== void 0 ? overflow : '',
  26527. overflowX: overflowX !== null && overflowX !== void 0 ? overflowX : '',
  26528. overflowY: overflowY !== null && overflowY !== void 0 ? overflowY : '',
  26529. };
  26530. }
  26531. }
  26532. restoreOverflowStyle() {
  26533. if (this.overflowStyles !== undefined && this.scrollEl !== undefined) {
  26534. const { overflow, overflowX, overflowY } = this.overflowStyles;
  26535. this.scrollEl.style.overflow = overflow;
  26536. this.scrollEl.style.overflowX = overflowX;
  26537. this.scrollEl.style.overflowY = overflowY;
  26538. this.overflowStyles = undefined;
  26539. }
  26540. }
  26541. render() {
  26542. const mode = getIonMode$1(this);
  26543. return (hAsync(Host, { key: 'c717c16f2ca3e42351848cc8ad37918dec28961d', slot: "fixed", class: {
  26544. [mode]: true,
  26545. // Used internally for styling
  26546. [`refresher-${mode}`]: true,
  26547. 'refresher-native': this.nativeRefresher,
  26548. 'refresher-active': this.state !== 1 /* RefresherState.Inactive */,
  26549. 'refresher-pulling': this.state === 2 /* RefresherState.Pulling */,
  26550. 'refresher-ready': this.state === 4 /* RefresherState.Ready */,
  26551. 'refresher-refreshing': this.state === 8 /* RefresherState.Refreshing */,
  26552. 'refresher-cancelling': this.state === 16 /* RefresherState.Cancelling */,
  26553. 'refresher-completing': this.state === 32 /* RefresherState.Completing */,
  26554. } }));
  26555. }
  26556. get el() { return getElement(this); }
  26557. static get watchers() { return {
  26558. "disabled": ["disabledChanged"]
  26559. }; }
  26560. static get style() { return {
  26561. ios: IonRefresherIosStyle0,
  26562. md: IonRefresherMdStyle0
  26563. }; }
  26564. static get cmpMeta() { return {
  26565. "$flags$": 32,
  26566. "$tagName$": "ion-refresher",
  26567. "$members$": {
  26568. "pullMin": [2, "pull-min"],
  26569. "pullMax": [2, "pull-max"],
  26570. "closeDuration": [1, "close-duration"],
  26571. "snapbackDuration": [1, "snapback-duration"],
  26572. "pullFactor": [2, "pull-factor"],
  26573. "disabled": [4],
  26574. "nativeRefresher": [32],
  26575. "state": [32],
  26576. "complete": [64],
  26577. "cancel": [64],
  26578. "getProgress": [64]
  26579. },
  26580. "$listeners$": undefined,
  26581. "$lazyBundleId$": "-",
  26582. "$attrsToReflect$": []
  26583. }; }
  26584. }
  26585. const spinners = {
  26586. bubbles: {
  26587. dur: 1000,
  26588. circles: 9,
  26589. fn: (dur, index, total) => {
  26590. const animationDelay = `${(dur * index) / total - dur}ms`;
  26591. const angle = (2 * Math.PI * index) / total;
  26592. return {
  26593. r: 5,
  26594. style: {
  26595. top: `${32 * Math.sin(angle)}%`,
  26596. left: `${32 * Math.cos(angle)}%`,
  26597. 'animation-delay': animationDelay,
  26598. },
  26599. };
  26600. },
  26601. },
  26602. circles: {
  26603. dur: 1000,
  26604. circles: 8,
  26605. fn: (dur, index, total) => {
  26606. const step = index / total;
  26607. const animationDelay = `${dur * step - dur}ms`;
  26608. const angle = 2 * Math.PI * step;
  26609. return {
  26610. r: 5,
  26611. style: {
  26612. top: `${32 * Math.sin(angle)}%`,
  26613. left: `${32 * Math.cos(angle)}%`,
  26614. 'animation-delay': animationDelay,
  26615. },
  26616. };
  26617. },
  26618. },
  26619. circular: {
  26620. dur: 1400,
  26621. elmDuration: true,
  26622. circles: 1,
  26623. fn: () => {
  26624. return {
  26625. r: 20,
  26626. cx: 48,
  26627. cy: 48,
  26628. fill: 'none',
  26629. viewBox: '24 24 48 48',
  26630. transform: 'translate(0,0)',
  26631. style: {},
  26632. };
  26633. },
  26634. },
  26635. crescent: {
  26636. dur: 750,
  26637. circles: 1,
  26638. fn: () => {
  26639. return {
  26640. r: 26,
  26641. style: {},
  26642. };
  26643. },
  26644. },
  26645. dots: {
  26646. dur: 750,
  26647. circles: 3,
  26648. fn: (_, index) => {
  26649. const animationDelay = -(110 * index) + 'ms';
  26650. return {
  26651. r: 6,
  26652. style: {
  26653. left: `${32 - 32 * index}%`,
  26654. 'animation-delay': animationDelay,
  26655. },
  26656. };
  26657. },
  26658. },
  26659. lines: {
  26660. dur: 1000,
  26661. lines: 8,
  26662. fn: (dur, index, total) => {
  26663. const transform = `rotate(${(360 / total) * index + (index < total / 2 ? 180 : -180)}deg)`;
  26664. const animationDelay = `${(dur * index) / total - dur}ms`;
  26665. return {
  26666. y1: 14,
  26667. y2: 26,
  26668. style: {
  26669. transform: transform,
  26670. 'animation-delay': animationDelay,
  26671. },
  26672. };
  26673. },
  26674. },
  26675. 'lines-small': {
  26676. dur: 1000,
  26677. lines: 8,
  26678. fn: (dur, index, total) => {
  26679. const transform = `rotate(${(360 / total) * index + (index < total / 2 ? 180 : -180)}deg)`;
  26680. const animationDelay = `${(dur * index) / total - dur}ms`;
  26681. return {
  26682. y1: 12,
  26683. y2: 20,
  26684. style: {
  26685. transform: transform,
  26686. 'animation-delay': animationDelay,
  26687. },
  26688. };
  26689. },
  26690. },
  26691. 'lines-sharp': {
  26692. dur: 1000,
  26693. lines: 12,
  26694. fn: (dur, index, total) => {
  26695. const transform = `rotate(${30 * index + (index < 6 ? 180 : -180)}deg)`;
  26696. const animationDelay = `${(dur * index) / total - dur}ms`;
  26697. return {
  26698. y1: 17,
  26699. y2: 29,
  26700. style: {
  26701. transform: transform,
  26702. 'animation-delay': animationDelay,
  26703. },
  26704. };
  26705. },
  26706. },
  26707. 'lines-sharp-small': {
  26708. dur: 1000,
  26709. lines: 12,
  26710. fn: (dur, index, total) => {
  26711. const transform = `rotate(${30 * index + (index < 6 ? 180 : -180)}deg)`;
  26712. const animationDelay = `${(dur * index) / total - dur}ms`;
  26713. return {
  26714. y1: 12,
  26715. y2: 20,
  26716. style: {
  26717. transform: transform,
  26718. 'animation-delay': animationDelay,
  26719. },
  26720. };
  26721. },
  26722. },
  26723. };
  26724. const SPINNERS = spinners;
  26725. class RefresherContent {
  26726. constructor(hostRef) {
  26727. registerInstance(this, hostRef);
  26728. this.customHTMLEnabled = config.get('innerHTMLTemplatesEnabled', ENABLE_HTML_CONTENT_DEFAULT);
  26729. this.pullingIcon = undefined;
  26730. this.pullingText = undefined;
  26731. this.refreshingSpinner = undefined;
  26732. this.refreshingText = undefined;
  26733. }
  26734. componentWillLoad() {
  26735. if (this.pullingIcon === undefined) {
  26736. /**
  26737. * The native iOS refresher uses a spinner instead of
  26738. * an icon, so we need to see if this device supports
  26739. * the native iOS refresher.
  26740. */
  26741. const hasRubberBandScrolling = supportsRubberBandScrolling();
  26742. const mode = getIonMode$1(this);
  26743. const overflowRefresher = hasRubberBandScrolling ? 'lines' : arrowDown;
  26744. this.pullingIcon = config.get('refreshingIcon', mode === 'ios' && hasRubberBandScrolling ? config.get('spinner', overflowRefresher) : 'circular');
  26745. }
  26746. if (this.refreshingSpinner === undefined) {
  26747. const mode = getIonMode$1(this);
  26748. this.refreshingSpinner = config.get('refreshingSpinner', config.get('spinner', mode === 'ios' ? 'lines' : 'circular'));
  26749. }
  26750. }
  26751. renderPullingText() {
  26752. const { customHTMLEnabled, pullingText } = this;
  26753. if (customHTMLEnabled) {
  26754. return hAsync("div", { class: "refresher-pulling-text", innerHTML: sanitizeDOMString(pullingText) });
  26755. }
  26756. return hAsync("div", { class: "refresher-pulling-text" }, pullingText);
  26757. }
  26758. renderRefreshingText() {
  26759. const { customHTMLEnabled, refreshingText } = this;
  26760. if (customHTMLEnabled) {
  26761. return hAsync("div", { class: "refresher-refreshing-text", innerHTML: sanitizeDOMString(refreshingText) });
  26762. }
  26763. return hAsync("div", { class: "refresher-refreshing-text" }, refreshingText);
  26764. }
  26765. render() {
  26766. const pullingIcon = this.pullingIcon;
  26767. const hasSpinner = pullingIcon != null && SPINNERS[pullingIcon] !== undefined;
  26768. const mode = getIonMode$1(this);
  26769. 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())));
  26770. }
  26771. get el() { return getElement(this); }
  26772. static get cmpMeta() { return {
  26773. "$flags$": 0,
  26774. "$tagName$": "ion-refresher-content",
  26775. "$members$": {
  26776. "pullingIcon": [1025, "pulling-icon"],
  26777. "pullingText": [1, "pulling-text"],
  26778. "refreshingSpinner": [1025, "refreshing-spinner"],
  26779. "refreshingText": [1, "refreshing-text"]
  26780. },
  26781. "$listeners$": undefined,
  26782. "$lazyBundleId$": "-",
  26783. "$attrsToReflect$": []
  26784. }; }
  26785. }
  26786. 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}";
  26787. var IonReorderIosStyle0 = reorderIosCss;
  26788. 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}";
  26789. var IonReorderMdStyle0 = reorderMdCss;
  26790. /**
  26791. * @part icon - The icon of the reorder handle (uses ion-icon).
  26792. */
  26793. class Reorder {
  26794. constructor(hostRef) {
  26795. registerInstance(this, hostRef);
  26796. }
  26797. onClick(ev) {
  26798. const reorderGroup = this.el.closest('ion-reorder-group');
  26799. ev.preventDefault();
  26800. // Only stop event propagation if the reorder is inside of an enabled
  26801. // reorder group. This allows interaction with clickable children components.
  26802. if (!reorderGroup || !reorderGroup.disabled) {
  26803. ev.stopImmediatePropagation();
  26804. }
  26805. }
  26806. render() {
  26807. const mode = getIonMode$1(this);
  26808. const reorderIcon = mode === 'ios' ? reorderThreeOutline : reorderTwoSharp;
  26809. 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" }))));
  26810. }
  26811. get el() { return getElement(this); }
  26812. static get style() { return {
  26813. ios: IonReorderIosStyle0,
  26814. md: IonReorderMdStyle0
  26815. }; }
  26816. static get cmpMeta() { return {
  26817. "$flags$": 41,
  26818. "$tagName$": "ion-reorder",
  26819. "$members$": undefined,
  26820. "$listeners$": [[2, "click", "onClick"]],
  26821. "$lazyBundleId$": "-",
  26822. "$attrsToReflect$": []
  26823. }; }
  26824. }
  26825. 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)}";
  26826. var IonReorderGroupStyle0 = reorderGroupCss;
  26827. class ReorderGroup {
  26828. constructor(hostRef) {
  26829. registerInstance(this, hostRef);
  26830. this.ionItemReorder = createEvent(this, "ionItemReorder", 7);
  26831. this.lastToIndex = -1;
  26832. this.cachedHeights = [];
  26833. this.scrollElTop = 0;
  26834. this.scrollElBottom = 0;
  26835. this.scrollElInitial = 0;
  26836. this.containerTop = 0;
  26837. this.containerBottom = 0;
  26838. this.state = 0 /* ReorderGroupState.Idle */;
  26839. this.disabled = true;
  26840. }
  26841. disabledChanged() {
  26842. if (this.gesture) {
  26843. this.gesture.enable(!this.disabled);
  26844. }
  26845. }
  26846. async connectedCallback() {
  26847. const contentEl = findClosestIonContent(this.el);
  26848. if (contentEl) {
  26849. this.scrollEl = await getScrollElement(contentEl);
  26850. }
  26851. this.gesture = (await Promise.resolve().then(function () { return index; })).createGesture({
  26852. el: this.el,
  26853. gestureName: 'reorder',
  26854. gesturePriority: 110,
  26855. threshold: 0,
  26856. direction: 'y',
  26857. passive: false,
  26858. canStart: (detail) => this.canStart(detail),
  26859. onStart: (ev) => this.onStart(ev),
  26860. onMove: (ev) => this.onMove(ev),
  26861. onEnd: () => this.onEnd(),
  26862. });
  26863. this.disabledChanged();
  26864. }
  26865. disconnectedCallback() {
  26866. this.onEnd();
  26867. if (this.gesture) {
  26868. this.gesture.destroy();
  26869. this.gesture = undefined;
  26870. }
  26871. }
  26872. /**
  26873. * Completes the reorder operation. Must be called by the `ionItemReorder` event.
  26874. *
  26875. * If a list of items is passed, the list will be reordered and returned in the
  26876. * proper order.
  26877. *
  26878. * If no parameters are passed or if `true` is passed in, the reorder will complete
  26879. * and the item will remain in the position it was dragged to. If `false` is passed,
  26880. * the reorder will complete and the item will bounce back to its original position.
  26881. *
  26882. * @param listOrReorder A list of items to be sorted and returned in the new order or a
  26883. * boolean of whether or not the reorder should reposition the item.
  26884. */
  26885. complete(listOrReorder) {
  26886. return Promise.resolve(this.completeReorder(listOrReorder));
  26887. }
  26888. canStart(ev) {
  26889. if (this.selectedItemEl || this.state !== 0 /* ReorderGroupState.Idle */) {
  26890. return false;
  26891. }
  26892. const target = ev.event.target;
  26893. const reorderEl = target.closest('ion-reorder');
  26894. if (!reorderEl) {
  26895. return false;
  26896. }
  26897. const item = findReorderItem(reorderEl, this.el);
  26898. if (!item) {
  26899. return false;
  26900. }
  26901. ev.data = item;
  26902. return true;
  26903. }
  26904. onStart(ev) {
  26905. ev.event.preventDefault();
  26906. const item = (this.selectedItemEl = ev.data);
  26907. const heights = this.cachedHeights;
  26908. heights.length = 0;
  26909. const el = this.el;
  26910. const children = el.children;
  26911. if (!children || children.length === 0) {
  26912. return;
  26913. }
  26914. let sum = 0;
  26915. for (let i = 0; i < children.length; i++) {
  26916. const child = children[i];
  26917. sum += child.offsetHeight;
  26918. heights.push(sum);
  26919. child.$ionIndex = i;
  26920. }
  26921. const box = el.getBoundingClientRect();
  26922. this.containerTop = box.top;
  26923. this.containerBottom = box.bottom;
  26924. if (this.scrollEl) {
  26925. const scrollBox = this.scrollEl.getBoundingClientRect();
  26926. this.scrollElInitial = this.scrollEl.scrollTop;
  26927. this.scrollElTop = scrollBox.top + AUTO_SCROLL_MARGIN;
  26928. this.scrollElBottom = scrollBox.bottom - AUTO_SCROLL_MARGIN;
  26929. }
  26930. else {
  26931. this.scrollElInitial = 0;
  26932. this.scrollElTop = 0;
  26933. this.scrollElBottom = 0;
  26934. }
  26935. this.lastToIndex = indexForItem(item);
  26936. this.selectedItemHeight = item.offsetHeight;
  26937. this.state = 1 /* ReorderGroupState.Active */;
  26938. item.classList.add(ITEM_REORDER_SELECTED);
  26939. hapticSelectionStart();
  26940. }
  26941. onMove(ev) {
  26942. const selectedItem = this.selectedItemEl;
  26943. if (!selectedItem) {
  26944. return;
  26945. }
  26946. // Scroll if we reach the scroll margins
  26947. const scroll = this.autoscroll(ev.currentY);
  26948. // // Get coordinate
  26949. const top = this.containerTop - scroll;
  26950. const bottom = this.containerBottom - scroll;
  26951. const currentY = Math.max(top, Math.min(ev.currentY, bottom));
  26952. const deltaY = scroll + currentY - ev.startY;
  26953. const normalizedY = currentY - top;
  26954. const toIndex = this.itemIndexForTop(normalizedY);
  26955. if (toIndex !== this.lastToIndex) {
  26956. const fromIndex = indexForItem(selectedItem);
  26957. this.lastToIndex = toIndex;
  26958. hapticSelectionChanged();
  26959. this.reorderMove(fromIndex, toIndex);
  26960. }
  26961. // Update selected item position
  26962. selectedItem.style.transform = `translateY(${deltaY}px)`;
  26963. }
  26964. onEnd() {
  26965. const selectedItemEl = this.selectedItemEl;
  26966. this.state = 2 /* ReorderGroupState.Complete */;
  26967. if (!selectedItemEl) {
  26968. this.state = 0 /* ReorderGroupState.Idle */;
  26969. return;
  26970. }
  26971. const toIndex = this.lastToIndex;
  26972. const fromIndex = indexForItem(selectedItemEl);
  26973. if (toIndex === fromIndex) {
  26974. this.completeReorder();
  26975. }
  26976. else {
  26977. this.ionItemReorder.emit({
  26978. from: fromIndex,
  26979. to: toIndex,
  26980. complete: this.completeReorder.bind(this),
  26981. });
  26982. }
  26983. hapticSelectionEnd();
  26984. }
  26985. completeReorder(listOrReorder) {
  26986. const selectedItemEl = this.selectedItemEl;
  26987. if (selectedItemEl && this.state === 2 /* ReorderGroupState.Complete */) {
  26988. const children = this.el.children;
  26989. const len = children.length;
  26990. const toIndex = this.lastToIndex;
  26991. const fromIndex = indexForItem(selectedItemEl);
  26992. /**
  26993. * insertBefore and setting the transform
  26994. * needs to happen in the same frame otherwise
  26995. * there will be a duplicate transition. This primarily
  26996. * impacts Firefox where insertBefore and transform operations
  26997. * are happening in two separate frames.
  26998. */
  26999. raf(() => {
  27000. if (toIndex !== fromIndex && (listOrReorder === undefined || listOrReorder === true)) {
  27001. const ref = fromIndex < toIndex ? children[toIndex + 1] : children[toIndex];
  27002. this.el.insertBefore(selectedItemEl, ref);
  27003. }
  27004. for (let i = 0; i < len; i++) {
  27005. children[i].style['transform'] = '';
  27006. }
  27007. });
  27008. if (Array.isArray(listOrReorder)) {
  27009. listOrReorder = reorderArray(listOrReorder, fromIndex, toIndex);
  27010. }
  27011. selectedItemEl.style.transition = '';
  27012. selectedItemEl.classList.remove(ITEM_REORDER_SELECTED);
  27013. this.selectedItemEl = undefined;
  27014. this.state = 0 /* ReorderGroupState.Idle */;
  27015. }
  27016. return listOrReorder;
  27017. }
  27018. itemIndexForTop(deltaY) {
  27019. const heights = this.cachedHeights;
  27020. for (let i = 0; i < heights.length; i++) {
  27021. if (heights[i] > deltaY) {
  27022. return i;
  27023. }
  27024. }
  27025. return heights.length - 1;
  27026. }
  27027. /********* DOM WRITE ********* */
  27028. reorderMove(fromIndex, toIndex) {
  27029. const itemHeight = this.selectedItemHeight;
  27030. const children = this.el.children;
  27031. for (let i = 0; i < children.length; i++) {
  27032. const style = children[i].style;
  27033. let value = '';
  27034. if (i > fromIndex && i <= toIndex) {
  27035. value = `translateY(${-itemHeight}px)`;
  27036. }
  27037. else if (i < fromIndex && i >= toIndex) {
  27038. value = `translateY(${itemHeight}px)`;
  27039. }
  27040. style['transform'] = value;
  27041. }
  27042. }
  27043. autoscroll(posY) {
  27044. if (!this.scrollEl) {
  27045. return 0;
  27046. }
  27047. let amount = 0;
  27048. if (posY < this.scrollElTop) {
  27049. amount = -SCROLL_JUMP;
  27050. }
  27051. else if (posY > this.scrollElBottom) {
  27052. amount = SCROLL_JUMP;
  27053. }
  27054. if (amount !== 0) {
  27055. this.scrollEl.scrollBy(0, amount);
  27056. }
  27057. return this.scrollEl.scrollTop - this.scrollElInitial;
  27058. }
  27059. render() {
  27060. const mode = getIonMode$1(this);
  27061. return (hAsync(Host, { key: '6ca009dd65302a914d459aec638e62977440db20', class: {
  27062. [mode]: true,
  27063. 'reorder-enabled': !this.disabled,
  27064. 'reorder-list-active': this.state !== 0 /* ReorderGroupState.Idle */,
  27065. } }));
  27066. }
  27067. get el() { return getElement(this); }
  27068. static get watchers() { return {
  27069. "disabled": ["disabledChanged"]
  27070. }; }
  27071. static get style() { return IonReorderGroupStyle0; }
  27072. static get cmpMeta() { return {
  27073. "$flags$": 0,
  27074. "$tagName$": "ion-reorder-group",
  27075. "$members$": {
  27076. "disabled": [4],
  27077. "state": [32],
  27078. "complete": [64]
  27079. },
  27080. "$listeners$": undefined,
  27081. "$lazyBundleId$": "-",
  27082. "$attrsToReflect$": []
  27083. }; }
  27084. }
  27085. const indexForItem = (element) => {
  27086. return element['$ionIndex'];
  27087. };
  27088. const findReorderItem = (node, container) => {
  27089. let parent;
  27090. while (node) {
  27091. parent = node.parentElement;
  27092. if (parent === container) {
  27093. return node;
  27094. }
  27095. node = parent;
  27096. }
  27097. return undefined;
  27098. };
  27099. const AUTO_SCROLL_MARGIN = 60;
  27100. const SCROLL_JUMP = 10;
  27101. const ITEM_REORDER_SELECTED = 'reorder-selected';
  27102. const reorderArray = (array, from, to) => {
  27103. const element = array[from];
  27104. array.splice(from, 1);
  27105. array.splice(to, 0, element);
  27106. return array.slice();
  27107. };
  27108. 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}}";
  27109. var IonRippleEffectStyle0 = rippleEffectCss;
  27110. class RippleEffect {
  27111. constructor(hostRef) {
  27112. registerInstance(this, hostRef);
  27113. this.type = 'bounded';
  27114. }
  27115. /**
  27116. * Adds the ripple effect to the parent element.
  27117. *
  27118. * @param x The horizontal coordinate of where the ripple should start.
  27119. * @param y The vertical coordinate of where the ripple should start.
  27120. */
  27121. async addRipple(x, y) {
  27122. return new Promise((resolve) => {
  27123. readTask(() => {
  27124. const rect = this.el.getBoundingClientRect();
  27125. const width = rect.width;
  27126. const height = rect.height;
  27127. const hypotenuse = Math.sqrt(width * width + height * height);
  27128. const maxDim = Math.max(height, width);
  27129. const maxRadius = this.unbounded ? maxDim : hypotenuse + PADDING;
  27130. const initialSize = Math.floor(maxDim * INITIAL_ORIGIN_SCALE);
  27131. const finalScale = maxRadius / initialSize;
  27132. let posX = x - rect.left;
  27133. let posY = y - rect.top;
  27134. if (this.unbounded) {
  27135. posX = width * 0.5;
  27136. posY = height * 0.5;
  27137. }
  27138. const styleX = posX - initialSize * 0.5;
  27139. const styleY = posY - initialSize * 0.5;
  27140. const moveX = width * 0.5 - posX;
  27141. const moveY = height * 0.5 - posY;
  27142. writeTask(() => {
  27143. const div = document.createElement('div');
  27144. div.classList.add('ripple-effect');
  27145. const style = div.style;
  27146. style.top = styleY + 'px';
  27147. style.left = styleX + 'px';
  27148. style.width = style.height = initialSize + 'px';
  27149. style.setProperty('--final-scale', `${finalScale}`);
  27150. style.setProperty('--translate-end', `${moveX}px, ${moveY}px`);
  27151. const container = this.el.shadowRoot || this.el;
  27152. container.appendChild(div);
  27153. setTimeout(() => {
  27154. resolve(() => {
  27155. removeRipple(div);
  27156. });
  27157. }, 225 + 100);
  27158. });
  27159. });
  27160. });
  27161. }
  27162. get unbounded() {
  27163. return this.type === 'unbounded';
  27164. }
  27165. render() {
  27166. const mode = getIonMode$1(this);
  27167. return (hAsync(Host, { key: '40c7f73e7f5f67e29f83e1236a61c6e1c9943c42', role: "presentation", class: {
  27168. [mode]: true,
  27169. unbounded: this.unbounded,
  27170. } }));
  27171. }
  27172. get el() { return getElement(this); }
  27173. static get style() { return IonRippleEffectStyle0; }
  27174. static get cmpMeta() { return {
  27175. "$flags$": 9,
  27176. "$tagName$": "ion-ripple-effect",
  27177. "$members$": {
  27178. "type": [1],
  27179. "addRipple": [64]
  27180. },
  27181. "$listeners$": undefined,
  27182. "$lazyBundleId$": "-",
  27183. "$attrsToReflect$": []
  27184. }; }
  27185. }
  27186. const removeRipple = (ripple) => {
  27187. ripple.classList.add('fade-out');
  27188. setTimeout(() => {
  27189. ripple.remove();
  27190. }, 200);
  27191. };
  27192. const PADDING = 10;
  27193. const INITIAL_ORIGIN_SCALE = 0.5;
  27194. // TODO(FW-2832): types
  27195. class Route {
  27196. constructor(hostRef) {
  27197. registerInstance(this, hostRef);
  27198. this.ionRouteDataChanged = createEvent(this, "ionRouteDataChanged", 7);
  27199. this.url = '';
  27200. this.component = undefined;
  27201. this.componentProps = undefined;
  27202. this.beforeLeave = undefined;
  27203. this.beforeEnter = undefined;
  27204. }
  27205. onUpdate(newValue) {
  27206. this.ionRouteDataChanged.emit(newValue);
  27207. }
  27208. onComponentProps(newValue, oldValue) {
  27209. if (newValue === oldValue) {
  27210. return;
  27211. }
  27212. const keys1 = newValue ? Object.keys(newValue) : [];
  27213. const keys2 = oldValue ? Object.keys(oldValue) : [];
  27214. if (keys1.length !== keys2.length) {
  27215. this.onUpdate(newValue);
  27216. return;
  27217. }
  27218. for (const key of keys1) {
  27219. if (newValue[key] !== oldValue[key]) {
  27220. this.onUpdate(newValue);
  27221. return;
  27222. }
  27223. }
  27224. }
  27225. connectedCallback() {
  27226. this.ionRouteDataChanged.emit();
  27227. }
  27228. static get watchers() { return {
  27229. "url": ["onUpdate"],
  27230. "component": ["onUpdate"],
  27231. "componentProps": ["onComponentProps"]
  27232. }; }
  27233. static get cmpMeta() { return {
  27234. "$flags$": 0,
  27235. "$tagName$": "ion-route",
  27236. "$members$": {
  27237. "url": [1],
  27238. "component": [1],
  27239. "componentProps": [16],
  27240. "beforeLeave": [16],
  27241. "beforeEnter": [16]
  27242. },
  27243. "$listeners$": undefined,
  27244. "$lazyBundleId$": "-",
  27245. "$attrsToReflect$": []
  27246. }; }
  27247. }
  27248. class RouteRedirect {
  27249. constructor(hostRef) {
  27250. registerInstance(this, hostRef);
  27251. this.ionRouteRedirectChanged = createEvent(this, "ionRouteRedirectChanged", 7);
  27252. this.from = undefined;
  27253. this.to = undefined;
  27254. }
  27255. propDidChange() {
  27256. this.ionRouteRedirectChanged.emit();
  27257. }
  27258. connectedCallback() {
  27259. this.ionRouteRedirectChanged.emit();
  27260. }
  27261. static get watchers() { return {
  27262. "from": ["propDidChange"],
  27263. "to": ["propDidChange"]
  27264. }; }
  27265. static get cmpMeta() { return {
  27266. "$flags$": 0,
  27267. "$tagName$": "ion-route-redirect",
  27268. "$members$": {
  27269. "from": [1],
  27270. "to": [1]
  27271. },
  27272. "$listeners$": undefined,
  27273. "$lazyBundleId$": "-",
  27274. "$attrsToReflect$": []
  27275. }; }
  27276. }
  27277. const ROUTER_INTENT_NONE = 'root';
  27278. const ROUTER_INTENT_FORWARD = 'forward';
  27279. const ROUTER_INTENT_BACK = 'back';
  27280. /** Join the non empty segments with "/". */
  27281. const generatePath = (segments) => {
  27282. const path = segments.filter((s) => s.length > 0).join('/');
  27283. return '/' + path;
  27284. };
  27285. const generateUrl = (segments, useHash, queryString) => {
  27286. let url = generatePath(segments);
  27287. if (useHash) {
  27288. url = '#' + url;
  27289. }
  27290. if (queryString !== undefined) {
  27291. url += '?' + queryString;
  27292. }
  27293. return url;
  27294. };
  27295. const writeSegments = (history, root, useHash, segments, direction, state, queryString) => {
  27296. const url = generateUrl([...parsePath(root).segments, ...segments], useHash, queryString);
  27297. if (direction === ROUTER_INTENT_FORWARD) {
  27298. history.pushState(state, '', url);
  27299. }
  27300. else {
  27301. history.replaceState(state, '', url);
  27302. }
  27303. };
  27304. /**
  27305. * Transforms a chain to a list of segments.
  27306. *
  27307. * Notes:
  27308. * - parameter segments of the form :param are replaced with their value,
  27309. * - null is returned when a value is missing for any parameter segment.
  27310. */
  27311. const chainToSegments = (chain) => {
  27312. const segments = [];
  27313. for (const route of chain) {
  27314. for (const segment of route.segments) {
  27315. if (segment[0] === ':') {
  27316. // eslint-disable-next-line @typescript-eslint/prefer-optional-chain
  27317. const param = route.params && route.params[segment.slice(1)];
  27318. if (!param) {
  27319. return null;
  27320. }
  27321. segments.push(param);
  27322. }
  27323. else if (segment !== '') {
  27324. segments.push(segment);
  27325. }
  27326. }
  27327. }
  27328. return segments;
  27329. };
  27330. /**
  27331. * Removes the prefix segments from the path segments.
  27332. *
  27333. * Return:
  27334. * - null when the path segments do not start with the passed prefix,
  27335. * - the path segments after the prefix otherwise.
  27336. */
  27337. const removePrefix = (prefix, segments) => {
  27338. if (prefix.length > segments.length) {
  27339. return null;
  27340. }
  27341. if (prefix.length <= 1 && prefix[0] === '') {
  27342. return segments;
  27343. }
  27344. for (let i = 0; i < prefix.length; i++) {
  27345. if (prefix[i] !== segments[i]) {
  27346. return null;
  27347. }
  27348. }
  27349. if (segments.length === prefix.length) {
  27350. return [''];
  27351. }
  27352. return segments.slice(prefix.length);
  27353. };
  27354. const readSegments = (loc, root, useHash) => {
  27355. const prefix = parsePath(root).segments;
  27356. const pathname = useHash ? loc.hash.slice(1) : loc.pathname;
  27357. const segments = parsePath(pathname).segments;
  27358. return removePrefix(prefix, segments);
  27359. };
  27360. /**
  27361. * Parses the path to:
  27362. * - segments an array of '/' separated parts,
  27363. * - queryString (undefined when no query string).
  27364. */
  27365. const parsePath = (path) => {
  27366. let segments = [''];
  27367. let queryString;
  27368. if (path != null) {
  27369. const qsStart = path.indexOf('?');
  27370. if (qsStart > -1) {
  27371. queryString = path.substring(qsStart + 1);
  27372. path = path.substring(0, qsStart);
  27373. }
  27374. segments = path
  27375. .split('/')
  27376. .map((s) => s.trim())
  27377. .filter((s) => s.length > 0);
  27378. if (segments.length === 0) {
  27379. segments = [''];
  27380. }
  27381. }
  27382. return { segments, queryString };
  27383. };
  27384. const printRoutes = (routes) => {
  27385. console.group(`[ion-core] ROUTES[${routes.length}]`);
  27386. for (const chain of routes) {
  27387. const segments = [];
  27388. chain.forEach((r) => segments.push(...r.segments));
  27389. const ids = chain.map((r) => r.id);
  27390. console.debug(`%c ${generatePath(segments)}`, 'font-weight: bold; padding-left: 20px', '=>\t', `(${ids.join(', ')})`);
  27391. }
  27392. console.groupEnd();
  27393. };
  27394. const printRedirects = (redirects) => {
  27395. console.group(`[ion-core] REDIRECTS[${redirects.length}]`);
  27396. for (const redirect of redirects) {
  27397. if (redirect.to) {
  27398. console.debug('FROM: ', `$c ${generatePath(redirect.from)}`, 'font-weight: bold', ' TO: ', `$c ${generatePath(redirect.to.segments)}`, 'font-weight: bold');
  27399. }
  27400. }
  27401. console.groupEnd();
  27402. };
  27403. /**
  27404. * Activates the passed route chain.
  27405. *
  27406. * There must be exactly one outlet per route entry in the chain.
  27407. *
  27408. * The methods calls setRouteId on each of the outlet with the corresponding route entry in the chain.
  27409. * setRouteId will create or select the view in the outlet.
  27410. */
  27411. const writeNavState = async (root, chain, direction, index, changed = false, animation) => {
  27412. try {
  27413. // find next navigation outlet in the DOM
  27414. const outlet = searchNavNode(root);
  27415. // make sure we can continue interacting the DOM, otherwise abort
  27416. if (index >= chain.length || !outlet) {
  27417. return changed;
  27418. }
  27419. await new Promise((resolve) => componentOnReady(outlet, resolve));
  27420. const route = chain[index];
  27421. const result = await outlet.setRouteId(route.id, route.params, direction, animation);
  27422. // if the outlet changed the page, reset navigation to neutral (no direction)
  27423. // this means nested outlets will not animate
  27424. if (result.changed) {
  27425. direction = ROUTER_INTENT_NONE;
  27426. changed = true;
  27427. }
  27428. // recursively set nested outlets
  27429. changed = await writeNavState(result.element, chain, direction, index + 1, changed, animation);
  27430. // once all nested outlets are visible let's make the parent visible too,
  27431. // using markVisible prevents flickering
  27432. if (result.markVisible) {
  27433. await result.markVisible();
  27434. }
  27435. return changed;
  27436. }
  27437. catch (e) {
  27438. printIonError('[ion-router] - Exception in writeNavState:', e);
  27439. return false;
  27440. }
  27441. };
  27442. /**
  27443. * Recursively walks the outlet in the DOM.
  27444. *
  27445. * The function returns a list of RouteID corresponding to each of the outlet and the last outlet without a RouteID.
  27446. */
  27447. const readNavState = async (root) => {
  27448. const ids = [];
  27449. let outlet;
  27450. let node = root;
  27451. // eslint-disable-next-line no-cond-assign
  27452. while ((outlet = searchNavNode(node))) {
  27453. const id = await outlet.getRouteId();
  27454. if (id) {
  27455. node = id.element;
  27456. id.element = undefined;
  27457. ids.push(id);
  27458. }
  27459. else {
  27460. break;
  27461. }
  27462. }
  27463. return { ids, outlet };
  27464. };
  27465. const waitUntilNavNode = () => {
  27466. if (searchNavNode(document.body)) {
  27467. return Promise.resolve();
  27468. }
  27469. return new Promise((resolve) => {
  27470. window.addEventListener('ionNavWillLoad', () => resolve(), { once: true });
  27471. });
  27472. };
  27473. /** Selector for all the outlets supported by the router. */
  27474. const OUTLET_SELECTOR = ':not([no-router]) ion-nav, :not([no-router]) ion-tabs, :not([no-router]) ion-router-outlet';
  27475. const searchNavNode = (root) => {
  27476. if (!root) {
  27477. return undefined;
  27478. }
  27479. if (root.matches(OUTLET_SELECTOR)) {
  27480. return root;
  27481. }
  27482. const outlet = root.querySelector(OUTLET_SELECTOR);
  27483. return outlet !== null && outlet !== void 0 ? outlet : undefined;
  27484. };
  27485. /**
  27486. * Returns whether the given redirect matches the given path segments.
  27487. *
  27488. * A redirect matches when the segments of the path and redirect.from are equal.
  27489. * Note that segments are only checked until redirect.from contains a '*' which matches any path segment.
  27490. * The path ['some', 'path', 'to', 'page'] matches both ['some', 'path', 'to', 'page'] and ['some', 'path', '*'].
  27491. */
  27492. const matchesRedirect = (segments, redirect) => {
  27493. const { from, to } = redirect;
  27494. if (to === undefined) {
  27495. return false;
  27496. }
  27497. if (from.length > segments.length) {
  27498. return false;
  27499. }
  27500. for (let i = 0; i < from.length; i++) {
  27501. const expected = from[i];
  27502. if (expected === '*') {
  27503. return true;
  27504. }
  27505. if (expected !== segments[i]) {
  27506. return false;
  27507. }
  27508. }
  27509. return from.length === segments.length;
  27510. };
  27511. /** Returns the first redirect matching the path segments or undefined when no match found. */
  27512. const findRouteRedirect = (segments, redirects) => {
  27513. return redirects.find((redirect) => matchesRedirect(segments, redirect));
  27514. };
  27515. const matchesIDs = (ids, chain) => {
  27516. const len = Math.min(ids.length, chain.length);
  27517. let score = 0;
  27518. for (let i = 0; i < len; i++) {
  27519. const routeId = ids[i];
  27520. const routeChain = chain[i];
  27521. // Skip results where the route id does not match the chain at the same index
  27522. if (routeId.id.toLowerCase() !== routeChain.id) {
  27523. break;
  27524. }
  27525. if (routeId.params) {
  27526. const routeIdParams = Object.keys(routeId.params);
  27527. // Only compare routes with the chain that have the same number of parameters.
  27528. if (routeIdParams.length === routeChain.segments.length) {
  27529. // Maps the route's params into a path based on the path variable names,
  27530. // to compare against the route chain format.
  27531. //
  27532. // Before:
  27533. // ```ts
  27534. // {
  27535. // params: {
  27536. // s1: 'a',
  27537. // s2: 'b'
  27538. // }
  27539. // }
  27540. // ```
  27541. //
  27542. // After:
  27543. // ```ts
  27544. // [':s1',':s2']
  27545. // ```
  27546. //
  27547. const pathWithParams = routeIdParams.map((key) => `:${key}`);
  27548. for (let j = 0; j < pathWithParams.length; j++) {
  27549. // Skip results where the path variable is not a match
  27550. if (pathWithParams[j].toLowerCase() !== routeChain.segments[j]) {
  27551. break;
  27552. }
  27553. // Weight path matches for the same index higher.
  27554. score++;
  27555. }
  27556. }
  27557. }
  27558. // Weight id matches
  27559. score++;
  27560. }
  27561. return score;
  27562. };
  27563. /**
  27564. * Matches the segments against the chain.
  27565. *
  27566. * Returns:
  27567. * - null when there is no match,
  27568. * - a chain with the params properties updated with the parameter segments on match.
  27569. */
  27570. const matchesSegments = (segments, chain) => {
  27571. const inputSegments = new RouterSegments(segments);
  27572. let matchesDefault = false;
  27573. let allparams;
  27574. for (let i = 0; i < chain.length; i++) {
  27575. const chainSegments = chain[i].segments;
  27576. if (chainSegments[0] === '') {
  27577. matchesDefault = true;
  27578. }
  27579. else {
  27580. for (const segment of chainSegments) {
  27581. const data = inputSegments.next();
  27582. // data param
  27583. if (segment[0] === ':') {
  27584. if (data === '') {
  27585. return null;
  27586. }
  27587. allparams = allparams || [];
  27588. const params = allparams[i] || (allparams[i] = {});
  27589. params[segment.slice(1)] = data;
  27590. }
  27591. else if (data !== segment) {
  27592. return null;
  27593. }
  27594. }
  27595. matchesDefault = false;
  27596. }
  27597. }
  27598. const matches = matchesDefault ? matchesDefault === (inputSegments.next() === '') : true;
  27599. if (!matches) {
  27600. return null;
  27601. }
  27602. if (allparams) {
  27603. return chain.map((route, i) => ({
  27604. id: route.id,
  27605. segments: route.segments,
  27606. params: mergeParams(route.params, allparams[i]),
  27607. beforeEnter: route.beforeEnter,
  27608. beforeLeave: route.beforeLeave,
  27609. }));
  27610. }
  27611. return chain;
  27612. };
  27613. /**
  27614. * Merges the route parameter objects.
  27615. * Returns undefined when both parameters are undefined.
  27616. */
  27617. const mergeParams = (a, b) => {
  27618. return a || b ? Object.assign(Object.assign({}, a), b) : undefined;
  27619. };
  27620. /**
  27621. * Finds the best match for the ids in the chains.
  27622. *
  27623. * Returns the best match or null when no match is found.
  27624. * When a chain is returned the parameters are updated from the RouteIDs.
  27625. * That is they contain both the componentProps of the <ion-route> and the parameter segment.
  27626. */
  27627. const findChainForIDs = (ids, chains) => {
  27628. let match = null;
  27629. let maxMatches = 0;
  27630. for (const chain of chains) {
  27631. const score = matchesIDs(ids, chain);
  27632. if (score > maxMatches) {
  27633. match = chain;
  27634. maxMatches = score;
  27635. }
  27636. }
  27637. if (match) {
  27638. return match.map((route, i) => {
  27639. var _a;
  27640. return ({
  27641. id: route.id,
  27642. segments: route.segments,
  27643. params: mergeParams(route.params, (_a = ids[i]) === null || _a === void 0 ? void 0 : _a.params),
  27644. });
  27645. });
  27646. }
  27647. return null;
  27648. };
  27649. /**
  27650. * Finds the best match for the segments in the chains.
  27651. *
  27652. * Returns the best match or null when no match is found.
  27653. * When a chain is returned the parameters are updated from the segments.
  27654. * That is they contain both the componentProps of the <ion-route> and the parameter segments.
  27655. */
  27656. const findChainForSegments = (segments, chains) => {
  27657. let match = null;
  27658. let bestScore = 0;
  27659. for (const chain of chains) {
  27660. const matchedChain = matchesSegments(segments, chain);
  27661. if (matchedChain !== null) {
  27662. const score = computePriority(matchedChain);
  27663. if (score > bestScore) {
  27664. bestScore = score;
  27665. match = matchedChain;
  27666. }
  27667. }
  27668. }
  27669. return match;
  27670. };
  27671. /**
  27672. * Computes the priority of a chain.
  27673. *
  27674. * Parameter segments are given a lower priority over fixed segments.
  27675. *
  27676. * Considering the following 2 chains matching the path /path/to/page:
  27677. * - /path/to/:where
  27678. * - /path/to/page
  27679. *
  27680. * The second one will be given a higher priority because "page" is a fixed segment (vs ":where", a parameter segment).
  27681. */
  27682. const computePriority = (chain) => {
  27683. let score = 1;
  27684. let level = 1;
  27685. for (const route of chain) {
  27686. for (const segment of route.segments) {
  27687. if (segment[0] === ':') {
  27688. score += Math.pow(1, level);
  27689. }
  27690. else if (segment !== '') {
  27691. score += Math.pow(2, level);
  27692. }
  27693. level++;
  27694. }
  27695. }
  27696. return score;
  27697. };
  27698. class RouterSegments {
  27699. constructor(segments) {
  27700. this.segments = segments.slice();
  27701. }
  27702. next() {
  27703. if (this.segments.length > 0) {
  27704. return this.segments.shift();
  27705. }
  27706. return '';
  27707. }
  27708. }
  27709. const readProp = (el, prop) => {
  27710. if (prop in el) {
  27711. return el[prop];
  27712. }
  27713. if (el.hasAttribute(prop)) {
  27714. return el.getAttribute(prop);
  27715. }
  27716. return null;
  27717. };
  27718. /**
  27719. * Extracts the redirects (that is <ion-route-redirect> elements inside the root).
  27720. *
  27721. * The redirects are returned as a list of RouteRedirect.
  27722. */
  27723. const readRedirects = (root) => {
  27724. return Array.from(root.children)
  27725. .filter((el) => el.tagName === 'ION-ROUTE-REDIRECT')
  27726. .map((el) => {
  27727. const to = readProp(el, 'to');
  27728. return {
  27729. from: parsePath(readProp(el, 'from')).segments,
  27730. to: to == null ? undefined : parsePath(to),
  27731. };
  27732. });
  27733. };
  27734. /**
  27735. * Extracts all the routes (that is <ion-route> elements inside the root).
  27736. *
  27737. * The routes are returned as a list of chains - the flattened tree.
  27738. */
  27739. const readRoutes = (root) => {
  27740. return flattenRouterTree(readRouteNodes(root));
  27741. };
  27742. /**
  27743. * Reads the route nodes as a tree modeled after the DOM tree of <ion-route> elements.
  27744. *
  27745. * Note: routes without a component are ignored together with their children.
  27746. */
  27747. const readRouteNodes = (node) => {
  27748. return Array.from(node.children)
  27749. .filter((el) => el.tagName === 'ION-ROUTE' && el.component)
  27750. .map((el) => {
  27751. const component = readProp(el, 'component');
  27752. return {
  27753. segments: parsePath(readProp(el, 'url')).segments,
  27754. id: component.toLowerCase(),
  27755. params: el.componentProps,
  27756. beforeLeave: el.beforeLeave,
  27757. beforeEnter: el.beforeEnter,
  27758. children: readRouteNodes(el),
  27759. };
  27760. });
  27761. };
  27762. /**
  27763. * Flattens a RouterTree in a list of chains.
  27764. *
  27765. * Each chain represents a path from the root node to a terminal node.
  27766. */
  27767. const flattenRouterTree = (nodes) => {
  27768. const chains = [];
  27769. for (const node of nodes) {
  27770. flattenNode([], chains, node);
  27771. }
  27772. return chains;
  27773. };
  27774. /** Flattens a route node recursively and push each branch to the chains list. */
  27775. const flattenNode = (chain, chains, node) => {
  27776. chain = [
  27777. ...chain,
  27778. {
  27779. id: node.id,
  27780. segments: node.segments,
  27781. params: node.params,
  27782. beforeLeave: node.beforeLeave,
  27783. beforeEnter: node.beforeEnter,
  27784. },
  27785. ];
  27786. if (node.children.length === 0) {
  27787. chains.push(chain);
  27788. return;
  27789. }
  27790. for (const child of node.children) {
  27791. flattenNode(chain, chains, child);
  27792. }
  27793. };
  27794. class Router {
  27795. constructor(hostRef) {
  27796. registerInstance(this, hostRef);
  27797. this.ionRouteWillChange = createEvent(this, "ionRouteWillChange", 7);
  27798. this.ionRouteDidChange = createEvent(this, "ionRouteDidChange", 7);
  27799. this.previousPath = null;
  27800. this.busy = false;
  27801. this.state = 0;
  27802. this.lastState = 0;
  27803. this.root = '/';
  27804. this.useHash = true;
  27805. }
  27806. async componentWillLoad() {
  27807. await waitUntilNavNode();
  27808. const canProceed = await this.runGuards(this.getSegments());
  27809. if (canProceed !== true) {
  27810. if (typeof canProceed === 'object') {
  27811. const { redirect } = canProceed;
  27812. const path = parsePath(redirect);
  27813. this.setSegments(path.segments, ROUTER_INTENT_NONE, path.queryString);
  27814. await this.writeNavStateRoot(path.segments, ROUTER_INTENT_NONE);
  27815. }
  27816. }
  27817. else {
  27818. await this.onRoutesChanged();
  27819. }
  27820. }
  27821. componentDidLoad() {
  27822. window.addEventListener('ionRouteRedirectChanged', debounce(this.onRedirectChanged.bind(this), 10));
  27823. window.addEventListener('ionRouteDataChanged', debounce(this.onRoutesChanged.bind(this), 100));
  27824. }
  27825. async onPopState() {
  27826. const direction = this.historyDirection();
  27827. let segments = this.getSegments();
  27828. const canProceed = await this.runGuards(segments);
  27829. if (canProceed !== true) {
  27830. if (typeof canProceed === 'object') {
  27831. segments = parsePath(canProceed.redirect).segments;
  27832. }
  27833. else {
  27834. return false;
  27835. }
  27836. }
  27837. return this.writeNavStateRoot(segments, direction);
  27838. }
  27839. onBackButton(ev) {
  27840. ev.detail.register(0, (processNextHandler) => {
  27841. this.back();
  27842. processNextHandler();
  27843. });
  27844. }
  27845. /** @internal */
  27846. async canTransition() {
  27847. const canProceed = await this.runGuards();
  27848. if (canProceed !== true) {
  27849. if (typeof canProceed === 'object') {
  27850. return canProceed.redirect;
  27851. }
  27852. else {
  27853. return false;
  27854. }
  27855. }
  27856. return true;
  27857. }
  27858. /**
  27859. * Navigate to the specified path.
  27860. *
  27861. * @param path The path to navigate to.
  27862. * @param direction The direction of the animation. Defaults to `"forward"`.
  27863. */
  27864. async push(path, direction = 'forward', animation) {
  27865. var _a;
  27866. if (path.startsWith('.')) {
  27867. const currentPath = (_a = this.previousPath) !== null && _a !== void 0 ? _a : '/';
  27868. // Convert currentPath to an URL by pre-pending a protocol and a host to resolve the relative path.
  27869. const url = new URL(path, `https://host/${currentPath}`);
  27870. path = url.pathname + url.search;
  27871. }
  27872. let parsedPath = parsePath(path);
  27873. const canProceed = await this.runGuards(parsedPath.segments);
  27874. if (canProceed !== true) {
  27875. if (typeof canProceed === 'object') {
  27876. parsedPath = parsePath(canProceed.redirect);
  27877. }
  27878. else {
  27879. return false;
  27880. }
  27881. }
  27882. this.setSegments(parsedPath.segments, direction, parsedPath.queryString);
  27883. return this.writeNavStateRoot(parsedPath.segments, direction, animation);
  27884. }
  27885. /** Go back to previous page in the window.history. */
  27886. back() {
  27887. window.history.back();
  27888. return Promise.resolve(this.waitPromise);
  27889. }
  27890. /** @internal */
  27891. async printDebug() {
  27892. printRoutes(readRoutes(this.el));
  27893. printRedirects(readRedirects(this.el));
  27894. }
  27895. /** @internal */
  27896. async navChanged(direction) {
  27897. if (this.busy) {
  27898. printIonWarning('[ion-router] - Router is busy, navChanged was cancelled.');
  27899. return false;
  27900. }
  27901. const { ids, outlet } = await readNavState(window.document.body);
  27902. const routes = readRoutes(this.el);
  27903. const chain = findChainForIDs(ids, routes);
  27904. if (!chain) {
  27905. printIonWarning('[ion-router] - No matching URL for', ids.map((i) => i.id));
  27906. return false;
  27907. }
  27908. const segments = chainToSegments(chain);
  27909. if (!segments) {
  27910. printIonWarning('[ion-router] - Router could not match path because some required param is missing.');
  27911. return false;
  27912. }
  27913. this.setSegments(segments, direction);
  27914. await this.safeWriteNavState(outlet, chain, ROUTER_INTENT_NONE, segments, null, ids.length);
  27915. return true;
  27916. }
  27917. /** 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. */
  27918. onRedirectChanged() {
  27919. const segments = this.getSegments();
  27920. if (segments && findRouteRedirect(segments, readRedirects(this.el))) {
  27921. this.writeNavStateRoot(segments, ROUTER_INTENT_NONE);
  27922. }
  27923. }
  27924. /** 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. */
  27925. onRoutesChanged() {
  27926. return this.writeNavStateRoot(this.getSegments(), ROUTER_INTENT_NONE);
  27927. }
  27928. historyDirection() {
  27929. var _a;
  27930. const win = window;
  27931. if (win.history.state === null) {
  27932. this.state++;
  27933. win.history.replaceState(this.state, win.document.title, (_a = win.document.location) === null || _a === void 0 ? void 0 : _a.href);
  27934. }
  27935. const state = win.history.state;
  27936. const lastState = this.lastState;
  27937. this.lastState = state;
  27938. if (state > lastState || (state >= lastState && lastState > 0)) {
  27939. return ROUTER_INTENT_FORWARD;
  27940. }
  27941. if (state < lastState) {
  27942. return ROUTER_INTENT_BACK;
  27943. }
  27944. return ROUTER_INTENT_NONE;
  27945. }
  27946. async writeNavStateRoot(segments, direction, animation) {
  27947. if (!segments) {
  27948. printIonError('[ion-router] - URL is not part of the routing set.');
  27949. return false;
  27950. }
  27951. // lookup redirect rule
  27952. const redirects = readRedirects(this.el);
  27953. const redirect = findRouteRedirect(segments, redirects);
  27954. let redirectFrom = null;
  27955. if (redirect) {
  27956. const { segments: toSegments, queryString } = redirect.to;
  27957. this.setSegments(toSegments, direction, queryString);
  27958. redirectFrom = redirect.from;
  27959. segments = toSegments;
  27960. }
  27961. // lookup route chain
  27962. const routes = readRoutes(this.el);
  27963. const chain = findChainForSegments(segments, routes);
  27964. if (!chain) {
  27965. printIonError('[ion-router] - The path does not match any route.');
  27966. return false;
  27967. }
  27968. // write DOM give
  27969. return this.safeWriteNavState(document.body, chain, direction, segments, redirectFrom, 0, animation);
  27970. }
  27971. async safeWriteNavState(node, chain, direction, segments, redirectFrom, index = 0, animation) {
  27972. const unlock = await this.lock();
  27973. let changed = false;
  27974. try {
  27975. changed = await this.writeNavState(node, chain, direction, segments, redirectFrom, index, animation);
  27976. }
  27977. catch (e) {
  27978. printIonError('[ion-router] - Exception in safeWriteNavState:', e);
  27979. }
  27980. unlock();
  27981. return changed;
  27982. }
  27983. async lock() {
  27984. const p = this.waitPromise;
  27985. let resolve;
  27986. this.waitPromise = new Promise((r) => (resolve = r));
  27987. if (p !== undefined) {
  27988. await p;
  27989. }
  27990. return resolve;
  27991. }
  27992. /**
  27993. * Executes the beforeLeave hook of the source route and the beforeEnter hook of the target route if they exist.
  27994. *
  27995. * When the beforeLeave hook does not return true (to allow navigating) then that value is returned early and the beforeEnter is executed.
  27996. * Otherwise the beforeEnterHook hook of the target route is executed.
  27997. */
  27998. async runGuards(to = this.getSegments(), from) {
  27999. if (from === undefined) {
  28000. from = parsePath(this.previousPath).segments;
  28001. }
  28002. if (!to || !from) {
  28003. return true;
  28004. }
  28005. const routes = readRoutes(this.el);
  28006. const fromChain = findChainForSegments(from, routes);
  28007. // eslint-disable-next-line @typescript-eslint/prefer-optional-chain
  28008. const beforeLeaveHook = fromChain && fromChain[fromChain.length - 1].beforeLeave;
  28009. const canLeave = beforeLeaveHook ? await beforeLeaveHook() : true;
  28010. if (canLeave === false || typeof canLeave === 'object') {
  28011. return canLeave;
  28012. }
  28013. const toChain = findChainForSegments(to, routes);
  28014. // eslint-disable-next-line @typescript-eslint/prefer-optional-chain
  28015. const beforeEnterHook = toChain && toChain[toChain.length - 1].beforeEnter;
  28016. return beforeEnterHook ? beforeEnterHook() : true;
  28017. }
  28018. async writeNavState(node, chain, direction, segments, redirectFrom, index = 0, animation) {
  28019. if (this.busy) {
  28020. printIonWarning('[ion-router] - Router is busy, transition was cancelled.');
  28021. return false;
  28022. }
  28023. this.busy = true;
  28024. // generate route event and emit will change
  28025. const routeEvent = this.routeChangeEvent(segments, redirectFrom);
  28026. if (routeEvent) {
  28027. this.ionRouteWillChange.emit(routeEvent);
  28028. }
  28029. const changed = await writeNavState(node, chain, direction, index, false, animation);
  28030. this.busy = false;
  28031. // emit did change
  28032. if (routeEvent) {
  28033. this.ionRouteDidChange.emit(routeEvent);
  28034. }
  28035. return changed;
  28036. }
  28037. setSegments(segments, direction, queryString) {
  28038. this.state++;
  28039. writeSegments(window.history, this.root, this.useHash, segments, direction, this.state, queryString);
  28040. }
  28041. getSegments() {
  28042. return readSegments(window.location, this.root, this.useHash);
  28043. }
  28044. routeChangeEvent(toSegments, redirectFromSegments) {
  28045. const from = this.previousPath;
  28046. const to = generatePath(toSegments);
  28047. this.previousPath = to;
  28048. if (to === from) {
  28049. return null;
  28050. }
  28051. const redirectedFrom = redirectFromSegments ? generatePath(redirectFromSegments) : null;
  28052. return {
  28053. from,
  28054. redirectedFrom,
  28055. to,
  28056. };
  28057. }
  28058. get el() { return getElement(this); }
  28059. static get cmpMeta() { return {
  28060. "$flags$": 0,
  28061. "$tagName$": "ion-router",
  28062. "$members$": {
  28063. "root": [1],
  28064. "useHash": [4, "use-hash"],
  28065. "canTransition": [64],
  28066. "push": [64],
  28067. "back": [64],
  28068. "printDebug": [64],
  28069. "navChanged": [64]
  28070. },
  28071. "$listeners$": [[8, "popstate", "onPopState"], [4, "ionBackButton", "onBackButton"]],
  28072. "$lazyBundleId$": "-",
  28073. "$attrsToReflect$": []
  28074. }; }
  28075. }
  28076. 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}";
  28077. var IonRouterLinkStyle0 = routerLinkCss;
  28078. class RouterLink {
  28079. constructor(hostRef) {
  28080. registerInstance(this, hostRef);
  28081. this.onClick = (ev) => {
  28082. openURL(this.href, ev, this.routerDirection, this.routerAnimation);
  28083. };
  28084. this.color = undefined;
  28085. this.href = undefined;
  28086. this.rel = undefined;
  28087. this.routerDirection = 'forward';
  28088. this.routerAnimation = undefined;
  28089. this.target = undefined;
  28090. }
  28091. render() {
  28092. const mode = getIonMode$1(this);
  28093. const attrs = {
  28094. href: this.href,
  28095. rel: this.rel,
  28096. target: this.target,
  28097. };
  28098. return (hAsync(Host, { key: '11183264fb6ae0db9a7a47c71b6862d60001b834', onClick: this.onClick, class: createColorClasses$1(this.color, {
  28099. [mode]: true,
  28100. 'ion-activatable': true,
  28101. }) }, hAsync("a", Object.assign({ key: '3e0e5242161cb0df593d6d573e51b8ba750065a1' }, attrs), hAsync("slot", { key: '5bd808e98a4627bb1236f0d955f4b32971355417' }))));
  28102. }
  28103. static get style() { return IonRouterLinkStyle0; }
  28104. static get cmpMeta() { return {
  28105. "$flags$": 9,
  28106. "$tagName$": "ion-router-link",
  28107. "$members$": {
  28108. "color": [513],
  28109. "href": [1],
  28110. "rel": [1],
  28111. "routerDirection": [1, "router-direction"],
  28112. "routerAnimation": [16],
  28113. "target": [1]
  28114. },
  28115. "$listeners$": undefined,
  28116. "$lazyBundleId$": "-",
  28117. "$attrsToReflect$": [["color", "color"]]
  28118. }; }
  28119. }
  28120. const routerOutletCss = ":host{left:0;right:0;top:0;bottom:0;position:absolute;contain:layout size style;z-index:0}";
  28121. var IonRouterOutletStyle0 = routerOutletCss;
  28122. class RouterOutlet {
  28123. constructor(hostRef) {
  28124. registerInstance(this, hostRef);
  28125. this.ionNavWillLoad = createEvent(this, "ionNavWillLoad", 7);
  28126. this.ionNavWillChange = createEvent(this, "ionNavWillChange", 3);
  28127. this.ionNavDidChange = createEvent(this, "ionNavDidChange", 3);
  28128. this.lockController = createLockController();
  28129. this.gestureOrAnimationInProgress = false;
  28130. this.mode = getIonMode$1(this);
  28131. this.delegate = undefined;
  28132. this.animated = true;
  28133. this.animation = undefined;
  28134. this.swipeHandler = undefined;
  28135. }
  28136. swipeHandlerChanged() {
  28137. if (this.gesture) {
  28138. this.gesture.enable(this.swipeHandler !== undefined);
  28139. }
  28140. }
  28141. async connectedCallback() {
  28142. const onStart = () => {
  28143. this.gestureOrAnimationInProgress = true;
  28144. if (this.swipeHandler) {
  28145. this.swipeHandler.onStart();
  28146. }
  28147. };
  28148. 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) => {
  28149. if (this.ani) {
  28150. this.ani.onFinish(() => {
  28151. this.gestureOrAnimationInProgress = false;
  28152. if (this.swipeHandler) {
  28153. this.swipeHandler.onEnd(shouldComplete);
  28154. }
  28155. }, { oneTimeCallback: true });
  28156. // Account for rounding errors in JS
  28157. let newStepValue = shouldComplete ? -0.001 : 0.001;
  28158. /**
  28159. * Animation will be reversed here, so need to
  28160. * reverse the easing curve as well
  28161. *
  28162. * Additionally, we need to account for the time relative
  28163. * to the new easing curve, as `stepValue` is going to be given
  28164. * in terms of a linear curve.
  28165. */
  28166. if (!shouldComplete) {
  28167. this.ani.easing('cubic-bezier(1, 0, 0.68, 0.28)');
  28168. newStepValue += getTimeGivenProgression([0, 0], [1, 0], [0.68, 0.28], [1, 1], step)[0];
  28169. }
  28170. else {
  28171. newStepValue += getTimeGivenProgression([0, 0], [0.32, 0.72], [0, 1], [1, 1], step)[0];
  28172. }
  28173. this.ani.progressEnd(shouldComplete ? 1 : 0, newStepValue, dur);
  28174. }
  28175. else {
  28176. this.gestureOrAnimationInProgress = false;
  28177. }
  28178. });
  28179. this.swipeHandlerChanged();
  28180. }
  28181. componentWillLoad() {
  28182. this.ionNavWillLoad.emit();
  28183. }
  28184. disconnectedCallback() {
  28185. if (this.gesture) {
  28186. this.gesture.destroy();
  28187. this.gesture = undefined;
  28188. }
  28189. }
  28190. /** @internal */
  28191. async commit(enteringEl, leavingEl, opts) {
  28192. const unlock = await this.lockController.lock();
  28193. let changed = false;
  28194. try {
  28195. changed = await this.transition(enteringEl, leavingEl, opts);
  28196. }
  28197. catch (e) {
  28198. printIonError('[ion-router-outlet] - Exception in commit:', e);
  28199. }
  28200. unlock();
  28201. return changed;
  28202. }
  28203. /** @internal */
  28204. async setRouteId(id, params, direction, animation) {
  28205. const changed = await this.setRoot(id, params, {
  28206. duration: direction === 'root' ? 0 : undefined,
  28207. direction: direction === 'back' ? 'back' : 'forward',
  28208. animationBuilder: animation,
  28209. });
  28210. return {
  28211. changed,
  28212. element: this.activeEl,
  28213. };
  28214. }
  28215. /** @internal */
  28216. async getRouteId() {
  28217. const active = this.activeEl;
  28218. return active
  28219. ? {
  28220. id: active.tagName,
  28221. element: active,
  28222. params: this.activeParams,
  28223. }
  28224. : undefined;
  28225. }
  28226. async setRoot(component, params, opts) {
  28227. if (this.activeComponent === component && shallowEqualStringMap(params, this.activeParams)) {
  28228. return false;
  28229. }
  28230. // attach entering view to DOM
  28231. const leavingEl = this.activeEl;
  28232. const enteringEl = await attachComponent(this.delegate, this.el, component, ['ion-page', 'ion-page-invisible'], params);
  28233. this.activeComponent = component;
  28234. this.activeEl = enteringEl;
  28235. this.activeParams = params;
  28236. // commit animation
  28237. await this.commit(enteringEl, leavingEl, opts);
  28238. await detachComponent(this.delegate, leavingEl);
  28239. return true;
  28240. }
  28241. async transition(enteringEl, leavingEl, opts = {}) {
  28242. if (leavingEl === enteringEl) {
  28243. return false;
  28244. }
  28245. // emit nav will change event
  28246. this.ionNavWillChange.emit();
  28247. const { el, mode } = this;
  28248. const animated = this.animated && config.getBoolean('animated', true);
  28249. const animationBuilder = opts.animationBuilder || this.animation || config.get('navAnimation');
  28250. await transition(Object.assign(Object.assign({ mode,
  28251. animated,
  28252. enteringEl,
  28253. leavingEl, baseEl: el,
  28254. /**
  28255. * We need to wait for all Stencil components
  28256. * to be ready only when using the lazy
  28257. * loaded bundle.
  28258. */
  28259. deepWait: hasLazyBuild(el), progressCallback: opts.progressAnimation
  28260. ? (ani) => {
  28261. /**
  28262. * Because this progress callback is called asynchronously
  28263. * it is possible for the gesture to start and end before
  28264. * the animation is ever set. In that scenario, we should
  28265. * immediately call progressEnd so that the transition promise
  28266. * resolves and the gesture does not get locked up.
  28267. */
  28268. if (ani !== undefined && !this.gestureOrAnimationInProgress) {
  28269. this.gestureOrAnimationInProgress = true;
  28270. ani.onFinish(() => {
  28271. this.gestureOrAnimationInProgress = false;
  28272. if (this.swipeHandler) {
  28273. this.swipeHandler.onEnd(false);
  28274. }
  28275. }, { oneTimeCallback: true });
  28276. /**
  28277. * Playing animation to beginning
  28278. * with a duration of 0 prevents
  28279. * any flickering when the animation
  28280. * is later cleaned up.
  28281. */
  28282. ani.progressEnd(0, 0, 0);
  28283. }
  28284. else {
  28285. this.ani = ani;
  28286. }
  28287. }
  28288. : undefined }, opts), { animationBuilder }));
  28289. // emit nav changed event
  28290. this.ionNavDidChange.emit();
  28291. return true;
  28292. }
  28293. render() {
  28294. return hAsync("slot", { key: 'e34e02b5154172c8d5cdd187b6ea58119b6946eb' });
  28295. }
  28296. get el() { return getElement(this); }
  28297. static get watchers() { return {
  28298. "swipeHandler": ["swipeHandlerChanged"]
  28299. }; }
  28300. static get style() { return IonRouterOutletStyle0; }
  28301. static get cmpMeta() { return {
  28302. "$flags$": 9,
  28303. "$tagName$": "ion-router-outlet",
  28304. "$members$": {
  28305. "mode": [1025],
  28306. "delegate": [16],
  28307. "animated": [4],
  28308. "animation": [16],
  28309. "swipeHandler": [16],
  28310. "commit": [64],
  28311. "setRouteId": [64],
  28312. "getRouteId": [64]
  28313. },
  28314. "$listeners$": undefined,
  28315. "$lazyBundleId$": "-",
  28316. "$attrsToReflect$": []
  28317. }; }
  28318. }
  28319. const rowCss = ":host{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap}";
  28320. var IonRowStyle0 = rowCss;
  28321. class Row {
  28322. constructor(hostRef) {
  28323. registerInstance(this, hostRef);
  28324. }
  28325. render() {
  28326. return (hAsync(Host, { key: 'a690022e2abdce6946d24264574e4aa0886a8ea5', class: getIonMode$1(this) }, hAsync("slot", { key: 'd1a0e831dd1dbfe7877d3ad01d0a3045a5fb29e3' })));
  28327. }
  28328. static get style() { return IonRowStyle0; }
  28329. static get cmpMeta() { return {
  28330. "$flags$": 9,
  28331. "$tagName$": "ion-row",
  28332. "$members$": undefined,
  28333. "$listeners$": undefined,
  28334. "$lazyBundleId$": "-",
  28335. "$attrsToReflect$": []
  28336. }; }
  28337. }
  28338. 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}";
  28339. var IonSearchbarIosStyle0 = searchbarIosCss;
  28340. 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}";
  28341. var IonSearchbarMdStyle0 = searchbarMdCss;
  28342. /**
  28343. * @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
  28344. */
  28345. class Searchbar {
  28346. constructor(hostRef) {
  28347. registerInstance(this, hostRef);
  28348. this.ionInput = createEvent(this, "ionInput", 7);
  28349. this.ionChange = createEvent(this, "ionChange", 7);
  28350. this.ionCancel = createEvent(this, "ionCancel", 7);
  28351. this.ionClear = createEvent(this, "ionClear", 7);
  28352. this.ionBlur = createEvent(this, "ionBlur", 7);
  28353. this.ionFocus = createEvent(this, "ionFocus", 7);
  28354. this.ionStyle = createEvent(this, "ionStyle", 7);
  28355. this.isCancelVisible = false;
  28356. this.shouldAlignLeft = true;
  28357. this.inputId = `ion-searchbar-${searchbarIds++}`;
  28358. this.inheritedAttributes = {};
  28359. /**
  28360. * Clears the input field and triggers the control change.
  28361. */
  28362. this.onClearInput = async (shouldFocus) => {
  28363. this.ionClear.emit();
  28364. return new Promise((resolve) => {
  28365. // setTimeout() fixes https://github.com/ionic-team/ionic-framework/issues/7527
  28366. // wait for 4 frames
  28367. setTimeout(() => {
  28368. const value = this.getValue();
  28369. if (value !== '') {
  28370. this.value = '';
  28371. this.emitInputChange();
  28372. /**
  28373. * When tapping clear button
  28374. * ensure input is focused after
  28375. * clearing input so users
  28376. * can quickly start typing.
  28377. */
  28378. if (shouldFocus && !this.focused) {
  28379. this.setFocus();
  28380. /**
  28381. * The setFocus call above will clear focusedValue,
  28382. * but ionChange will never have gotten a chance to
  28383. * fire. Manually revert focusedValue so onBlur can
  28384. * compare against what was in the box before the clear.
  28385. */
  28386. this.focusedValue = value;
  28387. }
  28388. }
  28389. resolve();
  28390. }, 16 * 4);
  28391. });
  28392. };
  28393. /**
  28394. * Clears the input field and tells the input to blur since
  28395. * the clearInput function doesn't want the input to blur
  28396. * then calls the custom cancel function if the user passed one in.
  28397. */
  28398. this.onCancelSearchbar = async (ev) => {
  28399. if (ev) {
  28400. ev.preventDefault();
  28401. ev.stopPropagation();
  28402. }
  28403. this.ionCancel.emit();
  28404. // get cached values before clearing the input
  28405. const value = this.getValue();
  28406. const focused = this.focused;
  28407. await this.onClearInput();
  28408. /**
  28409. * If there used to be something in the box, and we weren't focused
  28410. * beforehand (meaning no blur fired that would already handle this),
  28411. * manually fire ionChange.
  28412. */
  28413. if (value && !focused) {
  28414. this.emitValueChange(ev);
  28415. }
  28416. if (this.nativeInput) {
  28417. this.nativeInput.blur();
  28418. }
  28419. };
  28420. /**
  28421. * Update the Searchbar input value when the input changes
  28422. */
  28423. this.onInput = (ev) => {
  28424. const input = ev.target;
  28425. if (input) {
  28426. this.value = input.value;
  28427. }
  28428. this.emitInputChange(ev);
  28429. };
  28430. this.onChange = (ev) => {
  28431. this.emitValueChange(ev);
  28432. };
  28433. /**
  28434. * Sets the Searchbar to not focused and checks if it should align left
  28435. * based on whether there is a value in the searchbar or not.
  28436. */
  28437. this.onBlur = (ev) => {
  28438. this.focused = false;
  28439. this.ionBlur.emit();
  28440. this.positionElements();
  28441. if (this.focusedValue !== this.value) {
  28442. this.emitValueChange(ev);
  28443. }
  28444. this.focusedValue = undefined;
  28445. };
  28446. /**
  28447. * Sets the Searchbar to focused and active on input focus.
  28448. */
  28449. this.onFocus = () => {
  28450. this.focused = true;
  28451. this.focusedValue = this.value;
  28452. this.ionFocus.emit();
  28453. this.positionElements();
  28454. };
  28455. this.focused = false;
  28456. this.noAnimate = true;
  28457. this.color = undefined;
  28458. this.animated = false;
  28459. this.autocapitalize = 'off';
  28460. this.autocomplete = 'off';
  28461. this.autocorrect = 'off';
  28462. this.cancelButtonIcon = config.get('backButtonIcon', arrowBackSharp);
  28463. this.cancelButtonText = 'Cancel';
  28464. this.clearIcon = undefined;
  28465. this.debounce = undefined;
  28466. this.disabled = false;
  28467. this.inputmode = undefined;
  28468. this.enterkeyhint = undefined;
  28469. this.maxlength = undefined;
  28470. this.minlength = undefined;
  28471. this.name = this.inputId;
  28472. this.placeholder = 'Search';
  28473. this.searchIcon = undefined;
  28474. this.showCancelButton = 'never';
  28475. this.showClearButton = 'always';
  28476. this.spellcheck = false;
  28477. this.type = 'search';
  28478. this.value = '';
  28479. }
  28480. /**
  28481. * lang and dir are globally enumerated attributes.
  28482. * As a result, creating these as properties
  28483. * can have unintended side effects. Instead, we
  28484. * listen for attribute changes and inherit them
  28485. * to the inner `<input>` element.
  28486. */
  28487. onLangChanged(newValue) {
  28488. this.inheritedAttributes = Object.assign(Object.assign({}, this.inheritedAttributes), { lang: newValue });
  28489. }
  28490. onDirChanged(newValue) {
  28491. this.inheritedAttributes = Object.assign(Object.assign({}, this.inheritedAttributes), { dir: newValue });
  28492. }
  28493. debounceChanged() {
  28494. const { ionInput, debounce, originalIonInput } = this;
  28495. /**
  28496. * If debounce is undefined, we have to manually revert the ionInput emitter in case
  28497. * debounce used to be set to a number. Otherwise, the event would stay debounced.
  28498. */
  28499. this.ionInput = debounce === undefined ? originalIonInput !== null && originalIonInput !== void 0 ? originalIonInput : ionInput : debounceEvent(ionInput, debounce);
  28500. }
  28501. valueChanged() {
  28502. const inputEl = this.nativeInput;
  28503. const value = this.getValue();
  28504. if (inputEl && inputEl.value !== value) {
  28505. inputEl.value = value;
  28506. }
  28507. }
  28508. showCancelButtonChanged() {
  28509. requestAnimationFrame(() => {
  28510. this.positionElements();
  28511. });
  28512. }
  28513. connectedCallback() {
  28514. this.emitStyle();
  28515. }
  28516. componentWillLoad() {
  28517. this.inheritedAttributes = Object.assign({}, inheritAttributes$1(this.el, ['lang', 'dir']));
  28518. }
  28519. componentDidLoad() {
  28520. this.originalIonInput = this.ionInput;
  28521. this.positionElements();
  28522. this.debounceChanged();
  28523. setTimeout(() => {
  28524. this.noAnimate = false;
  28525. }, 300);
  28526. }
  28527. emitStyle() {
  28528. this.ionStyle.emit({
  28529. searchbar: true,
  28530. });
  28531. }
  28532. /**
  28533. * Sets focus on the native `input` in `ion-searchbar`. Use this method instead of the global
  28534. * `input.focus()`.
  28535. *
  28536. * Developers who wish to focus an input when a page enters
  28537. * should call `setFocus()` in the `ionViewDidEnter()` lifecycle method.
  28538. *
  28539. * Developers who wish to focus an input when an overlay is presented
  28540. * should call `setFocus` after `didPresent` has resolved.
  28541. *
  28542. * See [managing focus](/docs/developing/managing-focus) for more information.
  28543. */
  28544. async setFocus() {
  28545. if (this.nativeInput) {
  28546. this.nativeInput.focus();
  28547. }
  28548. }
  28549. /**
  28550. * Returns the native `<input>` element used under the hood.
  28551. */
  28552. async getInputElement() {
  28553. /**
  28554. * If this gets called in certain early lifecycle hooks (ex: Vue onMounted),
  28555. * nativeInput won't be defined yet with the custom elements build, so wait for it to load in.
  28556. */
  28557. if (!this.nativeInput) {
  28558. await new Promise((resolve) => componentOnReady(this.el, resolve));
  28559. }
  28560. return Promise.resolve(this.nativeInput);
  28561. }
  28562. /**
  28563. * Emits an `ionChange` event.
  28564. *
  28565. * This API should be called for user committed changes.
  28566. * This API should not be used for external value changes.
  28567. */
  28568. emitValueChange(event) {
  28569. const { value } = this;
  28570. // Checks for both null and undefined values
  28571. const newValue = value == null ? value : value.toString();
  28572. // Emitting a value change should update the internal state for tracking the focused value
  28573. this.focusedValue = newValue;
  28574. this.ionChange.emit({ value: newValue, event });
  28575. }
  28576. /**
  28577. * Emits an `ionInput` event.
  28578. */
  28579. emitInputChange(event) {
  28580. const { value } = this;
  28581. this.ionInput.emit({ value, event });
  28582. }
  28583. /**
  28584. * Positions the input search icon, placeholder, and the cancel button
  28585. * based on the input value and if it is focused. (ios only)
  28586. */
  28587. positionElements() {
  28588. const value = this.getValue();
  28589. const prevAlignLeft = this.shouldAlignLeft;
  28590. const mode = getIonMode$1(this);
  28591. const shouldAlignLeft = !this.animated || value.trim() !== '' || !!this.focused;
  28592. this.shouldAlignLeft = shouldAlignLeft;
  28593. if (mode !== 'ios') {
  28594. return;
  28595. }
  28596. if (prevAlignLeft !== shouldAlignLeft) {
  28597. this.positionPlaceholder();
  28598. }
  28599. if (this.animated) {
  28600. this.positionCancelButton();
  28601. }
  28602. }
  28603. /**
  28604. * Positions the input placeholder
  28605. */
  28606. positionPlaceholder() {
  28607. const inputEl = this.nativeInput;
  28608. if (!inputEl) {
  28609. return;
  28610. }
  28611. const rtl = isRTL$1(this.el);
  28612. const iconEl = (this.el.shadowRoot || this.el).querySelector('.searchbar-search-icon');
  28613. if (this.shouldAlignLeft) {
  28614. inputEl.removeAttribute('style');
  28615. iconEl.removeAttribute('style');
  28616. }
  28617. else {
  28618. // Create a dummy span to get the placeholder width
  28619. const doc = document;
  28620. const tempSpan = doc.createElement('span');
  28621. tempSpan.innerText = this.placeholder || '';
  28622. doc.body.appendChild(tempSpan);
  28623. // Get the width of the span then remove it
  28624. raf(() => {
  28625. const textWidth = tempSpan.offsetWidth;
  28626. tempSpan.remove();
  28627. // Calculate the input padding
  28628. const inputLeft = 'calc(50% - ' + textWidth / 2 + 'px)';
  28629. // Calculate the icon margin
  28630. /**
  28631. * We take the icon width to account
  28632. * for any text scales applied to the icon
  28633. * such as Dynamic Type on iOS as well as 8px
  28634. * of padding.
  28635. */
  28636. const iconLeft = 'calc(50% - ' + (textWidth / 2 + iconEl.clientWidth + 8) + 'px)';
  28637. // Set the input padding start and icon margin start
  28638. if (rtl) {
  28639. inputEl.style.paddingRight = inputLeft;
  28640. iconEl.style.marginRight = iconLeft;
  28641. }
  28642. else {
  28643. inputEl.style.paddingLeft = inputLeft;
  28644. iconEl.style.marginLeft = iconLeft;
  28645. }
  28646. });
  28647. }
  28648. }
  28649. /**
  28650. * Show the iOS Cancel button on focus, hide it offscreen otherwise
  28651. */
  28652. positionCancelButton() {
  28653. const rtl = isRTL$1(this.el);
  28654. const cancelButton = (this.el.shadowRoot || this.el).querySelector('.searchbar-cancel-button');
  28655. const shouldShowCancel = this.shouldShowCancelButton();
  28656. if (cancelButton !== null && shouldShowCancel !== this.isCancelVisible) {
  28657. const cancelStyle = cancelButton.style;
  28658. this.isCancelVisible = shouldShowCancel;
  28659. if (shouldShowCancel) {
  28660. if (rtl) {
  28661. cancelStyle.marginLeft = '0';
  28662. }
  28663. else {
  28664. cancelStyle.marginRight = '0';
  28665. }
  28666. }
  28667. else {
  28668. const offset = cancelButton.offsetWidth;
  28669. if (offset > 0) {
  28670. if (rtl) {
  28671. cancelStyle.marginLeft = -offset + 'px';
  28672. }
  28673. else {
  28674. cancelStyle.marginRight = -offset + 'px';
  28675. }
  28676. }
  28677. }
  28678. }
  28679. }
  28680. getValue() {
  28681. return this.value || '';
  28682. }
  28683. hasValue() {
  28684. return this.getValue() !== '';
  28685. }
  28686. /**
  28687. * Determines whether or not the cancel button should be visible onscreen.
  28688. * Cancel button should be shown if one of two conditions applies:
  28689. * 1. `showCancelButton` is set to `always`.
  28690. * 2. `showCancelButton` is set to `focus`, and the searchbar has been focused.
  28691. */
  28692. shouldShowCancelButton() {
  28693. if (this.showCancelButton === 'never' || (this.showCancelButton === 'focus' && !this.focused)) {
  28694. return false;
  28695. }
  28696. return true;
  28697. }
  28698. /**
  28699. * Determines whether or not the clear button should be visible onscreen.
  28700. * Clear button should be shown if one of two conditions applies:
  28701. * 1. `showClearButton` is set to `always`.
  28702. * 2. `showClearButton` is set to `focus`, and the searchbar has been focused.
  28703. */
  28704. shouldShowClearButton() {
  28705. if (this.showClearButton === 'never' || (this.showClearButton === 'focus' && !this.focused)) {
  28706. return false;
  28707. }
  28708. return true;
  28709. }
  28710. render() {
  28711. const { cancelButtonText, autocapitalize } = this;
  28712. const animated = this.animated && config.getBoolean('animated', true);
  28713. const mode = getIonMode$1(this);
  28714. const clearIcon = this.clearIcon || (mode === 'ios' ? closeCircle : closeSharp);
  28715. const searchIcon = this.searchIcon || (mode === 'ios' ? searchOutline : searchSharp);
  28716. const shouldShowCancelButton = this.shouldShowCancelButton();
  28717. 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))));
  28718. return (hAsync(Host, { key: 'd1a1972725e949fb102c91487aaa7b9d10c2d718', role: "search", "aria-disabled": this.disabled ? 'true' : null, class: createColorClasses$1(this.color, {
  28719. [mode]: true,
  28720. 'searchbar-animated': animated,
  28721. 'searchbar-disabled': this.disabled,
  28722. 'searchbar-no-animate': animated && this.noAnimate,
  28723. 'searchbar-has-value': this.hasValue(),
  28724. 'searchbar-left-aligned': this.shouldAlignLeft,
  28725. 'searchbar-has-focus': this.focused,
  28726. 'searchbar-should-show-clear': this.shouldShowClearButton(),
  28727. 'searchbar-should-show-cancel': this.shouldShowCancelButton(),
  28728. }) }, 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) => {
  28729. /**
  28730. * This prevents mobile browsers from
  28731. * blurring the input when the clear
  28732. * button is activated.
  28733. */
  28734. ev.preventDefault();
  28735. }, 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));
  28736. }
  28737. get el() { return getElement(this); }
  28738. static get watchers() { return {
  28739. "lang": ["onLangChanged"],
  28740. "dir": ["onDirChanged"],
  28741. "debounce": ["debounceChanged"],
  28742. "value": ["valueChanged"],
  28743. "showCancelButton": ["showCancelButtonChanged"]
  28744. }; }
  28745. static get style() { return {
  28746. ios: IonSearchbarIosStyle0,
  28747. md: IonSearchbarMdStyle0
  28748. }; }
  28749. static get cmpMeta() { return {
  28750. "$flags$": 34,
  28751. "$tagName$": "ion-searchbar",
  28752. "$members$": {
  28753. "color": [513],
  28754. "animated": [4],
  28755. "autocapitalize": [1],
  28756. "autocomplete": [1],
  28757. "autocorrect": [1],
  28758. "cancelButtonIcon": [1, "cancel-button-icon"],
  28759. "cancelButtonText": [1, "cancel-button-text"],
  28760. "clearIcon": [1, "clear-icon"],
  28761. "debounce": [2],
  28762. "disabled": [4],
  28763. "inputmode": [1],
  28764. "enterkeyhint": [1],
  28765. "maxlength": [2],
  28766. "minlength": [2],
  28767. "name": [1],
  28768. "placeholder": [1],
  28769. "searchIcon": [1, "search-icon"],
  28770. "showCancelButton": [1, "show-cancel-button"],
  28771. "showClearButton": [1, "show-clear-button"],
  28772. "spellcheck": [4],
  28773. "type": [1],
  28774. "value": [1025],
  28775. "focused": [32],
  28776. "noAnimate": [32],
  28777. "setFocus": [64],
  28778. "getInputElement": [64]
  28779. },
  28780. "$listeners$": undefined,
  28781. "$lazyBundleId$": "-",
  28782. "$attrsToReflect$": [["color", "color"]]
  28783. }; }
  28784. }
  28785. let searchbarIds = 0;
  28786. 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)}";
  28787. var IonSegmentIosStyle0 = segmentIosCss;
  28788. 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}";
  28789. var IonSegmentMdStyle0 = segmentMdCss;
  28790. /**
  28791. * @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
  28792. */
  28793. class Segment {
  28794. constructor(hostRef) {
  28795. registerInstance(this, hostRef);
  28796. this.ionChange = createEvent(this, "ionChange", 7);
  28797. this.ionSelect = createEvent(this, "ionSelect", 7);
  28798. this.ionStyle = createEvent(this, "ionStyle", 7);
  28799. this.segmentViewEl = null;
  28800. this.onClick = (ev) => {
  28801. const current = ev.target;
  28802. const previous = this.checked;
  28803. // If the current element is a segment then that means
  28804. // the user tried to swipe to a segment button and
  28805. // click a segment button at the same time so we should
  28806. // not update the checked segment button
  28807. if (current.tagName === 'ION-SEGMENT') {
  28808. return;
  28809. }
  28810. this.value = current.value;
  28811. if (current !== previous) {
  28812. this.emitValueChange();
  28813. }
  28814. if (this.segmentViewEl) {
  28815. this.updateSegmentView();
  28816. if (this.scrollable && previous) {
  28817. this.checkButton(previous, current);
  28818. }
  28819. }
  28820. else if (this.scrollable || !this.swipeGesture) {
  28821. if (previous) {
  28822. this.checkButton(previous, current);
  28823. }
  28824. else {
  28825. this.setCheckedClasses();
  28826. }
  28827. }
  28828. };
  28829. this.onSlottedItemsChange = () => {
  28830. /**
  28831. * When the slotted segment buttons change we need to
  28832. * ensure that the new segment buttons are checked if
  28833. * the value matches the segment button value.
  28834. */
  28835. this.valueChanged(this.value);
  28836. };
  28837. this.getSegmentButton = (selector) => {
  28838. var _a, _b;
  28839. const buttons = this.getButtons().filter((button) => !button.disabled);
  28840. const currIndex = buttons.findIndex((button) => button === document.activeElement);
  28841. switch (selector) {
  28842. case 'first':
  28843. return buttons[0];
  28844. case 'last':
  28845. return buttons[buttons.length - 1];
  28846. case 'next':
  28847. return (_a = buttons[currIndex + 1]) !== null && _a !== void 0 ? _a : buttons[0];
  28848. case 'previous':
  28849. return (_b = buttons[currIndex - 1]) !== null && _b !== void 0 ? _b : buttons[buttons.length - 1];
  28850. default:
  28851. return null;
  28852. }
  28853. };
  28854. this.activated = false;
  28855. this.color = undefined;
  28856. this.disabled = false;
  28857. this.scrollable = false;
  28858. this.swipeGesture = true;
  28859. this.value = undefined;
  28860. this.selectOnFocus = false;
  28861. }
  28862. colorChanged(value, oldValue) {
  28863. /**
  28864. * If color is set after not having
  28865. * previously been set (or vice versa),
  28866. * we need to emit style so the segment-buttons
  28867. * can apply their color classes properly.
  28868. */
  28869. if ((oldValue === undefined && value !== undefined) || (oldValue !== undefined && value === undefined)) {
  28870. this.emitStyle();
  28871. }
  28872. }
  28873. swipeGestureChanged() {
  28874. this.gestureChanged();
  28875. }
  28876. valueChanged(value, oldValue) {
  28877. // Force a value to exist if we're using a segment view
  28878. if (this.segmentViewEl && value === undefined) {
  28879. this.value = this.getButtons()[0].value;
  28880. return;
  28881. }
  28882. if (oldValue !== undefined && value !== undefined) {
  28883. const buttons = this.getButtons();
  28884. const previous = buttons.find((button) => button.value === oldValue);
  28885. const current = buttons.find((button) => button.value === value);
  28886. if (previous && current) {
  28887. if (!this.segmentViewEl) {
  28888. this.checkButton(previous, current);
  28889. }
  28890. else if (this.triggerScrollOnValueChange !== false) {
  28891. this.updateSegmentView();
  28892. }
  28893. }
  28894. }
  28895. else if (value !== undefined && oldValue === undefined && this.segmentViewEl) {
  28896. this.updateSegmentView();
  28897. }
  28898. /**
  28899. * `ionSelect` is emitted every time the value changes (internal or external changes).
  28900. * Used by `ion-segment-button` to determine if the button should be checked.
  28901. */
  28902. this.ionSelect.emit({ value });
  28903. // The scroll listener should handle scrolling the active button into view as needed
  28904. if (!this.segmentViewEl) {
  28905. this.scrollActiveButtonIntoView();
  28906. }
  28907. this.triggerScrollOnValueChange = undefined;
  28908. }
  28909. disabledChanged() {
  28910. this.gestureChanged();
  28911. if (!this.segmentViewEl) {
  28912. const buttons = this.getButtons();
  28913. for (const button of buttons) {
  28914. button.disabled = this.disabled;
  28915. }
  28916. }
  28917. else {
  28918. this.segmentViewEl.disabled = this.disabled;
  28919. }
  28920. }
  28921. gestureChanged() {
  28922. if (this.gesture) {
  28923. this.gesture.enable(!this.scrollable && !this.disabled && this.swipeGesture);
  28924. }
  28925. }
  28926. connectedCallback() {
  28927. this.emitStyle();
  28928. this.segmentViewEl = this.getSegmentView();
  28929. }
  28930. disconnectedCallback() {
  28931. this.segmentViewEl = null;
  28932. }
  28933. componentWillLoad() {
  28934. this.emitStyle();
  28935. }
  28936. async componentDidLoad() {
  28937. this.segmentViewEl = this.getSegmentView();
  28938. this.setCheckedClasses();
  28939. /**
  28940. * We need to wait for the buttons to all be rendered
  28941. * before we can scroll.
  28942. */
  28943. raf(() => {
  28944. /**
  28945. * When the segment loads for the first
  28946. * time we just want to snap the active button into
  28947. * place instead of scroll. Smooth scrolling should only
  28948. * happen when the user interacts with the segment.
  28949. */
  28950. this.scrollActiveButtonIntoView(false);
  28951. });
  28952. this.gesture = (await Promise.resolve().then(function () { return index; })).createGesture({
  28953. el: this.el,
  28954. gestureName: 'segment',
  28955. gesturePriority: 100,
  28956. threshold: 0,
  28957. passive: false,
  28958. onStart: (ev) => this.onStart(ev),
  28959. onMove: (ev) => this.onMove(ev),
  28960. onEnd: (ev) => this.onEnd(ev),
  28961. });
  28962. this.gestureChanged();
  28963. if (this.disabled) {
  28964. this.disabledChanged();
  28965. }
  28966. // Update segment view based on the initial value,
  28967. // but do not animate the scroll
  28968. this.updateSegmentView(false);
  28969. }
  28970. onStart(detail) {
  28971. this.valueBeforeGesture = this.value;
  28972. this.activate(detail);
  28973. }
  28974. onMove(detail) {
  28975. this.setNextIndex(detail);
  28976. }
  28977. onEnd(detail) {
  28978. this.setActivated(false);
  28979. this.setNextIndex(detail, true);
  28980. detail.event.stopImmediatePropagation();
  28981. const value = this.value;
  28982. if (value !== undefined) {
  28983. if (this.valueBeforeGesture !== value) {
  28984. this.emitValueChange();
  28985. this.updateSegmentView();
  28986. }
  28987. }
  28988. this.valueBeforeGesture = undefined;
  28989. }
  28990. /**
  28991. * Emits an `ionChange` event.
  28992. *
  28993. * This API should be called for user committed changes.
  28994. * This API should not be used for external value changes.
  28995. */
  28996. emitValueChange() {
  28997. const { value } = this;
  28998. this.ionChange.emit({ value });
  28999. }
  29000. getButtons() {
  29001. return Array.from(this.el.querySelectorAll('ion-segment-button'));
  29002. }
  29003. get checked() {
  29004. return this.getButtons().find((button) => button.value === this.value);
  29005. }
  29006. /*
  29007. * Activate both the segment and the buttons
  29008. * due to a bug with ::slotted in Safari
  29009. */
  29010. setActivated(activated) {
  29011. const buttons = this.getButtons();
  29012. buttons.forEach((button) => {
  29013. button.classList.toggle('segment-button-activated', activated);
  29014. });
  29015. this.activated = activated;
  29016. }
  29017. activate(detail) {
  29018. const clicked = detail.event.target;
  29019. const buttons = this.getButtons();
  29020. const checked = buttons.find((button) => button.value === this.value);
  29021. // Make sure we are only checking for activation on a segment button
  29022. // since disabled buttons will get the click on the segment
  29023. if (clicked.tagName !== 'ION-SEGMENT-BUTTON') {
  29024. return;
  29025. }
  29026. // If there are no checked buttons, set the current button to checked
  29027. if (!checked) {
  29028. this.value = clicked.value;
  29029. this.setCheckedClasses();
  29030. }
  29031. // If the gesture began on the clicked button with the indicator
  29032. // then we should activate the indicator
  29033. if (this.value === clicked.value) {
  29034. this.setActivated(true);
  29035. }
  29036. }
  29037. getIndicator(button) {
  29038. const root = button.shadowRoot || button;
  29039. return root.querySelector('.segment-button-indicator');
  29040. }
  29041. checkButton(previous, current) {
  29042. const previousIndicator = this.getIndicator(previous);
  29043. const currentIndicator = this.getIndicator(current);
  29044. if (previousIndicator === null || currentIndicator === null) {
  29045. return;
  29046. }
  29047. const previousClientRect = previousIndicator.getBoundingClientRect();
  29048. const currentClientRect = currentIndicator.getBoundingClientRect();
  29049. const widthDelta = previousClientRect.width / currentClientRect.width;
  29050. const xPosition = previousClientRect.left - currentClientRect.left;
  29051. // Scale the indicator width to match the previous indicator width
  29052. // and translate it on top of the previous indicator
  29053. const transform = `translate3d(${xPosition}px, 0, 0) scaleX(${widthDelta})`;
  29054. writeTask(() => {
  29055. // Remove the transition before positioning on top of the previous indicator
  29056. currentIndicator.classList.remove('segment-button-indicator-animated');
  29057. currentIndicator.style.setProperty('transform', transform);
  29058. // Force a repaint to ensure the transform happens
  29059. currentIndicator.getBoundingClientRect();
  29060. // Add the transition to move the indicator into place
  29061. currentIndicator.classList.add('segment-button-indicator-animated');
  29062. // Remove the transform to slide the indicator back to the button clicked
  29063. currentIndicator.style.setProperty('transform', '');
  29064. this.scrollActiveButtonIntoView(true);
  29065. });
  29066. this.value = current.value;
  29067. this.setCheckedClasses();
  29068. }
  29069. setCheckedClasses() {
  29070. const buttons = this.getButtons();
  29071. const index = buttons.findIndex((button) => button.value === this.value);
  29072. const next = index + 1;
  29073. for (const button of buttons) {
  29074. button.classList.remove('segment-button-after-checked');
  29075. }
  29076. if (next < buttons.length) {
  29077. buttons[next].classList.add('segment-button-after-checked');
  29078. }
  29079. }
  29080. getSegmentView() {
  29081. const buttons = this.getButtons();
  29082. // Get the first button with a contentId
  29083. const firstContentId = buttons.find((button) => button.contentId);
  29084. // Get the segment content with an id matching the button's contentId
  29085. const segmentContent = document.querySelector(`ion-segment-content[id="${firstContentId === null || firstContentId === void 0 ? void 0 : firstContentId.contentId}"]`);
  29086. // Return the segment view for that matching segment content
  29087. return segmentContent === null || segmentContent === void 0 ? void 0 : segmentContent.closest('ion-segment-view');
  29088. }
  29089. handleSegmentViewScroll(ev) {
  29090. const { scrollRatio, isManualScroll } = ev.detail;
  29091. if (!isManualScroll) {
  29092. return;
  29093. }
  29094. const dispatchedFrom = ev.target;
  29095. const segmentViewEl = this.segmentViewEl;
  29096. const segmentEl = this.el;
  29097. // Only update the indicator if the event was dispatched from the correct segment view
  29098. if (ev.composedPath().includes(segmentViewEl) || (dispatchedFrom === null || dispatchedFrom === void 0 ? void 0 : dispatchedFrom.contains(segmentEl))) {
  29099. const buttons = this.getButtons();
  29100. // If no buttons are found or there is no value set then do nothing
  29101. if (!buttons.length)
  29102. return;
  29103. const index = buttons.findIndex((button) => button.value === this.value);
  29104. const current = buttons[index];
  29105. const nextIndex = Math.round(scrollRatio * (buttons.length - 1));
  29106. if (this.lastNextIndex === undefined || this.lastNextIndex !== nextIndex) {
  29107. this.lastNextIndex = nextIndex;
  29108. this.triggerScrollOnValueChange = false;
  29109. this.checkButton(current, buttons[nextIndex]);
  29110. this.emitValueChange();
  29111. }
  29112. }
  29113. }
  29114. /**
  29115. * Finds the related segment view and sets its current content
  29116. * based on the selected segment button. This method
  29117. * should be called on initial load of the segment,
  29118. * after the gesture is completed (if dragging between segments)
  29119. * and when a segment button is clicked directly.
  29120. */
  29121. updateSegmentView(smoothScroll = true) {
  29122. const buttons = this.getButtons();
  29123. const button = buttons.find((btn) => btn.value === this.value);
  29124. // If the button does not have a contentId then there is
  29125. // no associated segment view to update
  29126. if (!(button === null || button === void 0 ? void 0 : button.contentId)) {
  29127. return;
  29128. }
  29129. const segmentView = this.segmentViewEl;
  29130. if (segmentView) {
  29131. segmentView.setContent(button.contentId, smoothScroll);
  29132. }
  29133. }
  29134. scrollActiveButtonIntoView(smoothScroll = true) {
  29135. const { scrollable, value, el } = this;
  29136. if (scrollable) {
  29137. const buttons = this.getButtons();
  29138. const activeButton = buttons.find((button) => button.value === value);
  29139. if (activeButton !== undefined) {
  29140. const scrollContainerBox = el.getBoundingClientRect();
  29141. const activeButtonBox = activeButton.getBoundingClientRect();
  29142. /**
  29143. * Subtract the active button x position from the scroll
  29144. * container x position. This will give us the x position
  29145. * of the active button within the scroll container.
  29146. */
  29147. const activeButtonLeft = activeButtonBox.x - scrollContainerBox.x;
  29148. /**
  29149. * If we just used activeButtonLeft, then the active button
  29150. * would be aligned with the left edge of the scroll container.
  29151. * Instead, we want the segment button to be centered. As a result,
  29152. * we subtract half of the scroll container width. This will position
  29153. * the left edge of the active button at the midpoint of the scroll container.
  29154. * We then add half of the active button width. This will position the active
  29155. * button such that the midpoint of the active button is at the midpoint of the
  29156. * scroll container.
  29157. */
  29158. const centeredX = activeButtonLeft - scrollContainerBox.width / 2 + activeButtonBox.width / 2;
  29159. /**
  29160. * newScrollPosition is the absolute scroll position that the
  29161. * container needs to move to in order to center the active button.
  29162. * It is calculated by adding the current scroll position
  29163. * (scrollLeft) to the offset needed to center the button
  29164. * (centeredX).
  29165. */
  29166. const newScrollPosition = el.scrollLeft + centeredX;
  29167. /**
  29168. * We intentionally use scrollTo here instead of scrollIntoView
  29169. * to avoid a WebKit bug where accelerated animations break
  29170. * when using scrollIntoView. Using scrollIntoView will cause the
  29171. * segment container to jump during the transition and then snap into place.
  29172. * This is because scrollIntoView can potentially cause parent element
  29173. * containers to also scroll. scrollTo does not have this same behavior, so
  29174. * we use this API instead.
  29175. *
  29176. * scrollTo is used instead of scrollBy because there is a
  29177. * Webkit bug that causes scrollBy to not work smoothly when
  29178. * the active button is near the edge of the scroll container.
  29179. * This leads to the buttons to jump around during the transition.
  29180. *
  29181. * Note that if there is not enough scrolling space to center the element
  29182. * within the scroll container, the browser will attempt
  29183. * to center by as much as it can.
  29184. */
  29185. el.scrollTo({
  29186. top: 0,
  29187. left: newScrollPosition,
  29188. behavior: smoothScroll ? 'smooth' : 'instant',
  29189. });
  29190. }
  29191. }
  29192. }
  29193. setNextIndex(detail, isEnd = false) {
  29194. const rtl = isRTL$1(this.el);
  29195. const activated = this.activated;
  29196. const buttons = this.getButtons();
  29197. const index = buttons.findIndex((button) => button.value === this.value);
  29198. const previous = buttons[index];
  29199. let current;
  29200. let nextIndex;
  29201. if (index === -1) {
  29202. return;
  29203. }
  29204. // Get the element that the touch event started on in case
  29205. // it was the checked button, then we will move the indicator
  29206. const rect = previous.getBoundingClientRect();
  29207. const left = rect.left;
  29208. const width = rect.width;
  29209. // Get the element that the gesture is on top of based on the currentX of the
  29210. // gesture event and the Y coordinate of the starting element, since the gesture
  29211. // can move up and down off of the segment
  29212. const currentX = detail.currentX;
  29213. const previousY = rect.top + rect.height / 2;
  29214. /**
  29215. * Segment can be used inside the shadow dom
  29216. * so doing document.elementFromPoint would never
  29217. * return a segment button in that instance.
  29218. * We use getRootNode to which will return the parent
  29219. * shadow root if used inside a shadow component and
  29220. * returns document otherwise.
  29221. */
  29222. const root = this.el.getRootNode();
  29223. const nextEl = root.elementFromPoint(currentX, previousY);
  29224. const decreaseIndex = rtl ? currentX > left + width : currentX < left;
  29225. const increaseIndex = rtl ? currentX < left : currentX > left + width;
  29226. // If the indicator is currently activated then we have started the gesture
  29227. // on top of the checked button so we need to slide the indicator
  29228. // by checking the button next to it as we move
  29229. if (activated && !isEnd) {
  29230. // Decrease index, move left in LTR & right in RTL
  29231. if (decreaseIndex) {
  29232. const newIndex = index - 1;
  29233. if (newIndex >= 0) {
  29234. nextIndex = newIndex;
  29235. }
  29236. // Increase index, moves right in LTR & left in RTL
  29237. }
  29238. else if (increaseIndex) {
  29239. if (activated && !isEnd) {
  29240. const newIndex = index + 1;
  29241. if (newIndex < buttons.length) {
  29242. nextIndex = newIndex;
  29243. }
  29244. }
  29245. }
  29246. if (nextIndex !== undefined && !buttons[nextIndex].disabled) {
  29247. current = buttons[nextIndex];
  29248. }
  29249. }
  29250. // If the indicator is not activated then we will just set the indicator
  29251. // to the element where the gesture ended
  29252. if (!activated && isEnd) {
  29253. current = nextEl;
  29254. }
  29255. if (current != null) {
  29256. /**
  29257. * If current element is ion-segment then that means
  29258. * user tried to select a disabled ion-segment-button,
  29259. * and we should not update the ripple.
  29260. */
  29261. if (current.tagName === 'ION-SEGMENT') {
  29262. return false;
  29263. }
  29264. if (previous !== current) {
  29265. this.checkButton(previous, current);
  29266. }
  29267. }
  29268. return true;
  29269. }
  29270. emitStyle() {
  29271. this.ionStyle.emit({
  29272. segment: true,
  29273. });
  29274. }
  29275. onKeyDown(ev) {
  29276. const rtl = isRTL$1(this.el);
  29277. let keyDownSelectsButton = this.selectOnFocus;
  29278. let current;
  29279. switch (ev.key) {
  29280. case 'ArrowRight':
  29281. ev.preventDefault();
  29282. current = rtl ? this.getSegmentButton('previous') : this.getSegmentButton('next');
  29283. break;
  29284. case 'ArrowLeft':
  29285. ev.preventDefault();
  29286. current = rtl ? this.getSegmentButton('next') : this.getSegmentButton('previous');
  29287. break;
  29288. case 'Home':
  29289. ev.preventDefault();
  29290. current = this.getSegmentButton('first');
  29291. break;
  29292. case 'End':
  29293. ev.preventDefault();
  29294. current = this.getSegmentButton('last');
  29295. break;
  29296. case ' ':
  29297. case 'Enter':
  29298. ev.preventDefault();
  29299. current = document.activeElement;
  29300. keyDownSelectsButton = true;
  29301. }
  29302. if (!current) {
  29303. return;
  29304. }
  29305. if (keyDownSelectsButton) {
  29306. const previous = this.checked;
  29307. this.checkButton(previous || current, current);
  29308. if (current !== previous) {
  29309. this.emitValueChange();
  29310. }
  29311. }
  29312. current.setFocus();
  29313. }
  29314. render() {
  29315. const mode = getIonMode$1(this);
  29316. return (hAsync(Host, { key: 'a64e39352050b516f7dc82ce95a4bcff8431d1d0', role: "tablist", onClick: this.onClick, class: createColorClasses$1(this.color, {
  29317. [mode]: true,
  29318. 'in-toolbar': hostContext('ion-toolbar', this.el),
  29319. 'in-toolbar-color': hostContext('ion-toolbar[color]', this.el),
  29320. 'segment-activated': this.activated,
  29321. 'segment-disabled': this.disabled,
  29322. 'segment-scrollable': this.scrollable,
  29323. }) }, hAsync("slot", { key: 'bb3f3ec30e59e0461fa620d8961ab730cc802a4e', onSlotchange: this.onSlottedItemsChange })));
  29324. }
  29325. get el() { return getElement(this); }
  29326. static get watchers() { return {
  29327. "color": ["colorChanged"],
  29328. "swipeGesture": ["swipeGestureChanged"],
  29329. "value": ["valueChanged"],
  29330. "disabled": ["disabledChanged"]
  29331. }; }
  29332. static get style() { return {
  29333. ios: IonSegmentIosStyle0,
  29334. md: IonSegmentMdStyle0
  29335. }; }
  29336. static get cmpMeta() { return {
  29337. "$flags$": 41,
  29338. "$tagName$": "ion-segment",
  29339. "$members$": {
  29340. "color": [513],
  29341. "disabled": [4],
  29342. "scrollable": [4],
  29343. "swipeGesture": [4, "swipe-gesture"],
  29344. "value": [1032],
  29345. "selectOnFocus": [4, "select-on-focus"],
  29346. "activated": [32]
  29347. },
  29348. "$listeners$": [[16, "ionSegmentViewScroll", "handleSegmentViewScroll"], [0, "keydown", "onKeyDown"]],
  29349. "$lazyBundleId$": "-",
  29350. "$attrsToReflect$": [["color", "color"]]
  29351. }; }
  29352. }
  29353. 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)}}";
  29354. var IonSegmentButtonIosStyle0 = segmentButtonIosCss;
  29355. 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)}";
  29356. var IonSegmentButtonMdStyle0 = segmentButtonMdCss;
  29357. let ids = 0;
  29358. /**
  29359. * @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
  29360. *
  29361. * @part native - The native HTML button element that wraps all child elements.
  29362. * @part indicator - The indicator displayed on the checked segment button.
  29363. * @part indicator-background - The background element for the indicator displayed on the checked segment button.
  29364. */
  29365. class SegmentButton {
  29366. constructor(hostRef) {
  29367. registerInstance(this, hostRef);
  29368. this.segmentEl = null;
  29369. this.inheritedAttributes = {};
  29370. this.updateStyle = () => {
  29371. };
  29372. this.updateState = () => {
  29373. const { segmentEl } = this;
  29374. if (segmentEl) {
  29375. this.checked = segmentEl.value === this.value;
  29376. if (segmentEl.disabled) {
  29377. this.disabled = true;
  29378. }
  29379. }
  29380. };
  29381. this.checked = false;
  29382. this.contentId = undefined;
  29383. this.disabled = false;
  29384. this.layout = 'icon-top';
  29385. this.type = 'button';
  29386. this.value = 'ion-sb-' + ids++;
  29387. }
  29388. valueChanged() {
  29389. this.updateState();
  29390. }
  29391. connectedCallback() {
  29392. const segmentEl = (this.segmentEl = this.el.closest('ion-segment'));
  29393. if (segmentEl) {
  29394. this.updateState();
  29395. addEventListener$1(segmentEl, 'ionSelect', this.updateState);
  29396. addEventListener$1(segmentEl, 'ionStyle', this.updateStyle);
  29397. }
  29398. // Prevent buttons from being disabled when associated with segment content
  29399. if (this.contentId && this.disabled) {
  29400. printIonWarning(`[ion-segment-button] - Segment buttons cannot be disabled when associated with an <ion-segment-content>.`);
  29401. this.disabled = false;
  29402. }
  29403. }
  29404. disconnectedCallback() {
  29405. const segmentEl = this.segmentEl;
  29406. if (segmentEl) {
  29407. removeEventListener(segmentEl, 'ionSelect', this.updateState);
  29408. removeEventListener(segmentEl, 'ionStyle', this.updateStyle);
  29409. this.segmentEl = null;
  29410. }
  29411. }
  29412. componentWillLoad() {
  29413. this.inheritedAttributes = Object.assign({}, inheritAttributes$1(this.el, ['aria-label']));
  29414. // Return if there is no contentId defined
  29415. if (!this.contentId)
  29416. return;
  29417. // Attempt to find the Segment Content by its contentId
  29418. const segmentContent = document.getElementById(this.contentId);
  29419. // If no associated Segment Content exists, log an error and return
  29420. if (!segmentContent) {
  29421. printIonError(`[ion-segment-button] - Unable to find Segment Content with id="${this.contentId}".`);
  29422. return;
  29423. }
  29424. // Ensure the found element is a valid ION-SEGMENT-CONTENT
  29425. if (segmentContent.tagName !== 'ION-SEGMENT-CONTENT') {
  29426. printIonError(`[ion-segment-button] - Element with id="${this.contentId}" is not an <ion-segment-content> element.`);
  29427. return;
  29428. }
  29429. }
  29430. get hasLabel() {
  29431. return !!this.el.querySelector('ion-label');
  29432. }
  29433. get hasIcon() {
  29434. return !!this.el.querySelector('ion-icon');
  29435. }
  29436. /**
  29437. * @internal
  29438. * Focuses the native <button> element
  29439. * inside of ion-segment-button.
  29440. */
  29441. async setFocus() {
  29442. const { nativeEl } = this;
  29443. if (nativeEl !== undefined) {
  29444. nativeEl.focus();
  29445. }
  29446. }
  29447. render() {
  29448. const { checked, type, disabled, hasIcon, hasLabel, layout, segmentEl } = this;
  29449. const mode = getIonMode$1(this);
  29450. const hasSegmentColor = () => (segmentEl === null || segmentEl === void 0 ? void 0 : segmentEl.color) !== undefined;
  29451. return (hAsync(Host, { key: 'd79dad80db69123510c6d52bbf4424558600c14a', class: {
  29452. [mode]: true,
  29453. 'in-toolbar': hostContext('ion-toolbar', this.el),
  29454. 'in-toolbar-color': hostContext('ion-toolbar[color]', this.el),
  29455. 'in-segment': hostContext('ion-segment', this.el),
  29456. 'in-segment-color': hasSegmentColor(),
  29457. 'segment-button-has-label': hasLabel,
  29458. 'segment-button-has-icon': hasIcon,
  29459. 'segment-button-has-label-only': hasLabel && !hasIcon,
  29460. 'segment-button-has-icon-only': hasIcon && !hasLabel,
  29461. 'segment-button-disabled': disabled,
  29462. 'segment-button-checked': checked,
  29463. [`segment-button-layout-${layout}`]: true,
  29464. 'ion-activatable': true,
  29465. 'ion-activatable-instant': true,
  29466. 'ion-focusable': true,
  29467. } }, 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" }))));
  29468. }
  29469. get el() { return getElement(this); }
  29470. static get watchers() { return {
  29471. "value": ["valueChanged"]
  29472. }; }
  29473. static get style() { return {
  29474. ios: IonSegmentButtonIosStyle0,
  29475. md: IonSegmentButtonMdStyle0
  29476. }; }
  29477. static get cmpMeta() { return {
  29478. "$flags$": 41,
  29479. "$tagName$": "ion-segment-button",
  29480. "$members$": {
  29481. "contentId": [513, "content-id"],
  29482. "disabled": [1028],
  29483. "layout": [1],
  29484. "type": [1],
  29485. "value": [8],
  29486. "checked": [32],
  29487. "setFocus": [64]
  29488. },
  29489. "$listeners$": undefined,
  29490. "$lazyBundleId$": "-",
  29491. "$attrsToReflect$": [["contentId", "content-id"]]
  29492. }; }
  29493. }
  29494. 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}";
  29495. var IonSegmentContentStyle0 = segmentContentCss;
  29496. class SegmentContent {
  29497. constructor(hostRef) {
  29498. registerInstance(this, hostRef);
  29499. }
  29500. render() {
  29501. return (hAsync(Host, { key: '64b3965b14c749e77e9ce13b59f349d971e245c8' }, hAsync("slot", { key: '2d0bed34f9bc93f92e713cb51e42220f3cecd8f5' })));
  29502. }
  29503. static get style() { return IonSegmentContentStyle0; }
  29504. static get cmpMeta() { return {
  29505. "$flags$": 9,
  29506. "$tagName$": "ion-segment-content",
  29507. "$members$": undefined,
  29508. "$listeners$": undefined,
  29509. "$lazyBundleId$": "-",
  29510. "$attrsToReflect$": []
  29511. }; }
  29512. }
  29513. 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}";
  29514. var IonSegmentViewIosStyle0 = segmentViewIosCss;
  29515. 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}";
  29516. var IonSegmentViewMdStyle0 = segmentViewMdCss;
  29517. class SegmentView {
  29518. constructor(hostRef) {
  29519. registerInstance(this, hostRef);
  29520. this.ionSegmentViewScroll = createEvent(this, "ionSegmentViewScroll", 7);
  29521. this.scrollEndTimeout = null;
  29522. this.isTouching = false;
  29523. this.disabled = false;
  29524. this.isManualScroll = undefined;
  29525. }
  29526. handleScroll(ev) {
  29527. var _a;
  29528. const { scrollLeft, scrollWidth, clientWidth } = ev.target;
  29529. const scrollRatio = scrollLeft / (scrollWidth - clientWidth);
  29530. this.ionSegmentViewScroll.emit({
  29531. scrollRatio,
  29532. isManualScroll: (_a = this.isManualScroll) !== null && _a !== void 0 ? _a : true,
  29533. });
  29534. // Reset the timeout to check for scroll end
  29535. this.resetScrollEndTimeout();
  29536. }
  29537. /**
  29538. * Handle touch start event to know when the user is actively dragging the segment view.
  29539. */
  29540. handleScrollStart() {
  29541. if (this.scrollEndTimeout) {
  29542. clearTimeout(this.scrollEndTimeout);
  29543. this.scrollEndTimeout = null;
  29544. }
  29545. this.isTouching = true;
  29546. }
  29547. /**
  29548. * Handle touch end event to know when the user is no longer dragging the segment view.
  29549. */
  29550. handleTouchEnd() {
  29551. this.isTouching = false;
  29552. }
  29553. /**
  29554. * Reset the scroll end detection timer. This is called on every scroll event.
  29555. */
  29556. resetScrollEndTimeout() {
  29557. if (this.scrollEndTimeout) {
  29558. clearTimeout(this.scrollEndTimeout);
  29559. this.scrollEndTimeout = null;
  29560. }
  29561. this.scrollEndTimeout = setTimeout(() => {
  29562. this.checkForScrollEnd();
  29563. },
  29564. // Setting this to a lower value may result in inconsistencies in behavior
  29565. // across browsers (particularly Firefox).
  29566. // Ideally, all of this logic is removed once the scroll end event is
  29567. // supported on all browsers (https://caniuse.com/?search=scrollend)
  29568. 100);
  29569. }
  29570. /**
  29571. * Check if the scroll has ended and the user is not actively touching.
  29572. * If the conditions are met (active content is enabled and no active touch),
  29573. * reset the scroll position and emit the scroll end event.
  29574. */
  29575. checkForScrollEnd() {
  29576. // Only emit scroll end event if the active content is not disabled and
  29577. // the user is not touching the segment view
  29578. if (!this.isTouching) {
  29579. this.isManualScroll = undefined;
  29580. }
  29581. }
  29582. /**
  29583. * @internal
  29584. *
  29585. * This method is used to programmatically set the displayed segment content
  29586. * in the segment view. Calling this method will update the `value` of the
  29587. * corresponding segment button.
  29588. *
  29589. * @param id: The id of the segment content to display.
  29590. * @param smoothScroll: Whether to animate the scroll transition.
  29591. */
  29592. async setContent(id, smoothScroll = true) {
  29593. const contents = this.getSegmentContents();
  29594. const index = contents.findIndex((content) => content.id === id);
  29595. if (index === -1)
  29596. return;
  29597. this.isManualScroll = false;
  29598. this.resetScrollEndTimeout();
  29599. const contentWidth = this.el.offsetWidth;
  29600. this.el.scrollTo({
  29601. top: 0,
  29602. left: index * contentWidth,
  29603. behavior: smoothScroll ? 'smooth' : 'instant',
  29604. });
  29605. }
  29606. getSegmentContents() {
  29607. return Array.from(this.el.querySelectorAll('ion-segment-content'));
  29608. }
  29609. render() {
  29610. const { disabled, isManualScroll } = this;
  29611. return (hAsync(Host, { key: 'fa528d2d9ae0f00fc3067defe2a047dce77c814a', class: {
  29612. 'segment-view-disabled': disabled,
  29613. 'segment-view-scroll-disabled': isManualScroll === false,
  29614. } }, hAsync("slot", { key: '74dc8b4d073caeff1bab272d11b9ea3e1a215954' })));
  29615. }
  29616. get el() { return getElement(this); }
  29617. static get style() { return {
  29618. ios: IonSegmentViewIosStyle0,
  29619. md: IonSegmentViewMdStyle0
  29620. }; }
  29621. static get cmpMeta() { return {
  29622. "$flags$": 41,
  29623. "$tagName$": "ion-segment-view",
  29624. "$members$": {
  29625. "disabled": [4],
  29626. "isManualScroll": [32],
  29627. "setContent": [64]
  29628. },
  29629. "$listeners$": [[1, "scroll", "handleScroll"], [1, "touchstart", "handleScrollStart"], [1, "touchend", "handleTouchEnd"]],
  29630. "$lazyBundleId$": "-",
  29631. "$attrsToReflect$": []
  29632. }; }
  29633. }
  29634. 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}";
  29635. var IonSelectIosStyle0 = selectIosCss;
  29636. 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}";
  29637. var IonSelectMdStyle0 = selectMdCss;
  29638. // TODO(FW-2832): types
  29639. /**
  29640. * @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
  29641. *
  29642. * @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.
  29643. * @slot start - Content to display at the leading edge of the select.
  29644. * @slot end - Content to display at the trailing edge of the select.
  29645. *
  29646. * @part placeholder - The text displayed in the select when there is no value.
  29647. * @part text - The displayed value of the select.
  29648. * @part icon - The select icon container.
  29649. * @part container - The container for the selected text or placeholder.
  29650. * @part label - The label text describing the select.
  29651. * @part supporting-text - Supporting text displayed beneath the select.
  29652. * @part helper-text - Supporting text displayed beneath the select when the select is valid.
  29653. * @part error-text - Supporting text displayed beneath the select when the select is invalid and touched.
  29654. */
  29655. class Select {
  29656. constructor(hostRef) {
  29657. registerInstance(this, hostRef);
  29658. this.ionChange = createEvent(this, "ionChange", 7);
  29659. this.ionCancel = createEvent(this, "ionCancel", 7);
  29660. this.ionDismiss = createEvent(this, "ionDismiss", 7);
  29661. this.ionFocus = createEvent(this, "ionFocus", 7);
  29662. this.ionBlur = createEvent(this, "ionBlur", 7);
  29663. this.ionStyle = createEvent(this, "ionStyle", 7);
  29664. this.inputId = `ion-sel-${selectIds++}`;
  29665. this.helperTextId = `${this.inputId}-helper-text`;
  29666. this.errorTextId = `${this.inputId}-error-text`;
  29667. this.inheritedAttributes = {};
  29668. this.onClick = (ev) => {
  29669. const target = ev.target;
  29670. const closestSlot = target.closest('[slot="start"], [slot="end"]');
  29671. if (target === this.el || closestSlot === null) {
  29672. this.setFocus();
  29673. this.open(ev);
  29674. }
  29675. else {
  29676. /**
  29677. * Prevent clicks to the start/end slots from opening the select.
  29678. * We ensure the target isn't this element in case the select is slotted
  29679. * in, for example, an item. This would prevent the select from ever
  29680. * being opened since the element itself has slot="start"/"end".
  29681. *
  29682. * Clicking a slotted element also causes a click
  29683. * on the <label> element (since it wraps the slots).
  29684. * Clicking <label> dispatches another click event on
  29685. * the native form control that then bubbles up to this
  29686. * listener. This additional event targets the host
  29687. * element, so the select overlay is opened.
  29688. *
  29689. * When the slotted elements are clicked (and therefore
  29690. * the ancestor <label> element) we want to prevent the label
  29691. * from dispatching another click event.
  29692. *
  29693. * Do not call stopPropagation() because this will cause
  29694. * click handlers on the slotted elements to never fire in React.
  29695. * When developers do onClick in React a native "click" listener
  29696. * is added on the root element, not the slotted element. When that
  29697. * native click listener fires, React then dispatches the synthetic
  29698. * click event on the slotted element. However, if stopPropagation
  29699. * is called then the native click event will never bubble up
  29700. * to the root element.
  29701. */
  29702. ev.preventDefault();
  29703. }
  29704. };
  29705. this.onFocus = () => {
  29706. this.hasFocus = true;
  29707. this.ionFocus.emit();
  29708. };
  29709. this.onBlur = () => {
  29710. this.hasFocus = false;
  29711. this.ionBlur.emit();
  29712. };
  29713. /**
  29714. * Stops propagation when the label is clicked,
  29715. * otherwise, two clicks will be triggered.
  29716. */
  29717. this.onLabelClick = (ev) => {
  29718. // Only stop propagation if the click was directly on the label
  29719. // and not on the input or other child elements
  29720. if (ev.target === ev.currentTarget) {
  29721. ev.stopPropagation();
  29722. }
  29723. };
  29724. this.isExpanded = false;
  29725. this.hasFocus = false;
  29726. this.cancelText = 'Cancel';
  29727. this.color = undefined;
  29728. this.compareWith = undefined;
  29729. this.disabled = false;
  29730. this.fill = undefined;
  29731. this.errorText = undefined;
  29732. this.helperText = undefined;
  29733. this.interface = 'alert';
  29734. this.interfaceOptions = {};
  29735. this.justify = undefined;
  29736. this.label = undefined;
  29737. this.labelPlacement = 'start';
  29738. this.multiple = false;
  29739. this.name = this.inputId;
  29740. this.okText = 'OK';
  29741. this.placeholder = undefined;
  29742. this.selectedText = undefined;
  29743. this.toggleIcon = undefined;
  29744. this.expandedIcon = undefined;
  29745. this.shape = undefined;
  29746. this.value = undefined;
  29747. this.required = false;
  29748. }
  29749. styleChanged() {
  29750. this.emitStyle();
  29751. }
  29752. setValue(value) {
  29753. this.value = value;
  29754. this.ionChange.emit({ value });
  29755. }
  29756. async connectedCallback() {
  29757. const { el } = this;
  29758. this.notchController = createNotchController(el, () => this.notchSpacerEl, () => this.labelSlot);
  29759. this.updateOverlayOptions();
  29760. this.emitStyle();
  29761. this.mutationO = watchForOptions(this.el, 'ion-select-option', async () => {
  29762. this.updateOverlayOptions();
  29763. });
  29764. }
  29765. componentWillLoad() {
  29766. this.inheritedAttributes = inheritAttributes$1(this.el, ['aria-label']);
  29767. }
  29768. componentDidLoad() {
  29769. /**
  29770. * If any of the conditions that trigger the styleChanged callback
  29771. * are met on component load, it is possible the event emitted
  29772. * prior to a parent web component registering an event listener.
  29773. *
  29774. * To ensure the parent web component receives the event, we
  29775. * emit the style event again after the component has loaded.
  29776. *
  29777. * This is often seen in Angular with the `dist` output target.
  29778. */
  29779. this.emitStyle();
  29780. }
  29781. disconnectedCallback() {
  29782. if (this.mutationO) {
  29783. this.mutationO.disconnect();
  29784. this.mutationO = undefined;
  29785. }
  29786. if (this.notchController) {
  29787. this.notchController.destroy();
  29788. this.notchController = undefined;
  29789. }
  29790. }
  29791. /**
  29792. * Open the select overlay. The overlay is either an alert, action sheet, or popover,
  29793. * depending on the `interface` property on the `ion-select`.
  29794. *
  29795. * @param event The user interface event that called the open.
  29796. */
  29797. async open(event) {
  29798. if (this.disabled || this.isExpanded) {
  29799. return undefined;
  29800. }
  29801. this.isExpanded = true;
  29802. const overlay = (this.overlay = await this.createOverlay(event));
  29803. // Add logic to scroll selected item into view before presenting
  29804. const scrollSelectedIntoView = () => {
  29805. const indexOfSelected = this.childOpts.findIndex((o) => o.value === this.value);
  29806. if (indexOfSelected > -1) {
  29807. const selectedItem = overlay.querySelector(`.select-interface-option:nth-child(${indexOfSelected + 1})`);
  29808. if (selectedItem) {
  29809. /**
  29810. * Browsers such as Firefox do not
  29811. * correctly delegate focus when manually
  29812. * focusing an element with delegatesFocus.
  29813. * We work around this by manually focusing
  29814. * the interactive element.
  29815. * ion-radio and ion-checkbox are the only
  29816. * elements that ion-select-popover uses, so
  29817. * we only need to worry about those two components
  29818. * when focusing.
  29819. */
  29820. const interactiveEl = selectedItem.querySelector('ion-radio, ion-checkbox');
  29821. if (interactiveEl) {
  29822. selectedItem.scrollIntoView({ block: 'nearest' });
  29823. // Needs to be called before `focusVisibleElement` to prevent issue with focus event bubbling
  29824. // and removing `ion-focused` style
  29825. interactiveEl.setFocus();
  29826. }
  29827. focusVisibleElement(selectedItem);
  29828. }
  29829. }
  29830. else {
  29831. /**
  29832. * If no value is set then focus the first enabled option.
  29833. */
  29834. const firstEnabledOption = overlay.querySelector('ion-radio:not(.radio-disabled), ion-checkbox:not(.checkbox-disabled)');
  29835. if (firstEnabledOption) {
  29836. /**
  29837. * Focus the option for the same reason as we do above.
  29838. *
  29839. * Needs to be called before `focusVisibleElement` to prevent issue with focus event bubbling
  29840. * and removing `ion-focused` style
  29841. */
  29842. firstEnabledOption.setFocus();
  29843. focusVisibleElement(firstEnabledOption.closest('ion-item'));
  29844. }
  29845. }
  29846. };
  29847. // For modals and popovers, we can scroll before they're visible
  29848. if (this.interface === 'modal') {
  29849. overlay.addEventListener('ionModalWillPresent', scrollSelectedIntoView, { once: true });
  29850. }
  29851. else if (this.interface === 'popover') {
  29852. overlay.addEventListener('ionPopoverWillPresent', scrollSelectedIntoView, { once: true });
  29853. }
  29854. else {
  29855. /**
  29856. * For alerts and action sheets, we need to wait a frame after willPresent
  29857. * because these overlays don't have their content in the DOM immediately
  29858. * when willPresent fires. By waiting a frame, we ensure the content is
  29859. * rendered and can be properly scrolled into view.
  29860. */
  29861. const scrollAfterRender = () => {
  29862. requestAnimationFrame(() => {
  29863. scrollSelectedIntoView();
  29864. });
  29865. };
  29866. if (this.interface === 'alert') {
  29867. overlay.addEventListener('ionAlertWillPresent', scrollAfterRender, { once: true });
  29868. }
  29869. else if (this.interface === 'action-sheet') {
  29870. overlay.addEventListener('ionActionSheetWillPresent', scrollAfterRender, { once: true });
  29871. }
  29872. }
  29873. overlay.onDidDismiss().then(() => {
  29874. this.overlay = undefined;
  29875. this.isExpanded = false;
  29876. this.ionDismiss.emit();
  29877. this.setFocus();
  29878. });
  29879. await overlay.present();
  29880. return overlay;
  29881. }
  29882. createOverlay(ev) {
  29883. let selectInterface = this.interface;
  29884. if (selectInterface === 'action-sheet' && this.multiple) {
  29885. printIonWarning(`[ion-select] - Interface cannot be "${selectInterface}" with a multi-value select. Using the "alert" interface instead.`);
  29886. selectInterface = 'alert';
  29887. }
  29888. if (selectInterface === 'popover' && !ev) {
  29889. printIonWarning(`[ion-select] - Interface cannot be a "${selectInterface}" without passing an event. Using the "alert" interface instead.`);
  29890. selectInterface = 'alert';
  29891. }
  29892. if (selectInterface === 'action-sheet') {
  29893. return this.openActionSheet();
  29894. }
  29895. if (selectInterface === 'popover') {
  29896. return this.openPopover(ev);
  29897. }
  29898. if (selectInterface === 'modal') {
  29899. return this.openModal();
  29900. }
  29901. return this.openAlert();
  29902. }
  29903. updateOverlayOptions() {
  29904. const overlay = this.overlay;
  29905. if (!overlay) {
  29906. return;
  29907. }
  29908. const childOpts = this.childOpts;
  29909. const value = this.value;
  29910. switch (this.interface) {
  29911. case 'action-sheet':
  29912. overlay.buttons = this.createActionSheetButtons(childOpts, value);
  29913. break;
  29914. case 'popover':
  29915. const popover = overlay.querySelector('ion-select-popover');
  29916. if (popover) {
  29917. popover.options = this.createOverlaySelectOptions(childOpts, value);
  29918. }
  29919. break;
  29920. case 'modal':
  29921. const modal = overlay.querySelector('ion-select-modal');
  29922. if (modal) {
  29923. modal.options = this.createOverlaySelectOptions(childOpts, value);
  29924. }
  29925. break;
  29926. case 'alert':
  29927. const inputType = this.multiple ? 'checkbox' : 'radio';
  29928. overlay.inputs = this.createAlertInputs(childOpts, inputType, value);
  29929. break;
  29930. }
  29931. }
  29932. createActionSheetButtons(data, selectValue) {
  29933. const actionSheetButtons = data.map((option) => {
  29934. const value = getOptionValue(option);
  29935. // Remove hydrated before copying over classes
  29936. const copyClasses = Array.from(option.classList)
  29937. .filter((cls) => cls !== 'hydrated')
  29938. .join(' ');
  29939. const optClass = `${OPTION_CLASS} ${copyClasses}`;
  29940. return {
  29941. role: isOptionSelected(selectValue, value, this.compareWith) ? 'selected' : '',
  29942. text: option.textContent,
  29943. cssClass: optClass,
  29944. handler: () => {
  29945. this.setValue(value);
  29946. },
  29947. };
  29948. });
  29949. // Add "cancel" button
  29950. actionSheetButtons.push({
  29951. text: this.cancelText,
  29952. role: 'cancel',
  29953. handler: () => {
  29954. this.ionCancel.emit();
  29955. },
  29956. });
  29957. return actionSheetButtons;
  29958. }
  29959. createAlertInputs(data, inputType, selectValue) {
  29960. const alertInputs = data.map((option) => {
  29961. const value = getOptionValue(option);
  29962. // Remove hydrated before copying over classes
  29963. const copyClasses = Array.from(option.classList)
  29964. .filter((cls) => cls !== 'hydrated')
  29965. .join(' ');
  29966. const optClass = `${OPTION_CLASS} ${copyClasses}`;
  29967. return {
  29968. type: inputType,
  29969. cssClass: optClass,
  29970. label: option.textContent || '',
  29971. value,
  29972. checked: isOptionSelected(selectValue, value, this.compareWith),
  29973. disabled: option.disabled,
  29974. };
  29975. });
  29976. return alertInputs;
  29977. }
  29978. createOverlaySelectOptions(data, selectValue) {
  29979. const popoverOptions = data.map((option) => {
  29980. const value = getOptionValue(option);
  29981. // Remove hydrated before copying over classes
  29982. const copyClasses = Array.from(option.classList)
  29983. .filter((cls) => cls !== 'hydrated')
  29984. .join(' ');
  29985. const optClass = `${OPTION_CLASS} ${copyClasses}`;
  29986. return {
  29987. text: option.textContent || '',
  29988. cssClass: optClass,
  29989. value,
  29990. checked: isOptionSelected(selectValue, value, this.compareWith),
  29991. disabled: option.disabled,
  29992. handler: (selected) => {
  29993. this.setValue(selected);
  29994. if (!this.multiple) {
  29995. this.close();
  29996. }
  29997. },
  29998. };
  29999. });
  30000. return popoverOptions;
  30001. }
  30002. async openPopover(ev) {
  30003. const { fill, labelPlacement } = this;
  30004. const interfaceOptions = this.interfaceOptions;
  30005. const mode = getIonMode$1(this);
  30006. const showBackdrop = mode === 'md' ? false : true;
  30007. const multiple = this.multiple;
  30008. const value = this.value;
  30009. let event = ev;
  30010. let size = 'auto';
  30011. const hasFloatingOrStackedLabel = labelPlacement === 'floating' || labelPlacement === 'stacked';
  30012. /**
  30013. * The popover should take up the full width
  30014. * when using a fill in MD mode or if the
  30015. * label is floating/stacked.
  30016. */
  30017. if (hasFloatingOrStackedLabel || (mode === 'md' && fill !== undefined)) {
  30018. size = 'cover';
  30019. /**
  30020. * Otherwise the popover
  30021. * should be positioned relative
  30022. * to the native element.
  30023. */
  30024. }
  30025. else {
  30026. event = Object.assign(Object.assign({}, ev), { detail: {
  30027. ionShadowTarget: this.nativeWrapperEl,
  30028. } });
  30029. }
  30030. const popoverOpts = Object.assign(Object.assign({ mode,
  30031. event, alignment: 'center', size,
  30032. showBackdrop }, interfaceOptions), { component: 'ion-select-popover', cssClass: ['select-popover', interfaceOptions.cssClass], componentProps: {
  30033. header: interfaceOptions.header,
  30034. subHeader: interfaceOptions.subHeader,
  30035. message: interfaceOptions.message,
  30036. multiple,
  30037. value,
  30038. options: this.createOverlaySelectOptions(this.childOpts, value),
  30039. } });
  30040. return popoverController.create(popoverOpts);
  30041. }
  30042. async openActionSheet() {
  30043. const mode = getIonMode$1(this);
  30044. const interfaceOptions = this.interfaceOptions;
  30045. const actionSheetOpts = Object.assign(Object.assign({ mode }, interfaceOptions), { buttons: this.createActionSheetButtons(this.childOpts, this.value), cssClass: ['select-action-sheet', interfaceOptions.cssClass] });
  30046. return actionSheetController.create(actionSheetOpts);
  30047. }
  30048. async openAlert() {
  30049. const interfaceOptions = this.interfaceOptions;
  30050. const inputType = this.multiple ? 'checkbox' : 'radio';
  30051. const mode = getIonMode$1(this);
  30052. const alertOpts = Object.assign(Object.assign({ mode }, interfaceOptions), { header: interfaceOptions.header ? interfaceOptions.header : this.labelText, inputs: this.createAlertInputs(this.childOpts, inputType, this.value), buttons: [
  30053. {
  30054. text: this.cancelText,
  30055. role: 'cancel',
  30056. handler: () => {
  30057. this.ionCancel.emit();
  30058. },
  30059. },
  30060. {
  30061. text: this.okText,
  30062. handler: (selectedValues) => {
  30063. this.setValue(selectedValues);
  30064. },
  30065. },
  30066. ], cssClass: [
  30067. 'select-alert',
  30068. interfaceOptions.cssClass,
  30069. this.multiple ? 'multiple-select-alert' : 'single-select-alert',
  30070. ] });
  30071. return alertController.create(alertOpts);
  30072. }
  30073. openModal() {
  30074. const { multiple, value, interfaceOptions } = this;
  30075. const mode = getIonMode$1(this);
  30076. const modalOpts = Object.assign(Object.assign({}, interfaceOptions), { mode, cssClass: ['select-modal', interfaceOptions.cssClass], component: 'ion-select-modal', componentProps: {
  30077. header: interfaceOptions.header,
  30078. multiple,
  30079. value,
  30080. options: this.createOverlaySelectOptions(this.childOpts, value),
  30081. } });
  30082. return modalController.create(modalOpts);
  30083. }
  30084. /**
  30085. * Close the select interface.
  30086. */
  30087. close() {
  30088. if (!this.overlay) {
  30089. return Promise.resolve(false);
  30090. }
  30091. return this.overlay.dismiss();
  30092. }
  30093. hasValue() {
  30094. return this.getText() !== '';
  30095. }
  30096. get childOpts() {
  30097. return Array.from(this.el.querySelectorAll('ion-select-option'));
  30098. }
  30099. /**
  30100. * Returns any plaintext associated with
  30101. * the label (either prop or slot).
  30102. * Note: This will not return any custom
  30103. * HTML. Use the `hasLabel` getter if you
  30104. * want to know if any slotted label content
  30105. * was passed.
  30106. */
  30107. get labelText() {
  30108. const { label } = this;
  30109. if (label !== undefined) {
  30110. return label;
  30111. }
  30112. const { labelSlot } = this;
  30113. if (labelSlot !== null) {
  30114. return labelSlot.textContent;
  30115. }
  30116. return;
  30117. }
  30118. getText() {
  30119. const selectedText = this.selectedText;
  30120. if (selectedText != null && selectedText !== '') {
  30121. return selectedText;
  30122. }
  30123. return generateText(this.childOpts, this.value, this.compareWith);
  30124. }
  30125. setFocus() {
  30126. if (this.focusEl) {
  30127. this.focusEl.focus();
  30128. }
  30129. }
  30130. emitStyle() {
  30131. const { disabled } = this;
  30132. const style = {
  30133. 'interactive-disabled': disabled,
  30134. };
  30135. this.ionStyle.emit(style);
  30136. }
  30137. renderLabel() {
  30138. const { label } = this;
  30139. return (hAsync("div", { class: {
  30140. 'label-text-wrapper': true,
  30141. 'label-text-wrapper-hidden': !this.hasLabel,
  30142. }, part: "label" }, label === undefined ? hAsync("slot", { name: "label" }) : hAsync("div", { class: "label-text" }, label)));
  30143. }
  30144. componentDidRender() {
  30145. var _a;
  30146. (_a = this.notchController) === null || _a === void 0 ? void 0 : _a.calculateNotchWidth();
  30147. }
  30148. /**
  30149. * Gets any content passed into the `label` slot,
  30150. * not the <slot> definition.
  30151. */
  30152. get labelSlot() {
  30153. return this.el.querySelector('[slot="label"]');
  30154. }
  30155. /**
  30156. * Returns `true` if label content is provided
  30157. * either by a prop or a content. If you want
  30158. * to get the plaintext value of the label use
  30159. * the `labelText` getter instead.
  30160. */
  30161. get hasLabel() {
  30162. return this.label !== undefined || this.labelSlot !== null;
  30163. }
  30164. /**
  30165. * Renders the border container
  30166. * when fill="outline".
  30167. */
  30168. renderLabelContainer() {
  30169. const mode = getIonMode$1(this);
  30170. const hasOutlineFill = mode === 'md' && this.fill === 'outline';
  30171. if (hasOutlineFill) {
  30172. /**
  30173. * The outline fill has a special outline
  30174. * that appears around the select and the label.
  30175. * Certain stacked and floating label placements cause the
  30176. * label to translate up and create a "cut out"
  30177. * inside of that border by using the notch-spacer element.
  30178. */
  30179. return [
  30180. hAsync("div", { class: "select-outline-container" }, hAsync("div", { class: "select-outline-start" }), hAsync("div", { class: {
  30181. 'select-outline-notch': true,
  30182. 'select-outline-notch-hidden': !this.hasLabel,
  30183. } }, hAsync("div", { class: "notch-spacer", "aria-hidden": "true", ref: (el) => (this.notchSpacerEl = el) }, this.label)), hAsync("div", { class: "select-outline-end" })),
  30184. this.renderLabel(),
  30185. ];
  30186. }
  30187. /**
  30188. * If not using the outline style,
  30189. * we can render just the label.
  30190. */
  30191. return this.renderLabel();
  30192. }
  30193. /**
  30194. * Renders either the placeholder
  30195. * or the selected values based on
  30196. * the state of the select.
  30197. */
  30198. renderSelectText() {
  30199. const { placeholder } = this;
  30200. const displayValue = this.getText();
  30201. let addPlaceholderClass = false;
  30202. let selectText = displayValue;
  30203. if (selectText === '' && placeholder !== undefined) {
  30204. selectText = placeholder;
  30205. addPlaceholderClass = true;
  30206. }
  30207. const selectTextClasses = {
  30208. 'select-text': true,
  30209. 'select-placeholder': addPlaceholderClass,
  30210. };
  30211. const textPart = addPlaceholderClass ? 'placeholder' : 'text';
  30212. return (hAsync("div", { "aria-hidden": "true", class: selectTextClasses, part: textPart }, selectText));
  30213. }
  30214. /**
  30215. * Renders the chevron icon
  30216. * next to the select text.
  30217. */
  30218. renderSelectIcon() {
  30219. const mode = getIonMode$1(this);
  30220. const { isExpanded, toggleIcon, expandedIcon } = this;
  30221. let icon;
  30222. if (isExpanded && expandedIcon !== undefined) {
  30223. icon = expandedIcon;
  30224. }
  30225. else {
  30226. const defaultIcon = mode === 'ios' ? chevronExpand : caretDownSharp;
  30227. icon = toggleIcon !== null && toggleIcon !== void 0 ? toggleIcon : defaultIcon;
  30228. }
  30229. return hAsync("ion-icon", { class: "select-icon", part: "icon", "aria-hidden": "true", icon: icon });
  30230. }
  30231. get ariaLabel() {
  30232. var _a;
  30233. const { placeholder, inheritedAttributes } = this;
  30234. const displayValue = this.getText();
  30235. // The aria label should be preferred over visible text if both are specified
  30236. const definedLabel = (_a = inheritedAttributes['aria-label']) !== null && _a !== void 0 ? _a : this.labelText;
  30237. /**
  30238. * If developer has specified a placeholder
  30239. * and there is nothing selected, the selectText
  30240. * should have the placeholder value.
  30241. */
  30242. let renderedLabel = displayValue;
  30243. if (renderedLabel === '' && placeholder !== undefined) {
  30244. renderedLabel = placeholder;
  30245. }
  30246. /**
  30247. * If there is a developer-defined label,
  30248. * then we need to concatenate the developer label
  30249. * string with the current current value.
  30250. * The label for the control should be read
  30251. * before the values of the control.
  30252. */
  30253. if (definedLabel !== undefined) {
  30254. renderedLabel = renderedLabel === '' ? definedLabel : `${definedLabel}, ${renderedLabel}`;
  30255. }
  30256. return renderedLabel;
  30257. }
  30258. renderListbox() {
  30259. const { disabled, inputId, isExpanded, required } = this;
  30260. 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) }));
  30261. }
  30262. getHintTextID() {
  30263. const { el, helperText, errorText, helperTextId, errorTextId } = this;
  30264. if (el.classList.contains('ion-touched') && el.classList.contains('ion-invalid') && errorText) {
  30265. return errorTextId;
  30266. }
  30267. if (helperText) {
  30268. return helperTextId;
  30269. }
  30270. return undefined;
  30271. }
  30272. /**
  30273. * Renders the helper text or error text values
  30274. */
  30275. renderHintText() {
  30276. const { helperText, errorText, helperTextId, errorTextId } = this;
  30277. return [
  30278. hAsync("div", { id: helperTextId, class: "helper-text", part: "supporting-text helper-text" }, helperText),
  30279. hAsync("div", { id: errorTextId, class: "error-text", part: "supporting-text error-text" }, errorText),
  30280. ];
  30281. }
  30282. /**
  30283. * Responsible for rendering helper text, and error text. This element
  30284. * should only be rendered if hint text is set.
  30285. */
  30286. renderBottomContent() {
  30287. const { helperText, errorText } = this;
  30288. /**
  30289. * undefined and empty string values should
  30290. * be treated as not having helper/error text.
  30291. */
  30292. const hasHintText = !!helperText || !!errorText;
  30293. if (!hasHintText) {
  30294. return;
  30295. }
  30296. return hAsync("div", { class: "select-bottom" }, this.renderHintText());
  30297. }
  30298. render() {
  30299. const { disabled, el, isExpanded, expandedIcon, labelPlacement, justify, placeholder, fill, shape, name, value, hasFocus, } = this;
  30300. const mode = getIonMode$1(this);
  30301. const hasFloatingOrStackedLabel = labelPlacement === 'floating' || labelPlacement === 'stacked';
  30302. const justifyEnabled = !hasFloatingOrStackedLabel && justify !== undefined;
  30303. const rtl = isRTL$1(el) ? 'rtl' : 'ltr';
  30304. const inItem = hostContext('ion-item', this.el);
  30305. const shouldRenderHighlight = mode === 'md' && fill !== 'outline' && !inItem;
  30306. const hasValue = this.hasValue();
  30307. const hasStartEndSlots = el.querySelector('[slot="start"], [slot="end"]') !== null;
  30308. renderHiddenInput(true, el, name, parseValue(value), disabled);
  30309. /**
  30310. * If the label is stacked, it should always sit above the select.
  30311. * For floating labels, the label should move above the select if
  30312. * the select has a value, is open, or has anything in either
  30313. * the start or end slot.
  30314. *
  30315. * If there is content in the start slot, the label would overlap
  30316. * it if not forced to float. This is also applied to the end slot
  30317. * because with the default or solid fills, the select is not
  30318. * vertically centered in the container, but the label is. This
  30319. * causes the slots and label to appear vertically offset from each
  30320. * other when the label isn't floating above the input. This doesn't
  30321. * apply to the outline fill, but this was not accounted for to keep
  30322. * things consistent.
  30323. *
  30324. * TODO(FW-5592): Remove hasStartEndSlots condition
  30325. */
  30326. const labelShouldFloat = labelPlacement === 'stacked' || (labelPlacement === 'floating' && (hasValue || isExpanded || hasStartEndSlots));
  30327. return (hAsync(Host, { key: '6dd3c92dc3c587960d767c7dd1c142fc20bef8ed', onClick: this.onClick, class: createColorClasses$1(this.color, {
  30328. [mode]: true,
  30329. 'in-item': inItem,
  30330. 'in-item-color': hostContext('ion-item.ion-color', el),
  30331. 'select-disabled': disabled,
  30332. 'select-expanded': isExpanded,
  30333. 'has-expanded-icon': expandedIcon !== undefined,
  30334. 'has-value': hasValue,
  30335. 'label-floating': labelShouldFloat,
  30336. 'has-placeholder': placeholder !== undefined,
  30337. 'has-focus': hasFocus,
  30338. // TODO(FW-6451): Remove `ion-focusable` class in favor of `has-focus`.
  30339. 'ion-focusable': true,
  30340. [`select-${rtl}`]: true,
  30341. [`select-fill-${fill}`]: fill !== undefined,
  30342. [`select-justify-${justify}`]: justifyEnabled,
  30343. [`select-shape-${shape}`]: shape !== undefined,
  30344. [`select-label-placement-${labelPlacement}`]: true,
  30345. }) }, 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()));
  30346. }
  30347. get el() { return getElement(this); }
  30348. static get watchers() { return {
  30349. "disabled": ["styleChanged"],
  30350. "isExpanded": ["styleChanged"],
  30351. "placeholder": ["styleChanged"],
  30352. "value": ["styleChanged"]
  30353. }; }
  30354. static get style() { return {
  30355. ios: IonSelectIosStyle0,
  30356. md: IonSelectMdStyle0
  30357. }; }
  30358. static get cmpMeta() { return {
  30359. "$flags$": 41,
  30360. "$tagName$": "ion-select",
  30361. "$members$": {
  30362. "cancelText": [1, "cancel-text"],
  30363. "color": [513],
  30364. "compareWith": [1, "compare-with"],
  30365. "disabled": [4],
  30366. "fill": [1],
  30367. "errorText": [1, "error-text"],
  30368. "helperText": [1, "helper-text"],
  30369. "interface": [1],
  30370. "interfaceOptions": [8, "interface-options"],
  30371. "justify": [1],
  30372. "label": [1],
  30373. "labelPlacement": [1, "label-placement"],
  30374. "multiple": [4],
  30375. "name": [1],
  30376. "okText": [1, "ok-text"],
  30377. "placeholder": [1],
  30378. "selectedText": [1, "selected-text"],
  30379. "toggleIcon": [1, "toggle-icon"],
  30380. "expandedIcon": [1, "expanded-icon"],
  30381. "shape": [1],
  30382. "value": [1032],
  30383. "required": [4],
  30384. "isExpanded": [32],
  30385. "hasFocus": [32],
  30386. "open": [64]
  30387. },
  30388. "$listeners$": undefined,
  30389. "$lazyBundleId$": "-",
  30390. "$attrsToReflect$": [["color", "color"]]
  30391. }; }
  30392. }
  30393. const getOptionValue = (el) => {
  30394. const value = el.value;
  30395. return value === undefined ? el.textContent || '' : value;
  30396. };
  30397. const parseValue = (value) => {
  30398. if (value == null) {
  30399. return undefined;
  30400. }
  30401. if (Array.isArray(value)) {
  30402. return value.join(',');
  30403. }
  30404. return value.toString();
  30405. };
  30406. const generateText = (opts, value, compareWith) => {
  30407. if (value === undefined) {
  30408. return '';
  30409. }
  30410. if (Array.isArray(value)) {
  30411. return value
  30412. .map((v) => textForValue(opts, v, compareWith))
  30413. .filter((opt) => opt !== null)
  30414. .join(', ');
  30415. }
  30416. else {
  30417. return textForValue(opts, value, compareWith) || '';
  30418. }
  30419. };
  30420. const textForValue = (opts, value, compareWith) => {
  30421. const selectOpt = opts.find((opt) => {
  30422. return compareOptions(value, getOptionValue(opt), compareWith);
  30423. });
  30424. return selectOpt ? selectOpt.textContent : null;
  30425. };
  30426. let selectIds = 0;
  30427. const OPTION_CLASS = 'select-interface-option';
  30428. 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)}";
  30429. var IonSelectModalIonicStyle0 = ionicSelectModalMdCss;
  30430. 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)}";
  30431. var IonSelectModalIosStyle0 = selectModalIosCss;
  30432. 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)}";
  30433. var IonSelectModalMdStyle0 = selectModalMdCss;
  30434. class SelectModal {
  30435. constructor(hostRef) {
  30436. registerInstance(this, hostRef);
  30437. this.header = undefined;
  30438. this.multiple = undefined;
  30439. this.options = [];
  30440. }
  30441. closeModal() {
  30442. const modal = this.el.closest('ion-modal');
  30443. if (modal) {
  30444. modal.dismiss();
  30445. }
  30446. }
  30447. findOptionFromEvent(ev) {
  30448. const { options } = this;
  30449. return options.find((o) => o.value === ev.target.value);
  30450. }
  30451. getValues(ev) {
  30452. const { multiple, options } = this;
  30453. if (multiple) {
  30454. // this is a modal with checkboxes (multiple value select)
  30455. // return an array of all the checked values
  30456. return options.filter((o) => o.checked).map((o) => o.value);
  30457. }
  30458. // this is a modal with radio buttons (single value select)
  30459. // return the value that was clicked, otherwise undefined
  30460. const option = ev ? this.findOptionFromEvent(ev) : null;
  30461. return option ? option.value : undefined;
  30462. }
  30463. callOptionHandler(ev) {
  30464. const option = this.findOptionFromEvent(ev);
  30465. const values = this.getValues(ev);
  30466. if (option === null || option === void 0 ? void 0 : option.handler) {
  30467. safeCall(option.handler, values);
  30468. }
  30469. }
  30470. setChecked(ev) {
  30471. const { multiple } = this;
  30472. const option = this.findOptionFromEvent(ev);
  30473. // this is a modal with checkboxes (multiple value select)
  30474. // we need to set the checked value for this option
  30475. if (multiple && option) {
  30476. option.checked = ev.detail.checked;
  30477. }
  30478. }
  30479. renderRadioOptions() {
  30480. const checked = this.options.filter((o) => o.checked).map((o) => o.value)[0];
  30481. return (hAsync("ion-radio-group", { value: checked, onIonChange: (ev) => this.callOptionHandler(ev) }, this.options.map((option) => (hAsync("ion-item", { lines: "none", class: Object.assign({
  30482. // TODO FW-4784
  30483. 'item-radio-checked': option.value === checked
  30484. }, getClassMap(option.cssClass)) }, hAsync("ion-radio", { value: option.value, disabled: option.disabled, justify: "start", labelPlacement: "end", onClick: () => this.closeModal(), onKeyUp: (ev) => {
  30485. if (ev.key === ' ') {
  30486. /**
  30487. * Selecting a radio option with keyboard navigation,
  30488. * either through the Enter or Space keys, should
  30489. * dismiss the modal.
  30490. */
  30491. this.closeModal();
  30492. }
  30493. } }, option.text))))));
  30494. }
  30495. renderCheckboxOptions() {
  30496. return this.options.map((option) => (hAsync("ion-item", { class: Object.assign({
  30497. // TODO FW-4784
  30498. 'item-checkbox-checked': option.checked
  30499. }, getClassMap(option.cssClass)) }, hAsync("ion-checkbox", { value: option.value, disabled: option.disabled, checked: option.checked, justify: "start", labelPlacement: "end", onIonChange: (ev) => {
  30500. this.setChecked(ev);
  30501. this.callOptionHandler(ev);
  30502. } }, option.text))));
  30503. }
  30504. render() {
  30505. 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()))));
  30506. }
  30507. get el() { return getElement(this); }
  30508. static get style() { return {
  30509. ionic: IonSelectModalIonicStyle0,
  30510. ios: IonSelectModalIosStyle0,
  30511. md: IonSelectModalMdStyle0
  30512. }; }
  30513. static get cmpMeta() { return {
  30514. "$flags$": 34,
  30515. "$tagName$": "ion-select-modal",
  30516. "$members$": {
  30517. "header": [1],
  30518. "multiple": [4],
  30519. "options": [16]
  30520. },
  30521. "$listeners$": undefined,
  30522. "$lazyBundleId$": "-",
  30523. "$attrsToReflect$": []
  30524. }; }
  30525. }
  30526. const selectOptionCss = ":host{display:none}";
  30527. var IonSelectOptionStyle0 = selectOptionCss;
  30528. class SelectOption {
  30529. constructor(hostRef) {
  30530. registerInstance(this, hostRef);
  30531. this.inputId = `ion-selopt-${selectOptionIds++}`;
  30532. this.disabled = false;
  30533. this.value = undefined;
  30534. }
  30535. render() {
  30536. return hAsync(Host, { key: '8c96c199ce3a3065de3fe446500f567236e0610a', role: "option", id: this.inputId, class: getIonMode$1(this) });
  30537. }
  30538. get el() { return getElement(this); }
  30539. static get style() { return IonSelectOptionStyle0; }
  30540. static get cmpMeta() { return {
  30541. "$flags$": 9,
  30542. "$tagName$": "ion-select-option",
  30543. "$members$": {
  30544. "disabled": [4],
  30545. "value": [8]
  30546. },
  30547. "$listeners$": undefined,
  30548. "$lazyBundleId$": "-",
  30549. "$attrsToReflect$": []
  30550. }; }
  30551. }
  30552. let selectOptionIds = 0;
  30553. 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}";
  30554. var IonSelectPopoverIosStyle0 = selectPopoverIosCss;
  30555. 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)}";
  30556. var IonSelectPopoverMdStyle0 = selectPopoverMdCss;
  30557. /**
  30558. * @internal
  30559. */
  30560. class SelectPopover {
  30561. constructor(hostRef) {
  30562. registerInstance(this, hostRef);
  30563. this.header = undefined;
  30564. this.subHeader = undefined;
  30565. this.message = undefined;
  30566. this.multiple = undefined;
  30567. this.options = [];
  30568. }
  30569. findOptionFromEvent(ev) {
  30570. const { options } = this;
  30571. return options.find((o) => o.value === ev.target.value);
  30572. }
  30573. /**
  30574. * When an option is selected we need to get the value(s)
  30575. * of the selected option(s) and return it in the option
  30576. * handler
  30577. */
  30578. callOptionHandler(ev) {
  30579. const option = this.findOptionFromEvent(ev);
  30580. const values = this.getValues(ev);
  30581. if (option === null || option === void 0 ? void 0 : option.handler) {
  30582. safeCall(option.handler, values);
  30583. }
  30584. }
  30585. /**
  30586. * Dismisses the host popover that the `ion-select-popover`
  30587. * is rendered within.
  30588. */
  30589. dismissParentPopover() {
  30590. const popover = this.el.closest('ion-popover');
  30591. if (popover) {
  30592. popover.dismiss();
  30593. }
  30594. }
  30595. setChecked(ev) {
  30596. const { multiple } = this;
  30597. const option = this.findOptionFromEvent(ev);
  30598. // this is a popover with checkboxes (multiple value select)
  30599. // we need to set the checked value for this option
  30600. if (multiple && option) {
  30601. option.checked = ev.detail.checked;
  30602. }
  30603. }
  30604. getValues(ev) {
  30605. const { multiple, options } = this;
  30606. if (multiple) {
  30607. // this is a popover with checkboxes (multiple value select)
  30608. // return an array of all the checked values
  30609. return options.filter((o) => o.checked).map((o) => o.value);
  30610. }
  30611. // this is a popover with radio buttons (single value select)
  30612. // return the value that was clicked, otherwise undefined
  30613. const option = this.findOptionFromEvent(ev);
  30614. return option ? option.value : undefined;
  30615. }
  30616. renderOptions(options) {
  30617. const { multiple } = this;
  30618. switch (multiple) {
  30619. case true:
  30620. return this.renderCheckboxOptions(options);
  30621. default:
  30622. return this.renderRadioOptions(options);
  30623. }
  30624. }
  30625. renderCheckboxOptions(options) {
  30626. return options.map((option) => (hAsync("ion-item", { class: Object.assign({
  30627. // TODO FW-4784
  30628. 'item-checkbox-checked': option.checked
  30629. }, getClassMap(option.cssClass)) }, hAsync("ion-checkbox", { value: option.value, disabled: option.disabled, checked: option.checked, justify: "start", labelPlacement: "end", onIonChange: (ev) => {
  30630. this.setChecked(ev);
  30631. this.callOptionHandler(ev);
  30632. } }, option.text))));
  30633. }
  30634. renderRadioOptions(options) {
  30635. const checked = options.filter((o) => o.checked).map((o) => o.value)[0];
  30636. return (hAsync("ion-radio-group", { value: checked, onIonChange: (ev) => this.callOptionHandler(ev) }, options.map((option) => (hAsync("ion-item", { class: Object.assign({
  30637. // TODO FW-4784
  30638. 'item-radio-checked': option.value === checked
  30639. }, getClassMap(option.cssClass)) }, hAsync("ion-radio", { value: option.value, disabled: option.disabled, onClick: () => this.dismissParentPopover(), onKeyUp: (ev) => {
  30640. if (ev.key === ' ') {
  30641. /**
  30642. * Selecting a radio option with keyboard navigation,
  30643. * either through the Enter or Space keys, should
  30644. * dismiss the popover.
  30645. */
  30646. this.dismissParentPopover();
  30647. }
  30648. } }, option.text))))));
  30649. }
  30650. render() {
  30651. const { header, message, options, subHeader } = this;
  30652. const hasSubHeaderOrMessage = subHeader !== undefined || message !== undefined;
  30653. 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))));
  30654. }
  30655. get el() { return getElement(this); }
  30656. static get style() { return {
  30657. ios: IonSelectPopoverIosStyle0,
  30658. md: IonSelectPopoverMdStyle0
  30659. }; }
  30660. static get cmpMeta() { return {
  30661. "$flags$": 34,
  30662. "$tagName$": "ion-select-popover",
  30663. "$members$": {
  30664. "header": [1],
  30665. "subHeader": [1, "sub-header"],
  30666. "message": [1],
  30667. "multiple": [4],
  30668. "options": [16]
  30669. },
  30670. "$listeners$": undefined,
  30671. "$lazyBundleId$": "-",
  30672. "$attrsToReflect$": []
  30673. }; }
  30674. }
  30675. 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}}";
  30676. var IonSkeletonTextStyle0 = skeletonTextCss;
  30677. class SkeletonText {
  30678. constructor(hostRef) {
  30679. registerInstance(this, hostRef);
  30680. this.ionStyle = createEvent(this, "ionStyle", 7);
  30681. this.animated = false;
  30682. }
  30683. componentWillLoad() {
  30684. this.emitStyle();
  30685. }
  30686. emitStyle() {
  30687. // The emitted property is used by item in order
  30688. // to add the item-skeleton-text class which applies
  30689. // overflow: hidden to its label
  30690. const style = {
  30691. 'skeleton-text': true,
  30692. };
  30693. this.ionStyle.emit(style);
  30694. }
  30695. render() {
  30696. const animated = this.animated && config.getBoolean('animated', true);
  30697. const inMedia = hostContext('ion-avatar', this.el) || hostContext('ion-thumbnail', this.el);
  30698. const mode = getIonMode$1(this);
  30699. return (hAsync(Host, { key: 'c193f9a8e8efab5139544f047bdae4b6d421aa86', class: {
  30700. [mode]: true,
  30701. 'skeleton-text-animated': animated,
  30702. 'in-media': inMedia,
  30703. } }, hAsync("span", { key: 'e15db679bd3c359b4df5123efd2f92e5b380fde3' }, "\u00A0")));
  30704. }
  30705. get el() { return getElement(this); }
  30706. static get style() { return IonSkeletonTextStyle0; }
  30707. static get cmpMeta() { return {
  30708. "$flags$": 9,
  30709. "$tagName$": "ion-skeleton-text",
  30710. "$members$": {
  30711. "animated": [4]
  30712. },
  30713. "$listeners$": undefined,
  30714. "$lazyBundleId$": "-",
  30715. "$attrsToReflect$": []
  30716. }; }
  30717. }
  30718. 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}}";
  30719. var IonSpinnerStyle0 = spinnerCss;
  30720. class Spinner {
  30721. constructor(hostRef) {
  30722. registerInstance(this, hostRef);
  30723. this.color = undefined;
  30724. this.duration = undefined;
  30725. this.name = undefined;
  30726. this.paused = false;
  30727. }
  30728. getName() {
  30729. const spinnerName = this.name || config.get('spinner');
  30730. const mode = getIonMode$1(this);
  30731. if (spinnerName) {
  30732. return spinnerName;
  30733. }
  30734. return mode === 'ios' ? 'lines' : 'circular';
  30735. }
  30736. render() {
  30737. var _a;
  30738. const self = this;
  30739. const mode = getIonMode$1(self);
  30740. const spinnerName = self.getName();
  30741. const spinner = (_a = SPINNERS[spinnerName]) !== null && _a !== void 0 ? _a : SPINNERS['lines'];
  30742. const duration = typeof self.duration === 'number' && self.duration > 10 ? self.duration : spinner.dur;
  30743. const svgs = [];
  30744. if (spinner.circles !== undefined) {
  30745. for (let i = 0; i < spinner.circles; i++) {
  30746. svgs.push(buildCircle(spinner, duration, i, spinner.circles));
  30747. }
  30748. }
  30749. else if (spinner.lines !== undefined) {
  30750. for (let i = 0; i < spinner.lines; i++) {
  30751. svgs.push(buildLine(spinner, duration, i, spinner.lines));
  30752. }
  30753. }
  30754. return (hAsync(Host, { key: 'e0dfa8a3ee2a0469eb31323f506750bd77d65797', class: createColorClasses$1(self.color, {
  30755. [mode]: true,
  30756. [`spinner-${spinnerName}`]: true,
  30757. 'spinner-paused': self.paused || config.getBoolean('_testing'),
  30758. }), role: "progressbar", style: spinner.elmDuration ? { animationDuration: duration + 'ms' } : {} }, svgs));
  30759. }
  30760. static get style() { return IonSpinnerStyle0; }
  30761. static get cmpMeta() { return {
  30762. "$flags$": 9,
  30763. "$tagName$": "ion-spinner",
  30764. "$members$": {
  30765. "color": [513],
  30766. "duration": [2],
  30767. "name": [1],
  30768. "paused": [4]
  30769. },
  30770. "$listeners$": undefined,
  30771. "$lazyBundleId$": "-",
  30772. "$attrsToReflect$": [["color", "color"]]
  30773. }; }
  30774. }
  30775. const buildCircle = (spinner, duration, index, total) => {
  30776. const data = spinner.fn(duration, index, total);
  30777. data.style['animation-duration'] = duration + 'ms';
  30778. 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' } : {} })));
  30779. };
  30780. const buildLine = (spinner, duration, index, total) => {
  30781. const data = spinner.fn(duration, index, total);
  30782. data.style['animation-duration'] = duration + 'ms';
  30783. 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 })));
  30784. };
  30785. 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%}";
  30786. var IonSplitPaneIosStyle0 = splitPaneIosCss;
  30787. 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%}";
  30788. var IonSplitPaneMdStyle0 = splitPaneMdCss;
  30789. const QUERY = {
  30790. xs: '(min-width: 0px)',
  30791. sm: '(min-width: 576px)',
  30792. md: '(min-width: 768px)',
  30793. lg: '(min-width: 992px)',
  30794. xl: '(min-width: 1200px)',
  30795. never: '',
  30796. };
  30797. class SplitPane {
  30798. constructor(hostRef) {
  30799. registerInstance(this, hostRef);
  30800. this.ionSplitPaneVisible = createEvent(this, "ionSplitPaneVisible", 7);
  30801. this.visible = false;
  30802. this.contentId = undefined;
  30803. this.disabled = false;
  30804. this.when = QUERY['lg'];
  30805. }
  30806. visibleChanged(visible) {
  30807. this.ionSplitPaneVisible.emit({ visible });
  30808. }
  30809. /**
  30810. * @internal
  30811. */
  30812. async isVisible() {
  30813. return Promise.resolve(this.visible);
  30814. }
  30815. async connectedCallback() {
  30816. // TODO: connectedCallback is fired in CE build
  30817. // before WC is defined. This needs to be fixed in Stencil.
  30818. if (typeof customElements !== 'undefined' && customElements != null) {
  30819. await customElements.whenDefined('ion-split-pane');
  30820. }
  30821. this.styleMainElement();
  30822. this.updateState();
  30823. }
  30824. disconnectedCallback() {
  30825. if (this.rmL) {
  30826. this.rmL();
  30827. this.rmL = undefined;
  30828. }
  30829. }
  30830. updateState() {
  30831. {
  30832. return;
  30833. }
  30834. }
  30835. /**
  30836. * Attempt to find the main content
  30837. * element inside of the split pane.
  30838. * If found, set it as the main node.
  30839. *
  30840. * We assume that the main node
  30841. * is available in the DOM on split
  30842. * pane load.
  30843. */
  30844. styleMainElement() {
  30845. {
  30846. return;
  30847. }
  30848. }
  30849. render() {
  30850. const mode = getIonMode$1(this);
  30851. return (hAsync(Host, { key: '098801b5a318e2fc6913fb0d9079b1552927b99b', class: {
  30852. [mode]: true,
  30853. // Used internally for styling
  30854. [`split-pane-${mode}`]: true,
  30855. 'split-pane-visible': this.visible,
  30856. } }, hAsync("slot", { key: '8cbc6a942ecba54fc3c62027d46917db067b65c8' })));
  30857. }
  30858. get el() { return getElement(this); }
  30859. static get watchers() { return {
  30860. "visible": ["visibleChanged"],
  30861. "disabled": ["updateState"],
  30862. "when": ["updateState"]
  30863. }; }
  30864. static get style() { return {
  30865. ios: IonSplitPaneIosStyle0,
  30866. md: IonSplitPaneMdStyle0
  30867. }; }
  30868. static get cmpMeta() { return {
  30869. "$flags$": 41,
  30870. "$tagName$": "ion-split-pane",
  30871. "$members$": {
  30872. "contentId": [513, "content-id"],
  30873. "disabled": [4],
  30874. "when": [8],
  30875. "visible": [32],
  30876. "isVisible": [64]
  30877. },
  30878. "$listeners$": undefined,
  30879. "$lazyBundleId$": "-",
  30880. "$attrsToReflect$": [["contentId", "content-id"]]
  30881. }; }
  30882. }
  30883. const tabCss = ":host(.tab-hidden){display:none !important}";
  30884. var IonTabStyle0 = tabCss;
  30885. class Tab {
  30886. constructor(hostRef) {
  30887. registerInstance(this, hostRef);
  30888. this.loaded = false;
  30889. this.active = false;
  30890. this.delegate = undefined;
  30891. this.tab = undefined;
  30892. this.component = undefined;
  30893. }
  30894. async componentWillLoad() {
  30895. if (this.active) {
  30896. await this.setActive();
  30897. }
  30898. }
  30899. /** Set the active component for the tab */
  30900. async setActive() {
  30901. await this.prepareLazyLoaded();
  30902. this.active = true;
  30903. }
  30904. changeActive(isActive) {
  30905. if (isActive) {
  30906. this.prepareLazyLoaded();
  30907. }
  30908. }
  30909. prepareLazyLoaded() {
  30910. if (!this.loaded && this.component != null) {
  30911. this.loaded = true;
  30912. try {
  30913. return attachComponent(this.delegate, this.el, this.component, ['ion-page']);
  30914. }
  30915. catch (e) {
  30916. printIonError('[ion-tab] - Exception in prepareLazyLoaded:', e);
  30917. }
  30918. }
  30919. return Promise.resolve(undefined);
  30920. }
  30921. render() {
  30922. const { tab, active, component } = this;
  30923. return (hAsync(Host, { key: 'c36c113e74e12b58459df9e3b546ad4856187e90', role: "tabpanel", "aria-hidden": !active ? 'true' : null, "aria-labelledby": `tab-button-${tab}`, class: {
  30924. 'ion-page': component === undefined,
  30925. 'tab-hidden': !active,
  30926. } }, hAsync("slot", { key: '0d7821dac70ba7a12edfb3331988f3df1566cc1a' })));
  30927. }
  30928. get el() { return getElement(this); }
  30929. static get watchers() { return {
  30930. "active": ["changeActive"]
  30931. }; }
  30932. static get style() { return IonTabStyle0; }
  30933. static get cmpMeta() { return {
  30934. "$flags$": 9,
  30935. "$tagName$": "ion-tab",
  30936. "$members$": {
  30937. "active": [1028],
  30938. "delegate": [16],
  30939. "tab": [1],
  30940. "component": [1],
  30941. "setActive": [64]
  30942. },
  30943. "$listeners$": undefined,
  30944. "$lazyBundleId$": "-",
  30945. "$attrsToReflect$": []
  30946. }; }
  30947. }
  30948. 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)}}";
  30949. var IonTabBarIosStyle0 = tabBarIosCss;
  30950. 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}";
  30951. var IonTabBarMdStyle0 = tabBarMdCss;
  30952. /**
  30953. * @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
  30954. */
  30955. class TabBar {
  30956. constructor(hostRef) {
  30957. registerInstance(this, hostRef);
  30958. this.ionTabBarChanged = createEvent(this, "ionTabBarChanged", 7);
  30959. this.ionTabBarLoaded = createEvent(this, "ionTabBarLoaded", 7);
  30960. this.keyboardCtrl = null;
  30961. this.keyboardVisible = false;
  30962. this.color = undefined;
  30963. this.selectedTab = undefined;
  30964. this.translucent = false;
  30965. }
  30966. selectedTabChanged() {
  30967. if (this.selectedTab !== undefined) {
  30968. this.ionTabBarChanged.emit({
  30969. tab: this.selectedTab,
  30970. });
  30971. }
  30972. }
  30973. componentWillLoad() {
  30974. this.selectedTabChanged();
  30975. }
  30976. async connectedCallback() {
  30977. this.keyboardCtrl = await createKeyboardController(async (keyboardOpen, waitForResize) => {
  30978. /**
  30979. * If the keyboard is hiding, then we need to wait
  30980. * for the webview to resize. Otherwise, the tab bar
  30981. * will flicker before the webview resizes.
  30982. */
  30983. if (keyboardOpen === false && waitForResize !== undefined) {
  30984. await waitForResize;
  30985. }
  30986. this.keyboardVisible = keyboardOpen; // trigger re-render by updating state
  30987. });
  30988. }
  30989. disconnectedCallback() {
  30990. if (this.keyboardCtrl) {
  30991. this.keyboardCtrl.destroy();
  30992. }
  30993. }
  30994. componentDidLoad() {
  30995. this.ionTabBarLoaded.emit();
  30996. }
  30997. render() {
  30998. const { color, translucent, keyboardVisible } = this;
  30999. const mode = getIonMode$1(this);
  31000. const shouldHide = keyboardVisible && this.el.getAttribute('slot') !== 'top';
  31001. return (hAsync(Host, { key: '62303a7f9d8c98ffab51a5900c144c5117b9c543', role: "tablist", "aria-hidden": shouldHide ? 'true' : null, class: createColorClasses$1(color, {
  31002. [mode]: true,
  31003. 'tab-bar-translucent': translucent,
  31004. 'tab-bar-hidden': shouldHide,
  31005. }) }, hAsync("slot", { key: '5771a9828f748c2bd6b5e26758b9723c6b3de5ff' })));
  31006. }
  31007. get el() { return getElement(this); }
  31008. static get watchers() { return {
  31009. "selectedTab": ["selectedTabChanged"]
  31010. }; }
  31011. static get style() { return {
  31012. ios: IonTabBarIosStyle0,
  31013. md: IonTabBarMdStyle0
  31014. }; }
  31015. static get cmpMeta() { return {
  31016. "$flags$": 41,
  31017. "$tagName$": "ion-tab-bar",
  31018. "$members$": {
  31019. "color": [513],
  31020. "selectedTab": [1, "selected-tab"],
  31021. "translucent": [4],
  31022. "keyboardVisible": [32]
  31023. },
  31024. "$listeners$": undefined,
  31025. "$lazyBundleId$": "-",
  31026. "$attrsToReflect$": [["color", "color"]]
  31027. }; }
  31028. }
  31029. 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}";
  31030. var IonTabButtonIosStyle0 = tabButtonIosCss;
  31031. 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}";
  31032. var IonTabButtonMdStyle0 = tabButtonMdCss;
  31033. /**
  31034. * @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
  31035. *
  31036. * @part native - The native HTML anchor element that wraps all child elements.
  31037. */
  31038. class TabButton {
  31039. constructor(hostRef) {
  31040. registerInstance(this, hostRef);
  31041. this.ionTabButtonClick = createEvent(this, "ionTabButtonClick", 7);
  31042. this.inheritedAttributes = {};
  31043. this.onKeyUp = (ev) => {
  31044. if (ev.key === 'Enter' || ev.key === ' ') {
  31045. this.selectTab(ev);
  31046. }
  31047. };
  31048. this.onClick = (ev) => {
  31049. this.selectTab(ev);
  31050. };
  31051. this.disabled = false;
  31052. this.download = undefined;
  31053. this.href = undefined;
  31054. this.rel = undefined;
  31055. this.layout = undefined;
  31056. this.selected = false;
  31057. this.tab = undefined;
  31058. this.target = undefined;
  31059. }
  31060. onTabBarChanged(ev) {
  31061. const dispatchedFrom = ev.target;
  31062. const parent = this.el.parentElement;
  31063. if (ev.composedPath().includes(parent) || (dispatchedFrom === null || dispatchedFrom === void 0 ? void 0 : dispatchedFrom.contains(this.el))) {
  31064. this.selected = this.tab === ev.detail.tab;
  31065. }
  31066. }
  31067. componentWillLoad() {
  31068. this.inheritedAttributes = Object.assign({}, inheritAttributes$1(this.el, ['aria-label']));
  31069. if (this.layout === undefined) {
  31070. this.layout = config.get('tabButtonLayout', 'icon-top');
  31071. }
  31072. }
  31073. selectTab(ev) {
  31074. if (this.tab !== undefined) {
  31075. if (!this.disabled) {
  31076. this.ionTabButtonClick.emit({
  31077. tab: this.tab,
  31078. href: this.href,
  31079. selected: this.selected,
  31080. });
  31081. }
  31082. ev.preventDefault();
  31083. }
  31084. }
  31085. get hasLabel() {
  31086. return !!this.el.querySelector('ion-label');
  31087. }
  31088. get hasIcon() {
  31089. return !!this.el.querySelector('ion-icon');
  31090. }
  31091. render() {
  31092. const { disabled, hasIcon, hasLabel, href, rel, target, layout, selected, tab, inheritedAttributes } = this;
  31093. const mode = getIonMode$1(this);
  31094. const attrs = {
  31095. download: this.download,
  31096. href,
  31097. rel,
  31098. target,
  31099. };
  31100. return (hAsync(Host, { key: 'a86d441d8df350fe991f2f948fc6b6ad007728f7', onClick: this.onClick, onKeyup: this.onKeyUp, id: tab !== undefined ? `tab-button-${tab}` : null, class: {
  31101. [mode]: true,
  31102. 'tab-selected': selected,
  31103. 'tab-disabled': disabled,
  31104. 'tab-has-label': hasLabel,
  31105. 'tab-has-icon': hasIcon,
  31106. 'tab-has-label-only': hasLabel && !hasIcon,
  31107. 'tab-has-icon-only': hasIcon && !hasLabel,
  31108. [`tab-layout-${layout}`]: true,
  31109. 'ion-activatable': true,
  31110. 'ion-selectable': true,
  31111. 'ion-focusable': true,
  31112. } }, 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" }))));
  31113. }
  31114. get el() { return getElement(this); }
  31115. static get style() { return {
  31116. ios: IonTabButtonIosStyle0,
  31117. md: IonTabButtonMdStyle0
  31118. }; }
  31119. static get cmpMeta() { return {
  31120. "$flags$": 41,
  31121. "$tagName$": "ion-tab-button",
  31122. "$members$": {
  31123. "disabled": [4],
  31124. "download": [1],
  31125. "href": [1],
  31126. "rel": [1],
  31127. "layout": [1025],
  31128. "selected": [1028],
  31129. "tab": [1],
  31130. "target": [1]
  31131. },
  31132. "$listeners$": [[8, "ionTabBarChanged", "onTabBarChanged"]],
  31133. "$lazyBundleId$": "-",
  31134. "$attrsToReflect$": []
  31135. }; }
  31136. }
  31137. 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}";
  31138. var IonTabsStyle0 = tabsCss;
  31139. /**
  31140. * @slot - Content is placed between the named slots if provided without a slot.
  31141. * @slot top - Content is placed at the top of the screen.
  31142. * @slot bottom - Content is placed at the bottom of the screen.
  31143. */
  31144. class Tabs {
  31145. constructor(hostRef) {
  31146. registerInstance(this, hostRef);
  31147. this.ionNavWillLoad = createEvent(this, "ionNavWillLoad", 7);
  31148. this.ionTabsWillChange = createEvent(this, "ionTabsWillChange", 3);
  31149. this.ionTabsDidChange = createEvent(this, "ionTabsDidChange", 3);
  31150. this.transitioning = false;
  31151. this.onTabClicked = (ev) => {
  31152. const { href, tab } = ev.detail;
  31153. if (this.useRouter && href !== undefined) {
  31154. const router = document.querySelector('ion-router');
  31155. if (router) {
  31156. router.push(href);
  31157. }
  31158. }
  31159. else {
  31160. this.select(tab);
  31161. }
  31162. };
  31163. this.selectedTab = undefined;
  31164. this.useRouter = false;
  31165. }
  31166. async componentWillLoad() {
  31167. if (!this.useRouter) {
  31168. /**
  31169. * JavaScript and StencilJS use `ion-router`, while
  31170. * the other frameworks use `ion-router-outlet`.
  31171. *
  31172. * If either component is present then tabs will not use
  31173. * a basic tab-based navigation. It will use the history
  31174. * stack or URL updates associated with the router.
  31175. */
  31176. this.useRouter =
  31177. (!!this.el.querySelector('ion-router-outlet') || !!document.querySelector('ion-router')) &&
  31178. !this.el.closest('[no-router]');
  31179. }
  31180. if (!this.useRouter) {
  31181. const tabs = this.tabs;
  31182. if (tabs.length > 0) {
  31183. await this.select(tabs[0]);
  31184. }
  31185. }
  31186. this.ionNavWillLoad.emit();
  31187. }
  31188. componentWillRender() {
  31189. const tabBar = this.el.querySelector('ion-tab-bar');
  31190. if (tabBar) {
  31191. const tab = this.selectedTab ? this.selectedTab.tab : undefined;
  31192. tabBar.selectedTab = tab;
  31193. }
  31194. }
  31195. /**
  31196. * 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.
  31197. *
  31198. * @param tab The tab instance to select. If passed a string, it should be the value of the tab's `tab` property.
  31199. */
  31200. async select(tab) {
  31201. const selectedTab = getTab(this.tabs, tab);
  31202. if (!this.shouldSwitch(selectedTab)) {
  31203. return false;
  31204. }
  31205. await this.setActive(selectedTab);
  31206. await this.notifyRouter();
  31207. this.tabSwitch();
  31208. return true;
  31209. }
  31210. /**
  31211. * 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.
  31212. *
  31213. * @param tab The tab instance to select. If passed a string, it should be the value of the tab's `tab` property.
  31214. */
  31215. async getTab(tab) {
  31216. return getTab(this.tabs, tab);
  31217. }
  31218. /**
  31219. * 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.
  31220. */
  31221. getSelected() {
  31222. return Promise.resolve(this.selectedTab ? this.selectedTab.tab : undefined);
  31223. }
  31224. /** @internal */
  31225. async setRouteId(id) {
  31226. const selectedTab = getTab(this.tabs, id);
  31227. if (!this.shouldSwitch(selectedTab)) {
  31228. return { changed: false, element: this.selectedTab };
  31229. }
  31230. await this.setActive(selectedTab);
  31231. return {
  31232. changed: true,
  31233. element: this.selectedTab,
  31234. markVisible: () => this.tabSwitch(),
  31235. };
  31236. }
  31237. /** @internal */
  31238. async getRouteId() {
  31239. var _a;
  31240. const tabId = (_a = this.selectedTab) === null || _a === void 0 ? void 0 : _a.tab;
  31241. return tabId !== undefined ? { id: tabId, element: this.selectedTab } : undefined;
  31242. }
  31243. setActive(selectedTab) {
  31244. if (this.transitioning) {
  31245. return Promise.reject('transitioning already happening');
  31246. }
  31247. this.transitioning = true;
  31248. this.leavingTab = this.selectedTab;
  31249. this.selectedTab = selectedTab;
  31250. this.ionTabsWillChange.emit({ tab: selectedTab.tab });
  31251. selectedTab.active = true;
  31252. return Promise.resolve();
  31253. }
  31254. tabSwitch() {
  31255. const selectedTab = this.selectedTab;
  31256. const leavingTab = this.leavingTab;
  31257. this.leavingTab = undefined;
  31258. this.transitioning = false;
  31259. if (!selectedTab) {
  31260. return;
  31261. }
  31262. if (leavingTab !== selectedTab) {
  31263. if (leavingTab) {
  31264. leavingTab.active = false;
  31265. }
  31266. this.ionTabsDidChange.emit({ tab: selectedTab.tab });
  31267. }
  31268. }
  31269. notifyRouter() {
  31270. if (this.useRouter) {
  31271. const router = document.querySelector('ion-router');
  31272. if (router) {
  31273. return router.navChanged('forward');
  31274. }
  31275. }
  31276. return Promise.resolve(false);
  31277. }
  31278. shouldSwitch(selectedTab) {
  31279. const leavingTab = this.selectedTab;
  31280. return selectedTab !== undefined && selectedTab !== leavingTab && !this.transitioning;
  31281. }
  31282. get tabs() {
  31283. return Array.from(this.el.querySelectorAll('ion-tab'));
  31284. }
  31285. render() {
  31286. 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" })));
  31287. }
  31288. get el() { return getElement(this); }
  31289. static get style() { return IonTabsStyle0; }
  31290. static get cmpMeta() { return {
  31291. "$flags$": 9,
  31292. "$tagName$": "ion-tabs",
  31293. "$members$": {
  31294. "useRouter": [1028, "use-router"],
  31295. "selectedTab": [32],
  31296. "select": [64],
  31297. "getTab": [64],
  31298. "getSelected": [64],
  31299. "setRouteId": [64],
  31300. "getRouteId": [64]
  31301. },
  31302. "$listeners$": undefined,
  31303. "$lazyBundleId$": "-",
  31304. "$attrsToReflect$": []
  31305. }; }
  31306. }
  31307. const getTab = (tabs, tab) => {
  31308. const tabEl = typeof tab === 'string' ? tabs.find((t) => t.tab === tab) : tab;
  31309. if (!tabEl) {
  31310. printIonError(`[ion-tabs] - Tab with id: "${tabEl}" does not exist`);
  31311. }
  31312. return tabEl;
  31313. };
  31314. const textCss = ":host(.ion-color){color:var(--ion-color-base)}";
  31315. var IonTextStyle0 = textCss;
  31316. /**
  31317. * @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
  31318. */
  31319. class Text {
  31320. constructor(hostRef) {
  31321. registerInstance(this, hostRef);
  31322. this.color = undefined;
  31323. }
  31324. render() {
  31325. const mode = getIonMode$1(this);
  31326. return (hAsync(Host, { key: '0c2546ea3f24b0a6bfd606199441d0a4edfa4ca1', class: createColorClasses$1(this.color, {
  31327. [mode]: true,
  31328. }) }, hAsync("slot", { key: 'b7623ccb06f9461090a1f33e9f85886c7a4d5eff' })));
  31329. }
  31330. static get style() { return IonTextStyle0; }
  31331. static get cmpMeta() { return {
  31332. "$flags$": 9,
  31333. "$tagName$": "ion-text",
  31334. "$members$": {
  31335. "color": [513]
  31336. },
  31337. "$listeners$": undefined,
  31338. "$lazyBundleId$": "-",
  31339. "$attrsToReflect$": [["color", "color"]]
  31340. }; }
  31341. }
  31342. 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}";
  31343. var IonTextareaIosStyle0 = textareaIosCss;
  31344. 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}";
  31345. var IonTextareaMdStyle0 = textareaMdCss;
  31346. /**
  31347. * @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
  31348. *
  31349. * @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)
  31350. * @slot start - Content to display at the leading edge of the textarea. (EXPERIMENTAL)
  31351. * @slot end - Content to display at the trailing edge of the textarea. (EXPERIMENTAL)
  31352. */
  31353. class Textarea {
  31354. constructor(hostRef) {
  31355. registerInstance(this, hostRef);
  31356. this.ionChange = createEvent(this, "ionChange", 7);
  31357. this.ionInput = createEvent(this, "ionInput", 7);
  31358. this.ionBlur = createEvent(this, "ionBlur", 7);
  31359. this.ionFocus = createEvent(this, "ionFocus", 7);
  31360. this.inputId = `ion-textarea-${textareaIds++}`;
  31361. this.helperTextId = `${this.inputId}-helper-text`;
  31362. this.errorTextId = `${this.inputId}-error-text`;
  31363. /**
  31364. * `true` if the textarea was cleared as a result of the user typing
  31365. * with `clearOnEdit` enabled.
  31366. *
  31367. * Resets when the textarea loses focus.
  31368. */
  31369. this.didTextareaClearOnEdit = false;
  31370. this.inheritedAttributes = {};
  31371. // `Event` type is used instead of `InputEvent`
  31372. // since the types from Stencil are not derived
  31373. // from the element (e.g. textarea and input
  31374. // should be InputEvent, but all other elements
  31375. // should be Event).
  31376. this.onInput = (ev) => {
  31377. const input = ev.target;
  31378. if (input) {
  31379. this.value = input.value || '';
  31380. }
  31381. this.emitInputChange(ev);
  31382. };
  31383. this.onChange = (ev) => {
  31384. this.emitValueChange(ev);
  31385. };
  31386. this.onFocus = (ev) => {
  31387. this.hasFocus = true;
  31388. this.focusedValue = this.value;
  31389. this.ionFocus.emit(ev);
  31390. };
  31391. this.onBlur = (ev) => {
  31392. this.hasFocus = false;
  31393. if (this.focusedValue !== this.value) {
  31394. /**
  31395. * Emits the `ionChange` event when the textarea value
  31396. * is different than the value when the textarea was focused.
  31397. */
  31398. this.emitValueChange(ev);
  31399. }
  31400. this.didTextareaClearOnEdit = false;
  31401. this.ionBlur.emit(ev);
  31402. };
  31403. this.onKeyDown = (ev) => {
  31404. this.checkClearOnEdit(ev);
  31405. };
  31406. /**
  31407. * Stops propagation when the label is clicked,
  31408. * otherwise, two clicks will be triggered.
  31409. */
  31410. this.onLabelClick = (ev) => {
  31411. // Only stop propagation if the click was directly on the label
  31412. // and not on the input or other child elements
  31413. if (ev.target === ev.currentTarget) {
  31414. ev.stopPropagation();
  31415. }
  31416. };
  31417. this.hasFocus = false;
  31418. this.color = undefined;
  31419. this.autocapitalize = 'none';
  31420. this.autofocus = false;
  31421. this.clearOnEdit = false;
  31422. this.debounce = undefined;
  31423. this.disabled = false;
  31424. this.fill = undefined;
  31425. this.inputmode = undefined;
  31426. this.enterkeyhint = undefined;
  31427. this.maxlength = undefined;
  31428. this.minlength = undefined;
  31429. this.name = this.inputId;
  31430. this.placeholder = undefined;
  31431. this.readonly = false;
  31432. this.required = false;
  31433. this.spellcheck = false;
  31434. this.cols = undefined;
  31435. this.rows = undefined;
  31436. this.wrap = undefined;
  31437. this.autoGrow = false;
  31438. this.value = '';
  31439. this.counter = false;
  31440. this.counterFormatter = undefined;
  31441. this.errorText = undefined;
  31442. this.helperText = undefined;
  31443. this.label = undefined;
  31444. this.labelPlacement = 'start';
  31445. this.shape = undefined;
  31446. }
  31447. debounceChanged() {
  31448. const { ionInput, debounce, originalIonInput } = this;
  31449. /**
  31450. * If debounce is undefined, we have to manually revert the ionInput emitter in case
  31451. * debounce used to be set to a number. Otherwise, the event would stay debounced.
  31452. */
  31453. this.ionInput = debounce === undefined ? originalIonInput !== null && originalIonInput !== void 0 ? originalIonInput : ionInput : debounceEvent(ionInput, debounce);
  31454. }
  31455. /**
  31456. * Update the native input element when the value changes
  31457. */
  31458. valueChanged() {
  31459. const nativeInput = this.nativeInput;
  31460. const value = this.getValue();
  31461. if (nativeInput && nativeInput.value !== value) {
  31462. nativeInput.value = value;
  31463. }
  31464. this.runAutoGrow();
  31465. }
  31466. /**
  31467. * dir is a globally enumerated attribute.
  31468. * As a result, creating these as properties
  31469. * can have unintended side effects. Instead, we
  31470. * listen for attribute changes and inherit them
  31471. * to the inner `<textarea>` element.
  31472. */
  31473. onDirChanged(newValue) {
  31474. this.inheritedAttributes = Object.assign(Object.assign({}, this.inheritedAttributes), { dir: newValue });
  31475. }
  31476. /**
  31477. * This prevents the native input from emitting the click event.
  31478. * Instead, the click event from the ion-textarea is emitted.
  31479. */
  31480. onClickCapture(ev) {
  31481. const nativeInput = this.nativeInput;
  31482. if (nativeInput && ev.target === nativeInput) {
  31483. ev.stopPropagation();
  31484. this.el.click();
  31485. }
  31486. }
  31487. connectedCallback() {
  31488. const { el } = this;
  31489. this.slotMutationController = createSlotMutationController(el, ['label', 'start', 'end'], () => forceUpdate());
  31490. this.notchController = createNotchController(el, () => this.notchSpacerEl, () => this.labelSlot);
  31491. this.debounceChanged();
  31492. }
  31493. disconnectedCallback() {
  31494. if (this.slotMutationController) {
  31495. this.slotMutationController.destroy();
  31496. this.slotMutationController = undefined;
  31497. }
  31498. if (this.notchController) {
  31499. this.notchController.destroy();
  31500. this.notchController = undefined;
  31501. }
  31502. }
  31503. componentWillLoad() {
  31504. this.inheritedAttributes = Object.assign(Object.assign({}, inheritAriaAttributes(this.el)), inheritAttributes$1(this.el, ['data-form-type', 'title', 'tabindex', 'dir']));
  31505. }
  31506. componentDidLoad() {
  31507. this.originalIonInput = this.ionInput;
  31508. this.runAutoGrow();
  31509. }
  31510. componentDidRender() {
  31511. var _a;
  31512. (_a = this.notchController) === null || _a === void 0 ? void 0 : _a.calculateNotchWidth();
  31513. }
  31514. /**
  31515. * Sets focus on the native `textarea` in `ion-textarea`. Use this method instead of the global
  31516. * `textarea.focus()`.
  31517. *
  31518. * See [managing focus](/docs/developing/managing-focus) for more information.
  31519. */
  31520. async setFocus() {
  31521. if (this.nativeInput) {
  31522. this.nativeInput.focus();
  31523. }
  31524. }
  31525. /**
  31526. * Returns the native `<textarea>` element used under the hood.
  31527. */
  31528. async getInputElement() {
  31529. /**
  31530. * If this gets called in certain early lifecycle hooks (ex: Vue onMounted),
  31531. * nativeInput won't be defined yet with the custom elements build, so wait for it to load in.
  31532. */
  31533. if (!this.nativeInput) {
  31534. await new Promise((resolve) => componentOnReady(this.el, resolve));
  31535. }
  31536. return Promise.resolve(this.nativeInput);
  31537. }
  31538. /**
  31539. * Emits an `ionChange` event.
  31540. *
  31541. * This API should be called for user committed changes.
  31542. * This API should not be used for external value changes.
  31543. */
  31544. emitValueChange(event) {
  31545. const { value } = this;
  31546. // Checks for both null and undefined values
  31547. const newValue = value == null ? value : value.toString();
  31548. // Emitting a value change should update the internal state for tracking the focused value
  31549. this.focusedValue = newValue;
  31550. this.ionChange.emit({ value: newValue, event });
  31551. }
  31552. /**
  31553. * Emits an `ionInput` event.
  31554. */
  31555. emitInputChange(event) {
  31556. const { value } = this;
  31557. this.ionInput.emit({ value, event });
  31558. }
  31559. runAutoGrow() {
  31560. if (this.nativeInput && this.autoGrow) {
  31561. writeTask(() => {
  31562. var _a;
  31563. if (this.textareaWrapper) {
  31564. // Replicated value is an attribute to be used in the stylesheet
  31565. // to set the inner contents of a pseudo element.
  31566. this.textareaWrapper.dataset.replicatedValue = (_a = this.value) !== null && _a !== void 0 ? _a : '';
  31567. }
  31568. });
  31569. }
  31570. }
  31571. /**
  31572. * Check if we need to clear the text input if clearOnEdit is enabled
  31573. */
  31574. checkClearOnEdit(ev) {
  31575. if (!this.clearOnEdit) {
  31576. return;
  31577. }
  31578. /**
  31579. * The following keys do not modify the
  31580. * contents of the input. As a result, pressing
  31581. * them should not edit the textarea.
  31582. *
  31583. * We can't check to see if the value of the textarea
  31584. * was changed because we call checkClearOnEdit
  31585. * in a keydown listener, and the key has not yet
  31586. * been added to the textarea.
  31587. *
  31588. * Unlike ion-input, the "Enter" key does modify the
  31589. * textarea by adding a new line, so "Enter" is not
  31590. * included in the IGNORED_KEYS array.
  31591. */
  31592. const IGNORED_KEYS = ['Tab', 'Shift', 'Meta', 'Alt', 'Control'];
  31593. const pressedIgnoredKey = IGNORED_KEYS.includes(ev.key);
  31594. /**
  31595. * Clear the textarea if the control has not been previously cleared
  31596. * during focus.
  31597. */
  31598. if (!this.didTextareaClearOnEdit && this.hasValue() && !pressedIgnoredKey) {
  31599. this.value = '';
  31600. this.emitInputChange(ev);
  31601. }
  31602. /**
  31603. * Pressing an IGNORED_KEYS first and
  31604. * then an allowed key will cause the input to not
  31605. * be cleared.
  31606. */
  31607. if (!pressedIgnoredKey) {
  31608. this.didTextareaClearOnEdit = true;
  31609. }
  31610. }
  31611. hasValue() {
  31612. return this.getValue() !== '';
  31613. }
  31614. getValue() {
  31615. return this.value || '';
  31616. }
  31617. renderLabel() {
  31618. const { label } = this;
  31619. return (hAsync("div", { class: {
  31620. 'label-text-wrapper': true,
  31621. 'label-text-wrapper-hidden': !this.hasLabel,
  31622. } }, label === undefined ? hAsync("slot", { name: "label" }) : hAsync("div", { class: "label-text" }, label)));
  31623. }
  31624. /**
  31625. * Gets any content passed into the `label` slot,
  31626. * not the <slot> definition.
  31627. */
  31628. get labelSlot() {
  31629. return this.el.querySelector('[slot="label"]');
  31630. }
  31631. /**
  31632. * Returns `true` if label content is provided
  31633. * either by a prop or a content. If you want
  31634. * to get the plaintext value of the label use
  31635. * the `labelText` getter instead.
  31636. */
  31637. get hasLabel() {
  31638. return this.label !== undefined || this.labelSlot !== null;
  31639. }
  31640. /**
  31641. * Renders the border container when fill="outline".
  31642. */
  31643. renderLabelContainer() {
  31644. const mode = getIonMode$1(this);
  31645. const hasOutlineFill = mode === 'md' && this.fill === 'outline';
  31646. if (hasOutlineFill) {
  31647. /**
  31648. * The outline fill has a special outline
  31649. * that appears around the textarea and the label.
  31650. * Certain stacked and floating label placements cause the
  31651. * label to translate up and create a "cut out"
  31652. * inside of that border by using the notch-spacer element.
  31653. */
  31654. return [
  31655. hAsync("div", { class: "textarea-outline-container" }, hAsync("div", { class: "textarea-outline-start" }), hAsync("div", { class: {
  31656. 'textarea-outline-notch': true,
  31657. 'textarea-outline-notch-hidden': !this.hasLabel,
  31658. } }, hAsync("div", { class: "notch-spacer", "aria-hidden": "true", ref: (el) => (this.notchSpacerEl = el) }, this.label)), hAsync("div", { class: "textarea-outline-end" })),
  31659. this.renderLabel(),
  31660. ];
  31661. }
  31662. /**
  31663. * If not using the outline style,
  31664. * we can render just the label.
  31665. */
  31666. return this.renderLabel();
  31667. }
  31668. /**
  31669. * Renders the helper text or error text values
  31670. */
  31671. renderHintText() {
  31672. const { helperText, errorText, helperTextId, errorTextId } = this;
  31673. return [
  31674. hAsync("div", { id: helperTextId, class: "helper-text" }, helperText),
  31675. hAsync("div", { id: errorTextId, class: "error-text" }, errorText),
  31676. ];
  31677. }
  31678. getHintTextID() {
  31679. const { el, helperText, errorText, helperTextId, errorTextId } = this;
  31680. if (el.classList.contains('ion-touched') && el.classList.contains('ion-invalid') && errorText) {
  31681. return errorTextId;
  31682. }
  31683. if (helperText) {
  31684. return helperTextId;
  31685. }
  31686. return undefined;
  31687. }
  31688. renderCounter() {
  31689. const { counter, maxlength, counterFormatter, value } = this;
  31690. if (counter !== true || maxlength === undefined) {
  31691. return;
  31692. }
  31693. return hAsync("div", { class: "counter" }, getCounterText(value, maxlength, counterFormatter));
  31694. }
  31695. /**
  31696. * Responsible for rendering helper text,
  31697. * error text, and counter. This element should only
  31698. * be rendered if hint text is set or counter is enabled.
  31699. */
  31700. renderBottomContent() {
  31701. const { counter, helperText, errorText, maxlength } = this;
  31702. /**
  31703. * undefined and empty string values should
  31704. * be treated as not having helper/error text.
  31705. */
  31706. const hasHintText = !!helperText || !!errorText;
  31707. const hasCounter = counter === true && maxlength !== undefined;
  31708. if (!hasHintText && !hasCounter) {
  31709. return;
  31710. }
  31711. return (hAsync("div", { class: "textarea-bottom" }, this.renderHintText(), this.renderCounter()));
  31712. }
  31713. render() {
  31714. const { inputId, disabled, fill, shape, labelPlacement, el, hasFocus } = this;
  31715. const mode = getIonMode$1(this);
  31716. const value = this.getValue();
  31717. const inItem = hostContext('ion-item', this.el);
  31718. const shouldRenderHighlight = mode === 'md' && fill !== 'outline' && !inItem;
  31719. const hasValue = this.hasValue();
  31720. const hasStartEndSlots = el.querySelector('[slot="start"], [slot="end"]') !== null;
  31721. /**
  31722. * If the label is stacked, it should always sit above the textarea.
  31723. * For floating labels, the label should move above the textarea if
  31724. * the textarea has a value, is focused, or has anything in either
  31725. * the start or end slot.
  31726. *
  31727. * If there is content in the start slot, the label would overlap
  31728. * it if not forced to float. This is also applied to the end slot
  31729. * because with the default or solid fills, the textarea is not
  31730. * vertically centered in the container, but the label is. This
  31731. * causes the slots and label to appear vertically offset from each
  31732. * other when the label isn't floating above the input. This doesn't
  31733. * apply to the outline fill, but this was not accounted for to keep
  31734. * things consistent.
  31735. *
  31736. * TODO(FW-5592): Remove hasStartEndSlots condition
  31737. */
  31738. const labelShouldFloat = labelPlacement === 'stacked' || (labelPlacement === 'floating' && (hasValue || hasFocus || hasStartEndSlots));
  31739. return (hAsync(Host, { key: '7eb390b79de0d671a785bbb783f97e09169472f9', class: createColorClasses$1(this.color, {
  31740. [mode]: true,
  31741. 'has-value': hasValue,
  31742. 'has-focus': hasFocus,
  31743. 'label-floating': labelShouldFloat,
  31744. [`textarea-fill-${fill}`]: fill !== undefined,
  31745. [`textarea-shape-${shape}`]: shape !== undefined,
  31746. [`textarea-label-placement-${labelPlacement}`]: true,
  31747. 'textarea-disabled': disabled,
  31748. }) }, 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()));
  31749. }
  31750. get el() { return getElement(this); }
  31751. static get watchers() { return {
  31752. "debounce": ["debounceChanged"],
  31753. "value": ["valueChanged"],
  31754. "dir": ["onDirChanged"]
  31755. }; }
  31756. static get style() { return {
  31757. ios: IonTextareaIosStyle0,
  31758. md: IonTextareaMdStyle0
  31759. }; }
  31760. static get cmpMeta() { return {
  31761. "$flags$": 38,
  31762. "$tagName$": "ion-textarea",
  31763. "$members$": {
  31764. "color": [513],
  31765. "autocapitalize": [1],
  31766. "autofocus": [4],
  31767. "clearOnEdit": [4, "clear-on-edit"],
  31768. "debounce": [2],
  31769. "disabled": [4],
  31770. "fill": [1],
  31771. "inputmode": [1],
  31772. "enterkeyhint": [1],
  31773. "maxlength": [2],
  31774. "minlength": [2],
  31775. "name": [1],
  31776. "placeholder": [1],
  31777. "readonly": [4],
  31778. "required": [4],
  31779. "spellcheck": [4],
  31780. "cols": [514],
  31781. "rows": [2],
  31782. "wrap": [1],
  31783. "autoGrow": [516, "auto-grow"],
  31784. "value": [1025],
  31785. "counter": [4],
  31786. "counterFormatter": [16],
  31787. "errorText": [1, "error-text"],
  31788. "helperText": [1, "helper-text"],
  31789. "label": [1],
  31790. "labelPlacement": [1, "label-placement"],
  31791. "shape": [1],
  31792. "hasFocus": [32],
  31793. "setFocus": [64],
  31794. "getInputElement": [64]
  31795. },
  31796. "$listeners$": [[2, "click", "onClickCapture"]],
  31797. "$lazyBundleId$": "-",
  31798. "$attrsToReflect$": [["color", "color"], ["cols", "cols"], ["autoGrow", "auto-grow"]]
  31799. }; }
  31800. }
  31801. let textareaIds = 0;
  31802. 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}";
  31803. var IonThumbnailStyle0 = thumbnailCss;
  31804. class Thumbnail {
  31805. constructor(hostRef) {
  31806. registerInstance(this, hostRef);
  31807. }
  31808. render() {
  31809. return (hAsync(Host, { key: '7f5fd6c056da2d82feb2c3c33f3e6dec898787f5', class: getIonMode$1(this) }, hAsync("slot", { key: 'd15fd2b6cdc03777edc1930be95ad838e1b376c8' })));
  31810. }
  31811. static get style() { return IonThumbnailStyle0; }
  31812. static get cmpMeta() { return {
  31813. "$flags$": 9,
  31814. "$tagName$": "ion-thumbnail",
  31815. "$members$": undefined,
  31816. "$listeners$": undefined,
  31817. "$lazyBundleId$": "-",
  31818. "$attrsToReflect$": []
  31819. }; }
  31820. }
  31821. /**
  31822. * Calculate the CSS top and bottom position of the toast, to be used
  31823. * as starting points for the animation keyframes.
  31824. *
  31825. * The default animations for both MD and iOS
  31826. * use translateY, which calculates from the
  31827. * top edge of the screen. This behavior impacts
  31828. * how we compute the offset when a toast has
  31829. * position='bottom' since we need to calculate from
  31830. * the bottom edge of the screen instead.
  31831. *
  31832. * @param position The value of the toast's position prop.
  31833. * @param positionAnchor The element the toast should be anchored to,
  31834. * if applicable.
  31835. * @param mode The toast component's mode (md, ios, etc).
  31836. * @param toast A reference to the toast element itself.
  31837. */
  31838. function getAnimationPosition(position, positionAnchor, mode, toast) {
  31839. /**
  31840. * Start with a predefined offset from the edge the toast will be
  31841. * positioned relative to, whether on the screen or anchor element.
  31842. */
  31843. let offset;
  31844. if (mode === 'md') {
  31845. offset = position === 'top' ? 8 : -8;
  31846. }
  31847. else {
  31848. offset = position === 'top' ? 10 : -10;
  31849. }
  31850. /**
  31851. * If positionAnchor is defined, add in the distance from the target
  31852. * screen edge to the target anchor edge. For position="top", the
  31853. * bottom anchor edge is targeted. For position="bottom", the top
  31854. * anchor edge is targeted.
  31855. */
  31856. if (positionAnchor && win$1) {
  31857. warnIfAnchorIsHidden(positionAnchor, toast);
  31858. const box = positionAnchor.getBoundingClientRect();
  31859. if (position === 'top') {
  31860. offset += box.bottom;
  31861. }
  31862. else if (position === 'bottom') {
  31863. /**
  31864. * Just box.top is the distance from the top edge of the screen
  31865. * to the top edge of the anchor. We want to calculate from the
  31866. * bottom edge of the screen instead.
  31867. */
  31868. offset -= win$1.innerHeight - box.top;
  31869. }
  31870. /**
  31871. * We don't include safe area here because that should already be
  31872. * accounted for when checking the position of the anchor.
  31873. */
  31874. return {
  31875. top: `${offset}px`,
  31876. bottom: `${offset}px`,
  31877. };
  31878. }
  31879. else {
  31880. return {
  31881. top: `calc(${offset}px + var(--ion-safe-area-top, 0px))`,
  31882. bottom: `calc(${offset}px - var(--ion-safe-area-bottom, 0px))`,
  31883. };
  31884. }
  31885. }
  31886. /**
  31887. * If the anchor element is hidden, getBoundingClientRect()
  31888. * will return all 0s for it, which can cause unexpected
  31889. * results in the position calculation when animating.
  31890. */
  31891. function warnIfAnchorIsHidden(positionAnchor, toast) {
  31892. if (positionAnchor.offsetParent === null) {
  31893. 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);
  31894. }
  31895. }
  31896. /**
  31897. * Returns the top offset required to place
  31898. * the toast in the middle of the screen.
  31899. * Only needed when position="toast".
  31900. * @param toastHeight - The height of the ion-toast element
  31901. * @param wrapperHeight - The height of the .toast-wrapper element
  31902. * inside the toast's shadow root.
  31903. */
  31904. const getOffsetForMiddlePosition = (toastHeight, wrapperHeight) => {
  31905. return Math.floor(toastHeight / 2 - wrapperHeight / 2);
  31906. };
  31907. /**
  31908. * iOS Toast Enter Animation
  31909. */
  31910. const iosEnterAnimation = (baseEl, opts) => {
  31911. const baseAnimation = createAnimation();
  31912. const wrapperAnimation = createAnimation();
  31913. const { position, top, bottom } = opts;
  31914. const root = getElementRoot(baseEl);
  31915. const wrapperEl = root.querySelector('.toast-wrapper');
  31916. wrapperAnimation.addElement(wrapperEl);
  31917. switch (position) {
  31918. case 'top':
  31919. wrapperAnimation.fromTo('transform', 'translateY(-100%)', `translateY(${top})`);
  31920. break;
  31921. case 'middle':
  31922. const topPosition = getOffsetForMiddlePosition(baseEl.clientHeight, wrapperEl.clientHeight);
  31923. wrapperEl.style.top = `${topPosition}px`;
  31924. wrapperAnimation.fromTo('opacity', 0.01, 1);
  31925. break;
  31926. default:
  31927. wrapperAnimation.fromTo('transform', 'translateY(100%)', `translateY(${bottom})`);
  31928. break;
  31929. }
  31930. return baseAnimation.easing('cubic-bezier(.155,1.105,.295,1.12)').duration(400).addAnimation(wrapperAnimation);
  31931. };
  31932. /**
  31933. * iOS Toast Leave Animation
  31934. */
  31935. const iosLeaveAnimation = (baseEl, opts) => {
  31936. const baseAnimation = createAnimation();
  31937. const wrapperAnimation = createAnimation();
  31938. const { position, top, bottom } = opts;
  31939. const root = getElementRoot(baseEl);
  31940. const wrapperEl = root.querySelector('.toast-wrapper');
  31941. wrapperAnimation.addElement(wrapperEl);
  31942. switch (position) {
  31943. case 'top':
  31944. wrapperAnimation.fromTo('transform', `translateY(${top})`, 'translateY(-100%)');
  31945. break;
  31946. case 'middle':
  31947. wrapperAnimation.fromTo('opacity', 0.99, 0);
  31948. break;
  31949. default:
  31950. wrapperAnimation.fromTo('transform', `translateY(${bottom})`, 'translateY(100%)');
  31951. break;
  31952. }
  31953. return baseAnimation.easing('cubic-bezier(.36,.66,.04,1)').duration(300).addAnimation(wrapperAnimation);
  31954. };
  31955. /**
  31956. * MD Toast Enter Animation
  31957. */
  31958. const mdEnterAnimation = (baseEl, opts) => {
  31959. const baseAnimation = createAnimation();
  31960. const wrapperAnimation = createAnimation();
  31961. const { position, top, bottom } = opts;
  31962. const root = getElementRoot(baseEl);
  31963. const wrapperEl = root.querySelector('.toast-wrapper');
  31964. wrapperAnimation.addElement(wrapperEl);
  31965. switch (position) {
  31966. case 'top':
  31967. wrapperEl.style.setProperty('transform', `translateY(${top})`);
  31968. wrapperAnimation.fromTo('opacity', 0.01, 1);
  31969. break;
  31970. case 'middle':
  31971. const topPosition = getOffsetForMiddlePosition(baseEl.clientHeight, wrapperEl.clientHeight);
  31972. wrapperEl.style.top = `${topPosition}px`;
  31973. wrapperAnimation.fromTo('opacity', 0.01, 1);
  31974. break;
  31975. default:
  31976. wrapperEl.style.setProperty('transform', `translateY(${bottom})`);
  31977. wrapperAnimation.fromTo('opacity', 0.01, 1);
  31978. break;
  31979. }
  31980. return baseAnimation.easing('cubic-bezier(.36,.66,.04,1)').duration(400).addAnimation(wrapperAnimation);
  31981. };
  31982. /**
  31983. * md Toast Leave Animation
  31984. */
  31985. const mdLeaveAnimation = (baseEl) => {
  31986. const baseAnimation = createAnimation();
  31987. const wrapperAnimation = createAnimation();
  31988. const root = getElementRoot(baseEl);
  31989. const wrapperEl = root.querySelector('.toast-wrapper');
  31990. wrapperAnimation.addElement(wrapperEl).fromTo('opacity', 0.99, 0);
  31991. return baseAnimation.easing('cubic-bezier(.36,.66,.04,1)').duration(300).addAnimation(wrapperAnimation);
  31992. };
  31993. /**
  31994. * Create a gesture that allows the Toast
  31995. * to be swiped to dismiss.
  31996. * @param el - The Toast element
  31997. * @param toastPosition - The last computed position of the Toast. This is computed in the "present" method.
  31998. * @param onDismiss - A callback to fire when the Toast was swiped to dismiss.
  31999. */
  32000. const createSwipeToDismissGesture = (el, toastPosition, onDismiss) => {
  32001. /**
  32002. * Users should swipe on the visible toast wrapper
  32003. * rather than on ion-toast which covers the entire screen.
  32004. * When testing the class instance the inner wrapper will not
  32005. * be defined. As a result, we use a placeholder element in those environments.
  32006. */
  32007. const wrapperEl = getElementRoot(el).querySelector('.toast-wrapper');
  32008. const hostElHeight = el.clientHeight;
  32009. const wrapperElBox = wrapperEl.getBoundingClientRect();
  32010. /**
  32011. * The maximum amount that
  32012. * the toast can be swiped. This should
  32013. * account for the wrapper element's height
  32014. * too so the toast can be swiped offscreen
  32015. * completely.
  32016. */
  32017. let MAX_SWIPE_DISTANCE = 0;
  32018. /**
  32019. * The step value at which a toast
  32020. * is eligible for dismissing via gesture.
  32021. */
  32022. const DISMISS_THRESHOLD = 0.5;
  32023. /**
  32024. * The middle position Toast starts 50% of the way
  32025. * through the animation, so we need to use this
  32026. * as the starting point for our step values.
  32027. */
  32028. const STEP_OFFSET = el.position === 'middle' ? 0.5 : 0;
  32029. /**
  32030. * When the Toast is at the top users will be
  32031. * swiping up. As a result, the delta values will be
  32032. * negative numbers which will result in negative steps
  32033. * and thresholds. As a result, we need to make those numbers
  32034. * positive.
  32035. */
  32036. const INVERSION_FACTOR = el.position === 'top' ? -1 : 1;
  32037. /**
  32038. * The top offset that places the
  32039. * toast in the middle of the screen.
  32040. * Only needed when position="middle".
  32041. */
  32042. const topPosition = getOffsetForMiddlePosition(hostElHeight, wrapperElBox.height);
  32043. const SWIPE_UP_DOWN_KEYFRAMES = [
  32044. { offset: 0, transform: `translateY(-${topPosition + wrapperElBox.height}px)` },
  32045. { offset: 0.5, transform: `translateY(0px)` },
  32046. { offset: 1, transform: `translateY(${topPosition + wrapperElBox.height}px)` },
  32047. ];
  32048. const swipeAnimation = createAnimation('toast-swipe-to-dismiss-animation')
  32049. .addElement(wrapperEl)
  32050. /**
  32051. * The specific value here does not actually
  32052. * matter. We just need this to be a positive
  32053. * value so the animation does not jump
  32054. * to the end when the user beings to drag.
  32055. */
  32056. .duration(100);
  32057. switch (el.position) {
  32058. case 'middle':
  32059. MAX_SWIPE_DISTANCE = hostElHeight + wrapperElBox.height;
  32060. swipeAnimation.keyframes(SWIPE_UP_DOWN_KEYFRAMES);
  32061. /**
  32062. * Toast can be swiped up or down but
  32063. * should start in the middle of the screen.
  32064. */
  32065. swipeAnimation.progressStart(true, 0.5);
  32066. break;
  32067. case 'top':
  32068. /**
  32069. * The bottom edge of the wrapper
  32070. * includes the distance between the top
  32071. * of the screen and the top of the wrapper
  32072. * as well as the wrapper height so the wrapper
  32073. * can be dragged fully offscreen.
  32074. */
  32075. MAX_SWIPE_DISTANCE = wrapperElBox.bottom;
  32076. swipeAnimation.keyframes([
  32077. { offset: 0, transform: `translateY(${toastPosition.top})` },
  32078. { offset: 1, transform: 'translateY(-100%)' },
  32079. ]);
  32080. swipeAnimation.progressStart(true, 0);
  32081. break;
  32082. case 'bottom':
  32083. default:
  32084. /**
  32085. * This computes the distance between the
  32086. * top of the wrapper and the bottom of the
  32087. * screen including the height of the wrapper
  32088. * element so it can be dragged fully offscreen.
  32089. */
  32090. MAX_SWIPE_DISTANCE = hostElHeight - wrapperElBox.top;
  32091. swipeAnimation.keyframes([
  32092. { offset: 0, transform: `translateY(${toastPosition.bottom})` },
  32093. { offset: 1, transform: 'translateY(100%)' },
  32094. ]);
  32095. swipeAnimation.progressStart(true, 0);
  32096. break;
  32097. }
  32098. const computeStep = (delta) => {
  32099. return (delta * INVERSION_FACTOR) / MAX_SWIPE_DISTANCE;
  32100. };
  32101. const onMove = (detail) => {
  32102. const step = STEP_OFFSET + computeStep(detail.deltaY);
  32103. swipeAnimation.progressStep(step);
  32104. };
  32105. const onEnd = (detail) => {
  32106. const velocity = detail.velocityY;
  32107. const threshold = ((detail.deltaY + velocity * 1000) / MAX_SWIPE_DISTANCE) * INVERSION_FACTOR;
  32108. /**
  32109. * Disable the gesture for the remainder of the animation.
  32110. * It will be re-enabled if the toast animates back to
  32111. * its initial presented position.
  32112. */
  32113. gesture.enable(false);
  32114. let shouldDismiss = true;
  32115. let playTo = 1;
  32116. let step = 0;
  32117. let remainingDistance = 0;
  32118. if (el.position === 'middle') {
  32119. /**
  32120. * A middle positioned Toast appears
  32121. * in the middle of the screen (at animation offset 0.5).
  32122. * As a result, the threshold will be calculated relative
  32123. * to this starting position. In other words at animation offset 0.5
  32124. * the threshold will be 0. We want the middle Toast to be eligible
  32125. * for dismiss when the user has swiped either half way up or down the
  32126. * screen. As a result, we divide DISMISS_THRESHOLD in half. We also
  32127. * consider when the threshold is a negative in the event the
  32128. * user drags up (since the deltaY will also be negative).
  32129. */
  32130. shouldDismiss = threshold >= DISMISS_THRESHOLD / 2 || threshold <= -DISMISS_THRESHOLD / 2;
  32131. /**
  32132. * Since we are replacing the keyframes
  32133. * below the animation always starts from
  32134. * the beginning of the new keyframes.
  32135. * Similarly, we are always playing to
  32136. * the end of the new keyframes.
  32137. */
  32138. playTo = 1;
  32139. step = 0;
  32140. /**
  32141. * The Toast should animate from wherever its
  32142. * current position is to the desired end state.
  32143. *
  32144. * To begin, we get the current position of the
  32145. * Toast for its starting state.
  32146. */
  32147. const wrapperElBox = wrapperEl.getBoundingClientRect();
  32148. const startOffset = wrapperElBox.top - topPosition;
  32149. const startPosition = `${startOffset}px`;
  32150. /**
  32151. * If the deltaY is negative then the user is swiping
  32152. * up, so the Toast should animate to the top of the screen.
  32153. * If the deltaY is positive then the user is swiping
  32154. * down, so the Toast should animate to the bottom of the screen.
  32155. * We also account for when the deltaY is 0, but realistically
  32156. * that should never happen because it means the user did not drag
  32157. * the toast.
  32158. */
  32159. const offsetFactor = detail.deltaY <= 0 ? -1 : 1;
  32160. const endOffset = (topPosition + wrapperElBox.height) * offsetFactor;
  32161. /**
  32162. * If the Toast should dismiss
  32163. * then we need to figure out which edge of
  32164. * the screen it should animate towards.
  32165. * By default, the Toast will come
  32166. * back to its default state in the
  32167. * middle of the screen.
  32168. */
  32169. const endPosition = shouldDismiss ? `${endOffset}px` : '0px';
  32170. const KEYFRAMES = [
  32171. { offset: 0, transform: `translateY(${startPosition})` },
  32172. { offset: 1, transform: `translateY(${endPosition})` },
  32173. ];
  32174. swipeAnimation.keyframes(KEYFRAMES);
  32175. /**
  32176. * Compute the remaining amount of pixels the
  32177. * toast needs to move to be fully dismissed.
  32178. */
  32179. remainingDistance = endOffset - startOffset;
  32180. }
  32181. else {
  32182. shouldDismiss = threshold >= DISMISS_THRESHOLD;
  32183. playTo = shouldDismiss ? 1 : 0;
  32184. step = computeStep(detail.deltaY);
  32185. /**
  32186. * Compute the remaining amount of pixels the
  32187. * toast needs to move to be fully dismissed.
  32188. */
  32189. const remainingStepAmount = shouldDismiss ? 1 - step : step;
  32190. remainingDistance = remainingStepAmount * MAX_SWIPE_DISTANCE;
  32191. }
  32192. /**
  32193. * The animation speed should depend on how quickly
  32194. * the user flicks the toast across the screen. However,
  32195. * it should be no slower than 200ms.
  32196. * We use Math.abs on the remainingDistance because that value
  32197. * can be negative when swiping up on a middle position toast.
  32198. */
  32199. const duration = Math.min(Math.abs(remainingDistance) / Math.abs(velocity), 200);
  32200. swipeAnimation
  32201. .onFinish(() => {
  32202. if (shouldDismiss) {
  32203. onDismiss();
  32204. swipeAnimation.destroy();
  32205. }
  32206. else {
  32207. if (el.position === 'middle') {
  32208. /**
  32209. * If the toast snapped back to
  32210. * the middle of the screen we need
  32211. * to reset the keyframes
  32212. * so the toast can be swiped
  32213. * up or down again.
  32214. */
  32215. swipeAnimation.keyframes(SWIPE_UP_DOWN_KEYFRAMES).progressStart(true, 0.5);
  32216. }
  32217. else {
  32218. swipeAnimation.progressStart(true, 0);
  32219. }
  32220. /**
  32221. * If the toast did not dismiss then
  32222. * the user should be able to swipe again.
  32223. */
  32224. gesture.enable(true);
  32225. }
  32226. /**
  32227. * This must be a one time callback
  32228. * otherwise a new callback will
  32229. * be added every time onEnd runs.
  32230. */
  32231. }, { oneTimeCallback: true })
  32232. .progressEnd(playTo, step, duration);
  32233. };
  32234. const gesture = createGesture({
  32235. el: wrapperEl,
  32236. gestureName: 'toast-swipe-to-dismiss',
  32237. gesturePriority: OVERLAY_GESTURE_PRIORITY,
  32238. /**
  32239. * Toast only supports vertical swipes.
  32240. * This needs to be updated if we later
  32241. * support horizontal swipes.
  32242. */
  32243. direction: 'y',
  32244. onMove,
  32245. onEnd,
  32246. });
  32247. return gesture;
  32248. };
  32249. 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}}";
  32250. var IonToastIosStyle0 = toastIosCss;
  32251. 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)}}";
  32252. var IonToastMdStyle0 = toastMdCss;
  32253. // TODO(FW-2832): types
  32254. /**
  32255. * @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
  32256. *
  32257. * @part button - Any button element that is displayed inside of the toast.
  32258. * @part button cancel - Any button element with role "cancel" that is displayed inside of the toast.
  32259. * @part container - The element that wraps all child elements.
  32260. * @part header - The header text of the toast.
  32261. * @part message - The body text of the toast.
  32262. * @part icon - The icon that appears next to the toast content.
  32263. */
  32264. class Toast {
  32265. constructor(hostRef) {
  32266. registerInstance(this, hostRef);
  32267. this.didPresent = createEvent(this, "ionToastDidPresent", 7);
  32268. this.willPresent = createEvent(this, "ionToastWillPresent", 7);
  32269. this.willDismiss = createEvent(this, "ionToastWillDismiss", 7);
  32270. this.didDismiss = createEvent(this, "ionToastDidDismiss", 7);
  32271. this.didPresentShorthand = createEvent(this, "didPresent", 7);
  32272. this.willPresentShorthand = createEvent(this, "willPresent", 7);
  32273. this.willDismissShorthand = createEvent(this, "willDismiss", 7);
  32274. this.didDismissShorthand = createEvent(this, "didDismiss", 7);
  32275. this.delegateController = createDelegateController(this);
  32276. this.lockController = createLockController();
  32277. this.triggerController = createTriggerController();
  32278. this.customHTMLEnabled = config.get('innerHTMLTemplatesEnabled', ENABLE_HTML_CONTENT_DEFAULT);
  32279. this.presented = false;
  32280. this.dispatchCancelHandler = (ev) => {
  32281. const role = ev.detail.role;
  32282. if (isCancel(role)) {
  32283. const cancelButton = this.getButtons().find((b) => b.role === 'cancel');
  32284. this.callButtonHandler(cancelButton);
  32285. }
  32286. };
  32287. /**
  32288. * Create a new swipe gesture so Toast
  32289. * can be swiped to dismiss.
  32290. */
  32291. this.createSwipeGesture = (toastPosition) => {
  32292. const gesture = (this.gesture = createSwipeToDismissGesture(this.el, toastPosition, () => {
  32293. /**
  32294. * If the gesture completed then
  32295. * we should dismiss the toast.
  32296. */
  32297. this.dismiss(undefined, GESTURE);
  32298. }));
  32299. gesture.enable(true);
  32300. };
  32301. /**
  32302. * Destroy an existing swipe gesture
  32303. * so Toast can no longer be swiped to dismiss.
  32304. */
  32305. this.destroySwipeGesture = () => {
  32306. const { gesture } = this;
  32307. if (gesture === undefined) {
  32308. return;
  32309. }
  32310. gesture.destroy();
  32311. this.gesture = undefined;
  32312. };
  32313. /**
  32314. * Returns `true` if swipeGesture
  32315. * is configured to a value that enables the swipe behavior.
  32316. * Returns `false` otherwise.
  32317. */
  32318. this.prefersSwipeGesture = () => {
  32319. const { swipeGesture } = this;
  32320. return swipeGesture === 'vertical';
  32321. };
  32322. this.revealContentToScreenReader = false;
  32323. this.overlayIndex = undefined;
  32324. this.delegate = undefined;
  32325. this.hasController = false;
  32326. this.color = undefined;
  32327. this.enterAnimation = undefined;
  32328. this.leaveAnimation = undefined;
  32329. this.cssClass = undefined;
  32330. this.duration = config.getNumber('toastDuration', 0);
  32331. this.header = undefined;
  32332. this.layout = 'baseline';
  32333. this.message = undefined;
  32334. this.keyboardClose = false;
  32335. this.position = 'bottom';
  32336. this.positionAnchor = undefined;
  32337. this.buttons = undefined;
  32338. this.translucent = false;
  32339. this.animated = true;
  32340. this.icon = undefined;
  32341. this.htmlAttributes = undefined;
  32342. this.swipeGesture = undefined;
  32343. this.isOpen = false;
  32344. this.trigger = undefined;
  32345. }
  32346. swipeGestureChanged() {
  32347. /**
  32348. * If the Toast is presented, then we need to destroy
  32349. * any actives gestures before a new gesture is potentially
  32350. * created below.
  32351. *
  32352. * If the Toast is dismissed, then no gesture should be available
  32353. * since the Toast is not visible. This case should never
  32354. * happen since the "dismiss" method handles destroying
  32355. * any active swipe gestures, but we keep this code
  32356. * around to handle the first case.
  32357. */
  32358. this.destroySwipeGesture();
  32359. /**
  32360. * A new swipe gesture should only be created
  32361. * if the Toast is presented. If the Toast is not
  32362. * yet presented then the "present" method will
  32363. * handle calling the swipe gesture setup function.
  32364. */
  32365. if (this.presented && this.prefersSwipeGesture()) {
  32366. /**
  32367. * If the Toast is presented then
  32368. * lastPresentedPosition is defined.
  32369. */
  32370. this.createSwipeGesture(this.lastPresentedPosition);
  32371. }
  32372. }
  32373. onIsOpenChange(newValue, oldValue) {
  32374. if (newValue === true && oldValue === false) {
  32375. this.present();
  32376. }
  32377. else if (newValue === false && oldValue === true) {
  32378. this.dismiss();
  32379. }
  32380. }
  32381. triggerChanged() {
  32382. const { trigger, el, triggerController } = this;
  32383. if (trigger) {
  32384. triggerController.addClickListener(el, trigger);
  32385. }
  32386. }
  32387. connectedCallback() {
  32388. prepareOverlay(this.el);
  32389. this.triggerChanged();
  32390. }
  32391. disconnectedCallback() {
  32392. this.triggerController.removeClickListener();
  32393. }
  32394. componentWillLoad() {
  32395. var _a;
  32396. if (!((_a = this.htmlAttributes) === null || _a === void 0 ? void 0 : _a.id)) {
  32397. setOverlayId(this.el);
  32398. }
  32399. }
  32400. componentDidLoad() {
  32401. /**
  32402. * If toast was rendered with isOpen="true"
  32403. * then we should open toast immediately.
  32404. */
  32405. if (this.isOpen === true) {
  32406. raf(() => this.present());
  32407. }
  32408. /**
  32409. * When binding values in frameworks such as Angular
  32410. * it is possible for the value to be set after the Web Component
  32411. * initializes but before the value watcher is set up in Stencil.
  32412. * As a result, the watcher callback may not be fired.
  32413. * We work around this by manually calling the watcher
  32414. * callback when the component has loaded and the watcher
  32415. * is configured.
  32416. */
  32417. this.triggerChanged();
  32418. }
  32419. /**
  32420. * Present the toast overlay after it has been created.
  32421. */
  32422. async present() {
  32423. const unlock = await this.lockController.lock();
  32424. await this.delegateController.attachViewToDom();
  32425. const { el, position } = this;
  32426. const anchor = this.getAnchorElement();
  32427. const animationPosition = getAnimationPosition(position, anchor, getIonMode$1(this), el);
  32428. /**
  32429. * Cache the calculated position of the toast, so we can re-use it
  32430. * in the dismiss animation.
  32431. */
  32432. this.lastPresentedPosition = animationPosition;
  32433. await present(this, 'toastEnter', iosEnterAnimation, mdEnterAnimation, {
  32434. position,
  32435. top: animationPosition.top,
  32436. bottom: animationPosition.bottom,
  32437. });
  32438. /**
  32439. * Content is revealed to screen readers after
  32440. * the transition to avoid jank since this
  32441. * state updates will cause a re-render.
  32442. */
  32443. this.revealContentToScreenReader = true;
  32444. if (this.duration > 0) {
  32445. this.durationTimeout = setTimeout(() => this.dismiss(undefined, 'timeout'), this.duration);
  32446. }
  32447. /**
  32448. * If the Toast has a swipe gesture then we can
  32449. * create the gesture so users can swipe the
  32450. * presented Toast.
  32451. */
  32452. if (this.prefersSwipeGesture()) {
  32453. this.createSwipeGesture(animationPosition);
  32454. }
  32455. unlock();
  32456. }
  32457. /**
  32458. * Dismiss the toast overlay after it has been presented.
  32459. *
  32460. * @param data Any data to emit in the dismiss events.
  32461. * @param role The role of the element that is dismissing the toast.
  32462. * This can be useful in a button handler for determining which button was
  32463. * clicked to dismiss the toast.
  32464. * Some examples include: ``"cancel"`, `"destructive"`, "selected"`, and `"backdrop"`.
  32465. *
  32466. * This is a no-op if the overlay has not been presented yet. If you want
  32467. * to remove an overlay from the DOM that was never presented, use the
  32468. * [remove](https://developer.mozilla.org/en-US/docs/Web/API/Element/remove) method.
  32469. */
  32470. async dismiss(data, role) {
  32471. var _a, _b;
  32472. const unlock = await this.lockController.lock();
  32473. const { durationTimeout, position, lastPresentedPosition } = this;
  32474. if (durationTimeout) {
  32475. clearTimeout(durationTimeout);
  32476. }
  32477. const dismissed = await dismiss(this, data, role, 'toastLeave', iosLeaveAnimation, mdLeaveAnimation,
  32478. /**
  32479. * Fetch the cached position that was calculated back in the present
  32480. * animation. We always want to animate the dismiss from the same
  32481. * position the present stopped at, so the animation looks continuous.
  32482. */
  32483. {
  32484. position,
  32485. top: (_a = lastPresentedPosition === null || lastPresentedPosition === void 0 ? void 0 : lastPresentedPosition.top) !== null && _a !== void 0 ? _a : '',
  32486. bottom: (_b = lastPresentedPosition === null || lastPresentedPosition === void 0 ? void 0 : lastPresentedPosition.bottom) !== null && _b !== void 0 ? _b : '',
  32487. });
  32488. if (dismissed) {
  32489. this.delegateController.removeViewFromDom();
  32490. this.revealContentToScreenReader = false;
  32491. }
  32492. this.lastPresentedPosition = undefined;
  32493. /**
  32494. * If the Toast has a swipe gesture then we can
  32495. * safely destroy it now that it is dismissed.
  32496. */
  32497. this.destroySwipeGesture();
  32498. unlock();
  32499. return dismissed;
  32500. }
  32501. /**
  32502. * Returns a promise that resolves when the toast did dismiss.
  32503. */
  32504. onDidDismiss() {
  32505. return eventMethod(this.el, 'ionToastDidDismiss');
  32506. }
  32507. /**
  32508. * Returns a promise that resolves when the toast will dismiss.
  32509. */
  32510. onWillDismiss() {
  32511. return eventMethod(this.el, 'ionToastWillDismiss');
  32512. }
  32513. getButtons() {
  32514. const buttons = this.buttons
  32515. ? this.buttons.map((b) => {
  32516. return typeof b === 'string' ? { text: b } : b;
  32517. })
  32518. : [];
  32519. return buttons;
  32520. }
  32521. /**
  32522. * Returns the element specified by the positionAnchor prop,
  32523. * or undefined if prop's value is an ID string and the element
  32524. * is not found in the DOM.
  32525. */
  32526. getAnchorElement() {
  32527. const { position, positionAnchor, el } = this;
  32528. /**
  32529. * If positionAnchor is undefined then
  32530. * no anchor should be used when presenting the toast.
  32531. */
  32532. if (positionAnchor === undefined) {
  32533. return;
  32534. }
  32535. if (position === 'middle' && positionAnchor !== undefined) {
  32536. printIonWarning('[ion-toast] - The positionAnchor property is ignored when using position="middle".', this.el);
  32537. return undefined;
  32538. }
  32539. if (typeof positionAnchor === 'string') {
  32540. /**
  32541. * If the anchor is defined as an ID, find the element.
  32542. * We do this on every present so the toast doesn't need
  32543. * to account for the surrounding DOM changing since the
  32544. * last time it was presented.
  32545. */
  32546. const foundEl = document.getElementById(positionAnchor);
  32547. if (foundEl === null) {
  32548. printIonWarning(`[ion-toast] - An anchor element with an ID of "${positionAnchor}" was not found in the DOM.`, el);
  32549. return undefined;
  32550. }
  32551. return foundEl;
  32552. }
  32553. if (positionAnchor instanceof HTMLElement) {
  32554. return positionAnchor;
  32555. }
  32556. printIonWarning('[ion-toast] - Invalid positionAnchor value:', positionAnchor, el);
  32557. return undefined;
  32558. }
  32559. async buttonClick(button) {
  32560. const role = button.role;
  32561. if (isCancel(role)) {
  32562. return this.dismiss(undefined, role);
  32563. }
  32564. const shouldDismiss = await this.callButtonHandler(button);
  32565. if (shouldDismiss) {
  32566. return this.dismiss(undefined, role);
  32567. }
  32568. return Promise.resolve();
  32569. }
  32570. async callButtonHandler(button) {
  32571. if (button === null || button === void 0 ? void 0 : button.handler) {
  32572. // a handler has been provided, execute it
  32573. // pass the handler the values from the inputs
  32574. try {
  32575. const rtn = await safeCall(button.handler);
  32576. if (rtn === false) {
  32577. // if the return value of the handler is false then do not dismiss
  32578. return false;
  32579. }
  32580. }
  32581. catch (e) {
  32582. printIonError('[ion-toast] - Exception in callButtonHandler:', e);
  32583. }
  32584. }
  32585. return true;
  32586. }
  32587. renderButtons(buttons, side) {
  32588. if (buttons.length === 0) {
  32589. return;
  32590. }
  32591. const mode = getIonMode$1(this);
  32592. const buttonGroupsClasses = {
  32593. 'toast-button-group': true,
  32594. [`toast-button-group-${side}`]: true,
  32595. };
  32596. 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' })))))));
  32597. }
  32598. /**
  32599. * Render the `message` property.
  32600. * @param key - A key to give the element a stable identity. This is used to improve compatibility with screen readers.
  32601. * @param ariaHidden - If "true" then content will be hidden from screen readers.
  32602. */
  32603. renderToastMessage(key, ariaHidden = null) {
  32604. const { customHTMLEnabled, message } = this;
  32605. if (customHTMLEnabled) {
  32606. return (hAsync("div", { key: key, "aria-hidden": ariaHidden, class: "toast-message", part: "message", innerHTML: sanitizeDOMString(message) }));
  32607. }
  32608. return (hAsync("div", { key: key, "aria-hidden": ariaHidden, class: "toast-message", part: "message" }, message));
  32609. }
  32610. /**
  32611. * Render the `header` property.
  32612. * @param key - A key to give the element a stable identity. This is used to improve compatibility with screen readers.
  32613. * @param ariaHidden - If "true" then content will be hidden from screen readers.
  32614. */
  32615. renderHeader(key, ariaHidden = null) {
  32616. return (hAsync("div", { key: key, class: "toast-header", "aria-hidden": ariaHidden, part: "header" }, this.header));
  32617. }
  32618. render() {
  32619. const { layout, el, revealContentToScreenReader, header, message } = this;
  32620. const allButtons = this.getButtons();
  32621. const startButtons = allButtons.filter((b) => b.side === 'start');
  32622. const endButtons = allButtons.filter((b) => b.side !== 'start');
  32623. const mode = getIonMode$1(this);
  32624. const wrapperClass = {
  32625. 'toast-wrapper': true,
  32626. [`toast-${this.position}`]: true,
  32627. [`toast-layout-${layout}`]: true,
  32628. };
  32629. /**
  32630. * Stacked buttons are only meant to be
  32631. * used with one type of button.
  32632. */
  32633. if (layout === 'stacked' && startButtons.length > 0 && endButtons.length > 0) {
  32634. 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);
  32635. }
  32636. return (hAsync(Host, Object.assign({ key: 'a2216d860255c99337464370dcb12f6125871a50', tabindex: "-1" }, this.htmlAttributes, { style: {
  32637. zIndex: `${60000 + this.overlayIndex}`,
  32638. }, 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')))));
  32639. }
  32640. get el() { return getElement(this); }
  32641. static get watchers() { return {
  32642. "swipeGesture": ["swipeGestureChanged"],
  32643. "isOpen": ["onIsOpenChange"],
  32644. "trigger": ["triggerChanged"]
  32645. }; }
  32646. static get style() { return {
  32647. ios: IonToastIosStyle0,
  32648. md: IonToastMdStyle0
  32649. }; }
  32650. static get cmpMeta() { return {
  32651. "$flags$": 41,
  32652. "$tagName$": "ion-toast",
  32653. "$members$": {
  32654. "overlayIndex": [2, "overlay-index"],
  32655. "delegate": [16],
  32656. "hasController": [4, "has-controller"],
  32657. "color": [513],
  32658. "enterAnimation": [16],
  32659. "leaveAnimation": [16],
  32660. "cssClass": [1, "css-class"],
  32661. "duration": [2],
  32662. "header": [1],
  32663. "layout": [1],
  32664. "message": [1],
  32665. "keyboardClose": [4, "keyboard-close"],
  32666. "position": [1],
  32667. "positionAnchor": [1, "position-anchor"],
  32668. "buttons": [16],
  32669. "translucent": [4],
  32670. "animated": [4],
  32671. "icon": [1],
  32672. "htmlAttributes": [16],
  32673. "swipeGesture": [1, "swipe-gesture"],
  32674. "isOpen": [4, "is-open"],
  32675. "trigger": [1],
  32676. "revealContentToScreenReader": [32],
  32677. "present": [64],
  32678. "dismiss": [64],
  32679. "onDidDismiss": [64],
  32680. "onWillDismiss": [64]
  32681. },
  32682. "$listeners$": undefined,
  32683. "$lazyBundleId$": "-",
  32684. "$attrsToReflect$": [["color", "color"]]
  32685. }; }
  32686. }
  32687. const buttonClass = (button) => {
  32688. return {
  32689. 'toast-button': true,
  32690. 'toast-button-icon-only': button.icon !== undefined && button.text === undefined,
  32691. [`toast-button-${button.role}`]: button.role !== undefined,
  32692. 'ion-focusable': true,
  32693. 'ion-activatable': true,
  32694. };
  32695. };
  32696. const buttonPart = (button) => {
  32697. return isCancel(button.role) ? 'button cancel' : 'button';
  32698. };
  32699. 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}";
  32700. var IonToggleIosStyle0 = toggleIosCss;
  32701. 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}";
  32702. var IonToggleMdStyle0 = toggleMdCss;
  32703. /**
  32704. * @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
  32705. *
  32706. * @slot - The label text to associate with the toggle. Use the "labelPlacement" property to control where the label is placed relative to the toggle.
  32707. *
  32708. * @part track - The background track of the toggle.
  32709. * @part handle - The toggle handle, or knob, used to change the checked state.
  32710. * @part label - The label text describing the toggle.
  32711. * @part supporting-text - Supporting text displayed beneath the toggle label.
  32712. * @part helper-text - Supporting text displayed beneath the toggle label when the toggle is valid.
  32713. * @part error-text - Supporting text displayed beneath the toggle label when the toggle is invalid and touched.
  32714. */
  32715. class Toggle {
  32716. constructor(hostRef) {
  32717. registerInstance(this, hostRef);
  32718. this.ionChange = createEvent(this, "ionChange", 7);
  32719. this.ionFocus = createEvent(this, "ionFocus", 7);
  32720. this.ionBlur = createEvent(this, "ionBlur", 7);
  32721. this.inputId = `ion-tg-${toggleIds++}`;
  32722. this.inputLabelId = `${this.inputId}-lbl`;
  32723. this.helperTextId = `${this.inputId}-helper-text`;
  32724. this.errorTextId = `${this.inputId}-error-text`;
  32725. this.lastDrag = 0;
  32726. this.inheritedAttributes = {};
  32727. this.didLoad = false;
  32728. this.setupGesture = async () => {
  32729. const { toggleTrack } = this;
  32730. if (toggleTrack) {
  32731. this.gesture = (await Promise.resolve().then(function () { return index; })).createGesture({
  32732. el: toggleTrack,
  32733. gestureName: 'toggle',
  32734. gesturePriority: 100,
  32735. threshold: 5,
  32736. passive: false,
  32737. onStart: () => this.onStart(),
  32738. onMove: (ev) => this.onMove(ev),
  32739. onEnd: (ev) => this.onEnd(ev),
  32740. });
  32741. this.disabledChanged();
  32742. }
  32743. };
  32744. this.onKeyDown = (ev) => {
  32745. if (ev.key === ' ') {
  32746. ev.preventDefault();
  32747. if (!this.disabled) {
  32748. this.toggleChecked();
  32749. }
  32750. }
  32751. };
  32752. this.onClick = (ev) => {
  32753. if (this.disabled) {
  32754. return;
  32755. }
  32756. ev.preventDefault();
  32757. if (this.lastDrag + 300 < Date.now()) {
  32758. this.toggleChecked();
  32759. }
  32760. };
  32761. /**
  32762. * Stops propagation when the display label is clicked,
  32763. * otherwise, two clicks will be triggered.
  32764. */
  32765. this.onDivLabelClick = (ev) => {
  32766. ev.stopPropagation();
  32767. };
  32768. this.onFocus = () => {
  32769. this.ionFocus.emit();
  32770. };
  32771. this.onBlur = () => {
  32772. this.ionBlur.emit();
  32773. };
  32774. this.getSwitchLabelIcon = (mode, checked) => {
  32775. if (mode === 'md') {
  32776. return checked ? checkmarkOutline : removeOutline;
  32777. }
  32778. return checked ? removeOutline : ellipseOutline;
  32779. };
  32780. this.activated = false;
  32781. this.color = undefined;
  32782. this.name = this.inputId;
  32783. this.checked = false;
  32784. this.disabled = false;
  32785. this.errorText = undefined;
  32786. this.helperText = undefined;
  32787. this.value = 'on';
  32788. this.enableOnOffLabels = config.get('toggleOnOffLabels');
  32789. this.labelPlacement = 'start';
  32790. this.justify = undefined;
  32791. this.alignment = undefined;
  32792. this.required = false;
  32793. }
  32794. disabledChanged() {
  32795. if (this.gesture) {
  32796. this.gesture.enable(!this.disabled);
  32797. }
  32798. }
  32799. toggleChecked() {
  32800. const { checked, value } = this;
  32801. const isNowChecked = !checked;
  32802. this.checked = isNowChecked;
  32803. this.setFocus();
  32804. this.ionChange.emit({
  32805. checked: isNowChecked,
  32806. value,
  32807. });
  32808. }
  32809. async connectedCallback() {
  32810. /**
  32811. * If we have not yet rendered
  32812. * ion-toggle, then toggleTrack is not defined.
  32813. * But if we are moving ion-toggle via appendChild,
  32814. * then toggleTrack will be defined.
  32815. */
  32816. if (this.didLoad) {
  32817. this.setupGesture();
  32818. }
  32819. }
  32820. componentDidLoad() {
  32821. this.setupGesture();
  32822. this.didLoad = true;
  32823. }
  32824. disconnectedCallback() {
  32825. if (this.gesture) {
  32826. this.gesture.destroy();
  32827. this.gesture = undefined;
  32828. }
  32829. }
  32830. componentWillLoad() {
  32831. this.inheritedAttributes = Object.assign({}, inheritAriaAttributes(this.el));
  32832. }
  32833. onStart() {
  32834. this.activated = true;
  32835. // touch-action does not work in iOS
  32836. this.setFocus();
  32837. }
  32838. onMove(detail) {
  32839. if (shouldToggle(isRTL$1(this.el), this.checked, detail.deltaX, -10)) {
  32840. this.toggleChecked();
  32841. hapticSelection();
  32842. }
  32843. }
  32844. onEnd(ev) {
  32845. this.activated = false;
  32846. this.lastDrag = Date.now();
  32847. ev.event.preventDefault();
  32848. ev.event.stopImmediatePropagation();
  32849. }
  32850. getValue() {
  32851. return this.value || '';
  32852. }
  32853. setFocus() {
  32854. if (this.focusEl) {
  32855. this.focusEl.focus();
  32856. }
  32857. }
  32858. renderOnOffSwitchLabels(mode, checked) {
  32859. const icon = this.getSwitchLabelIcon(mode, checked);
  32860. return (hAsync("ion-icon", { class: {
  32861. 'toggle-switch-icon': true,
  32862. 'toggle-switch-icon-checked': checked,
  32863. }, icon: icon, "aria-hidden": "true" }));
  32864. }
  32865. renderToggleControl() {
  32866. const mode = getIonMode$1(this);
  32867. const { enableOnOffLabels, checked } = this;
  32868. return (hAsync("div", { class: "toggle-icon", part: "track", ref: (el) => (this.toggleTrack = el) }, enableOnOffLabels &&
  32869. 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)))));
  32870. }
  32871. get hasLabel() {
  32872. return this.el.textContent !== '';
  32873. }
  32874. getHintTextID() {
  32875. const { el, helperText, errorText, helperTextId, errorTextId } = this;
  32876. if (el.classList.contains('ion-touched') && el.classList.contains('ion-invalid') && errorText) {
  32877. return errorTextId;
  32878. }
  32879. if (helperText) {
  32880. return helperTextId;
  32881. }
  32882. return undefined;
  32883. }
  32884. /**
  32885. * Responsible for rendering helper text and error text.
  32886. * This element should only be rendered if hint text is set.
  32887. */
  32888. renderHintText() {
  32889. const { helperText, errorText, helperTextId, errorTextId } = this;
  32890. /**
  32891. * undefined and empty string values should
  32892. * be treated as not having helper/error text.
  32893. */
  32894. const hasHintText = !!helperText || !!errorText;
  32895. if (!hasHintText) {
  32896. return;
  32897. }
  32898. 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)));
  32899. }
  32900. render() {
  32901. const { activated, alignment, checked, color, disabled, el, errorTextId, hasLabel, inheritedAttributes, inputId, inputLabelId, justify, labelPlacement, name, required, } = this;
  32902. const mode = getIonMode$1(this);
  32903. const value = this.getValue();
  32904. const rtl = isRTL$1(el) ? 'rtl' : 'ltr';
  32905. renderHiddenInput(true, el, name, checked ? value : '', disabled);
  32906. 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, {
  32907. [mode]: true,
  32908. 'in-item': hostContext('ion-item', el),
  32909. 'toggle-activated': activated,
  32910. 'toggle-checked': checked,
  32911. 'toggle-disabled': disabled,
  32912. [`toggle-justify-${justify}`]: justify !== undefined,
  32913. [`toggle-alignment-${alignment}`]: alignment !== undefined,
  32914. [`toggle-label-placement-${labelPlacement}`]: true,
  32915. [`toggle-${rtl}`]: true,
  32916. }) }, 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: {
  32917. 'label-text-wrapper': true,
  32918. 'label-text-wrapper-hidden': !hasLabel,
  32919. }, part: "label", id: inputLabelId, onClick: this.onDivLabelClick }, hAsync("slot", { key: '798220850b311a26b081914d5c774b757bde2992' }), this.renderHintText()), hAsync("div", { key: '3c6142c9697b60646f286f6fd59f54609377f7d0', class: "native-wrapper" }, this.renderToggleControl()))));
  32920. }
  32921. get el() { return getElement(this); }
  32922. static get watchers() { return {
  32923. "disabled": ["disabledChanged"]
  32924. }; }
  32925. static get style() { return {
  32926. ios: IonToggleIosStyle0,
  32927. md: IonToggleMdStyle0
  32928. }; }
  32929. static get cmpMeta() { return {
  32930. "$flags$": 41,
  32931. "$tagName$": "ion-toggle",
  32932. "$members$": {
  32933. "color": [513],
  32934. "name": [1],
  32935. "checked": [1028],
  32936. "disabled": [4],
  32937. "errorText": [1, "error-text"],
  32938. "helperText": [1, "helper-text"],
  32939. "value": [1],
  32940. "enableOnOffLabels": [4, "enable-on-off-labels"],
  32941. "labelPlacement": [1, "label-placement"],
  32942. "justify": [1],
  32943. "alignment": [1],
  32944. "required": [4],
  32945. "activated": [32]
  32946. },
  32947. "$listeners$": undefined,
  32948. "$lazyBundleId$": "-",
  32949. "$attrsToReflect$": [["color", "color"]]
  32950. }; }
  32951. }
  32952. const shouldToggle = (rtl, checked, deltaX, margin) => {
  32953. if (checked) {
  32954. return (!rtl && margin > deltaX) || (rtl && -margin < deltaX);
  32955. }
  32956. else {
  32957. return (!rtl && -margin < deltaX) || (rtl && margin > deltaX);
  32958. }
  32959. };
  32960. let toggleIds = 0;
  32961. 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%}";
  32962. var IonToolbarIosStyle0 = toolbarIosCss;
  32963. 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}";
  32964. var IonToolbarMdStyle0 = toolbarMdCss;
  32965. /**
  32966. * @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
  32967. *
  32968. * @slot - Content is placed between the named slots if provided without a slot.
  32969. * @slot start - Content is placed to the left of the toolbar text in LTR, and to the right in RTL.
  32970. * @slot secondary - Content is placed to the left of the toolbar text in `ios` mode, and directly to the right in `md` mode.
  32971. * @slot primary - Content is placed to the right of the toolbar text in `ios` mode, and to the far right in `md` mode.
  32972. * @slot end - Content is placed to the right of the toolbar text in LTR, and to the left in RTL.
  32973. *
  32974. * @part background - The background of the toolbar, covering the entire area behind the toolbar content.
  32975. * @part container - The container that wraps all toolbar content, including the default slot and named slot content.
  32976. * @part content - The container for the default slot, wrapping content provided without a named slot.
  32977. */
  32978. class Toolbar {
  32979. constructor(hostRef) {
  32980. registerInstance(this, hostRef);
  32981. this.childrenStyles = new Map();
  32982. this.color = undefined;
  32983. }
  32984. componentWillLoad() {
  32985. const buttons = Array.from(this.el.querySelectorAll('ion-buttons'));
  32986. const firstButtons = buttons.find((button) => {
  32987. return button.slot === 'start';
  32988. });
  32989. if (firstButtons) {
  32990. firstButtons.classList.add('buttons-first-slot');
  32991. }
  32992. const buttonsReversed = buttons.reverse();
  32993. const lastButtons = buttonsReversed.find((button) => button.slot === 'end') ||
  32994. buttonsReversed.find((button) => button.slot === 'primary') ||
  32995. buttonsReversed.find((button) => button.slot === 'secondary');
  32996. if (lastButtons) {
  32997. lastButtons.classList.add('buttons-last-slot');
  32998. }
  32999. }
  33000. childrenStyle(ev) {
  33001. ev.stopPropagation();
  33002. const tagName = ev.target.tagName;
  33003. const updatedStyles = ev.detail;
  33004. const newStyles = {};
  33005. const childStyles = this.childrenStyles.get(tagName) || {};
  33006. let hasStyleChange = false;
  33007. Object.keys(updatedStyles).forEach((key) => {
  33008. const childKey = `toolbar-${key}`;
  33009. const newValue = updatedStyles[key];
  33010. if (newValue !== childStyles[childKey]) {
  33011. hasStyleChange = true;
  33012. }
  33013. if (newValue) {
  33014. newStyles[childKey] = true;
  33015. }
  33016. });
  33017. if (hasStyleChange) {
  33018. this.childrenStyles.set(tagName, newStyles);
  33019. }
  33020. }
  33021. render() {
  33022. const mode = getIonMode$1(this);
  33023. const childStyles = {};
  33024. this.childrenStyles.forEach((value) => {
  33025. Object.assign(childStyles, value);
  33026. });
  33027. return (hAsync(Host, { key: '402afe7ce0c97883cedd0e48a5a0492a9bfe76ae', class: Object.assign(Object.assign({}, childStyles), createColorClasses$1(this.color, {
  33028. [mode]: true,
  33029. 'in-toolbar': hostContext('ion-toolbar', this.el),
  33030. })) }, 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" }))));
  33031. }
  33032. get el() { return getElement(this); }
  33033. static get style() { return {
  33034. ios: IonToolbarIosStyle0,
  33035. md: IonToolbarMdStyle0
  33036. }; }
  33037. static get cmpMeta() { return {
  33038. "$flags$": 41,
  33039. "$tagName$": "ion-toolbar",
  33040. "$members$": {
  33041. "color": [513]
  33042. },
  33043. "$listeners$": [[0, "ionStyle", "childrenStyle"]],
  33044. "$lazyBundleId$": "-",
  33045. "$attrsToReflect$": [["color", "color"]]
  33046. }; }
  33047. }
  33048. 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)}}";
  33049. var IonTitleIosStyle0 = titleIosCss;
  33050. 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}";
  33051. var IonTitleMdStyle0 = titleMdCss;
  33052. class ToolbarTitle {
  33053. constructor(hostRef) {
  33054. registerInstance(this, hostRef);
  33055. this.ionStyle = createEvent(this, "ionStyle", 7);
  33056. this.color = undefined;
  33057. this.size = undefined;
  33058. }
  33059. sizeChanged() {
  33060. this.emitStyle();
  33061. }
  33062. connectedCallback() {
  33063. this.emitStyle();
  33064. }
  33065. emitStyle() {
  33066. const size = this.getSize();
  33067. this.ionStyle.emit({
  33068. [`title-${size}`]: true,
  33069. });
  33070. }
  33071. getSize() {
  33072. return this.size !== undefined ? this.size : 'default';
  33073. }
  33074. render() {
  33075. const mode = getIonMode$1(this);
  33076. const size = this.getSize();
  33077. return (hAsync(Host, { key: '3f7b19c99961dbb86c0a925218332528b22e6880', class: createColorClasses$1(this.color, {
  33078. [mode]: true,
  33079. [`title-${size}`]: true,
  33080. 'title-rtl': document.dir === 'rtl',
  33081. }) }, hAsync("div", { key: '12054fbdd60e40a15875e442c20143766fc34fc3', class: "toolbar-title" }, hAsync("slot", { key: '9f14fb14a67d4bd1e4536a4d64a637fbe5a151c7' }))));
  33082. }
  33083. get el() { return getElement(this); }
  33084. static get watchers() { return {
  33085. "size": ["sizeChanged"]
  33086. }; }
  33087. static get style() { return {
  33088. ios: IonTitleIosStyle0,
  33089. md: IonTitleMdStyle0
  33090. }; }
  33091. static get cmpMeta() { return {
  33092. "$flags$": 41,
  33093. "$tagName$": "ion-title",
  33094. "$members$": {
  33095. "color": [513],
  33096. "size": [1]
  33097. },
  33098. "$listeners$": undefined,
  33099. "$lazyBundleId$": "-",
  33100. "$attrsToReflect$": [["color", "color"]]
  33101. }; }
  33102. }
  33103. registerComponents([
  33104. Accordion,
  33105. AccordionGroup,
  33106. ActionSheet,
  33107. Alert,
  33108. App,
  33109. Avatar,
  33110. BackButton,
  33111. Backdrop,
  33112. Badge,
  33113. Breadcrumb,
  33114. Breadcrumbs,
  33115. Button,
  33116. Buttons,
  33117. Card,
  33118. CardContent,
  33119. CardHeader,
  33120. CardSubtitle,
  33121. CardTitle,
  33122. Checkbox,
  33123. Chip,
  33124. Col,
  33125. Content,
  33126. Datetime,
  33127. DatetimeButton,
  33128. Fab,
  33129. FabButton,
  33130. FabList,
  33131. Footer,
  33132. Grid,
  33133. Header,
  33134. Icon,
  33135. Img,
  33136. InfiniteScroll,
  33137. InfiniteScrollContent,
  33138. Input,
  33139. InputPasswordToggle,
  33140. Item,
  33141. ItemDivider,
  33142. ItemGroup,
  33143. ItemOption,
  33144. ItemOptions,
  33145. ItemSliding,
  33146. Label,
  33147. List,
  33148. ListHeader,
  33149. Loading,
  33150. Menu,
  33151. MenuButton,
  33152. MenuToggle,
  33153. Modal,
  33154. Nav,
  33155. NavLink,
  33156. Note,
  33157. Picker$1,
  33158. Picker,
  33159. PickerColumn,
  33160. PickerColumnCmp,
  33161. PickerColumnOption,
  33162. Popover,
  33163. ProgressBar,
  33164. Radio,
  33165. RadioGroup,
  33166. Range,
  33167. Refresher,
  33168. RefresherContent,
  33169. Reorder,
  33170. ReorderGroup,
  33171. RippleEffect,
  33172. Route,
  33173. RouteRedirect,
  33174. Router,
  33175. RouterLink,
  33176. RouterOutlet,
  33177. Row,
  33178. Searchbar,
  33179. Segment,
  33180. SegmentButton,
  33181. SegmentContent,
  33182. SegmentView,
  33183. Select,
  33184. SelectModal,
  33185. SelectOption,
  33186. SelectPopover,
  33187. SkeletonText,
  33188. Spinner,
  33189. SplitPane,
  33190. Tab,
  33191. TabBar,
  33192. TabButton,
  33193. Tabs,
  33194. Text,
  33195. Textarea,
  33196. Thumbnail,
  33197. Toast,
  33198. Toggle,
  33199. Toolbar,
  33200. ToolbarTitle,
  33201. ]);
  33202. const DURATION = 540;
  33203. // TODO(FW-2832): types
  33204. const getClonedElement = (tagName) => {
  33205. return document.querySelector(`${tagName}.ion-cloned-element`);
  33206. };
  33207. const shadow = (el) => {
  33208. return el.shadowRoot || el;
  33209. };
  33210. const getLargeTitle = (refEl) => {
  33211. const tabs = refEl.tagName === 'ION-TABS' ? refEl : refEl.querySelector('ion-tabs');
  33212. const query = 'ion-content ion-header:not(.header-collapse-condense-inactive) ion-title.title-large';
  33213. if (tabs != null) {
  33214. const activeTab = tabs.querySelector('ion-tab:not(.tab-hidden), .ion-page:not(.ion-page-hidden)');
  33215. return activeTab != null ? activeTab.querySelector(query) : null;
  33216. }
  33217. return refEl.querySelector(query);
  33218. };
  33219. const getBackButton = (refEl, backDirection) => {
  33220. const tabs = refEl.tagName === 'ION-TABS' ? refEl : refEl.querySelector('ion-tabs');
  33221. let buttonsList = [];
  33222. if (tabs != null) {
  33223. const activeTab = tabs.querySelector('ion-tab:not(.tab-hidden), .ion-page:not(.ion-page-hidden)');
  33224. if (activeTab != null) {
  33225. buttonsList = activeTab.querySelectorAll('ion-buttons');
  33226. }
  33227. }
  33228. else {
  33229. buttonsList = refEl.querySelectorAll('ion-buttons');
  33230. }
  33231. for (const buttons of buttonsList) {
  33232. const parentHeader = buttons.closest('ion-header');
  33233. const activeHeader = parentHeader && !parentHeader.classList.contains('header-collapse-condense-inactive');
  33234. const backButton = buttons.querySelector('ion-back-button');
  33235. const buttonsCollapse = buttons.classList.contains('buttons-collapse');
  33236. const startSlot = buttons.slot === 'start' || buttons.slot === '';
  33237. if (backButton !== null && startSlot && ((buttonsCollapse && activeHeader && backDirection) || !buttonsCollapse)) {
  33238. return backButton;
  33239. }
  33240. }
  33241. return null;
  33242. };
  33243. const createLargeTitleTransition = (rootAnimation, rtl, backDirection, enteringEl, leavingEl) => {
  33244. const enteringBackButton = getBackButton(enteringEl, backDirection);
  33245. const leavingLargeTitle = getLargeTitle(leavingEl);
  33246. const enteringLargeTitle = getLargeTitle(enteringEl);
  33247. const leavingBackButton = getBackButton(leavingEl, backDirection);
  33248. const shouldAnimationForward = enteringBackButton !== null && leavingLargeTitle !== null && !backDirection;
  33249. const shouldAnimationBackward = enteringLargeTitle !== null && leavingBackButton !== null && backDirection;
  33250. if (shouldAnimationForward) {
  33251. const leavingLargeTitleBox = leavingLargeTitle.getBoundingClientRect();
  33252. const enteringBackButtonBox = enteringBackButton.getBoundingClientRect();
  33253. const enteringBackButtonTextEl = shadow(enteringBackButton).querySelector('.button-text');
  33254. // Text element not rendered if developers pass text="" to the back button
  33255. const enteringBackButtonTextBox = enteringBackButtonTextEl === null || enteringBackButtonTextEl === void 0 ? void 0 : enteringBackButtonTextEl.getBoundingClientRect();
  33256. const leavingLargeTitleTextEl = shadow(leavingLargeTitle).querySelector('.toolbar-title');
  33257. const leavingLargeTitleTextBox = leavingLargeTitleTextEl.getBoundingClientRect();
  33258. animateLargeTitle(rootAnimation, rtl, backDirection, leavingLargeTitle, leavingLargeTitleBox, leavingLargeTitleTextBox, enteringBackButtonBox, enteringBackButtonTextEl, enteringBackButtonTextBox);
  33259. animateBackButton(rootAnimation, rtl, backDirection, enteringBackButton, enteringBackButtonBox, enteringBackButtonTextEl, enteringBackButtonTextBox, leavingLargeTitle, leavingLargeTitleTextBox);
  33260. }
  33261. else if (shouldAnimationBackward) {
  33262. const enteringLargeTitleBox = enteringLargeTitle.getBoundingClientRect();
  33263. const leavingBackButtonBox = leavingBackButton.getBoundingClientRect();
  33264. const leavingBackButtonTextEl = shadow(leavingBackButton).querySelector('.button-text');
  33265. // Text element not rendered if developers pass text="" to the back button
  33266. const leavingBackButtonTextBox = leavingBackButtonTextEl === null || leavingBackButtonTextEl === void 0 ? void 0 : leavingBackButtonTextEl.getBoundingClientRect();
  33267. const enteringLargeTitleTextEl = shadow(enteringLargeTitle).querySelector('.toolbar-title');
  33268. const enteringLargeTitleTextBox = enteringLargeTitleTextEl.getBoundingClientRect();
  33269. animateLargeTitle(rootAnimation, rtl, backDirection, enteringLargeTitle, enteringLargeTitleBox, enteringLargeTitleTextBox, leavingBackButtonBox, leavingBackButtonTextEl, leavingBackButtonTextBox);
  33270. animateBackButton(rootAnimation, rtl, backDirection, leavingBackButton, leavingBackButtonBox, leavingBackButtonTextEl, leavingBackButtonTextBox, enteringLargeTitle, enteringLargeTitleTextBox);
  33271. }
  33272. return {
  33273. forward: shouldAnimationForward,
  33274. backward: shouldAnimationBackward,
  33275. };
  33276. };
  33277. const animateBackButton = (rootAnimation, rtl, backDirection, backButtonEl, backButtonBox, backButtonTextEl, backButtonTextBox, largeTitleEl, largeTitleTextBox) => {
  33278. var _a, _b;
  33279. const BACK_BUTTON_START_OFFSET = rtl ? `calc(100% - ${backButtonBox.right + 4}px)` : `${backButtonBox.left - 4}px`;
  33280. const TEXT_ORIGIN_X = rtl ? 'right' : 'left';
  33281. const ICON_ORIGIN_X = rtl ? 'left' : 'right';
  33282. const CONTAINER_ORIGIN_X = rtl ? 'right' : 'left';
  33283. let WIDTH_SCALE = 1;
  33284. let HEIGHT_SCALE = 1;
  33285. let TEXT_START_SCALE = `scale(${HEIGHT_SCALE})`;
  33286. const TEXT_END_SCALE = 'scale(1)';
  33287. if (backButtonTextEl && backButtonTextBox) {
  33288. /**
  33289. * When the title and back button texts match then they should overlap during the
  33290. * page transition. If the texts do not match up then the back button text scale
  33291. * adjusts to not perfectly match the large title text otherwise the proportions
  33292. * will be incorrect. When the texts match we scale both the width and height to
  33293. * account for font weight differences between the title and back button.
  33294. */
  33295. const doTitleAndButtonTextsMatch = ((_a = backButtonTextEl.textContent) === null || _a === void 0 ? void 0 : _a.trim()) === ((_b = largeTitleEl.textContent) === null || _b === void 0 ? void 0 : _b.trim());
  33296. WIDTH_SCALE = largeTitleTextBox.width / backButtonTextBox.width;
  33297. /**
  33298. * Subtract an offset to account for slight sizing/padding differences between the
  33299. * title and the back button.
  33300. */
  33301. HEIGHT_SCALE = (largeTitleTextBox.height - LARGE_TITLE_SIZE_OFFSET) / backButtonTextBox.height;
  33302. /**
  33303. * Even though we set TEXT_START_SCALE to HEIGHT_SCALE above, we potentially need
  33304. * to re-compute this here since the HEIGHT_SCALE may have changed.
  33305. */
  33306. TEXT_START_SCALE = doTitleAndButtonTextsMatch ? `scale(${WIDTH_SCALE}, ${HEIGHT_SCALE})` : `scale(${HEIGHT_SCALE})`;
  33307. }
  33308. const backButtonIconEl = shadow(backButtonEl).querySelector('ion-icon');
  33309. const backButtonIconBox = backButtonIconEl.getBoundingClientRect();
  33310. /**
  33311. * We need to offset the container by the icon dimensions
  33312. * so that the back button text aligns with the large title
  33313. * text. Otherwise, the back button icon will align with the
  33314. * large title text but the back button text will not.
  33315. */
  33316. const CONTAINER_START_TRANSLATE_X = rtl
  33317. ? `${backButtonIconBox.width / 2 - (backButtonIconBox.right - backButtonBox.right)}px`
  33318. : `${backButtonBox.left - backButtonIconBox.width / 2}px`;
  33319. const CONTAINER_END_TRANSLATE_X = rtl ? `-${window.innerWidth - backButtonBox.right}px` : `${backButtonBox.left}px`;
  33320. /**
  33321. * Back button container should be
  33322. * aligned to the top of the title container
  33323. * so the texts overlap as the back button
  33324. * text begins to fade in.
  33325. */
  33326. const CONTAINER_START_TRANSLATE_Y = `${largeTitleTextBox.top}px`;
  33327. /**
  33328. * The cloned back button should align exactly with the
  33329. * real back button on the entering page otherwise there will
  33330. * be a layout shift.
  33331. */
  33332. const CONTAINER_END_TRANSLATE_Y = `${backButtonBox.top}px`;
  33333. /**
  33334. * In the forward direction, the cloned back button
  33335. * container should translate from over the large title
  33336. * to over the back button. In the backward direction,
  33337. * it should translate from over the back button to over
  33338. * the large title.
  33339. */
  33340. const FORWARD_CONTAINER_KEYFRAMES = [
  33341. { offset: 0, transform: `translate3d(${CONTAINER_START_TRANSLATE_X}, ${CONTAINER_START_TRANSLATE_Y}, 0)` },
  33342. { offset: 1, transform: `translate3d(${CONTAINER_END_TRANSLATE_X}, ${CONTAINER_END_TRANSLATE_Y}, 0)` },
  33343. ];
  33344. const BACKWARD_CONTAINER_KEYFRAMES = [
  33345. { offset: 0, transform: `translate3d(${CONTAINER_END_TRANSLATE_X}, ${CONTAINER_END_TRANSLATE_Y}, 0)` },
  33346. { offset: 1, transform: `translate3d(${CONTAINER_START_TRANSLATE_X}, ${CONTAINER_START_TRANSLATE_Y}, 0)` },
  33347. ];
  33348. const CONTAINER_KEYFRAMES = backDirection ? BACKWARD_CONTAINER_KEYFRAMES : FORWARD_CONTAINER_KEYFRAMES;
  33349. /**
  33350. * In the forward direction, the text in the cloned back button
  33351. * should start to be (roughly) the size of the large title
  33352. * and then scale down to be the size of the actual back button.
  33353. * The text should also translate, but that translate is handled
  33354. * by the container keyframes.
  33355. */
  33356. const FORWARD_TEXT_KEYFRAMES = [
  33357. { offset: 0, opacity: 0, transform: TEXT_START_SCALE },
  33358. { offset: 1, opacity: 1, transform: TEXT_END_SCALE },
  33359. ];
  33360. const BACKWARD_TEXT_KEYFRAMES = [
  33361. { offset: 0, opacity: 1, transform: TEXT_END_SCALE },
  33362. { offset: 1, opacity: 0, transform: TEXT_START_SCALE },
  33363. ];
  33364. const TEXT_KEYFRAMES = backDirection ? BACKWARD_TEXT_KEYFRAMES : FORWARD_TEXT_KEYFRAMES;
  33365. /**
  33366. * The icon should scale in/out in the second
  33367. * half of the animation. The icon should also
  33368. * translate, but that translate is handled by the
  33369. * container keyframes.
  33370. */
  33371. const FORWARD_ICON_KEYFRAMES = [
  33372. { offset: 0, opacity: 0, transform: 'scale(0.6)' },
  33373. { offset: 0.6, opacity: 0, transform: 'scale(0.6)' },
  33374. { offset: 1, opacity: 1, transform: 'scale(1)' },
  33375. ];
  33376. const BACKWARD_ICON_KEYFRAMES = [
  33377. { offset: 0, opacity: 1, transform: 'scale(1)' },
  33378. { offset: 0.2, opacity: 0, transform: 'scale(0.6)' },
  33379. { offset: 1, opacity: 0, transform: 'scale(0.6)' },
  33380. ];
  33381. const ICON_KEYFRAMES = backDirection ? BACKWARD_ICON_KEYFRAMES : FORWARD_ICON_KEYFRAMES;
  33382. const enteringBackButtonTextAnimation = createAnimation();
  33383. const enteringBackButtonIconAnimation = createAnimation();
  33384. const enteringBackButtonAnimation = createAnimation();
  33385. const clonedBackButtonEl = getClonedElement('ion-back-button');
  33386. const clonedBackButtonTextEl = shadow(clonedBackButtonEl).querySelector('.button-text');
  33387. const clonedBackButtonIconEl = shadow(clonedBackButtonEl).querySelector('ion-icon');
  33388. clonedBackButtonEl.text = backButtonEl.text;
  33389. clonedBackButtonEl.mode = backButtonEl.mode;
  33390. clonedBackButtonEl.icon = backButtonEl.icon;
  33391. clonedBackButtonEl.color = backButtonEl.color;
  33392. clonedBackButtonEl.disabled = backButtonEl.disabled;
  33393. clonedBackButtonEl.style.setProperty('display', 'block');
  33394. clonedBackButtonEl.style.setProperty('position', 'fixed');
  33395. enteringBackButtonIconAnimation.addElement(clonedBackButtonIconEl);
  33396. enteringBackButtonTextAnimation.addElement(clonedBackButtonTextEl);
  33397. enteringBackButtonAnimation.addElement(clonedBackButtonEl);
  33398. enteringBackButtonAnimation
  33399. .beforeStyles({
  33400. position: 'absolute',
  33401. top: '0px',
  33402. [CONTAINER_ORIGIN_X]: '0px',
  33403. })
  33404. /**
  33405. * The write hooks must be set on this animation as it is guaranteed to run. Other
  33406. * animations such as the back button text animation will not run if the back button
  33407. * has no visible text.
  33408. */
  33409. .beforeAddWrite(() => {
  33410. backButtonEl.style.setProperty('display', 'none');
  33411. clonedBackButtonEl.style.setProperty(TEXT_ORIGIN_X, BACK_BUTTON_START_OFFSET);
  33412. })
  33413. .afterAddWrite(() => {
  33414. backButtonEl.style.setProperty('display', '');
  33415. clonedBackButtonEl.style.setProperty('display', 'none');
  33416. clonedBackButtonEl.style.removeProperty(TEXT_ORIGIN_X);
  33417. })
  33418. .keyframes(CONTAINER_KEYFRAMES);
  33419. enteringBackButtonTextAnimation
  33420. .beforeStyles({
  33421. 'transform-origin': `${TEXT_ORIGIN_X} top`,
  33422. })
  33423. .keyframes(TEXT_KEYFRAMES);
  33424. enteringBackButtonIconAnimation
  33425. .beforeStyles({
  33426. 'transform-origin': `${ICON_ORIGIN_X} center`,
  33427. })
  33428. .keyframes(ICON_KEYFRAMES);
  33429. rootAnimation.addAnimation([
  33430. enteringBackButtonTextAnimation,
  33431. enteringBackButtonIconAnimation,
  33432. enteringBackButtonAnimation,
  33433. ]);
  33434. };
  33435. const animateLargeTitle = (rootAnimation, rtl, backDirection, largeTitleEl, largeTitleBox, largeTitleTextBox, backButtonBox, backButtonTextEl, backButtonTextBox) => {
  33436. var _a, _b;
  33437. /**
  33438. * The horizontal transform origin for the large title
  33439. */
  33440. const ORIGIN_X = rtl ? 'right' : 'left';
  33441. const TITLE_START_OFFSET = rtl ? `calc(100% - ${largeTitleBox.right}px)` : `${largeTitleBox.left}px`;
  33442. /**
  33443. * The cloned large should align exactly with the
  33444. * real large title on the leaving page otherwise there will
  33445. * be a layout shift.
  33446. */
  33447. const START_TRANSLATE_X = '0px';
  33448. const START_TRANSLATE_Y = `${largeTitleBox.top}px`;
  33449. /**
  33450. * How much to offset the large title translation by.
  33451. * This accounts for differences in sizing between the large
  33452. * title and the back button due to padding and font weight.
  33453. */
  33454. const LARGE_TITLE_TRANSLATION_OFFSET = 8;
  33455. let END_TRANSLATE_X = rtl
  33456. ? `-${window.innerWidth - backButtonBox.right - LARGE_TITLE_TRANSLATION_OFFSET}px`
  33457. : `${backButtonBox.x + LARGE_TITLE_TRANSLATION_OFFSET}px`;
  33458. /**
  33459. * How much to scale the large title up/down by.
  33460. */
  33461. let HEIGHT_SCALE = 0.5;
  33462. /**
  33463. * The large title always starts full size.
  33464. */
  33465. const START_SCALE = 'scale(1)';
  33466. /**
  33467. * By default, we don't worry about having the large title scaled to perfectly
  33468. * match the back button because we don't know if the back button's text matches
  33469. * the large title's text.
  33470. */
  33471. let END_SCALE = `scale(${HEIGHT_SCALE})`;
  33472. // Text element not rendered if developers pass text="" to the back button
  33473. if (backButtonTextEl && backButtonTextBox) {
  33474. /**
  33475. * The scaled title should (roughly) overlap the back button. This ensures that
  33476. * the back button and title overlap during the animation. Note that since both
  33477. * elements either fade in or fade out over the course of the animation, neither
  33478. * element will be fully visible on top of the other. As a result, the overlap
  33479. * does not need to be perfect, so approximate values are acceptable here.
  33480. */
  33481. END_TRANSLATE_X = rtl
  33482. ? `-${window.innerWidth - backButtonTextBox.right - LARGE_TITLE_TRANSLATION_OFFSET}px`
  33483. : `${backButtonTextBox.x - LARGE_TITLE_TRANSLATION_OFFSET}px`;
  33484. /**
  33485. * In the forward direction, the large title should start at its normal size and
  33486. * then scale down to be (roughly) the size of the back button on the other view.
  33487. * In the backward direction, the large title should start at (roughly) the size
  33488. * of the back button and then scale up to its original size.
  33489. * Note that since both elements either fade in or fade out over the course of the
  33490. * animation, neither element will be fully visible on top of the other. As a result,
  33491. * the overlap does not need to be perfect, so approximate values are acceptable here.
  33492. */
  33493. /**
  33494. * When the title and back button texts match then they should overlap during the
  33495. * page transition. If the texts do not match up then the large title text scale
  33496. * adjusts to not perfectly match the back button text otherwise the proportions
  33497. * will be incorrect. When the texts match we scale both the width and height to
  33498. * account for font weight differences between the title and back button.
  33499. */
  33500. const doTitleAndButtonTextsMatch = ((_a = backButtonTextEl.textContent) === null || _a === void 0 ? void 0 : _a.trim()) === ((_b = largeTitleEl.textContent) === null || _b === void 0 ? void 0 : _b.trim());
  33501. const WIDTH_SCALE = backButtonTextBox.width / largeTitleTextBox.width;
  33502. HEIGHT_SCALE = backButtonTextBox.height / (largeTitleTextBox.height - LARGE_TITLE_SIZE_OFFSET);
  33503. /**
  33504. * Even though we set TEXT_START_SCALE to HEIGHT_SCALE above, we potentially need
  33505. * to re-compute this here since the HEIGHT_SCALE may have changed.
  33506. */
  33507. END_SCALE = doTitleAndButtonTextsMatch ? `scale(${WIDTH_SCALE}, ${HEIGHT_SCALE})` : `scale(${HEIGHT_SCALE})`;
  33508. }
  33509. /**
  33510. * The midpoints of the back button and the title should align such that the back
  33511. * button and title appear to be centered with each other.
  33512. */
  33513. const backButtonMidPoint = backButtonBox.top + backButtonBox.height / 2;
  33514. const titleMidPoint = (largeTitleBox.height * HEIGHT_SCALE) / 2;
  33515. const END_TRANSLATE_Y = `${backButtonMidPoint - titleMidPoint}px`;
  33516. const BACKWARDS_KEYFRAMES = [
  33517. { offset: 0, opacity: 0, transform: `translate3d(${END_TRANSLATE_X}, ${END_TRANSLATE_Y}, 0) ${END_SCALE}` },
  33518. { offset: 0.1, opacity: 0 },
  33519. { offset: 1, opacity: 1, transform: `translate3d(${START_TRANSLATE_X}, ${START_TRANSLATE_Y}, 0) ${START_SCALE}` },
  33520. ];
  33521. const FORWARDS_KEYFRAMES = [
  33522. {
  33523. offset: 0,
  33524. opacity: 0.99,
  33525. transform: `translate3d(${START_TRANSLATE_X}, ${START_TRANSLATE_Y}, 0) ${START_SCALE}`,
  33526. },
  33527. { offset: 0.6, opacity: 0 },
  33528. { offset: 1, opacity: 0, transform: `translate3d(${END_TRANSLATE_X}, ${END_TRANSLATE_Y}, 0) ${END_SCALE}` },
  33529. ];
  33530. const KEYFRAMES = backDirection ? BACKWARDS_KEYFRAMES : FORWARDS_KEYFRAMES;
  33531. const clonedTitleEl = getClonedElement('ion-title');
  33532. const clonedLargeTitleAnimation = createAnimation();
  33533. clonedTitleEl.innerText = largeTitleEl.innerText;
  33534. clonedTitleEl.size = largeTitleEl.size;
  33535. clonedTitleEl.color = largeTitleEl.color;
  33536. clonedLargeTitleAnimation.addElement(clonedTitleEl);
  33537. clonedLargeTitleAnimation
  33538. .beforeStyles({
  33539. 'transform-origin': `${ORIGIN_X} top`,
  33540. /**
  33541. * Since font size changes will cause
  33542. * the dimension of the large title to change
  33543. * we need to set the cloned title height
  33544. * equal to that of the original large title height.
  33545. */
  33546. height: `${largeTitleBox.height}px`,
  33547. display: '',
  33548. position: 'relative',
  33549. [ORIGIN_X]: TITLE_START_OFFSET,
  33550. })
  33551. .beforeAddWrite(() => {
  33552. largeTitleEl.style.setProperty('opacity', '0');
  33553. })
  33554. .afterAddWrite(() => {
  33555. largeTitleEl.style.setProperty('opacity', '');
  33556. clonedTitleEl.style.setProperty('display', 'none');
  33557. })
  33558. .keyframes(KEYFRAMES);
  33559. rootAnimation.addAnimation(clonedLargeTitleAnimation);
  33560. };
  33561. const iosTransitionAnimation = (navEl, opts) => {
  33562. var _a;
  33563. try {
  33564. const EASING = 'cubic-bezier(0.32,0.72,0,1)';
  33565. const OPACITY = 'opacity';
  33566. const TRANSFORM = 'transform';
  33567. const CENTER = '0%';
  33568. const OFF_OPACITY = 0.8;
  33569. const isRTL = navEl.ownerDocument.dir === 'rtl';
  33570. const OFF_RIGHT = isRTL ? '-99.5%' : '99.5%';
  33571. const OFF_LEFT = isRTL ? '33%' : '-33%';
  33572. const enteringEl = opts.enteringEl;
  33573. const leavingEl = opts.leavingEl;
  33574. const backDirection = opts.direction === 'back';
  33575. const contentEl = enteringEl.querySelector(':scope > ion-content');
  33576. const headerEls = enteringEl.querySelectorAll(':scope > ion-header > *:not(ion-toolbar), :scope > ion-footer > *');
  33577. const enteringToolBarEls = enteringEl.querySelectorAll(':scope > ion-header > ion-toolbar');
  33578. const rootAnimation = createAnimation();
  33579. const enteringContentAnimation = createAnimation();
  33580. rootAnimation
  33581. .addElement(enteringEl)
  33582. .duration(((_a = opts.duration) !== null && _a !== void 0 ? _a : 0) || DURATION)
  33583. .easing(opts.easing || EASING)
  33584. .fill('both')
  33585. .beforeRemoveClass('ion-page-invisible');
  33586. // eslint-disable-next-line @typescript-eslint/prefer-optional-chain
  33587. if (leavingEl && navEl !== null && navEl !== undefined) {
  33588. const navDecorAnimation = createAnimation();
  33589. navDecorAnimation.addElement(navEl);
  33590. rootAnimation.addAnimation(navDecorAnimation);
  33591. }
  33592. if (!contentEl && enteringToolBarEls.length === 0 && headerEls.length === 0) {
  33593. enteringContentAnimation.addElement(enteringEl.querySelector(':scope > .ion-page, :scope > ion-nav, :scope > ion-tabs')); // REVIEW
  33594. }
  33595. else {
  33596. enteringContentAnimation.addElement(contentEl); // REVIEW
  33597. enteringContentAnimation.addElement(headerEls);
  33598. }
  33599. rootAnimation.addAnimation(enteringContentAnimation);
  33600. if (backDirection) {
  33601. enteringContentAnimation
  33602. .beforeClearStyles([OPACITY])
  33603. .fromTo('transform', `translateX(${OFF_LEFT})`, `translateX(${CENTER})`)
  33604. .fromTo(OPACITY, OFF_OPACITY, 1);
  33605. }
  33606. else {
  33607. // entering content, forward direction
  33608. enteringContentAnimation
  33609. .beforeClearStyles([OPACITY])
  33610. .fromTo('transform', `translateX(${OFF_RIGHT})`, `translateX(${CENTER})`);
  33611. }
  33612. if (contentEl) {
  33613. const enteringTransitionEffectEl = shadow(contentEl).querySelector('.transition-effect');
  33614. if (enteringTransitionEffectEl) {
  33615. const enteringTransitionCoverEl = enteringTransitionEffectEl.querySelector('.transition-cover');
  33616. const enteringTransitionShadowEl = enteringTransitionEffectEl.querySelector('.transition-shadow');
  33617. const enteringTransitionEffect = createAnimation();
  33618. const enteringTransitionCover = createAnimation();
  33619. const enteringTransitionShadow = createAnimation();
  33620. enteringTransitionEffect
  33621. .addElement(enteringTransitionEffectEl)
  33622. .beforeStyles({ opacity: '1', display: 'block' })
  33623. .afterStyles({ opacity: '', display: '' });
  33624. enteringTransitionCover
  33625. .addElement(enteringTransitionCoverEl) // REVIEW
  33626. .beforeClearStyles([OPACITY])
  33627. .fromTo(OPACITY, 0, 0.1);
  33628. enteringTransitionShadow
  33629. .addElement(enteringTransitionShadowEl) // REVIEW
  33630. .beforeClearStyles([OPACITY])
  33631. .fromTo(OPACITY, 0.03, 0.7);
  33632. enteringTransitionEffect.addAnimation([enteringTransitionCover, enteringTransitionShadow]);
  33633. enteringContentAnimation.addAnimation([enteringTransitionEffect]);
  33634. }
  33635. }
  33636. const enteringContentHasLargeTitle = enteringEl.querySelector('ion-header.header-collapse-condense');
  33637. const { forward, backward } = createLargeTitleTransition(rootAnimation, isRTL, backDirection, enteringEl, leavingEl);
  33638. enteringToolBarEls.forEach((enteringToolBarEl) => {
  33639. const enteringToolBar = createAnimation();
  33640. enteringToolBar.addElement(enteringToolBarEl);
  33641. rootAnimation.addAnimation(enteringToolBar);
  33642. const enteringTitle = createAnimation();
  33643. enteringTitle.addElement(enteringToolBarEl.querySelector('ion-title')); // REVIEW
  33644. const enteringToolBarButtons = createAnimation();
  33645. const buttons = Array.from(enteringToolBarEl.querySelectorAll('ion-buttons,[menuToggle]'));
  33646. const parentHeader = enteringToolBarEl.closest('ion-header');
  33647. const inactiveHeader = parentHeader === null || parentHeader === void 0 ? void 0 : parentHeader.classList.contains('header-collapse-condense-inactive');
  33648. let buttonsToAnimate;
  33649. if (backDirection) {
  33650. buttonsToAnimate = buttons.filter((button) => {
  33651. const isCollapseButton = button.classList.contains('buttons-collapse');
  33652. return (isCollapseButton && !inactiveHeader) || !isCollapseButton;
  33653. });
  33654. }
  33655. else {
  33656. buttonsToAnimate = buttons.filter((button) => !button.classList.contains('buttons-collapse'));
  33657. }
  33658. enteringToolBarButtons.addElement(buttonsToAnimate);
  33659. const enteringToolBarItems = createAnimation();
  33660. enteringToolBarItems.addElement(enteringToolBarEl.querySelectorAll(':scope > *:not(ion-title):not(ion-buttons):not([menuToggle])'));
  33661. const enteringToolBarBg = createAnimation();
  33662. enteringToolBarBg.addElement(shadow(enteringToolBarEl).querySelector('.toolbar-background')); // REVIEW
  33663. const enteringBackButton = createAnimation();
  33664. const backButtonEl = enteringToolBarEl.querySelector('ion-back-button');
  33665. if (backButtonEl) {
  33666. enteringBackButton.addElement(backButtonEl);
  33667. }
  33668. enteringToolBar.addAnimation([
  33669. enteringTitle,
  33670. enteringToolBarButtons,
  33671. enteringToolBarItems,
  33672. enteringToolBarBg,
  33673. enteringBackButton,
  33674. ]);
  33675. enteringToolBarButtons.fromTo(OPACITY, 0.01, 1);
  33676. enteringToolBarItems.fromTo(OPACITY, 0.01, 1);
  33677. if (backDirection) {
  33678. if (!inactiveHeader) {
  33679. enteringTitle
  33680. .fromTo('transform', `translateX(${OFF_LEFT})`, `translateX(${CENTER})`)
  33681. .fromTo(OPACITY, 0.01, 1);
  33682. }
  33683. enteringToolBarItems.fromTo('transform', `translateX(${OFF_LEFT})`, `translateX(${CENTER})`);
  33684. // back direction, entering page has a back button
  33685. enteringBackButton.fromTo(OPACITY, 0.01, 1);
  33686. }
  33687. else {
  33688. // entering toolbar, forward direction
  33689. if (!enteringContentHasLargeTitle) {
  33690. enteringTitle
  33691. .fromTo('transform', `translateX(${OFF_RIGHT})`, `translateX(${CENTER})`)
  33692. .fromTo(OPACITY, 0.01, 1);
  33693. }
  33694. enteringToolBarItems.fromTo('transform', `translateX(${OFF_RIGHT})`, `translateX(${CENTER})`);
  33695. enteringToolBarBg.beforeClearStyles([OPACITY, 'transform']);
  33696. const translucentHeader = parentHeader === null || parentHeader === void 0 ? void 0 : parentHeader.translucent;
  33697. if (!translucentHeader) {
  33698. enteringToolBarBg.fromTo(OPACITY, 0.01, 'var(--opacity)');
  33699. }
  33700. else {
  33701. enteringToolBarBg.fromTo('transform', isRTL ? 'translateX(-100%)' : 'translateX(100%)', 'translateX(0px)');
  33702. }
  33703. // forward direction, entering page has a back button
  33704. if (!forward) {
  33705. enteringBackButton.fromTo(OPACITY, 0.01, 1);
  33706. }
  33707. if (backButtonEl && !forward) {
  33708. const enteringBackBtnText = createAnimation();
  33709. enteringBackBtnText
  33710. .addElement(shadow(backButtonEl).querySelector('.button-text')) // REVIEW
  33711. .fromTo(`transform`, isRTL ? 'translateX(-100px)' : 'translateX(100px)', 'translateX(0px)');
  33712. enteringToolBar.addAnimation(enteringBackBtnText);
  33713. }
  33714. }
  33715. });
  33716. // setup leaving view
  33717. if (leavingEl) {
  33718. const leavingContent = createAnimation();
  33719. const leavingContentEl = leavingEl.querySelector(':scope > ion-content');
  33720. const leavingToolBarEls = leavingEl.querySelectorAll(':scope > ion-header > ion-toolbar');
  33721. const leavingHeaderEls = leavingEl.querySelectorAll(':scope > ion-header > *:not(ion-toolbar), :scope > ion-footer > *');
  33722. if (!leavingContentEl && leavingToolBarEls.length === 0 && leavingHeaderEls.length === 0) {
  33723. leavingContent.addElement(leavingEl.querySelector(':scope > .ion-page, :scope > ion-nav, :scope > ion-tabs')); // REVIEW
  33724. }
  33725. else {
  33726. leavingContent.addElement(leavingContentEl); // REVIEW
  33727. leavingContent.addElement(leavingHeaderEls);
  33728. }
  33729. rootAnimation.addAnimation(leavingContent);
  33730. if (backDirection) {
  33731. // leaving content, back direction
  33732. leavingContent
  33733. .beforeClearStyles([OPACITY])
  33734. .fromTo('transform', `translateX(${CENTER})`, isRTL ? 'translateX(-100%)' : 'translateX(100%)');
  33735. const leavingPage = getIonPageElement(leavingEl);
  33736. rootAnimation.afterAddWrite(() => {
  33737. if (rootAnimation.getDirection() === 'normal') {
  33738. leavingPage.style.setProperty('display', 'none');
  33739. }
  33740. });
  33741. }
  33742. else {
  33743. // leaving content, forward direction
  33744. leavingContent
  33745. .fromTo('transform', `translateX(${CENTER})`, `translateX(${OFF_LEFT})`)
  33746. .fromTo(OPACITY, 1, OFF_OPACITY);
  33747. }
  33748. if (leavingContentEl) {
  33749. const leavingTransitionEffectEl = shadow(leavingContentEl).querySelector('.transition-effect');
  33750. if (leavingTransitionEffectEl) {
  33751. const leavingTransitionCoverEl = leavingTransitionEffectEl.querySelector('.transition-cover');
  33752. const leavingTransitionShadowEl = leavingTransitionEffectEl.querySelector('.transition-shadow');
  33753. const leavingTransitionEffect = createAnimation();
  33754. const leavingTransitionCover = createAnimation();
  33755. const leavingTransitionShadow = createAnimation();
  33756. leavingTransitionEffect
  33757. .addElement(leavingTransitionEffectEl)
  33758. .beforeStyles({ opacity: '1', display: 'block' })
  33759. .afterStyles({ opacity: '', display: '' });
  33760. leavingTransitionCover
  33761. .addElement(leavingTransitionCoverEl) // REVIEW
  33762. .beforeClearStyles([OPACITY])
  33763. .fromTo(OPACITY, 0.1, 0);
  33764. leavingTransitionShadow
  33765. .addElement(leavingTransitionShadowEl) // REVIEW
  33766. .beforeClearStyles([OPACITY])
  33767. .fromTo(OPACITY, 0.7, 0.03);
  33768. leavingTransitionEffect.addAnimation([leavingTransitionCover, leavingTransitionShadow]);
  33769. leavingContent.addAnimation([leavingTransitionEffect]);
  33770. }
  33771. }
  33772. leavingToolBarEls.forEach((leavingToolBarEl) => {
  33773. const leavingToolBar = createAnimation();
  33774. leavingToolBar.addElement(leavingToolBarEl);
  33775. const leavingTitle = createAnimation();
  33776. leavingTitle.addElement(leavingToolBarEl.querySelector('ion-title')); // REVIEW
  33777. const leavingToolBarButtons = createAnimation();
  33778. const buttons = leavingToolBarEl.querySelectorAll('ion-buttons,[menuToggle]');
  33779. const parentHeader = leavingToolBarEl.closest('ion-header');
  33780. const inactiveHeader = parentHeader === null || parentHeader === void 0 ? void 0 : parentHeader.classList.contains('header-collapse-condense-inactive');
  33781. const buttonsToAnimate = Array.from(buttons).filter((button) => {
  33782. const isCollapseButton = button.classList.contains('buttons-collapse');
  33783. return (isCollapseButton && !inactiveHeader) || !isCollapseButton;
  33784. });
  33785. leavingToolBarButtons.addElement(buttonsToAnimate);
  33786. const leavingToolBarItems = createAnimation();
  33787. const leavingToolBarItemEls = leavingToolBarEl.querySelectorAll(':scope > *:not(ion-title):not(ion-buttons):not([menuToggle])');
  33788. if (leavingToolBarItemEls.length > 0) {
  33789. leavingToolBarItems.addElement(leavingToolBarItemEls);
  33790. }
  33791. const leavingToolBarBg = createAnimation();
  33792. leavingToolBarBg.addElement(shadow(leavingToolBarEl).querySelector('.toolbar-background')); // REVIEW
  33793. const leavingBackButton = createAnimation();
  33794. const backButtonEl = leavingToolBarEl.querySelector('ion-back-button');
  33795. if (backButtonEl) {
  33796. leavingBackButton.addElement(backButtonEl);
  33797. }
  33798. leavingToolBar.addAnimation([
  33799. leavingTitle,
  33800. leavingToolBarButtons,
  33801. leavingToolBarItems,
  33802. leavingBackButton,
  33803. leavingToolBarBg,
  33804. ]);
  33805. rootAnimation.addAnimation(leavingToolBar);
  33806. // fade out leaving toolbar items
  33807. leavingBackButton.fromTo(OPACITY, 0.99, 0);
  33808. leavingToolBarButtons.fromTo(OPACITY, 0.99, 0);
  33809. leavingToolBarItems.fromTo(OPACITY, 0.99, 0);
  33810. if (backDirection) {
  33811. if (!inactiveHeader) {
  33812. // leaving toolbar, back direction
  33813. leavingTitle
  33814. .fromTo('transform', `translateX(${CENTER})`, isRTL ? 'translateX(-100%)' : 'translateX(100%)')
  33815. .fromTo(OPACITY, 0.99, 0);
  33816. }
  33817. leavingToolBarItems.fromTo('transform', `translateX(${CENTER})`, isRTL ? 'translateX(-100%)' : 'translateX(100%)');
  33818. leavingToolBarBg.beforeClearStyles([OPACITY, 'transform']);
  33819. // leaving toolbar, back direction, and there's no entering toolbar
  33820. // should just slide out, no fading out
  33821. const translucentHeader = parentHeader === null || parentHeader === void 0 ? void 0 : parentHeader.translucent;
  33822. if (!translucentHeader) {
  33823. leavingToolBarBg.fromTo(OPACITY, 'var(--opacity)', 0);
  33824. }
  33825. else {
  33826. leavingToolBarBg.fromTo('transform', 'translateX(0px)', isRTL ? 'translateX(-100%)' : 'translateX(100%)');
  33827. }
  33828. if (backButtonEl && !backward) {
  33829. const leavingBackBtnText = createAnimation();
  33830. leavingBackBtnText
  33831. .addElement(shadow(backButtonEl).querySelector('.button-text')) // REVIEW
  33832. .fromTo('transform', `translateX(${CENTER})`, `translateX(${(isRTL ? -124 : 124) + 'px'})`);
  33833. leavingToolBar.addAnimation(leavingBackBtnText);
  33834. }
  33835. }
  33836. else {
  33837. // leaving toolbar, forward direction
  33838. if (!inactiveHeader) {
  33839. leavingTitle
  33840. .fromTo('transform', `translateX(${CENTER})`, `translateX(${OFF_LEFT})`)
  33841. .fromTo(OPACITY, 0.99, 0)
  33842. .afterClearStyles([TRANSFORM, OPACITY]);
  33843. }
  33844. leavingToolBarItems
  33845. .fromTo('transform', `translateX(${CENTER})`, `translateX(${OFF_LEFT})`)
  33846. .afterClearStyles([TRANSFORM, OPACITY]);
  33847. leavingBackButton.afterClearStyles([OPACITY]);
  33848. leavingTitle.afterClearStyles([OPACITY]);
  33849. leavingToolBarButtons.afterClearStyles([OPACITY]);
  33850. }
  33851. });
  33852. }
  33853. return rootAnimation;
  33854. }
  33855. catch (err) {
  33856. throw err;
  33857. }
  33858. };
  33859. /**
  33860. * The scale of the back button during the animation
  33861. * is computed based on the scale of the large title
  33862. * and vice versa. However, we need to account for slight
  33863. * variations in the size of the large title due to
  33864. * padding and font weight. This value should be used to subtract
  33865. * a small amount from the large title height when computing scales
  33866. * to get more accurate scale results.
  33867. */
  33868. const LARGE_TITLE_SIZE_OFFSET = 10;
  33869. var ios_transition = /*#__PURE__*/Object.freeze({
  33870. __proto__: null,
  33871. shadow: shadow,
  33872. iosTransitionAnimation: iosTransitionAnimation
  33873. });
  33874. const mdTransitionAnimation = (_, opts) => {
  33875. var _a, _b, _c;
  33876. const OFF_BOTTOM = '40px';
  33877. const CENTER = '0px';
  33878. const backDirection = opts.direction === 'back';
  33879. const enteringEl = opts.enteringEl;
  33880. const leavingEl = opts.leavingEl;
  33881. const ionPageElement = getIonPageElement(enteringEl);
  33882. const enteringToolbarEle = ionPageElement.querySelector('ion-toolbar');
  33883. const rootTransition = createAnimation();
  33884. rootTransition.addElement(ionPageElement).fill('both').beforeRemoveClass('ion-page-invisible');
  33885. // animate the component itself
  33886. if (backDirection) {
  33887. rootTransition.duration(((_a = opts.duration) !== null && _a !== void 0 ? _a : 0) || 200).easing('cubic-bezier(0.47,0,0.745,0.715)');
  33888. }
  33889. else {
  33890. rootTransition
  33891. .duration(((_b = opts.duration) !== null && _b !== void 0 ? _b : 0) || 280)
  33892. .easing('cubic-bezier(0.36,0.66,0.04,1)')
  33893. .fromTo('transform', `translateY(${OFF_BOTTOM})`, `translateY(${CENTER})`)
  33894. .fromTo('opacity', 0.01, 1);
  33895. }
  33896. // Animate toolbar if it's there
  33897. if (enteringToolbarEle) {
  33898. const enteringToolBar = createAnimation();
  33899. enteringToolBar.addElement(enteringToolbarEle);
  33900. rootTransition.addAnimation(enteringToolBar);
  33901. }
  33902. // setup leaving view
  33903. if (leavingEl && backDirection) {
  33904. // leaving content
  33905. rootTransition.duration(((_c = opts.duration) !== null && _c !== void 0 ? _c : 0) || 200).easing('cubic-bezier(0.47,0,0.745,0.715)');
  33906. const leavingPage = createAnimation();
  33907. leavingPage
  33908. .addElement(getIonPageElement(leavingEl))
  33909. .onFinish((currentStep) => {
  33910. if (currentStep === 1 && leavingPage.elements.length > 0) {
  33911. leavingPage.elements[0].style.setProperty('display', 'none');
  33912. }
  33913. })
  33914. .fromTo('transform', `translateY(${CENTER})`, `translateY(${OFF_BOTTOM})`)
  33915. .fromTo('opacity', 1, 0);
  33916. rootTransition.addAnimation(leavingPage);
  33917. }
  33918. return rootTransition;
  33919. };
  33920. var md_transition = /*#__PURE__*/Object.freeze({
  33921. __proto__: null,
  33922. mdTransitionAnimation: mdTransitionAnimation
  33923. });
  33924. const createSwipeBackGesture = (el, canStartHandler, onStartHandler, onMoveHandler, onEndHandler) => {
  33925. const win = el.ownerDocument.defaultView;
  33926. let rtl = isRTL$1(el);
  33927. /**
  33928. * Determine if a gesture is near the edge
  33929. * of the screen. If true, then the swipe
  33930. * to go back gesture should proceed.
  33931. */
  33932. const isAtEdge = (detail) => {
  33933. const threshold = 50;
  33934. const { startX } = detail;
  33935. if (rtl) {
  33936. return startX >= win.innerWidth - threshold;
  33937. }
  33938. return startX <= threshold;
  33939. };
  33940. const getDeltaX = (detail) => {
  33941. return rtl ? -detail.deltaX : detail.deltaX;
  33942. };
  33943. const getVelocityX = (detail) => {
  33944. return rtl ? -detail.velocityX : detail.velocityX;
  33945. };
  33946. const canStart = (detail) => {
  33947. /**
  33948. * The user's locale can change mid-session,
  33949. * so we need to check text direction at
  33950. * the beginning of every gesture.
  33951. */
  33952. rtl = isRTL$1(el);
  33953. return isAtEdge(detail) && canStartHandler();
  33954. };
  33955. const onMove = (detail) => {
  33956. // set the transition animation's progress
  33957. const delta = getDeltaX(detail);
  33958. const stepValue = delta / win.innerWidth;
  33959. onMoveHandler(stepValue);
  33960. };
  33961. const onEnd = (detail) => {
  33962. // the swipe back gesture has ended
  33963. const delta = getDeltaX(detail);
  33964. const width = win.innerWidth;
  33965. const stepValue = delta / width;
  33966. const velocity = getVelocityX(detail);
  33967. const z = width / 2.0;
  33968. const shouldComplete = velocity >= 0 && (velocity > 0.2 || delta > z);
  33969. const missing = shouldComplete ? 1 - stepValue : stepValue;
  33970. const missingDistance = missing * width;
  33971. let realDur = 0;
  33972. if (missingDistance > 5) {
  33973. const dur = missingDistance / Math.abs(velocity);
  33974. realDur = Math.min(dur, 540);
  33975. }
  33976. onEndHandler(shouldComplete, stepValue <= 0 ? 0.01 : clamp(0, stepValue, 0.9999), realDur);
  33977. };
  33978. return createGesture({
  33979. el,
  33980. gestureName: 'goback-swipe',
  33981. /**
  33982. * Swipe to go back should have priority over other horizontal swipe
  33983. * gestures. These gestures have a priority of 100 which is why 101 was chosen here.
  33984. */
  33985. gesturePriority: 101,
  33986. threshold: 10,
  33987. canStart,
  33988. onStart: onStartHandler,
  33989. onMove,
  33990. onEnd,
  33991. });
  33992. };
  33993. var swipeBack = /*#__PURE__*/Object.freeze({
  33994. __proto__: null,
  33995. createSwipeBackGesture: createSwipeBackGesture
  33996. });
  33997. exports.hydrateApp = hydrateApp;
  33998. /*hydrateAppClosure end*/
  33999. hydrateApp(window, $stencilHydrateOpts, $stencilHydrateResults, $stencilAfterHydrate, $stencilHydrateResolve);
  34000. }
  34001. hydrateAppClosure($stencilWindow);
  34002. }
  34003. /*
  34004. Stencil Hydrate Runner v4.20.0 | MIT Licensed | https://stenciljs.com
  34005. */
  34006. var __defProp = Object.defineProperty;
  34007. var __export = (target, all) => {
  34008. for (var name in all)
  34009. __defProp(target, name, { get: all[name], enumerable: true });
  34010. };
  34011. // src/runtime/runtime-constants.ts
  34012. var CONTENT_REF_ID = "r";
  34013. var ORG_LOCATION_ID = "o";
  34014. var SLOT_NODE_ID = "s";
  34015. var TEXT_NODE_ID = "t";
  34016. var XLINK_NS = "http://www.w3.org/1999/xlink";
  34017. // src/mock-doc/attribute.ts
  34018. var attrHandler = {
  34019. get(obj, prop) {
  34020. if (prop in obj) {
  34021. return obj[prop];
  34022. }
  34023. if (typeof prop !== "symbol" && !isNaN(prop)) {
  34024. return obj.__items[prop];
  34025. }
  34026. return void 0;
  34027. }
  34028. };
  34029. var createAttributeProxy = (caseInsensitive) => new Proxy(new MockAttributeMap(caseInsensitive), attrHandler);
  34030. var MockAttributeMap = class {
  34031. constructor(caseInsensitive = false) {
  34032. this.caseInsensitive = caseInsensitive;
  34033. this.__items = [];
  34034. }
  34035. get length() {
  34036. return this.__items.length;
  34037. }
  34038. item(index) {
  34039. return this.__items[index] || null;
  34040. }
  34041. setNamedItem(attr) {
  34042. attr.namespaceURI = null;
  34043. this.setNamedItemNS(attr);
  34044. }
  34045. setNamedItemNS(attr) {
  34046. if (attr != null && attr.value != null) {
  34047. attr.value = String(attr.value);
  34048. }
  34049. const existingAttr = this.__items.find((a) => a.name === attr.name && a.namespaceURI === attr.namespaceURI);
  34050. if (existingAttr != null) {
  34051. existingAttr.value = attr.value;
  34052. } else {
  34053. this.__items.push(attr);
  34054. }
  34055. }
  34056. getNamedItem(attrName) {
  34057. if (this.caseInsensitive) {
  34058. attrName = attrName.toLowerCase();
  34059. }
  34060. return this.getNamedItemNS(null, attrName);
  34061. }
  34062. getNamedItemNS(namespaceURI, attrName) {
  34063. namespaceURI = getNamespaceURI(namespaceURI);
  34064. return this.__items.find((attr) => attr.name === attrName && getNamespaceURI(attr.namespaceURI) === namespaceURI) || null;
  34065. }
  34066. removeNamedItem(attr) {
  34067. this.removeNamedItemNS(attr);
  34068. }
  34069. removeNamedItemNS(attr) {
  34070. for (let i = 0, ii = this.__items.length; i < ii; i++) {
  34071. if (this.__items[i].name === attr.name && this.__items[i].namespaceURI === attr.namespaceURI) {
  34072. this.__items.splice(i, 1);
  34073. break;
  34074. }
  34075. }
  34076. }
  34077. [Symbol.iterator]() {
  34078. let i = 0;
  34079. return {
  34080. next: () => ({
  34081. done: i === this.length,
  34082. value: this.item(i++)
  34083. })
  34084. };
  34085. }
  34086. get [Symbol.toStringTag]() {
  34087. return "MockAttributeMap";
  34088. }
  34089. };
  34090. function getNamespaceURI(namespaceURI) {
  34091. return namespaceURI === XLINK_NS ? null : namespaceURI;
  34092. }
  34093. function cloneAttributes(srcAttrs, sortByName = false) {
  34094. const dstAttrs = new MockAttributeMap(srcAttrs.caseInsensitive);
  34095. if (srcAttrs != null) {
  34096. const attrLen = srcAttrs.length;
  34097. if (sortByName && attrLen > 1) {
  34098. const sortedAttrs = [];
  34099. for (let i = 0; i < attrLen; i++) {
  34100. const srcAttr = srcAttrs.item(i);
  34101. const dstAttr = new MockAttr(srcAttr.name, srcAttr.value, srcAttr.namespaceURI);
  34102. sortedAttrs.push(dstAttr);
  34103. }
  34104. sortedAttrs.sort(sortAttributes).forEach((attr) => {
  34105. dstAttrs.setNamedItemNS(attr);
  34106. });
  34107. } else {
  34108. for (let i = 0; i < attrLen; i++) {
  34109. const srcAttr = srcAttrs.item(i);
  34110. const dstAttr = new MockAttr(srcAttr.name, srcAttr.value, srcAttr.namespaceURI);
  34111. dstAttrs.setNamedItemNS(dstAttr);
  34112. }
  34113. }
  34114. }
  34115. return dstAttrs;
  34116. }
  34117. function sortAttributes(a, b) {
  34118. if (a.name < b.name) return -1;
  34119. if (a.name > b.name) return 1;
  34120. return 0;
  34121. }
  34122. var MockAttr = class {
  34123. constructor(attrName, attrValue, namespaceURI = null) {
  34124. this._name = attrName;
  34125. this._value = String(attrValue);
  34126. this._namespaceURI = namespaceURI;
  34127. }
  34128. get name() {
  34129. return this._name;
  34130. }
  34131. set name(value) {
  34132. this._name = value;
  34133. }
  34134. get value() {
  34135. return this._value;
  34136. }
  34137. set value(value) {
  34138. this._value = String(value);
  34139. }
  34140. get nodeName() {
  34141. return this._name;
  34142. }
  34143. set nodeName(value) {
  34144. this._name = value;
  34145. }
  34146. get nodeValue() {
  34147. return this._value;
  34148. }
  34149. set nodeValue(value) {
  34150. this._value = String(value);
  34151. }
  34152. get namespaceURI() {
  34153. return this._namespaceURI;
  34154. }
  34155. set namespaceURI(namespaceURI) {
  34156. this._namespaceURI = namespaceURI;
  34157. }
  34158. };
  34159. // src/mock-doc/class-list.ts
  34160. var MockClassList = class {
  34161. constructor(elm) {
  34162. this.elm = elm;
  34163. }
  34164. add(...classNames) {
  34165. const clsNames = getItems(this.elm);
  34166. let updated = false;
  34167. classNames.forEach((className) => {
  34168. className = String(className);
  34169. validateClass(className);
  34170. if (clsNames.includes(className) === false) {
  34171. clsNames.push(className);
  34172. updated = true;
  34173. }
  34174. });
  34175. if (updated) {
  34176. this.elm.setAttributeNS(null, "class", clsNames.join(" "));
  34177. }
  34178. }
  34179. remove(...classNames) {
  34180. const clsNames = getItems(this.elm);
  34181. let updated = false;
  34182. classNames.forEach((className) => {
  34183. className = String(className);
  34184. validateClass(className);
  34185. const index = clsNames.indexOf(className);
  34186. if (index > -1) {
  34187. clsNames.splice(index, 1);
  34188. updated = true;
  34189. }
  34190. });
  34191. if (updated) {
  34192. this.elm.setAttributeNS(null, "class", clsNames.filter((c) => c.length > 0).join(" "));
  34193. }
  34194. }
  34195. contains(className) {
  34196. className = String(className);
  34197. return getItems(this.elm).includes(className);
  34198. }
  34199. toggle(className) {
  34200. className = String(className);
  34201. if (this.contains(className) === true) {
  34202. this.remove(className);
  34203. } else {
  34204. this.add(className);
  34205. }
  34206. }
  34207. get length() {
  34208. return getItems(this.elm).length;
  34209. }
  34210. item(index) {
  34211. return getItems(this.elm)[index];
  34212. }
  34213. toString() {
  34214. return getItems(this.elm).join(" ");
  34215. }
  34216. };
  34217. function validateClass(className) {
  34218. if (className === "") {
  34219. throw new Error("The token provided must not be empty.");
  34220. }
  34221. if (/\s/.test(className)) {
  34222. throw new Error(
  34223. `The token provided ('${className}') contains HTML space characters, which are not valid in tokens.`
  34224. );
  34225. }
  34226. }
  34227. function getItems(elm) {
  34228. const className = elm.getAttribute("class");
  34229. if (typeof className === "string" && className.length > 0) {
  34230. return className.trim().split(" ").filter((c) => c.length > 0);
  34231. }
  34232. return [];
  34233. }
  34234. // src/mock-doc/css-style-declaration.ts
  34235. var MockCSSStyleDeclaration = class {
  34236. constructor() {
  34237. this._styles = /* @__PURE__ */ new Map();
  34238. }
  34239. setProperty(prop, value) {
  34240. prop = jsCaseToCssCase(prop);
  34241. if (value == null || value === "") {
  34242. this._styles.delete(prop);
  34243. } else {
  34244. this._styles.set(prop, String(value));
  34245. }
  34246. }
  34247. getPropertyValue(prop) {
  34248. prop = jsCaseToCssCase(prop);
  34249. return String(this._styles.get(prop) || "");
  34250. }
  34251. removeProperty(prop) {
  34252. prop = jsCaseToCssCase(prop);
  34253. this._styles.delete(prop);
  34254. }
  34255. get length() {
  34256. return this._styles.size;
  34257. }
  34258. get cssText() {
  34259. const cssText = [];
  34260. this._styles.forEach((value, prop) => {
  34261. cssText.push(`${prop}: ${value};`);
  34262. });
  34263. return cssText.join(" ").trim();
  34264. }
  34265. set cssText(cssText) {
  34266. if (cssText == null || cssText === "") {
  34267. this._styles.clear();
  34268. return;
  34269. }
  34270. cssText.split(";").forEach((rule) => {
  34271. rule = rule.trim();
  34272. if (rule.length > 0) {
  34273. const splt = rule.split(":");
  34274. if (splt.length > 1) {
  34275. const prop = splt[0].trim();
  34276. const value = splt.slice(1).join(":").trim();
  34277. if (prop !== "" && value !== "") {
  34278. this._styles.set(jsCaseToCssCase(prop), value);
  34279. }
  34280. }
  34281. }
  34282. });
  34283. }
  34284. };
  34285. function createCSSStyleDeclaration() {
  34286. return new Proxy(new MockCSSStyleDeclaration(), cssProxyHandler);
  34287. }
  34288. var cssProxyHandler = {
  34289. get(cssStyle, prop) {
  34290. if (prop in cssStyle) {
  34291. return cssStyle[prop];
  34292. }
  34293. prop = cssCaseToJsCase(prop);
  34294. return cssStyle.getPropertyValue(prop);
  34295. },
  34296. set(cssStyle, prop, value) {
  34297. if (prop in cssStyle) {
  34298. cssStyle[prop] = value;
  34299. } else {
  34300. cssStyle.setProperty(prop, value);
  34301. }
  34302. return true;
  34303. }
  34304. };
  34305. function cssCaseToJsCase(str) {
  34306. if (str.length > 1 && str.includes("-") === true) {
  34307. str = str.toLowerCase().split("-").map((segment) => segment.charAt(0).toUpperCase() + segment.slice(1)).join("");
  34308. str = str.slice(0, 1).toLowerCase() + str.slice(1);
  34309. }
  34310. return str;
  34311. }
  34312. function jsCaseToCssCase(str) {
  34313. if (str.length > 1 && str.includes("-") === false && /[A-Z]/.test(str) === true) {
  34314. str = str.replace(/([A-Z])/g, (g) => " " + g[0]).trim().replace(/ /g, "-").toLowerCase();
  34315. }
  34316. return str;
  34317. }
  34318. // src/mock-doc/custom-element-registry.ts
  34319. var MockCustomElementRegistry = class {
  34320. constructor(win) {
  34321. this.win = win;
  34322. }
  34323. define(tagName, cstr, options) {
  34324. if (tagName.toLowerCase() !== tagName) {
  34325. throw new Error(
  34326. `Failed to execute 'define' on 'CustomElementRegistry': "${tagName}" is not a valid custom element name`
  34327. );
  34328. }
  34329. if (this.__registry == null) {
  34330. this.__registry = /* @__PURE__ */ new Map();
  34331. }
  34332. this.__registry.set(tagName, { cstr, options });
  34333. if (this.__whenDefined != null) {
  34334. const whenDefinedResolveFns = this.__whenDefined.get(tagName);
  34335. if (whenDefinedResolveFns != null) {
  34336. whenDefinedResolveFns.forEach((whenDefinedResolveFn) => {
  34337. whenDefinedResolveFn();
  34338. });
  34339. whenDefinedResolveFns.length = 0;
  34340. this.__whenDefined.delete(tagName);
  34341. }
  34342. }
  34343. const doc = this.win.document;
  34344. if (doc != null) {
  34345. const hosts = doc.querySelectorAll(tagName);
  34346. hosts.forEach((host) => {
  34347. if (upgradedElements.has(host) === false) {
  34348. tempDisableCallbacks.add(doc);
  34349. const upgradedCmp = createCustomElement(this, doc, tagName);
  34350. for (let i = 0; i < host.childNodes.length; i++) {
  34351. const childNode = host.childNodes[i];
  34352. childNode.remove();
  34353. upgradedCmp.appendChild(childNode);
  34354. }
  34355. tempDisableCallbacks.delete(doc);
  34356. if (proxyElements.has(host)) {
  34357. proxyElements.set(host, upgradedCmp);
  34358. }
  34359. }
  34360. fireConnectedCallback(host);
  34361. });
  34362. }
  34363. }
  34364. get(tagName) {
  34365. if (this.__registry != null) {
  34366. const def = this.__registry.get(tagName.toLowerCase());
  34367. if (def != null) {
  34368. return def.cstr;
  34369. }
  34370. }
  34371. return void 0;
  34372. }
  34373. getName(cstr) {
  34374. for (const [tagName, def] of this.__registry.entries()) {
  34375. if (def.cstr === cstr) {
  34376. return tagName;
  34377. }
  34378. }
  34379. return void 0;
  34380. }
  34381. upgrade(_rootNode) {
  34382. }
  34383. clear() {
  34384. if (this.__registry != null) {
  34385. this.__registry.clear();
  34386. }
  34387. if (this.__whenDefined != null) {
  34388. this.__whenDefined.clear();
  34389. }
  34390. }
  34391. whenDefined(tagName) {
  34392. tagName = tagName.toLowerCase();
  34393. if (this.__registry != null && this.__registry.has(tagName) === true) {
  34394. return Promise.resolve(this.__registry.get(tagName).cstr);
  34395. }
  34396. return new Promise((resolve) => {
  34397. if (this.__whenDefined == null) {
  34398. this.__whenDefined = /* @__PURE__ */ new Map();
  34399. }
  34400. let whenDefinedResolveFns = this.__whenDefined.get(tagName);
  34401. if (whenDefinedResolveFns == null) {
  34402. whenDefinedResolveFns = [];
  34403. this.__whenDefined.set(tagName, whenDefinedResolveFns);
  34404. }
  34405. whenDefinedResolveFns.push(resolve);
  34406. });
  34407. }
  34408. };
  34409. function createCustomElement(customElements, ownerDocument, tagName) {
  34410. const Cstr = customElements.get(tagName);
  34411. if (Cstr != null) {
  34412. const cmp = new Cstr(ownerDocument);
  34413. cmp.nodeName = tagName.toUpperCase();
  34414. upgradedElements.add(cmp);
  34415. return cmp;
  34416. }
  34417. const host = new Proxy(
  34418. {},
  34419. {
  34420. get(obj, prop) {
  34421. const elm2 = proxyElements.get(host);
  34422. if (elm2 != null) {
  34423. return elm2[prop];
  34424. }
  34425. return obj[prop];
  34426. },
  34427. set(obj, prop, val) {
  34428. const elm2 = proxyElements.get(host);
  34429. if (elm2 != null) {
  34430. elm2[prop] = val;
  34431. } else {
  34432. obj[prop] = val;
  34433. }
  34434. return true;
  34435. },
  34436. has(obj, prop) {
  34437. const elm2 = proxyElements.get(host);
  34438. if (prop in elm2) {
  34439. return true;
  34440. }
  34441. if (prop in obj) {
  34442. return true;
  34443. }
  34444. return false;
  34445. }
  34446. }
  34447. );
  34448. const elm = new MockHTMLElement(ownerDocument, tagName);
  34449. proxyElements.set(host, elm);
  34450. return host;
  34451. }
  34452. var proxyElements = /* @__PURE__ */ new WeakMap();
  34453. var upgradedElements = /* @__PURE__ */ new WeakSet();
  34454. function connectNode(ownerDocument, node) {
  34455. node.ownerDocument = ownerDocument;
  34456. if (node.nodeType === 1 /* ELEMENT_NODE */) {
  34457. if (ownerDocument != null && node.nodeName.includes("-")) {
  34458. const win = ownerDocument.defaultView;
  34459. if (win != null && typeof node.connectedCallback === "function" && node.isConnected) {
  34460. fireConnectedCallback(node);
  34461. }
  34462. const shadowRoot = node.shadowRoot;
  34463. if (shadowRoot != null) {
  34464. shadowRoot.childNodes.forEach((childNode) => {
  34465. connectNode(ownerDocument, childNode);
  34466. });
  34467. }
  34468. }
  34469. node.childNodes.forEach((childNode) => {
  34470. connectNode(ownerDocument, childNode);
  34471. });
  34472. } else {
  34473. node.childNodes.forEach((childNode) => {
  34474. childNode.ownerDocument = ownerDocument;
  34475. });
  34476. }
  34477. }
  34478. function fireConnectedCallback(node) {
  34479. if (typeof node.connectedCallback === "function") {
  34480. if (tempDisableCallbacks.has(node.ownerDocument) === false) {
  34481. try {
  34482. node.connectedCallback();
  34483. } catch (e) {
  34484. console.error(e);
  34485. }
  34486. }
  34487. }
  34488. }
  34489. function disconnectNode(node) {
  34490. if (node.nodeType === 1 /* ELEMENT_NODE */) {
  34491. if (node.nodeName.includes("-") === true && typeof node.disconnectedCallback === "function") {
  34492. if (tempDisableCallbacks.has(node.ownerDocument) === false) {
  34493. try {
  34494. node.disconnectedCallback();
  34495. } catch (e) {
  34496. console.error(e);
  34497. }
  34498. }
  34499. }
  34500. node.childNodes.forEach(disconnectNode);
  34501. }
  34502. }
  34503. function attributeChanged(node, attrName, oldValue, newValue) {
  34504. attrName = attrName.toLowerCase();
  34505. const observedAttributes = node.constructor.observedAttributes;
  34506. if (Array.isArray(observedAttributes) === true && observedAttributes.some((obs) => obs.toLowerCase() === attrName) === true) {
  34507. try {
  34508. node.attributeChangedCallback(attrName, oldValue, newValue);
  34509. } catch (e) {
  34510. console.error(e);
  34511. }
  34512. }
  34513. }
  34514. function checkAttributeChanged(node) {
  34515. return node.nodeName.includes("-") === true && typeof node.attributeChangedCallback === "function";
  34516. }
  34517. var tempDisableCallbacks = /* @__PURE__ */ new Set();
  34518. // src/mock-doc/dataset.ts
  34519. function dataset(elm) {
  34520. const ds = {};
  34521. const attributes = elm.attributes;
  34522. const attrLen = attributes.length;
  34523. for (let i = 0; i < attrLen; i++) {
  34524. const attr = attributes.item(i);
  34525. const nodeName = attr.nodeName;
  34526. if (nodeName.startsWith("data-")) {
  34527. ds[dashToPascalCase(nodeName)] = attr.nodeValue;
  34528. }
  34529. }
  34530. return new Proxy(ds, {
  34531. get(_obj, camelCaseProp) {
  34532. return ds[camelCaseProp];
  34533. },
  34534. set(_obj, camelCaseProp, value) {
  34535. const dataAttr = toDataAttribute(camelCaseProp);
  34536. elm.setAttribute(dataAttr, value);
  34537. return true;
  34538. }
  34539. });
  34540. }
  34541. function toDataAttribute(str) {
  34542. return "data-" + String(str).replace(/([A-Z0-9])/g, (g) => " " + g[0]).trim().replace(/ /g, "-").toLowerCase();
  34543. }
  34544. function dashToPascalCase(str) {
  34545. str = String(str).slice(5);
  34546. return str.split("-").map((segment, index) => {
  34547. if (index === 0) {
  34548. return segment.charAt(0).toLowerCase() + segment.slice(1);
  34549. }
  34550. return segment.charAt(0).toUpperCase() + segment.slice(1);
  34551. }).join("");
  34552. }
  34553. // src/mock-doc/event.ts
  34554. var MockEvent = class {
  34555. constructor(type, eventInitDict) {
  34556. this.bubbles = false;
  34557. this.cancelBubble = false;
  34558. this.cancelable = false;
  34559. this.composed = false;
  34560. this.currentTarget = null;
  34561. this.defaultPrevented = false;
  34562. this.srcElement = null;
  34563. this.target = null;
  34564. if (typeof type !== "string") {
  34565. throw new Error(`Event type required`);
  34566. }
  34567. this.type = type;
  34568. this.timeStamp = Date.now();
  34569. if (eventInitDict != null) {
  34570. Object.assign(this, eventInitDict);
  34571. }
  34572. }
  34573. preventDefault() {
  34574. this.defaultPrevented = true;
  34575. }
  34576. stopPropagation() {
  34577. this.cancelBubble = true;
  34578. }
  34579. stopImmediatePropagation() {
  34580. this.cancelBubble = true;
  34581. }
  34582. /**
  34583. * @ref https://developer.mozilla.org/en-US/docs/Web/API/Event/composedPath
  34584. * @returns a composed path of the event
  34585. */
  34586. composedPath() {
  34587. const composedPath = [];
  34588. let currentElement = this.target;
  34589. while (currentElement) {
  34590. composedPath.push(currentElement);
  34591. if (!currentElement.parentElement && currentElement.nodeName === "#document" /* DOCUMENT_NODE */) {
  34592. composedPath.push(currentElement.defaultView);
  34593. break;
  34594. }
  34595. if (currentElement.parentElement == null && currentElement.tagName === "HTML") {
  34596. currentElement = currentElement.ownerDocument;
  34597. } else {
  34598. currentElement = currentElement.parentElement;
  34599. }
  34600. }
  34601. return composedPath;
  34602. }
  34603. };
  34604. var MockCustomEvent = class extends MockEvent {
  34605. constructor(type, customEventInitDic) {
  34606. super(type);
  34607. this.detail = null;
  34608. if (customEventInitDic != null) {
  34609. Object.assign(this, customEventInitDic);
  34610. }
  34611. }
  34612. };
  34613. var MockKeyboardEvent = class extends MockEvent {
  34614. constructor(type, keyboardEventInitDic) {
  34615. super(type);
  34616. this.code = "";
  34617. this.key = "";
  34618. this.altKey = false;
  34619. this.ctrlKey = false;
  34620. this.metaKey = false;
  34621. this.shiftKey = false;
  34622. this.location = 0;
  34623. this.repeat = false;
  34624. if (keyboardEventInitDic != null) {
  34625. Object.assign(this, keyboardEventInitDic);
  34626. }
  34627. }
  34628. };
  34629. var MockMouseEvent = class extends MockEvent {
  34630. constructor(type, mouseEventInitDic) {
  34631. super(type);
  34632. this.screenX = 0;
  34633. this.screenY = 0;
  34634. this.clientX = 0;
  34635. this.clientY = 0;
  34636. this.ctrlKey = false;
  34637. this.shiftKey = false;
  34638. this.altKey = false;
  34639. this.metaKey = false;
  34640. this.button = 0;
  34641. this.buttons = 0;
  34642. this.relatedTarget = null;
  34643. if (mouseEventInitDic != null) {
  34644. Object.assign(this, mouseEventInitDic);
  34645. }
  34646. }
  34647. };
  34648. var MockUIEvent = class extends MockEvent {
  34649. constructor(type, uiEventInitDic) {
  34650. super(type);
  34651. this.detail = null;
  34652. this.view = null;
  34653. if (uiEventInitDic != null) {
  34654. Object.assign(this, uiEventInitDic);
  34655. }
  34656. }
  34657. };
  34658. var MockFocusEvent = class extends MockUIEvent {
  34659. constructor(type, focusEventInitDic) {
  34660. super(type);
  34661. this.relatedTarget = null;
  34662. if (focusEventInitDic != null) {
  34663. Object.assign(this, focusEventInitDic);
  34664. }
  34665. }
  34666. };
  34667. var MockEventListener = class {
  34668. constructor(type, handler) {
  34669. this.type = type;
  34670. this.handler = handler;
  34671. }
  34672. };
  34673. function addEventListener(elm, type, handler) {
  34674. const target = elm;
  34675. if (target.__listeners == null) {
  34676. target.__listeners = [];
  34677. }
  34678. target.__listeners.push(new MockEventListener(type, handler));
  34679. }
  34680. function removeEventListener(elm, type, handler) {
  34681. const target = elm;
  34682. if (target != null && Array.isArray(target.__listeners) === true) {
  34683. const elmListener = target.__listeners.find((e) => e.type === type && e.handler === handler);
  34684. if (elmListener != null) {
  34685. const index = target.__listeners.indexOf(elmListener);
  34686. target.__listeners.splice(index, 1);
  34687. }
  34688. }
  34689. }
  34690. function resetEventListeners(target) {
  34691. if (target != null && target.__listeners != null) {
  34692. target.__listeners = null;
  34693. }
  34694. }
  34695. function triggerEventListener(elm, ev) {
  34696. if (elm == null || ev.cancelBubble === true) {
  34697. return;
  34698. }
  34699. const target = elm;
  34700. ev.currentTarget = elm;
  34701. if (Array.isArray(target.__listeners) === true) {
  34702. const listeners = target.__listeners.filter((e) => e.type === ev.type);
  34703. listeners.forEach((listener) => {
  34704. try {
  34705. listener.handler.call(target, ev);
  34706. } catch (err2) {
  34707. console.error(err2);
  34708. }
  34709. });
  34710. }
  34711. if (ev.bubbles === false) {
  34712. return;
  34713. }
  34714. if (elm.nodeName === "#document" /* DOCUMENT_NODE */) {
  34715. triggerEventListener(elm.defaultView, ev);
  34716. } else if (elm.parentElement == null && elm.tagName === "HTML") {
  34717. triggerEventListener(elm.ownerDocument, ev);
  34718. } else {
  34719. triggerEventListener(elm.parentElement, ev);
  34720. }
  34721. }
  34722. function dispatchEvent(currentTarget, ev) {
  34723. ev.target = currentTarget;
  34724. triggerEventListener(currentTarget, ev);
  34725. return true;
  34726. }
  34727. // node_modules/parse5/dist/common/unicode.js
  34728. var UNDEFINED_CODE_POINTS = /* @__PURE__ */ new Set([
  34729. 65534,
  34730. 65535,
  34731. 131070,
  34732. 131071,
  34733. 196606,
  34734. 196607,
  34735. 262142,
  34736. 262143,
  34737. 327678,
  34738. 327679,
  34739. 393214,
  34740. 393215,
  34741. 458750,
  34742. 458751,
  34743. 524286,
  34744. 524287,
  34745. 589822,
  34746. 589823,
  34747. 655358,
  34748. 655359,
  34749. 720894,
  34750. 720895,
  34751. 786430,
  34752. 786431,
  34753. 851966,
  34754. 851967,
  34755. 917502,
  34756. 917503,
  34757. 983038,
  34758. 983039,
  34759. 1048574,
  34760. 1048575,
  34761. 1114110,
  34762. 1114111
  34763. ]);
  34764. var REPLACEMENT_CHARACTER = "\uFFFD";
  34765. var CODE_POINTS;
  34766. (function(CODE_POINTS2) {
  34767. CODE_POINTS2[CODE_POINTS2["EOF"] = -1] = "EOF";
  34768. CODE_POINTS2[CODE_POINTS2["NULL"] = 0] = "NULL";
  34769. CODE_POINTS2[CODE_POINTS2["TABULATION"] = 9] = "TABULATION";
  34770. CODE_POINTS2[CODE_POINTS2["CARRIAGE_RETURN"] = 13] = "CARRIAGE_RETURN";
  34771. CODE_POINTS2[CODE_POINTS2["LINE_FEED"] = 10] = "LINE_FEED";
  34772. CODE_POINTS2[CODE_POINTS2["FORM_FEED"] = 12] = "FORM_FEED";
  34773. CODE_POINTS2[CODE_POINTS2["SPACE"] = 32] = "SPACE";
  34774. CODE_POINTS2[CODE_POINTS2["EXCLAMATION_MARK"] = 33] = "EXCLAMATION_MARK";
  34775. CODE_POINTS2[CODE_POINTS2["QUOTATION_MARK"] = 34] = "QUOTATION_MARK";
  34776. CODE_POINTS2[CODE_POINTS2["NUMBER_SIGN"] = 35] = "NUMBER_SIGN";
  34777. CODE_POINTS2[CODE_POINTS2["AMPERSAND"] = 38] = "AMPERSAND";
  34778. CODE_POINTS2[CODE_POINTS2["APOSTROPHE"] = 39] = "APOSTROPHE";
  34779. CODE_POINTS2[CODE_POINTS2["HYPHEN_MINUS"] = 45] = "HYPHEN_MINUS";
  34780. CODE_POINTS2[CODE_POINTS2["SOLIDUS"] = 47] = "SOLIDUS";
  34781. CODE_POINTS2[CODE_POINTS2["DIGIT_0"] = 48] = "DIGIT_0";
  34782. CODE_POINTS2[CODE_POINTS2["DIGIT_9"] = 57] = "DIGIT_9";
  34783. CODE_POINTS2[CODE_POINTS2["SEMICOLON"] = 59] = "SEMICOLON";
  34784. CODE_POINTS2[CODE_POINTS2["LESS_THAN_SIGN"] = 60] = "LESS_THAN_SIGN";
  34785. CODE_POINTS2[CODE_POINTS2["EQUALS_SIGN"] = 61] = "EQUALS_SIGN";
  34786. CODE_POINTS2[CODE_POINTS2["GREATER_THAN_SIGN"] = 62] = "GREATER_THAN_SIGN";
  34787. CODE_POINTS2[CODE_POINTS2["QUESTION_MARK"] = 63] = "QUESTION_MARK";
  34788. CODE_POINTS2[CODE_POINTS2["LATIN_CAPITAL_A"] = 65] = "LATIN_CAPITAL_A";
  34789. CODE_POINTS2[CODE_POINTS2["LATIN_CAPITAL_F"] = 70] = "LATIN_CAPITAL_F";
  34790. CODE_POINTS2[CODE_POINTS2["LATIN_CAPITAL_X"] = 88] = "LATIN_CAPITAL_X";
  34791. CODE_POINTS2[CODE_POINTS2["LATIN_CAPITAL_Z"] = 90] = "LATIN_CAPITAL_Z";
  34792. CODE_POINTS2[CODE_POINTS2["RIGHT_SQUARE_BRACKET"] = 93] = "RIGHT_SQUARE_BRACKET";
  34793. CODE_POINTS2[CODE_POINTS2["GRAVE_ACCENT"] = 96] = "GRAVE_ACCENT";
  34794. CODE_POINTS2[CODE_POINTS2["LATIN_SMALL_A"] = 97] = "LATIN_SMALL_A";
  34795. CODE_POINTS2[CODE_POINTS2["LATIN_SMALL_F"] = 102] = "LATIN_SMALL_F";
  34796. CODE_POINTS2[CODE_POINTS2["LATIN_SMALL_X"] = 120] = "LATIN_SMALL_X";
  34797. CODE_POINTS2[CODE_POINTS2["LATIN_SMALL_Z"] = 122] = "LATIN_SMALL_Z";
  34798. CODE_POINTS2[CODE_POINTS2["REPLACEMENT_CHARACTER"] = 65533] = "REPLACEMENT_CHARACTER";
  34799. })(CODE_POINTS = CODE_POINTS || (CODE_POINTS = {}));
  34800. var SEQUENCES = {
  34801. DASH_DASH: "--",
  34802. CDATA_START: "[CDATA[",
  34803. DOCTYPE: "doctype",
  34804. SCRIPT: "script",
  34805. PUBLIC: "public",
  34806. SYSTEM: "system"
  34807. };
  34808. function isSurrogate(cp) {
  34809. return cp >= 55296 && cp <= 57343;
  34810. }
  34811. function isSurrogatePair(cp) {
  34812. return cp >= 56320 && cp <= 57343;
  34813. }
  34814. function getSurrogatePairCodePoint(cp1, cp2) {
  34815. return (cp1 - 55296) * 1024 + 9216 + cp2;
  34816. }
  34817. function isControlCodePoint(cp) {
  34818. return cp !== 32 && cp !== 10 && cp !== 13 && cp !== 9 && cp !== 12 && cp >= 1 && cp <= 31 || cp >= 127 && cp <= 159;
  34819. }
  34820. function isUndefinedCodePoint(cp) {
  34821. return cp >= 64976 && cp <= 65007 || UNDEFINED_CODE_POINTS.has(cp);
  34822. }
  34823. // node_modules/parse5/dist/common/error-codes.js
  34824. var ERR;
  34825. (function(ERR2) {
  34826. ERR2["controlCharacterInInputStream"] = "control-character-in-input-stream";
  34827. ERR2["noncharacterInInputStream"] = "noncharacter-in-input-stream";
  34828. ERR2["surrogateInInputStream"] = "surrogate-in-input-stream";
  34829. ERR2["nonVoidHtmlElementStartTagWithTrailingSolidus"] = "non-void-html-element-start-tag-with-trailing-solidus";
  34830. ERR2["endTagWithAttributes"] = "end-tag-with-attributes";
  34831. ERR2["endTagWithTrailingSolidus"] = "end-tag-with-trailing-solidus";
  34832. ERR2["unexpectedSolidusInTag"] = "unexpected-solidus-in-tag";
  34833. ERR2["unexpectedNullCharacter"] = "unexpected-null-character";
  34834. ERR2["unexpectedQuestionMarkInsteadOfTagName"] = "unexpected-question-mark-instead-of-tag-name";
  34835. ERR2["invalidFirstCharacterOfTagName"] = "invalid-first-character-of-tag-name";
  34836. ERR2["unexpectedEqualsSignBeforeAttributeName"] = "unexpected-equals-sign-before-attribute-name";
  34837. ERR2["missingEndTagName"] = "missing-end-tag-name";
  34838. ERR2["unexpectedCharacterInAttributeName"] = "unexpected-character-in-attribute-name";
  34839. ERR2["unknownNamedCharacterReference"] = "unknown-named-character-reference";
  34840. ERR2["missingSemicolonAfterCharacterReference"] = "missing-semicolon-after-character-reference";
  34841. ERR2["unexpectedCharacterAfterDoctypeSystemIdentifier"] = "unexpected-character-after-doctype-system-identifier";
  34842. ERR2["unexpectedCharacterInUnquotedAttributeValue"] = "unexpected-character-in-unquoted-attribute-value";
  34843. ERR2["eofBeforeTagName"] = "eof-before-tag-name";
  34844. ERR2["eofInTag"] = "eof-in-tag";
  34845. ERR2["missingAttributeValue"] = "missing-attribute-value";
  34846. ERR2["missingWhitespaceBetweenAttributes"] = "missing-whitespace-between-attributes";
  34847. ERR2["missingWhitespaceAfterDoctypePublicKeyword"] = "missing-whitespace-after-doctype-public-keyword";
  34848. ERR2["missingWhitespaceBetweenDoctypePublicAndSystemIdentifiers"] = "missing-whitespace-between-doctype-public-and-system-identifiers";
  34849. ERR2["missingWhitespaceAfterDoctypeSystemKeyword"] = "missing-whitespace-after-doctype-system-keyword";
  34850. ERR2["missingQuoteBeforeDoctypePublicIdentifier"] = "missing-quote-before-doctype-public-identifier";
  34851. ERR2["missingQuoteBeforeDoctypeSystemIdentifier"] = "missing-quote-before-doctype-system-identifier";
  34852. ERR2["missingDoctypePublicIdentifier"] = "missing-doctype-public-identifier";
  34853. ERR2["missingDoctypeSystemIdentifier"] = "missing-doctype-system-identifier";
  34854. ERR2["abruptDoctypePublicIdentifier"] = "abrupt-doctype-public-identifier";
  34855. ERR2["abruptDoctypeSystemIdentifier"] = "abrupt-doctype-system-identifier";
  34856. ERR2["cdataInHtmlContent"] = "cdata-in-html-content";
  34857. ERR2["incorrectlyOpenedComment"] = "incorrectly-opened-comment";
  34858. ERR2["eofInScriptHtmlCommentLikeText"] = "eof-in-script-html-comment-like-text";
  34859. ERR2["eofInDoctype"] = "eof-in-doctype";
  34860. ERR2["nestedComment"] = "nested-comment";
  34861. ERR2["abruptClosingOfEmptyComment"] = "abrupt-closing-of-empty-comment";
  34862. ERR2["eofInComment"] = "eof-in-comment";
  34863. ERR2["incorrectlyClosedComment"] = "incorrectly-closed-comment";
  34864. ERR2["eofInCdata"] = "eof-in-cdata";
  34865. ERR2["absenceOfDigitsInNumericCharacterReference"] = "absence-of-digits-in-numeric-character-reference";
  34866. ERR2["nullCharacterReference"] = "null-character-reference";
  34867. ERR2["surrogateCharacterReference"] = "surrogate-character-reference";
  34868. ERR2["characterReferenceOutsideUnicodeRange"] = "character-reference-outside-unicode-range";
  34869. ERR2["controlCharacterReference"] = "control-character-reference";
  34870. ERR2["noncharacterCharacterReference"] = "noncharacter-character-reference";
  34871. ERR2["missingWhitespaceBeforeDoctypeName"] = "missing-whitespace-before-doctype-name";
  34872. ERR2["missingDoctypeName"] = "missing-doctype-name";
  34873. ERR2["invalidCharacterSequenceAfterDoctypeName"] = "invalid-character-sequence-after-doctype-name";
  34874. ERR2["duplicateAttribute"] = "duplicate-attribute";
  34875. ERR2["nonConformingDoctype"] = "non-conforming-doctype";
  34876. ERR2["missingDoctype"] = "missing-doctype";
  34877. ERR2["misplacedDoctype"] = "misplaced-doctype";
  34878. ERR2["endTagWithoutMatchingOpenElement"] = "end-tag-without-matching-open-element";
  34879. ERR2["closingOfElementWithOpenChildElements"] = "closing-of-element-with-open-child-elements";
  34880. ERR2["disallowedContentInNoscriptInHead"] = "disallowed-content-in-noscript-in-head";
  34881. ERR2["openElementsLeftAfterEof"] = "open-elements-left-after-eof";
  34882. ERR2["abandonedHeadElementChild"] = "abandoned-head-element-child";
  34883. ERR2["misplacedStartTagForHeadElement"] = "misplaced-start-tag-for-head-element";
  34884. ERR2["nestedNoscriptInHead"] = "nested-noscript-in-head";
  34885. ERR2["eofInElementThatCanContainOnlyText"] = "eof-in-element-that-can-contain-only-text";
  34886. })(ERR = ERR || (ERR = {}));
  34887. // node_modules/parse5/dist/tokenizer/preprocessor.js
  34888. var DEFAULT_BUFFER_WATERLINE = 1 << 16;
  34889. var Preprocessor = class {
  34890. constructor(handler) {
  34891. this.handler = handler;
  34892. this.html = "";
  34893. this.pos = -1;
  34894. this.lastGapPos = -2;
  34895. this.gapStack = [];
  34896. this.skipNextNewLine = false;
  34897. this.lastChunkWritten = false;
  34898. this.endOfChunkHit = false;
  34899. this.bufferWaterline = DEFAULT_BUFFER_WATERLINE;
  34900. this.isEol = false;
  34901. this.lineStartPos = 0;
  34902. this.droppedBufferSize = 0;
  34903. this.line = 1;
  34904. this.lastErrOffset = -1;
  34905. }
  34906. /** The column on the current line. If we just saw a gap (eg. a surrogate pair), return the index before. */
  34907. get col() {
  34908. return this.pos - this.lineStartPos + Number(this.lastGapPos !== this.pos);
  34909. }
  34910. get offset() {
  34911. return this.droppedBufferSize + this.pos;
  34912. }
  34913. getError(code) {
  34914. const { line, col, offset } = this;
  34915. return {
  34916. code,
  34917. startLine: line,
  34918. endLine: line,
  34919. startCol: col,
  34920. endCol: col,
  34921. startOffset: offset,
  34922. endOffset: offset
  34923. };
  34924. }
  34925. _err(code) {
  34926. if (this.handler.onParseError && this.lastErrOffset !== this.offset) {
  34927. this.lastErrOffset = this.offset;
  34928. this.handler.onParseError(this.getError(code));
  34929. }
  34930. }
  34931. _addGap() {
  34932. this.gapStack.push(this.lastGapPos);
  34933. this.lastGapPos = this.pos;
  34934. }
  34935. _processSurrogate(cp) {
  34936. if (this.pos !== this.html.length - 1) {
  34937. const nextCp = this.html.charCodeAt(this.pos + 1);
  34938. if (isSurrogatePair(nextCp)) {
  34939. this.pos++;
  34940. this._addGap();
  34941. return getSurrogatePairCodePoint(cp, nextCp);
  34942. }
  34943. } else if (!this.lastChunkWritten) {
  34944. this.endOfChunkHit = true;
  34945. return CODE_POINTS.EOF;
  34946. }
  34947. this._err(ERR.surrogateInInputStream);
  34948. return cp;
  34949. }
  34950. willDropParsedChunk() {
  34951. return this.pos > this.bufferWaterline;
  34952. }
  34953. dropParsedChunk() {
  34954. if (this.willDropParsedChunk()) {
  34955. this.html = this.html.substring(this.pos);
  34956. this.lineStartPos -= this.pos;
  34957. this.droppedBufferSize += this.pos;
  34958. this.pos = 0;
  34959. this.lastGapPos = -2;
  34960. this.gapStack.length = 0;
  34961. }
  34962. }
  34963. write(chunk, isLastChunk) {
  34964. if (this.html.length > 0) {
  34965. this.html += chunk;
  34966. } else {
  34967. this.html = chunk;
  34968. }
  34969. this.endOfChunkHit = false;
  34970. this.lastChunkWritten = isLastChunk;
  34971. }
  34972. insertHtmlAtCurrentPos(chunk) {
  34973. this.html = this.html.substring(0, this.pos + 1) + chunk + this.html.substring(this.pos + 1);
  34974. this.endOfChunkHit = false;
  34975. }
  34976. startsWith(pattern, caseSensitive) {
  34977. if (this.pos + pattern.length > this.html.length) {
  34978. this.endOfChunkHit = !this.lastChunkWritten;
  34979. return false;
  34980. }
  34981. if (caseSensitive) {
  34982. return this.html.startsWith(pattern, this.pos);
  34983. }
  34984. for (let i = 0; i < pattern.length; i++) {
  34985. const cp = this.html.charCodeAt(this.pos + i) | 32;
  34986. if (cp !== pattern.charCodeAt(i)) {
  34987. return false;
  34988. }
  34989. }
  34990. return true;
  34991. }
  34992. peek(offset) {
  34993. const pos = this.pos + offset;
  34994. if (pos >= this.html.length) {
  34995. this.endOfChunkHit = !this.lastChunkWritten;
  34996. return CODE_POINTS.EOF;
  34997. }
  34998. const code = this.html.charCodeAt(pos);
  34999. return code === CODE_POINTS.CARRIAGE_RETURN ? CODE_POINTS.LINE_FEED : code;
  35000. }
  35001. advance() {
  35002. this.pos++;
  35003. if (this.isEol) {
  35004. this.isEol = false;
  35005. this.line++;
  35006. this.lineStartPos = this.pos;
  35007. }
  35008. if (this.pos >= this.html.length) {
  35009. this.endOfChunkHit = !this.lastChunkWritten;
  35010. return CODE_POINTS.EOF;
  35011. }
  35012. let cp = this.html.charCodeAt(this.pos);
  35013. if (cp === CODE_POINTS.CARRIAGE_RETURN) {
  35014. this.isEol = true;
  35015. this.skipNextNewLine = true;
  35016. return CODE_POINTS.LINE_FEED;
  35017. }
  35018. if (cp === CODE_POINTS.LINE_FEED) {
  35019. this.isEol = true;
  35020. if (this.skipNextNewLine) {
  35021. this.line--;
  35022. this.skipNextNewLine = false;
  35023. this._addGap();
  35024. return this.advance();
  35025. }
  35026. }
  35027. this.skipNextNewLine = false;
  35028. if (isSurrogate(cp)) {
  35029. cp = this._processSurrogate(cp);
  35030. }
  35031. const isCommonValidRange = this.handler.onParseError === null || cp > 31 && cp < 127 || cp === CODE_POINTS.LINE_FEED || cp === CODE_POINTS.CARRIAGE_RETURN || cp > 159 && cp < 64976;
  35032. if (!isCommonValidRange) {
  35033. this._checkForProblematicCharacters(cp);
  35034. }
  35035. return cp;
  35036. }
  35037. _checkForProblematicCharacters(cp) {
  35038. if (isControlCodePoint(cp)) {
  35039. this._err(ERR.controlCharacterInInputStream);
  35040. } else if (isUndefinedCodePoint(cp)) {
  35041. this._err(ERR.noncharacterInInputStream);
  35042. }
  35043. }
  35044. retreat(count) {
  35045. this.pos -= count;
  35046. while (this.pos < this.lastGapPos) {
  35047. this.lastGapPos = this.gapStack.pop();
  35048. this.pos--;
  35049. }
  35050. this.isEol = false;
  35051. }
  35052. };
  35053. // node_modules/parse5/dist/common/token.js
  35054. var token_exports = {};
  35055. __export(token_exports, {
  35056. TokenType: () => TokenType,
  35057. getTokenAttr: () => getTokenAttr
  35058. });
  35059. var TokenType;
  35060. (function(TokenType2) {
  35061. TokenType2[TokenType2["CHARACTER"] = 0] = "CHARACTER";
  35062. TokenType2[TokenType2["NULL_CHARACTER"] = 1] = "NULL_CHARACTER";
  35063. TokenType2[TokenType2["WHITESPACE_CHARACTER"] = 2] = "WHITESPACE_CHARACTER";
  35064. TokenType2[TokenType2["START_TAG"] = 3] = "START_TAG";
  35065. TokenType2[TokenType2["END_TAG"] = 4] = "END_TAG";
  35066. TokenType2[TokenType2["COMMENT"] = 5] = "COMMENT";
  35067. TokenType2[TokenType2["DOCTYPE"] = 6] = "DOCTYPE";
  35068. TokenType2[TokenType2["EOF"] = 7] = "EOF";
  35069. TokenType2[TokenType2["HIBERNATION"] = 8] = "HIBERNATION";
  35070. })(TokenType = TokenType || (TokenType = {}));
  35071. function getTokenAttr(token, attrName) {
  35072. for (let i = token.attrs.length - 1; i >= 0; i--) {
  35073. if (token.attrs[i].name === attrName) {
  35074. return token.attrs[i].value;
  35075. }
  35076. }
  35077. return null;
  35078. }
  35079. // node_modules/entities/lib/esm/generated/decode-data-html.js
  35080. var decode_data_html_default = new Uint16Array(
  35081. // prettier-ignore
  35082. '\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))
  35083. );
  35084. // node_modules/entities/lib/esm/generated/decode-data-xml.js
  35085. var decode_data_xml_default = new Uint16Array(
  35086. // prettier-ignore
  35087. "\u0200aglq \x1B\u026D\0\0p;\u4026os;\u4027t;\u403Et;\u403Cuot;\u4022".split("").map((c) => c.charCodeAt(0))
  35088. );
  35089. // node_modules/entities/lib/esm/decode_codepoint.js
  35090. var _a;
  35091. var decodeMap = /* @__PURE__ */ new Map([
  35092. [0, 65533],
  35093. // C1 Unicode control character reference replacements
  35094. [128, 8364],
  35095. [130, 8218],
  35096. [131, 402],
  35097. [132, 8222],
  35098. [133, 8230],
  35099. [134, 8224],
  35100. [135, 8225],
  35101. [136, 710],
  35102. [137, 8240],
  35103. [138, 352],
  35104. [139, 8249],
  35105. [140, 338],
  35106. [142, 381],
  35107. [145, 8216],
  35108. [146, 8217],
  35109. [147, 8220],
  35110. [148, 8221],
  35111. [149, 8226],
  35112. [150, 8211],
  35113. [151, 8212],
  35114. [152, 732],
  35115. [153, 8482],
  35116. [154, 353],
  35117. [155, 8250],
  35118. [156, 339],
  35119. [158, 382],
  35120. [159, 376]
  35121. ]);
  35122. var fromCodePoint = (
  35123. // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition, node/no-unsupported-features/es-builtins
  35124. (_a = String.fromCodePoint) !== null && _a !== void 0 ? _a : function(codePoint) {
  35125. let output = "";
  35126. if (codePoint > 65535) {
  35127. codePoint -= 65536;
  35128. output += String.fromCharCode(codePoint >>> 10 & 1023 | 55296);
  35129. codePoint = 56320 | codePoint & 1023;
  35130. }
  35131. output += String.fromCharCode(codePoint);
  35132. return output;
  35133. }
  35134. );
  35135. function replaceCodePoint(codePoint) {
  35136. var _a2;
  35137. if (codePoint >= 55296 && codePoint <= 57343 || codePoint > 1114111) {
  35138. return 65533;
  35139. }
  35140. return (_a2 = decodeMap.get(codePoint)) !== null && _a2 !== void 0 ? _a2 : codePoint;
  35141. }
  35142. // node_modules/entities/lib/esm/decode.js
  35143. var CharCodes;
  35144. (function(CharCodes2) {
  35145. CharCodes2[CharCodes2["NUM"] = 35] = "NUM";
  35146. CharCodes2[CharCodes2["SEMI"] = 59] = "SEMI";
  35147. CharCodes2[CharCodes2["EQUALS"] = 61] = "EQUALS";
  35148. CharCodes2[CharCodes2["ZERO"] = 48] = "ZERO";
  35149. CharCodes2[CharCodes2["NINE"] = 57] = "NINE";
  35150. CharCodes2[CharCodes2["LOWER_A"] = 97] = "LOWER_A";
  35151. CharCodes2[CharCodes2["LOWER_F"] = 102] = "LOWER_F";
  35152. CharCodes2[CharCodes2["LOWER_X"] = 120] = "LOWER_X";
  35153. CharCodes2[CharCodes2["LOWER_Z"] = 122] = "LOWER_Z";
  35154. CharCodes2[CharCodes2["UPPER_A"] = 65] = "UPPER_A";
  35155. CharCodes2[CharCodes2["UPPER_F"] = 70] = "UPPER_F";
  35156. CharCodes2[CharCodes2["UPPER_Z"] = 90] = "UPPER_Z";
  35157. })(CharCodes || (CharCodes = {}));
  35158. var TO_LOWER_BIT = 32;
  35159. var BinTrieFlags;
  35160. (function(BinTrieFlags2) {
  35161. BinTrieFlags2[BinTrieFlags2["VALUE_LENGTH"] = 49152] = "VALUE_LENGTH";
  35162. BinTrieFlags2[BinTrieFlags2["BRANCH_LENGTH"] = 16256] = "BRANCH_LENGTH";
  35163. BinTrieFlags2[BinTrieFlags2["JUMP_TABLE"] = 127] = "JUMP_TABLE";
  35164. })(BinTrieFlags || (BinTrieFlags = {}));
  35165. function isNumber(code) {
  35166. return code >= CharCodes.ZERO && code <= CharCodes.NINE;
  35167. }
  35168. function isHexadecimalCharacter(code) {
  35169. return code >= CharCodes.UPPER_A && code <= CharCodes.UPPER_F || code >= CharCodes.LOWER_A && code <= CharCodes.LOWER_F;
  35170. }
  35171. function isAsciiAlphaNumeric(code) {
  35172. return code >= CharCodes.UPPER_A && code <= CharCodes.UPPER_Z || code >= CharCodes.LOWER_A && code <= CharCodes.LOWER_Z || isNumber(code);
  35173. }
  35174. function isEntityInAttributeInvalidEnd(code) {
  35175. return code === CharCodes.EQUALS || isAsciiAlphaNumeric(code);
  35176. }
  35177. var EntityDecoderState;
  35178. (function(EntityDecoderState2) {
  35179. EntityDecoderState2[EntityDecoderState2["EntityStart"] = 0] = "EntityStart";
  35180. EntityDecoderState2[EntityDecoderState2["NumericStart"] = 1] = "NumericStart";
  35181. EntityDecoderState2[EntityDecoderState2["NumericDecimal"] = 2] = "NumericDecimal";
  35182. EntityDecoderState2[EntityDecoderState2["NumericHex"] = 3] = "NumericHex";
  35183. EntityDecoderState2[EntityDecoderState2["NamedEntity"] = 4] = "NamedEntity";
  35184. })(EntityDecoderState || (EntityDecoderState = {}));
  35185. var DecodingMode;
  35186. (function(DecodingMode2) {
  35187. DecodingMode2[DecodingMode2["Legacy"] = 0] = "Legacy";
  35188. DecodingMode2[DecodingMode2["Strict"] = 1] = "Strict";
  35189. DecodingMode2[DecodingMode2["Attribute"] = 2] = "Attribute";
  35190. })(DecodingMode || (DecodingMode = {}));
  35191. var EntityDecoder = class {
  35192. constructor(decodeTree, emitCodePoint, errors) {
  35193. this.decodeTree = decodeTree;
  35194. this.emitCodePoint = emitCodePoint;
  35195. this.errors = errors;
  35196. this.state = EntityDecoderState.EntityStart;
  35197. this.consumed = 1;
  35198. this.result = 0;
  35199. this.treeIndex = 0;
  35200. this.excess = 1;
  35201. this.decodeMode = DecodingMode.Strict;
  35202. }
  35203. /** Resets the instance to make it reusable. */
  35204. startEntity(decodeMode) {
  35205. this.decodeMode = decodeMode;
  35206. this.state = EntityDecoderState.EntityStart;
  35207. this.result = 0;
  35208. this.treeIndex = 0;
  35209. this.excess = 1;
  35210. this.consumed = 1;
  35211. }
  35212. /**
  35213. * Write an entity to the decoder. This can be called multiple times with partial entities.
  35214. * If the entity is incomplete, the decoder will return -1.
  35215. *
  35216. * Mirrors the implementation of `getDecoder`, but with the ability to stop decoding if the
  35217. * entity is incomplete, and resume when the next string is written.
  35218. *
  35219. * @param string The string containing the entity (or a continuation of the entity).
  35220. * @param offset The offset at which the entity begins. Should be 0 if this is not the first call.
  35221. * @returns The number of characters that were consumed, or -1 if the entity is incomplete.
  35222. */
  35223. write(str, offset) {
  35224. switch (this.state) {
  35225. case EntityDecoderState.EntityStart: {
  35226. if (str.charCodeAt(offset) === CharCodes.NUM) {
  35227. this.state = EntityDecoderState.NumericStart;
  35228. this.consumed += 1;
  35229. return this.stateNumericStart(str, offset + 1);
  35230. }
  35231. this.state = EntityDecoderState.NamedEntity;
  35232. return this.stateNamedEntity(str, offset);
  35233. }
  35234. case EntityDecoderState.NumericStart: {
  35235. return this.stateNumericStart(str, offset);
  35236. }
  35237. case EntityDecoderState.NumericDecimal: {
  35238. return this.stateNumericDecimal(str, offset);
  35239. }
  35240. case EntityDecoderState.NumericHex: {
  35241. return this.stateNumericHex(str, offset);
  35242. }
  35243. case EntityDecoderState.NamedEntity: {
  35244. return this.stateNamedEntity(str, offset);
  35245. }
  35246. }
  35247. }
  35248. /**
  35249. * Switches between the numeric decimal and hexadecimal states.
  35250. *
  35251. * Equivalent to the `Numeric character reference state` in the HTML spec.
  35252. *
  35253. * @param str The string containing the entity (or a continuation of the entity).
  35254. * @param offset The current offset.
  35255. * @returns The number of characters that were consumed, or -1 if the entity is incomplete.
  35256. */
  35257. stateNumericStart(str, offset) {
  35258. if (offset >= str.length) {
  35259. return -1;
  35260. }
  35261. if ((str.charCodeAt(offset) | TO_LOWER_BIT) === CharCodes.LOWER_X) {
  35262. this.state = EntityDecoderState.NumericHex;
  35263. this.consumed += 1;
  35264. return this.stateNumericHex(str, offset + 1);
  35265. }
  35266. this.state = EntityDecoderState.NumericDecimal;
  35267. return this.stateNumericDecimal(str, offset);
  35268. }
  35269. addToNumericResult(str, start, end, base) {
  35270. if (start !== end) {
  35271. const digitCount = end - start;
  35272. this.result = this.result * Math.pow(base, digitCount) + parseInt(str.substr(start, digitCount), base);
  35273. this.consumed += digitCount;
  35274. }
  35275. }
  35276. /**
  35277. * Parses a hexadecimal numeric entity.
  35278. *
  35279. * Equivalent to the `Hexademical character reference state` in the HTML spec.
  35280. *
  35281. * @param str The string containing the entity (or a continuation of the entity).
  35282. * @param offset The current offset.
  35283. * @returns The number of characters that were consumed, or -1 if the entity is incomplete.
  35284. */
  35285. stateNumericHex(str, offset) {
  35286. const startIdx = offset;
  35287. while (offset < str.length) {
  35288. const char = str.charCodeAt(offset);
  35289. if (isNumber(char) || isHexadecimalCharacter(char)) {
  35290. offset += 1;
  35291. } else {
  35292. this.addToNumericResult(str, startIdx, offset, 16);
  35293. return this.emitNumericEntity(char, 3);
  35294. }
  35295. }
  35296. this.addToNumericResult(str, startIdx, offset, 16);
  35297. return -1;
  35298. }
  35299. /**
  35300. * Parses a decimal numeric entity.
  35301. *
  35302. * Equivalent to the `Decimal character reference state` in the HTML spec.
  35303. *
  35304. * @param str The string containing the entity (or a continuation of the entity).
  35305. * @param offset The current offset.
  35306. * @returns The number of characters that were consumed, or -1 if the entity is incomplete.
  35307. */
  35308. stateNumericDecimal(str, offset) {
  35309. const startIdx = offset;
  35310. while (offset < str.length) {
  35311. const char = str.charCodeAt(offset);
  35312. if (isNumber(char)) {
  35313. offset += 1;
  35314. } else {
  35315. this.addToNumericResult(str, startIdx, offset, 10);
  35316. return this.emitNumericEntity(char, 2);
  35317. }
  35318. }
  35319. this.addToNumericResult(str, startIdx, offset, 10);
  35320. return -1;
  35321. }
  35322. /**
  35323. * Validate and emit a numeric entity.
  35324. *
  35325. * Implements the logic from the `Hexademical character reference start
  35326. * state` and `Numeric character reference end state` in the HTML spec.
  35327. *
  35328. * @param lastCp The last code point of the entity. Used to see if the
  35329. * entity was terminated with a semicolon.
  35330. * @param expectedLength The minimum number of characters that should be
  35331. * consumed. Used to validate that at least one digit
  35332. * was consumed.
  35333. * @returns The number of characters that were consumed.
  35334. */
  35335. emitNumericEntity(lastCp, expectedLength) {
  35336. var _a2;
  35337. if (this.consumed <= expectedLength) {
  35338. (_a2 = this.errors) === null || _a2 === void 0 ? void 0 : _a2.absenceOfDigitsInNumericCharacterReference(this.consumed);
  35339. return 0;
  35340. }
  35341. if (lastCp === CharCodes.SEMI) {
  35342. this.consumed += 1;
  35343. } else if (this.decodeMode === DecodingMode.Strict) {
  35344. return 0;
  35345. }
  35346. this.emitCodePoint(replaceCodePoint(this.result), this.consumed);
  35347. if (this.errors) {
  35348. if (lastCp !== CharCodes.SEMI) {
  35349. this.errors.missingSemicolonAfterCharacterReference();
  35350. }
  35351. this.errors.validateNumericCharacterReference(this.result);
  35352. }
  35353. return this.consumed;
  35354. }
  35355. /**
  35356. * Parses a named entity.
  35357. *
  35358. * Equivalent to the `Named character reference state` in the HTML spec.
  35359. *
  35360. * @param str The string containing the entity (or a continuation of the entity).
  35361. * @param offset The current offset.
  35362. * @returns The number of characters that were consumed, or -1 if the entity is incomplete.
  35363. */
  35364. stateNamedEntity(str, offset) {
  35365. const { decodeTree } = this;
  35366. let current = decodeTree[this.treeIndex];
  35367. let valueLength = (current & BinTrieFlags.VALUE_LENGTH) >> 14;
  35368. for (; offset < str.length; offset++, this.excess++) {
  35369. const char = str.charCodeAt(offset);
  35370. this.treeIndex = determineBranch(decodeTree, current, this.treeIndex + Math.max(1, valueLength), char);
  35371. if (this.treeIndex < 0) {
  35372. return this.result === 0 || // If we are parsing an attribute
  35373. this.decodeMode === DecodingMode.Attribute && // We shouldn't have consumed any characters after the entity,
  35374. (valueLength === 0 || // And there should be no invalid characters.
  35375. isEntityInAttributeInvalidEnd(char)) ? 0 : this.emitNotTerminatedNamedEntity();
  35376. }
  35377. current = decodeTree[this.treeIndex];
  35378. valueLength = (current & BinTrieFlags.VALUE_LENGTH) >> 14;
  35379. if (valueLength !== 0) {
  35380. if (char === CharCodes.SEMI) {
  35381. return this.emitNamedEntityData(this.treeIndex, valueLength, this.consumed + this.excess);
  35382. }
  35383. if (this.decodeMode !== DecodingMode.Strict) {
  35384. this.result = this.treeIndex;
  35385. this.consumed += this.excess;
  35386. this.excess = 0;
  35387. }
  35388. }
  35389. }
  35390. return -1;
  35391. }
  35392. /**
  35393. * Emit a named entity that was not terminated with a semicolon.
  35394. *
  35395. * @returns The number of characters consumed.
  35396. */
  35397. emitNotTerminatedNamedEntity() {
  35398. var _a2;
  35399. const { result, decodeTree } = this;
  35400. const valueLength = (decodeTree[result] & BinTrieFlags.VALUE_LENGTH) >> 14;
  35401. this.emitNamedEntityData(result, valueLength, this.consumed);
  35402. (_a2 = this.errors) === null || _a2 === void 0 ? void 0 : _a2.missingSemicolonAfterCharacterReference();
  35403. return this.consumed;
  35404. }
  35405. /**
  35406. * Emit a named entity.
  35407. *
  35408. * @param result The index of the entity in the decode tree.
  35409. * @param valueLength The number of bytes in the entity.
  35410. * @param consumed The number of characters consumed.
  35411. *
  35412. * @returns The number of characters consumed.
  35413. */
  35414. emitNamedEntityData(result, valueLength, consumed) {
  35415. const { decodeTree } = this;
  35416. this.emitCodePoint(valueLength === 1 ? decodeTree[result] & ~BinTrieFlags.VALUE_LENGTH : decodeTree[result + 1], consumed);
  35417. if (valueLength === 3) {
  35418. this.emitCodePoint(decodeTree[result + 2], consumed);
  35419. }
  35420. return consumed;
  35421. }
  35422. /**
  35423. * Signal to the parser that the end of the input was reached.
  35424. *
  35425. * Remaining data will be emitted and relevant errors will be produced.
  35426. *
  35427. * @returns The number of characters consumed.
  35428. */
  35429. end() {
  35430. var _a2;
  35431. switch (this.state) {
  35432. case EntityDecoderState.NamedEntity: {
  35433. return this.result !== 0 && (this.decodeMode !== DecodingMode.Attribute || this.result === this.treeIndex) ? this.emitNotTerminatedNamedEntity() : 0;
  35434. }
  35435. case EntityDecoderState.NumericDecimal: {
  35436. return this.emitNumericEntity(0, 2);
  35437. }
  35438. case EntityDecoderState.NumericHex: {
  35439. return this.emitNumericEntity(0, 3);
  35440. }
  35441. case EntityDecoderState.NumericStart: {
  35442. (_a2 = this.errors) === null || _a2 === void 0 ? void 0 : _a2.absenceOfDigitsInNumericCharacterReference(this.consumed);
  35443. return 0;
  35444. }
  35445. case EntityDecoderState.EntityStart: {
  35446. return 0;
  35447. }
  35448. }
  35449. }
  35450. };
  35451. function getDecoder(decodeTree) {
  35452. let ret = "";
  35453. const decoder = new EntityDecoder(decodeTree, (str) => ret += fromCodePoint(str));
  35454. return function decodeWithTrie(str, decodeMode) {
  35455. let lastIndex = 0;
  35456. let offset = 0;
  35457. while ((offset = str.indexOf("&", offset)) >= 0) {
  35458. ret += str.slice(lastIndex, offset);
  35459. decoder.startEntity(decodeMode);
  35460. const len = decoder.write(
  35461. str,
  35462. // Skip the "&"
  35463. offset + 1
  35464. );
  35465. if (len < 0) {
  35466. lastIndex = offset + decoder.end();
  35467. break;
  35468. }
  35469. lastIndex = offset + len;
  35470. offset = len === 0 ? lastIndex + 1 : lastIndex;
  35471. }
  35472. const result = ret + str.slice(lastIndex);
  35473. ret = "";
  35474. return result;
  35475. };
  35476. }
  35477. function determineBranch(decodeTree, current, nodeIdx, char) {
  35478. const branchCount = (current & BinTrieFlags.BRANCH_LENGTH) >> 7;
  35479. const jumpOffset = current & BinTrieFlags.JUMP_TABLE;
  35480. if (branchCount === 0) {
  35481. return jumpOffset !== 0 && char === jumpOffset ? nodeIdx : -1;
  35482. }
  35483. if (jumpOffset) {
  35484. const value = char - jumpOffset;
  35485. return value < 0 || value >= branchCount ? -1 : decodeTree[nodeIdx + value] - 1;
  35486. }
  35487. let lo = nodeIdx;
  35488. let hi = lo + branchCount - 1;
  35489. while (lo <= hi) {
  35490. const mid = lo + hi >>> 1;
  35491. const midVal = decodeTree[mid];
  35492. if (midVal < char) {
  35493. lo = mid + 1;
  35494. } else if (midVal > char) {
  35495. hi = mid - 1;
  35496. } else {
  35497. return decodeTree[mid + branchCount];
  35498. }
  35499. }
  35500. return -1;
  35501. }
  35502. var htmlDecoder = getDecoder(decode_data_html_default);
  35503. var xmlDecoder = getDecoder(decode_data_xml_default);
  35504. // node_modules/parse5/dist/common/html.js
  35505. var html_exports = {};
  35506. __export(html_exports, {
  35507. ATTRS: () => ATTRS,
  35508. DOCUMENT_MODE: () => DOCUMENT_MODE,
  35509. NS: () => NS,
  35510. SPECIAL_ELEMENTS: () => SPECIAL_ELEMENTS,
  35511. TAG_ID: () => TAG_ID,
  35512. TAG_NAMES: () => TAG_NAMES,
  35513. getTagID: () => getTagID,
  35514. hasUnescapedText: () => hasUnescapedText,
  35515. isNumberedHeader: () => isNumberedHeader
  35516. });
  35517. var NS;
  35518. (function(NS2) {
  35519. NS2["HTML"] = "http://www.w3.org/1999/xhtml";
  35520. NS2["MATHML"] = "http://www.w3.org/1998/Math/MathML";
  35521. NS2["SVG"] = "http://www.w3.org/2000/svg";
  35522. NS2["XLINK"] = "http://www.w3.org/1999/xlink";
  35523. NS2["XML"] = "http://www.w3.org/XML/1998/namespace";
  35524. NS2["XMLNS"] = "http://www.w3.org/2000/xmlns/";
  35525. })(NS = NS || (NS = {}));
  35526. var ATTRS;
  35527. (function(ATTRS2) {
  35528. ATTRS2["TYPE"] = "type";
  35529. ATTRS2["ACTION"] = "action";
  35530. ATTRS2["ENCODING"] = "encoding";
  35531. ATTRS2["PROMPT"] = "prompt";
  35532. ATTRS2["NAME"] = "name";
  35533. ATTRS2["COLOR"] = "color";
  35534. ATTRS2["FACE"] = "face";
  35535. ATTRS2["SIZE"] = "size";
  35536. })(ATTRS = ATTRS || (ATTRS = {}));
  35537. var DOCUMENT_MODE;
  35538. (function(DOCUMENT_MODE2) {
  35539. DOCUMENT_MODE2["NO_QUIRKS"] = "no-quirks";
  35540. DOCUMENT_MODE2["QUIRKS"] = "quirks";
  35541. DOCUMENT_MODE2["LIMITED_QUIRKS"] = "limited-quirks";
  35542. })(DOCUMENT_MODE = DOCUMENT_MODE || (DOCUMENT_MODE = {}));
  35543. var TAG_NAMES;
  35544. (function(TAG_NAMES2) {
  35545. TAG_NAMES2["A"] = "a";
  35546. TAG_NAMES2["ADDRESS"] = "address";
  35547. TAG_NAMES2["ANNOTATION_XML"] = "annotation-xml";
  35548. TAG_NAMES2["APPLET"] = "applet";
  35549. TAG_NAMES2["AREA"] = "area";
  35550. TAG_NAMES2["ARTICLE"] = "article";
  35551. TAG_NAMES2["ASIDE"] = "aside";
  35552. TAG_NAMES2["B"] = "b";
  35553. TAG_NAMES2["BASE"] = "base";
  35554. TAG_NAMES2["BASEFONT"] = "basefont";
  35555. TAG_NAMES2["BGSOUND"] = "bgsound";
  35556. TAG_NAMES2["BIG"] = "big";
  35557. TAG_NAMES2["BLOCKQUOTE"] = "blockquote";
  35558. TAG_NAMES2["BODY"] = "body";
  35559. TAG_NAMES2["BR"] = "br";
  35560. TAG_NAMES2["BUTTON"] = "button";
  35561. TAG_NAMES2["CAPTION"] = "caption";
  35562. TAG_NAMES2["CENTER"] = "center";
  35563. TAG_NAMES2["CODE"] = "code";
  35564. TAG_NAMES2["COL"] = "col";
  35565. TAG_NAMES2["COLGROUP"] = "colgroup";
  35566. TAG_NAMES2["DD"] = "dd";
  35567. TAG_NAMES2["DESC"] = "desc";
  35568. TAG_NAMES2["DETAILS"] = "details";
  35569. TAG_NAMES2["DIALOG"] = "dialog";
  35570. TAG_NAMES2["DIR"] = "dir";
  35571. TAG_NAMES2["DIV"] = "div";
  35572. TAG_NAMES2["DL"] = "dl";
  35573. TAG_NAMES2["DT"] = "dt";
  35574. TAG_NAMES2["EM"] = "em";
  35575. TAG_NAMES2["EMBED"] = "embed";
  35576. TAG_NAMES2["FIELDSET"] = "fieldset";
  35577. TAG_NAMES2["FIGCAPTION"] = "figcaption";
  35578. TAG_NAMES2["FIGURE"] = "figure";
  35579. TAG_NAMES2["FONT"] = "font";
  35580. TAG_NAMES2["FOOTER"] = "footer";
  35581. TAG_NAMES2["FOREIGN_OBJECT"] = "foreignObject";
  35582. TAG_NAMES2["FORM"] = "form";
  35583. TAG_NAMES2["FRAME"] = "frame";
  35584. TAG_NAMES2["FRAMESET"] = "frameset";
  35585. TAG_NAMES2["H1"] = "h1";
  35586. TAG_NAMES2["H2"] = "h2";
  35587. TAG_NAMES2["H3"] = "h3";
  35588. TAG_NAMES2["H4"] = "h4";
  35589. TAG_NAMES2["H5"] = "h5";
  35590. TAG_NAMES2["H6"] = "h6";
  35591. TAG_NAMES2["HEAD"] = "head";
  35592. TAG_NAMES2["HEADER"] = "header";
  35593. TAG_NAMES2["HGROUP"] = "hgroup";
  35594. TAG_NAMES2["HR"] = "hr";
  35595. TAG_NAMES2["HTML"] = "html";
  35596. TAG_NAMES2["I"] = "i";
  35597. TAG_NAMES2["IMG"] = "img";
  35598. TAG_NAMES2["IMAGE"] = "image";
  35599. TAG_NAMES2["INPUT"] = "input";
  35600. TAG_NAMES2["IFRAME"] = "iframe";
  35601. TAG_NAMES2["KEYGEN"] = "keygen";
  35602. TAG_NAMES2["LABEL"] = "label";
  35603. TAG_NAMES2["LI"] = "li";
  35604. TAG_NAMES2["LINK"] = "link";
  35605. TAG_NAMES2["LISTING"] = "listing";
  35606. TAG_NAMES2["MAIN"] = "main";
  35607. TAG_NAMES2["MALIGNMARK"] = "malignmark";
  35608. TAG_NAMES2["MARQUEE"] = "marquee";
  35609. TAG_NAMES2["MATH"] = "math";
  35610. TAG_NAMES2["MENU"] = "menu";
  35611. TAG_NAMES2["META"] = "meta";
  35612. TAG_NAMES2["MGLYPH"] = "mglyph";
  35613. TAG_NAMES2["MI"] = "mi";
  35614. TAG_NAMES2["MO"] = "mo";
  35615. TAG_NAMES2["MN"] = "mn";
  35616. TAG_NAMES2["MS"] = "ms";
  35617. TAG_NAMES2["MTEXT"] = "mtext";
  35618. TAG_NAMES2["NAV"] = "nav";
  35619. TAG_NAMES2["NOBR"] = "nobr";
  35620. TAG_NAMES2["NOFRAMES"] = "noframes";
  35621. TAG_NAMES2["NOEMBED"] = "noembed";
  35622. TAG_NAMES2["NOSCRIPT"] = "noscript";
  35623. TAG_NAMES2["OBJECT"] = "object";
  35624. TAG_NAMES2["OL"] = "ol";
  35625. TAG_NAMES2["OPTGROUP"] = "optgroup";
  35626. TAG_NAMES2["OPTION"] = "option";
  35627. TAG_NAMES2["P"] = "p";
  35628. TAG_NAMES2["PARAM"] = "param";
  35629. TAG_NAMES2["PLAINTEXT"] = "plaintext";
  35630. TAG_NAMES2["PRE"] = "pre";
  35631. TAG_NAMES2["RB"] = "rb";
  35632. TAG_NAMES2["RP"] = "rp";
  35633. TAG_NAMES2["RT"] = "rt";
  35634. TAG_NAMES2["RTC"] = "rtc";
  35635. TAG_NAMES2["RUBY"] = "ruby";
  35636. TAG_NAMES2["S"] = "s";
  35637. TAG_NAMES2["SCRIPT"] = "script";
  35638. TAG_NAMES2["SECTION"] = "section";
  35639. TAG_NAMES2["SELECT"] = "select";
  35640. TAG_NAMES2["SOURCE"] = "source";
  35641. TAG_NAMES2["SMALL"] = "small";
  35642. TAG_NAMES2["SPAN"] = "span";
  35643. TAG_NAMES2["STRIKE"] = "strike";
  35644. TAG_NAMES2["STRONG"] = "strong";
  35645. TAG_NAMES2["STYLE"] = "style";
  35646. TAG_NAMES2["SUB"] = "sub";
  35647. TAG_NAMES2["SUMMARY"] = "summary";
  35648. TAG_NAMES2["SUP"] = "sup";
  35649. TAG_NAMES2["TABLE"] = "table";
  35650. TAG_NAMES2["TBODY"] = "tbody";
  35651. TAG_NAMES2["TEMPLATE"] = "template";
  35652. TAG_NAMES2["TEXTAREA"] = "textarea";
  35653. TAG_NAMES2["TFOOT"] = "tfoot";
  35654. TAG_NAMES2["TD"] = "td";
  35655. TAG_NAMES2["TH"] = "th";
  35656. TAG_NAMES2["THEAD"] = "thead";
  35657. TAG_NAMES2["TITLE"] = "title";
  35658. TAG_NAMES2["TR"] = "tr";
  35659. TAG_NAMES2["TRACK"] = "track";
  35660. TAG_NAMES2["TT"] = "tt";
  35661. TAG_NAMES2["U"] = "u";
  35662. TAG_NAMES2["UL"] = "ul";
  35663. TAG_NAMES2["SVG"] = "svg";
  35664. TAG_NAMES2["VAR"] = "var";
  35665. TAG_NAMES2["WBR"] = "wbr";
  35666. TAG_NAMES2["XMP"] = "xmp";
  35667. })(TAG_NAMES = TAG_NAMES || (TAG_NAMES = {}));
  35668. var TAG_ID;
  35669. (function(TAG_ID2) {
  35670. TAG_ID2[TAG_ID2["UNKNOWN"] = 0] = "UNKNOWN";
  35671. TAG_ID2[TAG_ID2["A"] = 1] = "A";
  35672. TAG_ID2[TAG_ID2["ADDRESS"] = 2] = "ADDRESS";
  35673. TAG_ID2[TAG_ID2["ANNOTATION_XML"] = 3] = "ANNOTATION_XML";
  35674. TAG_ID2[TAG_ID2["APPLET"] = 4] = "APPLET";
  35675. TAG_ID2[TAG_ID2["AREA"] = 5] = "AREA";
  35676. TAG_ID2[TAG_ID2["ARTICLE"] = 6] = "ARTICLE";
  35677. TAG_ID2[TAG_ID2["ASIDE"] = 7] = "ASIDE";
  35678. TAG_ID2[TAG_ID2["B"] = 8] = "B";
  35679. TAG_ID2[TAG_ID2["BASE"] = 9] = "BASE";
  35680. TAG_ID2[TAG_ID2["BASEFONT"] = 10] = "BASEFONT";
  35681. TAG_ID2[TAG_ID2["BGSOUND"] = 11] = "BGSOUND";
  35682. TAG_ID2[TAG_ID2["BIG"] = 12] = "BIG";
  35683. TAG_ID2[TAG_ID2["BLOCKQUOTE"] = 13] = "BLOCKQUOTE";
  35684. TAG_ID2[TAG_ID2["BODY"] = 14] = "BODY";
  35685. TAG_ID2[TAG_ID2["BR"] = 15] = "BR";
  35686. TAG_ID2[TAG_ID2["BUTTON"] = 16] = "BUTTON";
  35687. TAG_ID2[TAG_ID2["CAPTION"] = 17] = "CAPTION";
  35688. TAG_ID2[TAG_ID2["CENTER"] = 18] = "CENTER";
  35689. TAG_ID2[TAG_ID2["CODE"] = 19] = "CODE";
  35690. TAG_ID2[TAG_ID2["COL"] = 20] = "COL";
  35691. TAG_ID2[TAG_ID2["COLGROUP"] = 21] = "COLGROUP";
  35692. TAG_ID2[TAG_ID2["DD"] = 22] = "DD";
  35693. TAG_ID2[TAG_ID2["DESC"] = 23] = "DESC";
  35694. TAG_ID2[TAG_ID2["DETAILS"] = 24] = "DETAILS";
  35695. TAG_ID2[TAG_ID2["DIALOG"] = 25] = "DIALOG";
  35696. TAG_ID2[TAG_ID2["DIR"] = 26] = "DIR";
  35697. TAG_ID2[TAG_ID2["DIV"] = 27] = "DIV";
  35698. TAG_ID2[TAG_ID2["DL"] = 28] = "DL";
  35699. TAG_ID2[TAG_ID2["DT"] = 29] = "DT";
  35700. TAG_ID2[TAG_ID2["EM"] = 30] = "EM";
  35701. TAG_ID2[TAG_ID2["EMBED"] = 31] = "EMBED";
  35702. TAG_ID2[TAG_ID2["FIELDSET"] = 32] = "FIELDSET";
  35703. TAG_ID2[TAG_ID2["FIGCAPTION"] = 33] = "FIGCAPTION";
  35704. TAG_ID2[TAG_ID2["FIGURE"] = 34] = "FIGURE";
  35705. TAG_ID2[TAG_ID2["FONT"] = 35] = "FONT";
  35706. TAG_ID2[TAG_ID2["FOOTER"] = 36] = "FOOTER";
  35707. TAG_ID2[TAG_ID2["FOREIGN_OBJECT"] = 37] = "FOREIGN_OBJECT";
  35708. TAG_ID2[TAG_ID2["FORM"] = 38] = "FORM";
  35709. TAG_ID2[TAG_ID2["FRAME"] = 39] = "FRAME";
  35710. TAG_ID2[TAG_ID2["FRAMESET"] = 40] = "FRAMESET";
  35711. TAG_ID2[TAG_ID2["H1"] = 41] = "H1";
  35712. TAG_ID2[TAG_ID2["H2"] = 42] = "H2";
  35713. TAG_ID2[TAG_ID2["H3"] = 43] = "H3";
  35714. TAG_ID2[TAG_ID2["H4"] = 44] = "H4";
  35715. TAG_ID2[TAG_ID2["H5"] = 45] = "H5";
  35716. TAG_ID2[TAG_ID2["H6"] = 46] = "H6";
  35717. TAG_ID2[TAG_ID2["HEAD"] = 47] = "HEAD";
  35718. TAG_ID2[TAG_ID2["HEADER"] = 48] = "HEADER";
  35719. TAG_ID2[TAG_ID2["HGROUP"] = 49] = "HGROUP";
  35720. TAG_ID2[TAG_ID2["HR"] = 50] = "HR";
  35721. TAG_ID2[TAG_ID2["HTML"] = 51] = "HTML";
  35722. TAG_ID2[TAG_ID2["I"] = 52] = "I";
  35723. TAG_ID2[TAG_ID2["IMG"] = 53] = "IMG";
  35724. TAG_ID2[TAG_ID2["IMAGE"] = 54] = "IMAGE";
  35725. TAG_ID2[TAG_ID2["INPUT"] = 55] = "INPUT";
  35726. TAG_ID2[TAG_ID2["IFRAME"] = 56] = "IFRAME";
  35727. TAG_ID2[TAG_ID2["KEYGEN"] = 57] = "KEYGEN";
  35728. TAG_ID2[TAG_ID2["LABEL"] = 58] = "LABEL";
  35729. TAG_ID2[TAG_ID2["LI"] = 59] = "LI";
  35730. TAG_ID2[TAG_ID2["LINK"] = 60] = "LINK";
  35731. TAG_ID2[TAG_ID2["LISTING"] = 61] = "LISTING";
  35732. TAG_ID2[TAG_ID2["MAIN"] = 62] = "MAIN";
  35733. TAG_ID2[TAG_ID2["MALIGNMARK"] = 63] = "MALIGNMARK";
  35734. TAG_ID2[TAG_ID2["MARQUEE"] = 64] = "MARQUEE";
  35735. TAG_ID2[TAG_ID2["MATH"] = 65] = "MATH";
  35736. TAG_ID2[TAG_ID2["MENU"] = 66] = "MENU";
  35737. TAG_ID2[TAG_ID2["META"] = 67] = "META";
  35738. TAG_ID2[TAG_ID2["MGLYPH"] = 68] = "MGLYPH";
  35739. TAG_ID2[TAG_ID2["MI"] = 69] = "MI";
  35740. TAG_ID2[TAG_ID2["MO"] = 70] = "MO";
  35741. TAG_ID2[TAG_ID2["MN"] = 71] = "MN";
  35742. TAG_ID2[TAG_ID2["MS"] = 72] = "MS";
  35743. TAG_ID2[TAG_ID2["MTEXT"] = 73] = "MTEXT";
  35744. TAG_ID2[TAG_ID2["NAV"] = 74] = "NAV";
  35745. TAG_ID2[TAG_ID2["NOBR"] = 75] = "NOBR";
  35746. TAG_ID2[TAG_ID2["NOFRAMES"] = 76] = "NOFRAMES";
  35747. TAG_ID2[TAG_ID2["NOEMBED"] = 77] = "NOEMBED";
  35748. TAG_ID2[TAG_ID2["NOSCRIPT"] = 78] = "NOSCRIPT";
  35749. TAG_ID2[TAG_ID2["OBJECT"] = 79] = "OBJECT";
  35750. TAG_ID2[TAG_ID2["OL"] = 80] = "OL";
  35751. TAG_ID2[TAG_ID2["OPTGROUP"] = 81] = "OPTGROUP";
  35752. TAG_ID2[TAG_ID2["OPTION"] = 82] = "OPTION";
  35753. TAG_ID2[TAG_ID2["P"] = 83] = "P";
  35754. TAG_ID2[TAG_ID2["PARAM"] = 84] = "PARAM";
  35755. TAG_ID2[TAG_ID2["PLAINTEXT"] = 85] = "PLAINTEXT";
  35756. TAG_ID2[TAG_ID2["PRE"] = 86] = "PRE";
  35757. TAG_ID2[TAG_ID2["RB"] = 87] = "RB";
  35758. TAG_ID2[TAG_ID2["RP"] = 88] = "RP";
  35759. TAG_ID2[TAG_ID2["RT"] = 89] = "RT";
  35760. TAG_ID2[TAG_ID2["RTC"] = 90] = "RTC";
  35761. TAG_ID2[TAG_ID2["RUBY"] = 91] = "RUBY";
  35762. TAG_ID2[TAG_ID2["S"] = 92] = "S";
  35763. TAG_ID2[TAG_ID2["SCRIPT"] = 93] = "SCRIPT";
  35764. TAG_ID2[TAG_ID2["SECTION"] = 94] = "SECTION";
  35765. TAG_ID2[TAG_ID2["SELECT"] = 95] = "SELECT";
  35766. TAG_ID2[TAG_ID2["SOURCE"] = 96] = "SOURCE";
  35767. TAG_ID2[TAG_ID2["SMALL"] = 97] = "SMALL";
  35768. TAG_ID2[TAG_ID2["SPAN"] = 98] = "SPAN";
  35769. TAG_ID2[TAG_ID2["STRIKE"] = 99] = "STRIKE";
  35770. TAG_ID2[TAG_ID2["STRONG"] = 100] = "STRONG";
  35771. TAG_ID2[TAG_ID2["STYLE"] = 101] = "STYLE";
  35772. TAG_ID2[TAG_ID2["SUB"] = 102] = "SUB";
  35773. TAG_ID2[TAG_ID2["SUMMARY"] = 103] = "SUMMARY";
  35774. TAG_ID2[TAG_ID2["SUP"] = 104] = "SUP";
  35775. TAG_ID2[TAG_ID2["TABLE"] = 105] = "TABLE";
  35776. TAG_ID2[TAG_ID2["TBODY"] = 106] = "TBODY";
  35777. TAG_ID2[TAG_ID2["TEMPLATE"] = 107] = "TEMPLATE";
  35778. TAG_ID2[TAG_ID2["TEXTAREA"] = 108] = "TEXTAREA";
  35779. TAG_ID2[TAG_ID2["TFOOT"] = 109] = "TFOOT";
  35780. TAG_ID2[TAG_ID2["TD"] = 110] = "TD";
  35781. TAG_ID2[TAG_ID2["TH"] = 111] = "TH";
  35782. TAG_ID2[TAG_ID2["THEAD"] = 112] = "THEAD";
  35783. TAG_ID2[TAG_ID2["TITLE"] = 113] = "TITLE";
  35784. TAG_ID2[TAG_ID2["TR"] = 114] = "TR";
  35785. TAG_ID2[TAG_ID2["TRACK"] = 115] = "TRACK";
  35786. TAG_ID2[TAG_ID2["TT"] = 116] = "TT";
  35787. TAG_ID2[TAG_ID2["U"] = 117] = "U";
  35788. TAG_ID2[TAG_ID2["UL"] = 118] = "UL";
  35789. TAG_ID2[TAG_ID2["SVG"] = 119] = "SVG";
  35790. TAG_ID2[TAG_ID2["VAR"] = 120] = "VAR";
  35791. TAG_ID2[TAG_ID2["WBR"] = 121] = "WBR";
  35792. TAG_ID2[TAG_ID2["XMP"] = 122] = "XMP";
  35793. })(TAG_ID = TAG_ID || (TAG_ID = {}));
  35794. var TAG_NAME_TO_ID = /* @__PURE__ */ new Map([
  35795. [TAG_NAMES.A, TAG_ID.A],
  35796. [TAG_NAMES.ADDRESS, TAG_ID.ADDRESS],
  35797. [TAG_NAMES.ANNOTATION_XML, TAG_ID.ANNOTATION_XML],
  35798. [TAG_NAMES.APPLET, TAG_ID.APPLET],
  35799. [TAG_NAMES.AREA, TAG_ID.AREA],
  35800. [TAG_NAMES.ARTICLE, TAG_ID.ARTICLE],
  35801. [TAG_NAMES.ASIDE, TAG_ID.ASIDE],
  35802. [TAG_NAMES.B, TAG_ID.B],
  35803. [TAG_NAMES.BASE, TAG_ID.BASE],
  35804. [TAG_NAMES.BASEFONT, TAG_ID.BASEFONT],
  35805. [TAG_NAMES.BGSOUND, TAG_ID.BGSOUND],
  35806. [TAG_NAMES.BIG, TAG_ID.BIG],
  35807. [TAG_NAMES.BLOCKQUOTE, TAG_ID.BLOCKQUOTE],
  35808. [TAG_NAMES.BODY, TAG_ID.BODY],
  35809. [TAG_NAMES.BR, TAG_ID.BR],
  35810. [TAG_NAMES.BUTTON, TAG_ID.BUTTON],
  35811. [TAG_NAMES.CAPTION, TAG_ID.CAPTION],
  35812. [TAG_NAMES.CENTER, TAG_ID.CENTER],
  35813. [TAG_NAMES.CODE, TAG_ID.CODE],
  35814. [TAG_NAMES.COL, TAG_ID.COL],
  35815. [TAG_NAMES.COLGROUP, TAG_ID.COLGROUP],
  35816. [TAG_NAMES.DD, TAG_ID.DD],
  35817. [TAG_NAMES.DESC, TAG_ID.DESC],
  35818. [TAG_NAMES.DETAILS, TAG_ID.DETAILS],
  35819. [TAG_NAMES.DIALOG, TAG_ID.DIALOG],
  35820. [TAG_NAMES.DIR, TAG_ID.DIR],
  35821. [TAG_NAMES.DIV, TAG_ID.DIV],
  35822. [TAG_NAMES.DL, TAG_ID.DL],
  35823. [TAG_NAMES.DT, TAG_ID.DT],
  35824. [TAG_NAMES.EM, TAG_ID.EM],
  35825. [TAG_NAMES.EMBED, TAG_ID.EMBED],
  35826. [TAG_NAMES.FIELDSET, TAG_ID.FIELDSET],
  35827. [TAG_NAMES.FIGCAPTION, TAG_ID.FIGCAPTION],
  35828. [TAG_NAMES.FIGURE, TAG_ID.FIGURE],
  35829. [TAG_NAMES.FONT, TAG_ID.FONT],
  35830. [TAG_NAMES.FOOTER, TAG_ID.FOOTER],
  35831. [TAG_NAMES.FOREIGN_OBJECT, TAG_ID.FOREIGN_OBJECT],
  35832. [TAG_NAMES.FORM, TAG_ID.FORM],
  35833. [TAG_NAMES.FRAME, TAG_ID.FRAME],
  35834. [TAG_NAMES.FRAMESET, TAG_ID.FRAMESET],
  35835. [TAG_NAMES.H1, TAG_ID.H1],
  35836. [TAG_NAMES.H2, TAG_ID.H2],
  35837. [TAG_NAMES.H3, TAG_ID.H3],
  35838. [TAG_NAMES.H4, TAG_ID.H4],
  35839. [TAG_NAMES.H5, TAG_ID.H5],
  35840. [TAG_NAMES.H6, TAG_ID.H6],
  35841. [TAG_NAMES.HEAD, TAG_ID.HEAD],
  35842. [TAG_NAMES.HEADER, TAG_ID.HEADER],
  35843. [TAG_NAMES.HGROUP, TAG_ID.HGROUP],
  35844. [TAG_NAMES.HR, TAG_ID.HR],
  35845. [TAG_NAMES.HTML, TAG_ID.HTML],
  35846. [TAG_NAMES.I, TAG_ID.I],
  35847. [TAG_NAMES.IMG, TAG_ID.IMG],
  35848. [TAG_NAMES.IMAGE, TAG_ID.IMAGE],
  35849. [TAG_NAMES.INPUT, TAG_ID.INPUT],
  35850. [TAG_NAMES.IFRAME, TAG_ID.IFRAME],
  35851. [TAG_NAMES.KEYGEN, TAG_ID.KEYGEN],
  35852. [TAG_NAMES.LABEL, TAG_ID.LABEL],
  35853. [TAG_NAMES.LI, TAG_ID.LI],
  35854. [TAG_NAMES.LINK, TAG_ID.LINK],
  35855. [TAG_NAMES.LISTING, TAG_ID.LISTING],
  35856. [TAG_NAMES.MAIN, TAG_ID.MAIN],
  35857. [TAG_NAMES.MALIGNMARK, TAG_ID.MALIGNMARK],
  35858. [TAG_NAMES.MARQUEE, TAG_ID.MARQUEE],
  35859. [TAG_NAMES.MATH, TAG_ID.MATH],
  35860. [TAG_NAMES.MENU, TAG_ID.MENU],
  35861. [TAG_NAMES.META, TAG_ID.META],
  35862. [TAG_NAMES.MGLYPH, TAG_ID.MGLYPH],
  35863. [TAG_NAMES.MI, TAG_ID.MI],
  35864. [TAG_NAMES.MO, TAG_ID.MO],
  35865. [TAG_NAMES.MN, TAG_ID.MN],
  35866. [TAG_NAMES.MS, TAG_ID.MS],
  35867. [TAG_NAMES.MTEXT, TAG_ID.MTEXT],
  35868. [TAG_NAMES.NAV, TAG_ID.NAV],
  35869. [TAG_NAMES.NOBR, TAG_ID.NOBR],
  35870. [TAG_NAMES.NOFRAMES, TAG_ID.NOFRAMES],
  35871. [TAG_NAMES.NOEMBED, TAG_ID.NOEMBED],
  35872. [TAG_NAMES.NOSCRIPT, TAG_ID.NOSCRIPT],
  35873. [TAG_NAMES.OBJECT, TAG_ID.OBJECT],
  35874. [TAG_NAMES.OL, TAG_ID.OL],
  35875. [TAG_NAMES.OPTGROUP, TAG_ID.OPTGROUP],
  35876. [TAG_NAMES.OPTION, TAG_ID.OPTION],
  35877. [TAG_NAMES.P, TAG_ID.P],
  35878. [TAG_NAMES.PARAM, TAG_ID.PARAM],
  35879. [TAG_NAMES.PLAINTEXT, TAG_ID.PLAINTEXT],
  35880. [TAG_NAMES.PRE, TAG_ID.PRE],
  35881. [TAG_NAMES.RB, TAG_ID.RB],
  35882. [TAG_NAMES.RP, TAG_ID.RP],
  35883. [TAG_NAMES.RT, TAG_ID.RT],
  35884. [TAG_NAMES.RTC, TAG_ID.RTC],
  35885. [TAG_NAMES.RUBY, TAG_ID.RUBY],
  35886. [TAG_NAMES.S, TAG_ID.S],
  35887. [TAG_NAMES.SCRIPT, TAG_ID.SCRIPT],
  35888. [TAG_NAMES.SECTION, TAG_ID.SECTION],
  35889. [TAG_NAMES.SELECT, TAG_ID.SELECT],
  35890. [TAG_NAMES.SOURCE, TAG_ID.SOURCE],
  35891. [TAG_NAMES.SMALL, TAG_ID.SMALL],
  35892. [TAG_NAMES.SPAN, TAG_ID.SPAN],
  35893. [TAG_NAMES.STRIKE, TAG_ID.STRIKE],
  35894. [TAG_NAMES.STRONG, TAG_ID.STRONG],
  35895. [TAG_NAMES.STYLE, TAG_ID.STYLE],
  35896. [TAG_NAMES.SUB, TAG_ID.SUB],
  35897. [TAG_NAMES.SUMMARY, TAG_ID.SUMMARY],
  35898. [TAG_NAMES.SUP, TAG_ID.SUP],
  35899. [TAG_NAMES.TABLE, TAG_ID.TABLE],
  35900. [TAG_NAMES.TBODY, TAG_ID.TBODY],
  35901. [TAG_NAMES.TEMPLATE, TAG_ID.TEMPLATE],
  35902. [TAG_NAMES.TEXTAREA, TAG_ID.TEXTAREA],
  35903. [TAG_NAMES.TFOOT, TAG_ID.TFOOT],
  35904. [TAG_NAMES.TD, TAG_ID.TD],
  35905. [TAG_NAMES.TH, TAG_ID.TH],
  35906. [TAG_NAMES.THEAD, TAG_ID.THEAD],
  35907. [TAG_NAMES.TITLE, TAG_ID.TITLE],
  35908. [TAG_NAMES.TR, TAG_ID.TR],
  35909. [TAG_NAMES.TRACK, TAG_ID.TRACK],
  35910. [TAG_NAMES.TT, TAG_ID.TT],
  35911. [TAG_NAMES.U, TAG_ID.U],
  35912. [TAG_NAMES.UL, TAG_ID.UL],
  35913. [TAG_NAMES.SVG, TAG_ID.SVG],
  35914. [TAG_NAMES.VAR, TAG_ID.VAR],
  35915. [TAG_NAMES.WBR, TAG_ID.WBR],
  35916. [TAG_NAMES.XMP, TAG_ID.XMP]
  35917. ]);
  35918. function getTagID(tagName) {
  35919. var _a2;
  35920. return (_a2 = TAG_NAME_TO_ID.get(tagName)) !== null && _a2 !== void 0 ? _a2 : TAG_ID.UNKNOWN;
  35921. }
  35922. var $ = TAG_ID;
  35923. var SPECIAL_ELEMENTS = {
  35924. [NS.HTML]: /* @__PURE__ */ new Set([
  35925. $.ADDRESS,
  35926. $.APPLET,
  35927. $.AREA,
  35928. $.ARTICLE,
  35929. $.ASIDE,
  35930. $.BASE,
  35931. $.BASEFONT,
  35932. $.BGSOUND,
  35933. $.BLOCKQUOTE,
  35934. $.BODY,
  35935. $.BR,
  35936. $.BUTTON,
  35937. $.CAPTION,
  35938. $.CENTER,
  35939. $.COL,
  35940. $.COLGROUP,
  35941. $.DD,
  35942. $.DETAILS,
  35943. $.DIR,
  35944. $.DIV,
  35945. $.DL,
  35946. $.DT,
  35947. $.EMBED,
  35948. $.FIELDSET,
  35949. $.FIGCAPTION,
  35950. $.FIGURE,
  35951. $.FOOTER,
  35952. $.FORM,
  35953. $.FRAME,
  35954. $.FRAMESET,
  35955. $.H1,
  35956. $.H2,
  35957. $.H3,
  35958. $.H4,
  35959. $.H5,
  35960. $.H6,
  35961. $.HEAD,
  35962. $.HEADER,
  35963. $.HGROUP,
  35964. $.HR,
  35965. $.HTML,
  35966. $.IFRAME,
  35967. $.IMG,
  35968. $.INPUT,
  35969. $.LI,
  35970. $.LINK,
  35971. $.LISTING,
  35972. $.MAIN,
  35973. $.MARQUEE,
  35974. $.MENU,
  35975. $.META,
  35976. $.NAV,
  35977. $.NOEMBED,
  35978. $.NOFRAMES,
  35979. $.NOSCRIPT,
  35980. $.OBJECT,
  35981. $.OL,
  35982. $.P,
  35983. $.PARAM,
  35984. $.PLAINTEXT,
  35985. $.PRE,
  35986. $.SCRIPT,
  35987. $.SECTION,
  35988. $.SELECT,
  35989. $.SOURCE,
  35990. $.STYLE,
  35991. $.SUMMARY,
  35992. $.TABLE,
  35993. $.TBODY,
  35994. $.TD,
  35995. $.TEMPLATE,
  35996. $.TEXTAREA,
  35997. $.TFOOT,
  35998. $.TH,
  35999. $.THEAD,
  36000. $.TITLE,
  36001. $.TR,
  36002. $.TRACK,
  36003. $.UL,
  36004. $.WBR,
  36005. $.XMP
  36006. ]),
  36007. [NS.MATHML]: /* @__PURE__ */ new Set([$.MI, $.MO, $.MN, $.MS, $.MTEXT, $.ANNOTATION_XML]),
  36008. [NS.SVG]: /* @__PURE__ */ new Set([$.TITLE, $.FOREIGN_OBJECT, $.DESC]),
  36009. [NS.XLINK]: /* @__PURE__ */ new Set(),
  36010. [NS.XML]: /* @__PURE__ */ new Set(),
  36011. [NS.XMLNS]: /* @__PURE__ */ new Set()
  36012. };
  36013. function isNumberedHeader(tn) {
  36014. return tn === $.H1 || tn === $.H2 || tn === $.H3 || tn === $.H4 || tn === $.H5 || tn === $.H6;
  36015. }
  36016. var UNESCAPED_TEXT = /* @__PURE__ */ new Set([
  36017. TAG_NAMES.STYLE,
  36018. TAG_NAMES.SCRIPT,
  36019. TAG_NAMES.XMP,
  36020. TAG_NAMES.IFRAME,
  36021. TAG_NAMES.NOEMBED,
  36022. TAG_NAMES.NOFRAMES,
  36023. TAG_NAMES.PLAINTEXT
  36024. ]);
  36025. function hasUnescapedText(tn, scriptingEnabled) {
  36026. return UNESCAPED_TEXT.has(tn) || scriptingEnabled && tn === TAG_NAMES.NOSCRIPT;
  36027. }
  36028. // node_modules/parse5/dist/tokenizer/index.js
  36029. var C1_CONTROLS_REFERENCE_REPLACEMENTS = /* @__PURE__ */ new Map([
  36030. [128, 8364],
  36031. [130, 8218],
  36032. [131, 402],
  36033. [132, 8222],
  36034. [133, 8230],
  36035. [134, 8224],
  36036. [135, 8225],
  36037. [136, 710],
  36038. [137, 8240],
  36039. [138, 352],
  36040. [139, 8249],
  36041. [140, 338],
  36042. [142, 381],
  36043. [145, 8216],
  36044. [146, 8217],
  36045. [147, 8220],
  36046. [148, 8221],
  36047. [149, 8226],
  36048. [150, 8211],
  36049. [151, 8212],
  36050. [152, 732],
  36051. [153, 8482],
  36052. [154, 353],
  36053. [155, 8250],
  36054. [156, 339],
  36055. [158, 382],
  36056. [159, 376]
  36057. ]);
  36058. var State;
  36059. (function(State2) {
  36060. State2[State2["DATA"] = 0] = "DATA";
  36061. State2[State2["RCDATA"] = 1] = "RCDATA";
  36062. State2[State2["RAWTEXT"] = 2] = "RAWTEXT";
  36063. State2[State2["SCRIPT_DATA"] = 3] = "SCRIPT_DATA";
  36064. State2[State2["PLAINTEXT"] = 4] = "PLAINTEXT";
  36065. State2[State2["TAG_OPEN"] = 5] = "TAG_OPEN";
  36066. State2[State2["END_TAG_OPEN"] = 6] = "END_TAG_OPEN";
  36067. State2[State2["TAG_NAME"] = 7] = "TAG_NAME";
  36068. State2[State2["RCDATA_LESS_THAN_SIGN"] = 8] = "RCDATA_LESS_THAN_SIGN";
  36069. State2[State2["RCDATA_END_TAG_OPEN"] = 9] = "RCDATA_END_TAG_OPEN";
  36070. State2[State2["RCDATA_END_TAG_NAME"] = 10] = "RCDATA_END_TAG_NAME";
  36071. State2[State2["RAWTEXT_LESS_THAN_SIGN"] = 11] = "RAWTEXT_LESS_THAN_SIGN";
  36072. State2[State2["RAWTEXT_END_TAG_OPEN"] = 12] = "RAWTEXT_END_TAG_OPEN";
  36073. State2[State2["RAWTEXT_END_TAG_NAME"] = 13] = "RAWTEXT_END_TAG_NAME";
  36074. State2[State2["SCRIPT_DATA_LESS_THAN_SIGN"] = 14] = "SCRIPT_DATA_LESS_THAN_SIGN";
  36075. State2[State2["SCRIPT_DATA_END_TAG_OPEN"] = 15] = "SCRIPT_DATA_END_TAG_OPEN";
  36076. State2[State2["SCRIPT_DATA_END_TAG_NAME"] = 16] = "SCRIPT_DATA_END_TAG_NAME";
  36077. State2[State2["SCRIPT_DATA_ESCAPE_START"] = 17] = "SCRIPT_DATA_ESCAPE_START";
  36078. State2[State2["SCRIPT_DATA_ESCAPE_START_DASH"] = 18] = "SCRIPT_DATA_ESCAPE_START_DASH";
  36079. State2[State2["SCRIPT_DATA_ESCAPED"] = 19] = "SCRIPT_DATA_ESCAPED";
  36080. State2[State2["SCRIPT_DATA_ESCAPED_DASH"] = 20] = "SCRIPT_DATA_ESCAPED_DASH";
  36081. State2[State2["SCRIPT_DATA_ESCAPED_DASH_DASH"] = 21] = "SCRIPT_DATA_ESCAPED_DASH_DASH";
  36082. State2[State2["SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN"] = 22] = "SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN";
  36083. State2[State2["SCRIPT_DATA_ESCAPED_END_TAG_OPEN"] = 23] = "SCRIPT_DATA_ESCAPED_END_TAG_OPEN";
  36084. State2[State2["SCRIPT_DATA_ESCAPED_END_TAG_NAME"] = 24] = "SCRIPT_DATA_ESCAPED_END_TAG_NAME";
  36085. State2[State2["SCRIPT_DATA_DOUBLE_ESCAPE_START"] = 25] = "SCRIPT_DATA_DOUBLE_ESCAPE_START";
  36086. State2[State2["SCRIPT_DATA_DOUBLE_ESCAPED"] = 26] = "SCRIPT_DATA_DOUBLE_ESCAPED";
  36087. State2[State2["SCRIPT_DATA_DOUBLE_ESCAPED_DASH"] = 27] = "SCRIPT_DATA_DOUBLE_ESCAPED_DASH";
  36088. State2[State2["SCRIPT_DATA_DOUBLE_ESCAPED_DASH_DASH"] = 28] = "SCRIPT_DATA_DOUBLE_ESCAPED_DASH_DASH";
  36089. State2[State2["SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN"] = 29] = "SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN";
  36090. State2[State2["SCRIPT_DATA_DOUBLE_ESCAPE_END"] = 30] = "SCRIPT_DATA_DOUBLE_ESCAPE_END";
  36091. State2[State2["BEFORE_ATTRIBUTE_NAME"] = 31] = "BEFORE_ATTRIBUTE_NAME";
  36092. State2[State2["ATTRIBUTE_NAME"] = 32] = "ATTRIBUTE_NAME";
  36093. State2[State2["AFTER_ATTRIBUTE_NAME"] = 33] = "AFTER_ATTRIBUTE_NAME";
  36094. State2[State2["BEFORE_ATTRIBUTE_VALUE"] = 34] = "BEFORE_ATTRIBUTE_VALUE";
  36095. State2[State2["ATTRIBUTE_VALUE_DOUBLE_QUOTED"] = 35] = "ATTRIBUTE_VALUE_DOUBLE_QUOTED";
  36096. State2[State2["ATTRIBUTE_VALUE_SINGLE_QUOTED"] = 36] = "ATTRIBUTE_VALUE_SINGLE_QUOTED";
  36097. State2[State2["ATTRIBUTE_VALUE_UNQUOTED"] = 37] = "ATTRIBUTE_VALUE_UNQUOTED";
  36098. State2[State2["AFTER_ATTRIBUTE_VALUE_QUOTED"] = 38] = "AFTER_ATTRIBUTE_VALUE_QUOTED";
  36099. State2[State2["SELF_CLOSING_START_TAG"] = 39] = "SELF_CLOSING_START_TAG";
  36100. State2[State2["BOGUS_COMMENT"] = 40] = "BOGUS_COMMENT";
  36101. State2[State2["MARKUP_DECLARATION_OPEN"] = 41] = "MARKUP_DECLARATION_OPEN";
  36102. State2[State2["COMMENT_START"] = 42] = "COMMENT_START";
  36103. State2[State2["COMMENT_START_DASH"] = 43] = "COMMENT_START_DASH";
  36104. State2[State2["COMMENT"] = 44] = "COMMENT";
  36105. State2[State2["COMMENT_LESS_THAN_SIGN"] = 45] = "COMMENT_LESS_THAN_SIGN";
  36106. State2[State2["COMMENT_LESS_THAN_SIGN_BANG"] = 46] = "COMMENT_LESS_THAN_SIGN_BANG";
  36107. State2[State2["COMMENT_LESS_THAN_SIGN_BANG_DASH"] = 47] = "COMMENT_LESS_THAN_SIGN_BANG_DASH";
  36108. State2[State2["COMMENT_LESS_THAN_SIGN_BANG_DASH_DASH"] = 48] = "COMMENT_LESS_THAN_SIGN_BANG_DASH_DASH";
  36109. State2[State2["COMMENT_END_DASH"] = 49] = "COMMENT_END_DASH";
  36110. State2[State2["COMMENT_END"] = 50] = "COMMENT_END";
  36111. State2[State2["COMMENT_END_BANG"] = 51] = "COMMENT_END_BANG";
  36112. State2[State2["DOCTYPE"] = 52] = "DOCTYPE";
  36113. State2[State2["BEFORE_DOCTYPE_NAME"] = 53] = "BEFORE_DOCTYPE_NAME";
  36114. State2[State2["DOCTYPE_NAME"] = 54] = "DOCTYPE_NAME";
  36115. State2[State2["AFTER_DOCTYPE_NAME"] = 55] = "AFTER_DOCTYPE_NAME";
  36116. State2[State2["AFTER_DOCTYPE_PUBLIC_KEYWORD"] = 56] = "AFTER_DOCTYPE_PUBLIC_KEYWORD";
  36117. State2[State2["BEFORE_DOCTYPE_PUBLIC_IDENTIFIER"] = 57] = "BEFORE_DOCTYPE_PUBLIC_IDENTIFIER";
  36118. State2[State2["DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED"] = 58] = "DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED";
  36119. State2[State2["DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED"] = 59] = "DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED";
  36120. State2[State2["AFTER_DOCTYPE_PUBLIC_IDENTIFIER"] = 60] = "AFTER_DOCTYPE_PUBLIC_IDENTIFIER";
  36121. State2[State2["BETWEEN_DOCTYPE_PUBLIC_AND_SYSTEM_IDENTIFIERS"] = 61] = "BETWEEN_DOCTYPE_PUBLIC_AND_SYSTEM_IDENTIFIERS";
  36122. State2[State2["AFTER_DOCTYPE_SYSTEM_KEYWORD"] = 62] = "AFTER_DOCTYPE_SYSTEM_KEYWORD";
  36123. State2[State2["BEFORE_DOCTYPE_SYSTEM_IDENTIFIER"] = 63] = "BEFORE_DOCTYPE_SYSTEM_IDENTIFIER";
  36124. State2[State2["DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED"] = 64] = "DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED";
  36125. State2[State2["DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED"] = 65] = "DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED";
  36126. State2[State2["AFTER_DOCTYPE_SYSTEM_IDENTIFIER"] = 66] = "AFTER_DOCTYPE_SYSTEM_IDENTIFIER";
  36127. State2[State2["BOGUS_DOCTYPE"] = 67] = "BOGUS_DOCTYPE";
  36128. State2[State2["CDATA_SECTION"] = 68] = "CDATA_SECTION";
  36129. State2[State2["CDATA_SECTION_BRACKET"] = 69] = "CDATA_SECTION_BRACKET";
  36130. State2[State2["CDATA_SECTION_END"] = 70] = "CDATA_SECTION_END";
  36131. State2[State2["CHARACTER_REFERENCE"] = 71] = "CHARACTER_REFERENCE";
  36132. State2[State2["NAMED_CHARACTER_REFERENCE"] = 72] = "NAMED_CHARACTER_REFERENCE";
  36133. State2[State2["AMBIGUOUS_AMPERSAND"] = 73] = "AMBIGUOUS_AMPERSAND";
  36134. State2[State2["NUMERIC_CHARACTER_REFERENCE"] = 74] = "NUMERIC_CHARACTER_REFERENCE";
  36135. State2[State2["HEXADEMICAL_CHARACTER_REFERENCE_START"] = 75] = "HEXADEMICAL_CHARACTER_REFERENCE_START";
  36136. State2[State2["HEXADEMICAL_CHARACTER_REFERENCE"] = 76] = "HEXADEMICAL_CHARACTER_REFERENCE";
  36137. State2[State2["DECIMAL_CHARACTER_REFERENCE"] = 77] = "DECIMAL_CHARACTER_REFERENCE";
  36138. State2[State2["NUMERIC_CHARACTER_REFERENCE_END"] = 78] = "NUMERIC_CHARACTER_REFERENCE_END";
  36139. })(State || (State = {}));
  36140. var TokenizerMode = {
  36141. DATA: State.DATA,
  36142. RCDATA: State.RCDATA,
  36143. RAWTEXT: State.RAWTEXT,
  36144. SCRIPT_DATA: State.SCRIPT_DATA,
  36145. PLAINTEXT: State.PLAINTEXT,
  36146. CDATA_SECTION: State.CDATA_SECTION
  36147. };
  36148. function isAsciiDigit(cp) {
  36149. return cp >= CODE_POINTS.DIGIT_0 && cp <= CODE_POINTS.DIGIT_9;
  36150. }
  36151. function isAsciiUpper(cp) {
  36152. return cp >= CODE_POINTS.LATIN_CAPITAL_A && cp <= CODE_POINTS.LATIN_CAPITAL_Z;
  36153. }
  36154. function isAsciiLower(cp) {
  36155. return cp >= CODE_POINTS.LATIN_SMALL_A && cp <= CODE_POINTS.LATIN_SMALL_Z;
  36156. }
  36157. function isAsciiLetter(cp) {
  36158. return isAsciiLower(cp) || isAsciiUpper(cp);
  36159. }
  36160. function isAsciiAlphaNumeric2(cp) {
  36161. return isAsciiLetter(cp) || isAsciiDigit(cp);
  36162. }
  36163. function isAsciiUpperHexDigit(cp) {
  36164. return cp >= CODE_POINTS.LATIN_CAPITAL_A && cp <= CODE_POINTS.LATIN_CAPITAL_F;
  36165. }
  36166. function isAsciiLowerHexDigit(cp) {
  36167. return cp >= CODE_POINTS.LATIN_SMALL_A && cp <= CODE_POINTS.LATIN_SMALL_F;
  36168. }
  36169. function isAsciiHexDigit(cp) {
  36170. return isAsciiDigit(cp) || isAsciiUpperHexDigit(cp) || isAsciiLowerHexDigit(cp);
  36171. }
  36172. function toAsciiLower(cp) {
  36173. return cp + 32;
  36174. }
  36175. function isWhitespace(cp) {
  36176. return cp === CODE_POINTS.SPACE || cp === CODE_POINTS.LINE_FEED || cp === CODE_POINTS.TABULATION || cp === CODE_POINTS.FORM_FEED;
  36177. }
  36178. function isEntityInAttributeInvalidEnd2(nextCp) {
  36179. return nextCp === CODE_POINTS.EQUALS_SIGN || isAsciiAlphaNumeric2(nextCp);
  36180. }
  36181. function isScriptDataDoubleEscapeSequenceEnd(cp) {
  36182. return isWhitespace(cp) || cp === CODE_POINTS.SOLIDUS || cp === CODE_POINTS.GREATER_THAN_SIGN;
  36183. }
  36184. var Tokenizer = class {
  36185. constructor(options, handler) {
  36186. this.options = options;
  36187. this.handler = handler;
  36188. this.paused = false;
  36189. this.inLoop = false;
  36190. this.inForeignNode = false;
  36191. this.lastStartTagName = "";
  36192. this.active = false;
  36193. this.state = State.DATA;
  36194. this.returnState = State.DATA;
  36195. this.charRefCode = -1;
  36196. this.consumedAfterSnapshot = -1;
  36197. this.currentCharacterToken = null;
  36198. this.currentToken = null;
  36199. this.currentAttr = { name: "", value: "" };
  36200. this.preprocessor = new Preprocessor(handler);
  36201. this.currentLocation = this.getCurrentLocation(-1);
  36202. }
  36203. //Errors
  36204. _err(code) {
  36205. var _a2, _b;
  36206. (_b = (_a2 = this.handler).onParseError) === null || _b === void 0 ? void 0 : _b.call(_a2, this.preprocessor.getError(code));
  36207. }
  36208. // NOTE: `offset` may never run across line boundaries.
  36209. getCurrentLocation(offset) {
  36210. if (!this.options.sourceCodeLocationInfo) {
  36211. return null;
  36212. }
  36213. return {
  36214. startLine: this.preprocessor.line,
  36215. startCol: this.preprocessor.col - offset,
  36216. startOffset: this.preprocessor.offset - offset,
  36217. endLine: -1,
  36218. endCol: -1,
  36219. endOffset: -1
  36220. };
  36221. }
  36222. _runParsingLoop() {
  36223. if (this.inLoop)
  36224. return;
  36225. this.inLoop = true;
  36226. while (this.active && !this.paused) {
  36227. this.consumedAfterSnapshot = 0;
  36228. const cp = this._consume();
  36229. if (!this._ensureHibernation()) {
  36230. this._callState(cp);
  36231. }
  36232. }
  36233. this.inLoop = false;
  36234. }
  36235. //API
  36236. pause() {
  36237. this.paused = true;
  36238. }
  36239. resume(writeCallback) {
  36240. if (!this.paused) {
  36241. throw new Error("Parser was already resumed");
  36242. }
  36243. this.paused = false;
  36244. if (this.inLoop)
  36245. return;
  36246. this._runParsingLoop();
  36247. if (!this.paused) {
  36248. writeCallback === null || writeCallback === void 0 ? void 0 : writeCallback();
  36249. }
  36250. }
  36251. write(chunk, isLastChunk, writeCallback) {
  36252. this.active = true;
  36253. this.preprocessor.write(chunk, isLastChunk);
  36254. this._runParsingLoop();
  36255. if (!this.paused) {
  36256. writeCallback === null || writeCallback === void 0 ? void 0 : writeCallback();
  36257. }
  36258. }
  36259. insertHtmlAtCurrentPos(chunk) {
  36260. this.active = true;
  36261. this.preprocessor.insertHtmlAtCurrentPos(chunk);
  36262. this._runParsingLoop();
  36263. }
  36264. //Hibernation
  36265. _ensureHibernation() {
  36266. if (this.preprocessor.endOfChunkHit) {
  36267. this._unconsume(this.consumedAfterSnapshot);
  36268. this.active = false;
  36269. return true;
  36270. }
  36271. return false;
  36272. }
  36273. //Consumption
  36274. _consume() {
  36275. this.consumedAfterSnapshot++;
  36276. return this.preprocessor.advance();
  36277. }
  36278. _unconsume(count) {
  36279. this.consumedAfterSnapshot -= count;
  36280. this.preprocessor.retreat(count);
  36281. }
  36282. _reconsumeInState(state, cp) {
  36283. this.state = state;
  36284. this._callState(cp);
  36285. }
  36286. _advanceBy(count) {
  36287. this.consumedAfterSnapshot += count;
  36288. for (let i = 0; i < count; i++) {
  36289. this.preprocessor.advance();
  36290. }
  36291. }
  36292. _consumeSequenceIfMatch(pattern, caseSensitive) {
  36293. if (this.preprocessor.startsWith(pattern, caseSensitive)) {
  36294. this._advanceBy(pattern.length - 1);
  36295. return true;
  36296. }
  36297. return false;
  36298. }
  36299. //Token creation
  36300. _createStartTagToken() {
  36301. this.currentToken = {
  36302. type: TokenType.START_TAG,
  36303. tagName: "",
  36304. tagID: TAG_ID.UNKNOWN,
  36305. selfClosing: false,
  36306. ackSelfClosing: false,
  36307. attrs: [],
  36308. location: this.getCurrentLocation(1)
  36309. };
  36310. }
  36311. _createEndTagToken() {
  36312. this.currentToken = {
  36313. type: TokenType.END_TAG,
  36314. tagName: "",
  36315. tagID: TAG_ID.UNKNOWN,
  36316. selfClosing: false,
  36317. ackSelfClosing: false,
  36318. attrs: [],
  36319. location: this.getCurrentLocation(2)
  36320. };
  36321. }
  36322. _createCommentToken(offset) {
  36323. this.currentToken = {
  36324. type: TokenType.COMMENT,
  36325. data: "",
  36326. location: this.getCurrentLocation(offset)
  36327. };
  36328. }
  36329. _createDoctypeToken(initialName) {
  36330. this.currentToken = {
  36331. type: TokenType.DOCTYPE,
  36332. name: initialName,
  36333. forceQuirks: false,
  36334. publicId: null,
  36335. systemId: null,
  36336. location: this.currentLocation
  36337. };
  36338. }
  36339. _createCharacterToken(type, chars) {
  36340. this.currentCharacterToken = {
  36341. type,
  36342. chars,
  36343. location: this.currentLocation
  36344. };
  36345. }
  36346. //Tag attributes
  36347. _createAttr(attrNameFirstCh) {
  36348. this.currentAttr = {
  36349. name: attrNameFirstCh,
  36350. value: ""
  36351. };
  36352. this.currentLocation = this.getCurrentLocation(0);
  36353. }
  36354. _leaveAttrName() {
  36355. var _a2;
  36356. var _b;
  36357. const token = this.currentToken;
  36358. if (getTokenAttr(token, this.currentAttr.name) === null) {
  36359. token.attrs.push(this.currentAttr);
  36360. if (token.location && this.currentLocation) {
  36361. const attrLocations = (_a2 = (_b = token.location).attrs) !== null && _a2 !== void 0 ? _a2 : _b.attrs = /* @__PURE__ */ Object.create(null);
  36362. attrLocations[this.currentAttr.name] = this.currentLocation;
  36363. this._leaveAttrValue();
  36364. }
  36365. } else {
  36366. this._err(ERR.duplicateAttribute);
  36367. }
  36368. }
  36369. _leaveAttrValue() {
  36370. if (this.currentLocation) {
  36371. this.currentLocation.endLine = this.preprocessor.line;
  36372. this.currentLocation.endCol = this.preprocessor.col;
  36373. this.currentLocation.endOffset = this.preprocessor.offset;
  36374. }
  36375. }
  36376. //Token emission
  36377. prepareToken(ct) {
  36378. this._emitCurrentCharacterToken(ct.location);
  36379. this.currentToken = null;
  36380. if (ct.location) {
  36381. ct.location.endLine = this.preprocessor.line;
  36382. ct.location.endCol = this.preprocessor.col + 1;
  36383. ct.location.endOffset = this.preprocessor.offset + 1;
  36384. }
  36385. this.currentLocation = this.getCurrentLocation(-1);
  36386. }
  36387. emitCurrentTagToken() {
  36388. const ct = this.currentToken;
  36389. this.prepareToken(ct);
  36390. ct.tagID = getTagID(ct.tagName);
  36391. if (ct.type === TokenType.START_TAG) {
  36392. this.lastStartTagName = ct.tagName;
  36393. this.handler.onStartTag(ct);
  36394. } else {
  36395. if (ct.attrs.length > 0) {
  36396. this._err(ERR.endTagWithAttributes);
  36397. }
  36398. if (ct.selfClosing) {
  36399. this._err(ERR.endTagWithTrailingSolidus);
  36400. }
  36401. this.handler.onEndTag(ct);
  36402. }
  36403. this.preprocessor.dropParsedChunk();
  36404. }
  36405. emitCurrentComment(ct) {
  36406. this.prepareToken(ct);
  36407. this.handler.onComment(ct);
  36408. this.preprocessor.dropParsedChunk();
  36409. }
  36410. emitCurrentDoctype(ct) {
  36411. this.prepareToken(ct);
  36412. this.handler.onDoctype(ct);
  36413. this.preprocessor.dropParsedChunk();
  36414. }
  36415. _emitCurrentCharacterToken(nextLocation) {
  36416. if (this.currentCharacterToken) {
  36417. if (nextLocation && this.currentCharacterToken.location) {
  36418. this.currentCharacterToken.location.endLine = nextLocation.startLine;
  36419. this.currentCharacterToken.location.endCol = nextLocation.startCol;
  36420. this.currentCharacterToken.location.endOffset = nextLocation.startOffset;
  36421. }
  36422. switch (this.currentCharacterToken.type) {
  36423. case TokenType.CHARACTER: {
  36424. this.handler.onCharacter(this.currentCharacterToken);
  36425. break;
  36426. }
  36427. case TokenType.NULL_CHARACTER: {
  36428. this.handler.onNullCharacter(this.currentCharacterToken);
  36429. break;
  36430. }
  36431. case TokenType.WHITESPACE_CHARACTER: {
  36432. this.handler.onWhitespaceCharacter(this.currentCharacterToken);
  36433. break;
  36434. }
  36435. }
  36436. this.currentCharacterToken = null;
  36437. }
  36438. }
  36439. _emitEOFToken() {
  36440. const location2 = this.getCurrentLocation(0);
  36441. if (location2) {
  36442. location2.endLine = location2.startLine;
  36443. location2.endCol = location2.startCol;
  36444. location2.endOffset = location2.startOffset;
  36445. }
  36446. this._emitCurrentCharacterToken(location2);
  36447. this.handler.onEof({ type: TokenType.EOF, location: location2 });
  36448. this.active = false;
  36449. }
  36450. //Characters emission
  36451. //OPTIMIZATION: specification uses only one type of character tokens (one token per character).
  36452. //This causes a huge memory overhead and a lot of unnecessary parser loops. parse5 uses 3 groups of characters.
  36453. //If we have a sequence of characters that belong to the same group, the parser can process it
  36454. //as a single solid character token.
  36455. //So, there are 3 types of character tokens in parse5:
  36456. //1)TokenType.NULL_CHARACTER - \u0000-character sequences (e.g. '\u0000\u0000\u0000')
  36457. //2)TokenType.WHITESPACE_CHARACTER - any whitespace/new-line character sequences (e.g. '\n \r\t \f')
  36458. //3)TokenType.CHARACTER - any character sequence which don't belong to groups 1 and 2 (e.g. 'abcdef1234@@#$%^')
  36459. _appendCharToCurrentCharacterToken(type, ch) {
  36460. if (this.currentCharacterToken) {
  36461. if (this.currentCharacterToken.type !== type) {
  36462. this.currentLocation = this.getCurrentLocation(0);
  36463. this._emitCurrentCharacterToken(this.currentLocation);
  36464. this.preprocessor.dropParsedChunk();
  36465. } else {
  36466. this.currentCharacterToken.chars += ch;
  36467. return;
  36468. }
  36469. }
  36470. this._createCharacterToken(type, ch);
  36471. }
  36472. _emitCodePoint(cp) {
  36473. const type = isWhitespace(cp) ? TokenType.WHITESPACE_CHARACTER : cp === CODE_POINTS.NULL ? TokenType.NULL_CHARACTER : TokenType.CHARACTER;
  36474. this._appendCharToCurrentCharacterToken(type, String.fromCodePoint(cp));
  36475. }
  36476. //NOTE: used when we emit characters explicitly.
  36477. //This is always for non-whitespace and non-null characters, which allows us to avoid additional checks.
  36478. _emitChars(ch) {
  36479. this._appendCharToCurrentCharacterToken(TokenType.CHARACTER, ch);
  36480. }
  36481. // Character reference helpers
  36482. _matchNamedCharacterReference(cp) {
  36483. let result = null;
  36484. let excess = 0;
  36485. let withoutSemicolon = false;
  36486. for (let i = 0, current = decode_data_html_default[0]; i >= 0; cp = this._consume()) {
  36487. i = determineBranch(decode_data_html_default, current, i + 1, cp);
  36488. if (i < 0)
  36489. break;
  36490. excess += 1;
  36491. current = decode_data_html_default[i];
  36492. const masked = current & BinTrieFlags.VALUE_LENGTH;
  36493. if (masked) {
  36494. const valueLength = (masked >> 14) - 1;
  36495. if (cp !== CODE_POINTS.SEMICOLON && this._isCharacterReferenceInAttribute() && isEntityInAttributeInvalidEnd2(this.preprocessor.peek(1))) {
  36496. result = [CODE_POINTS.AMPERSAND];
  36497. i += valueLength;
  36498. } else {
  36499. 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]];
  36500. excess = 0;
  36501. withoutSemicolon = cp !== CODE_POINTS.SEMICOLON;
  36502. }
  36503. if (valueLength === 0) {
  36504. this._consume();
  36505. break;
  36506. }
  36507. }
  36508. }
  36509. this._unconsume(excess);
  36510. if (withoutSemicolon && !this.preprocessor.endOfChunkHit) {
  36511. this._err(ERR.missingSemicolonAfterCharacterReference);
  36512. }
  36513. this._unconsume(1);
  36514. return result;
  36515. }
  36516. _isCharacterReferenceInAttribute() {
  36517. return this.returnState === State.ATTRIBUTE_VALUE_DOUBLE_QUOTED || this.returnState === State.ATTRIBUTE_VALUE_SINGLE_QUOTED || this.returnState === State.ATTRIBUTE_VALUE_UNQUOTED;
  36518. }
  36519. _flushCodePointConsumedAsCharacterReference(cp) {
  36520. if (this._isCharacterReferenceInAttribute()) {
  36521. this.currentAttr.value += String.fromCodePoint(cp);
  36522. } else {
  36523. this._emitCodePoint(cp);
  36524. }
  36525. }
  36526. // Calling states this way turns out to be much faster than any other approach.
  36527. _callState(cp) {
  36528. switch (this.state) {
  36529. case State.DATA: {
  36530. this._stateData(cp);
  36531. break;
  36532. }
  36533. case State.RCDATA: {
  36534. this._stateRcdata(cp);
  36535. break;
  36536. }
  36537. case State.RAWTEXT: {
  36538. this._stateRawtext(cp);
  36539. break;
  36540. }
  36541. case State.SCRIPT_DATA: {
  36542. this._stateScriptData(cp);
  36543. break;
  36544. }
  36545. case State.PLAINTEXT: {
  36546. this._statePlaintext(cp);
  36547. break;
  36548. }
  36549. case State.TAG_OPEN: {
  36550. this._stateTagOpen(cp);
  36551. break;
  36552. }
  36553. case State.END_TAG_OPEN: {
  36554. this._stateEndTagOpen(cp);
  36555. break;
  36556. }
  36557. case State.TAG_NAME: {
  36558. this._stateTagName(cp);
  36559. break;
  36560. }
  36561. case State.RCDATA_LESS_THAN_SIGN: {
  36562. this._stateRcdataLessThanSign(cp);
  36563. break;
  36564. }
  36565. case State.RCDATA_END_TAG_OPEN: {
  36566. this._stateRcdataEndTagOpen(cp);
  36567. break;
  36568. }
  36569. case State.RCDATA_END_TAG_NAME: {
  36570. this._stateRcdataEndTagName(cp);
  36571. break;
  36572. }
  36573. case State.RAWTEXT_LESS_THAN_SIGN: {
  36574. this._stateRawtextLessThanSign(cp);
  36575. break;
  36576. }
  36577. case State.RAWTEXT_END_TAG_OPEN: {
  36578. this._stateRawtextEndTagOpen(cp);
  36579. break;
  36580. }
  36581. case State.RAWTEXT_END_TAG_NAME: {
  36582. this._stateRawtextEndTagName(cp);
  36583. break;
  36584. }
  36585. case State.SCRIPT_DATA_LESS_THAN_SIGN: {
  36586. this._stateScriptDataLessThanSign(cp);
  36587. break;
  36588. }
  36589. case State.SCRIPT_DATA_END_TAG_OPEN: {
  36590. this._stateScriptDataEndTagOpen(cp);
  36591. break;
  36592. }
  36593. case State.SCRIPT_DATA_END_TAG_NAME: {
  36594. this._stateScriptDataEndTagName(cp);
  36595. break;
  36596. }
  36597. case State.SCRIPT_DATA_ESCAPE_START: {
  36598. this._stateScriptDataEscapeStart(cp);
  36599. break;
  36600. }
  36601. case State.SCRIPT_DATA_ESCAPE_START_DASH: {
  36602. this._stateScriptDataEscapeStartDash(cp);
  36603. break;
  36604. }
  36605. case State.SCRIPT_DATA_ESCAPED: {
  36606. this._stateScriptDataEscaped(cp);
  36607. break;
  36608. }
  36609. case State.SCRIPT_DATA_ESCAPED_DASH: {
  36610. this._stateScriptDataEscapedDash(cp);
  36611. break;
  36612. }
  36613. case State.SCRIPT_DATA_ESCAPED_DASH_DASH: {
  36614. this._stateScriptDataEscapedDashDash(cp);
  36615. break;
  36616. }
  36617. case State.SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN: {
  36618. this._stateScriptDataEscapedLessThanSign(cp);
  36619. break;
  36620. }
  36621. case State.SCRIPT_DATA_ESCAPED_END_TAG_OPEN: {
  36622. this._stateScriptDataEscapedEndTagOpen(cp);
  36623. break;
  36624. }
  36625. case State.SCRIPT_DATA_ESCAPED_END_TAG_NAME: {
  36626. this._stateScriptDataEscapedEndTagName(cp);
  36627. break;
  36628. }
  36629. case State.SCRIPT_DATA_DOUBLE_ESCAPE_START: {
  36630. this._stateScriptDataDoubleEscapeStart(cp);
  36631. break;
  36632. }
  36633. case State.SCRIPT_DATA_DOUBLE_ESCAPED: {
  36634. this._stateScriptDataDoubleEscaped(cp);
  36635. break;
  36636. }
  36637. case State.SCRIPT_DATA_DOUBLE_ESCAPED_DASH: {
  36638. this._stateScriptDataDoubleEscapedDash(cp);
  36639. break;
  36640. }
  36641. case State.SCRIPT_DATA_DOUBLE_ESCAPED_DASH_DASH: {
  36642. this._stateScriptDataDoubleEscapedDashDash(cp);
  36643. break;
  36644. }
  36645. case State.SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN: {
  36646. this._stateScriptDataDoubleEscapedLessThanSign(cp);
  36647. break;
  36648. }
  36649. case State.SCRIPT_DATA_DOUBLE_ESCAPE_END: {
  36650. this._stateScriptDataDoubleEscapeEnd(cp);
  36651. break;
  36652. }
  36653. case State.BEFORE_ATTRIBUTE_NAME: {
  36654. this._stateBeforeAttributeName(cp);
  36655. break;
  36656. }
  36657. case State.ATTRIBUTE_NAME: {
  36658. this._stateAttributeName(cp);
  36659. break;
  36660. }
  36661. case State.AFTER_ATTRIBUTE_NAME: {
  36662. this._stateAfterAttributeName(cp);
  36663. break;
  36664. }
  36665. case State.BEFORE_ATTRIBUTE_VALUE: {
  36666. this._stateBeforeAttributeValue(cp);
  36667. break;
  36668. }
  36669. case State.ATTRIBUTE_VALUE_DOUBLE_QUOTED: {
  36670. this._stateAttributeValueDoubleQuoted(cp);
  36671. break;
  36672. }
  36673. case State.ATTRIBUTE_VALUE_SINGLE_QUOTED: {
  36674. this._stateAttributeValueSingleQuoted(cp);
  36675. break;
  36676. }
  36677. case State.ATTRIBUTE_VALUE_UNQUOTED: {
  36678. this._stateAttributeValueUnquoted(cp);
  36679. break;
  36680. }
  36681. case State.AFTER_ATTRIBUTE_VALUE_QUOTED: {
  36682. this._stateAfterAttributeValueQuoted(cp);
  36683. break;
  36684. }
  36685. case State.SELF_CLOSING_START_TAG: {
  36686. this._stateSelfClosingStartTag(cp);
  36687. break;
  36688. }
  36689. case State.BOGUS_COMMENT: {
  36690. this._stateBogusComment(cp);
  36691. break;
  36692. }
  36693. case State.MARKUP_DECLARATION_OPEN: {
  36694. this._stateMarkupDeclarationOpen(cp);
  36695. break;
  36696. }
  36697. case State.COMMENT_START: {
  36698. this._stateCommentStart(cp);
  36699. break;
  36700. }
  36701. case State.COMMENT_START_DASH: {
  36702. this._stateCommentStartDash(cp);
  36703. break;
  36704. }
  36705. case State.COMMENT: {
  36706. this._stateComment(cp);
  36707. break;
  36708. }
  36709. case State.COMMENT_LESS_THAN_SIGN: {
  36710. this._stateCommentLessThanSign(cp);
  36711. break;
  36712. }
  36713. case State.COMMENT_LESS_THAN_SIGN_BANG: {
  36714. this._stateCommentLessThanSignBang(cp);
  36715. break;
  36716. }
  36717. case State.COMMENT_LESS_THAN_SIGN_BANG_DASH: {
  36718. this._stateCommentLessThanSignBangDash(cp);
  36719. break;
  36720. }
  36721. case State.COMMENT_LESS_THAN_SIGN_BANG_DASH_DASH: {
  36722. this._stateCommentLessThanSignBangDashDash(cp);
  36723. break;
  36724. }
  36725. case State.COMMENT_END_DASH: {
  36726. this._stateCommentEndDash(cp);
  36727. break;
  36728. }
  36729. case State.COMMENT_END: {
  36730. this._stateCommentEnd(cp);
  36731. break;
  36732. }
  36733. case State.COMMENT_END_BANG: {
  36734. this._stateCommentEndBang(cp);
  36735. break;
  36736. }
  36737. case State.DOCTYPE: {
  36738. this._stateDoctype(cp);
  36739. break;
  36740. }
  36741. case State.BEFORE_DOCTYPE_NAME: {
  36742. this._stateBeforeDoctypeName(cp);
  36743. break;
  36744. }
  36745. case State.DOCTYPE_NAME: {
  36746. this._stateDoctypeName(cp);
  36747. break;
  36748. }
  36749. case State.AFTER_DOCTYPE_NAME: {
  36750. this._stateAfterDoctypeName(cp);
  36751. break;
  36752. }
  36753. case State.AFTER_DOCTYPE_PUBLIC_KEYWORD: {
  36754. this._stateAfterDoctypePublicKeyword(cp);
  36755. break;
  36756. }
  36757. case State.BEFORE_DOCTYPE_PUBLIC_IDENTIFIER: {
  36758. this._stateBeforeDoctypePublicIdentifier(cp);
  36759. break;
  36760. }
  36761. case State.DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED: {
  36762. this._stateDoctypePublicIdentifierDoubleQuoted(cp);
  36763. break;
  36764. }
  36765. case State.DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED: {
  36766. this._stateDoctypePublicIdentifierSingleQuoted(cp);
  36767. break;
  36768. }
  36769. case State.AFTER_DOCTYPE_PUBLIC_IDENTIFIER: {
  36770. this._stateAfterDoctypePublicIdentifier(cp);
  36771. break;
  36772. }
  36773. case State.BETWEEN_DOCTYPE_PUBLIC_AND_SYSTEM_IDENTIFIERS: {
  36774. this._stateBetweenDoctypePublicAndSystemIdentifiers(cp);
  36775. break;
  36776. }
  36777. case State.AFTER_DOCTYPE_SYSTEM_KEYWORD: {
  36778. this._stateAfterDoctypeSystemKeyword(cp);
  36779. break;
  36780. }
  36781. case State.BEFORE_DOCTYPE_SYSTEM_IDENTIFIER: {
  36782. this._stateBeforeDoctypeSystemIdentifier(cp);
  36783. break;
  36784. }
  36785. case State.DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED: {
  36786. this._stateDoctypeSystemIdentifierDoubleQuoted(cp);
  36787. break;
  36788. }
  36789. case State.DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED: {
  36790. this._stateDoctypeSystemIdentifierSingleQuoted(cp);
  36791. break;
  36792. }
  36793. case State.AFTER_DOCTYPE_SYSTEM_IDENTIFIER: {
  36794. this._stateAfterDoctypeSystemIdentifier(cp);
  36795. break;
  36796. }
  36797. case State.BOGUS_DOCTYPE: {
  36798. this._stateBogusDoctype(cp);
  36799. break;
  36800. }
  36801. case State.CDATA_SECTION: {
  36802. this._stateCdataSection(cp);
  36803. break;
  36804. }
  36805. case State.CDATA_SECTION_BRACKET: {
  36806. this._stateCdataSectionBracket(cp);
  36807. break;
  36808. }
  36809. case State.CDATA_SECTION_END: {
  36810. this._stateCdataSectionEnd(cp);
  36811. break;
  36812. }
  36813. case State.CHARACTER_REFERENCE: {
  36814. this._stateCharacterReference(cp);
  36815. break;
  36816. }
  36817. case State.NAMED_CHARACTER_REFERENCE: {
  36818. this._stateNamedCharacterReference(cp);
  36819. break;
  36820. }
  36821. case State.AMBIGUOUS_AMPERSAND: {
  36822. this._stateAmbiguousAmpersand(cp);
  36823. break;
  36824. }
  36825. case State.NUMERIC_CHARACTER_REFERENCE: {
  36826. this._stateNumericCharacterReference(cp);
  36827. break;
  36828. }
  36829. case State.HEXADEMICAL_CHARACTER_REFERENCE_START: {
  36830. this._stateHexademicalCharacterReferenceStart(cp);
  36831. break;
  36832. }
  36833. case State.HEXADEMICAL_CHARACTER_REFERENCE: {
  36834. this._stateHexademicalCharacterReference(cp);
  36835. break;
  36836. }
  36837. case State.DECIMAL_CHARACTER_REFERENCE: {
  36838. this._stateDecimalCharacterReference(cp);
  36839. break;
  36840. }
  36841. case State.NUMERIC_CHARACTER_REFERENCE_END: {
  36842. this._stateNumericCharacterReferenceEnd(cp);
  36843. break;
  36844. }
  36845. default: {
  36846. throw new Error("Unknown state");
  36847. }
  36848. }
  36849. }
  36850. // State machine
  36851. // Data state
  36852. //------------------------------------------------------------------
  36853. _stateData(cp) {
  36854. switch (cp) {
  36855. case CODE_POINTS.LESS_THAN_SIGN: {
  36856. this.state = State.TAG_OPEN;
  36857. break;
  36858. }
  36859. case CODE_POINTS.AMPERSAND: {
  36860. this.returnState = State.DATA;
  36861. this.state = State.CHARACTER_REFERENCE;
  36862. break;
  36863. }
  36864. case CODE_POINTS.NULL: {
  36865. this._err(ERR.unexpectedNullCharacter);
  36866. this._emitCodePoint(cp);
  36867. break;
  36868. }
  36869. case CODE_POINTS.EOF: {
  36870. this._emitEOFToken();
  36871. break;
  36872. }
  36873. default: {
  36874. this._emitCodePoint(cp);
  36875. }
  36876. }
  36877. }
  36878. // RCDATA state
  36879. //------------------------------------------------------------------
  36880. _stateRcdata(cp) {
  36881. switch (cp) {
  36882. case CODE_POINTS.AMPERSAND: {
  36883. this.returnState = State.RCDATA;
  36884. this.state = State.CHARACTER_REFERENCE;
  36885. break;
  36886. }
  36887. case CODE_POINTS.LESS_THAN_SIGN: {
  36888. this.state = State.RCDATA_LESS_THAN_SIGN;
  36889. break;
  36890. }
  36891. case CODE_POINTS.NULL: {
  36892. this._err(ERR.unexpectedNullCharacter);
  36893. this._emitChars(REPLACEMENT_CHARACTER);
  36894. break;
  36895. }
  36896. case CODE_POINTS.EOF: {
  36897. this._emitEOFToken();
  36898. break;
  36899. }
  36900. default: {
  36901. this._emitCodePoint(cp);
  36902. }
  36903. }
  36904. }
  36905. // RAWTEXT state
  36906. //------------------------------------------------------------------
  36907. _stateRawtext(cp) {
  36908. switch (cp) {
  36909. case CODE_POINTS.LESS_THAN_SIGN: {
  36910. this.state = State.RAWTEXT_LESS_THAN_SIGN;
  36911. break;
  36912. }
  36913. case CODE_POINTS.NULL: {
  36914. this._err(ERR.unexpectedNullCharacter);
  36915. this._emitChars(REPLACEMENT_CHARACTER);
  36916. break;
  36917. }
  36918. case CODE_POINTS.EOF: {
  36919. this._emitEOFToken();
  36920. break;
  36921. }
  36922. default: {
  36923. this._emitCodePoint(cp);
  36924. }
  36925. }
  36926. }
  36927. // Script data state
  36928. //------------------------------------------------------------------
  36929. _stateScriptData(cp) {
  36930. switch (cp) {
  36931. case CODE_POINTS.LESS_THAN_SIGN: {
  36932. this.state = State.SCRIPT_DATA_LESS_THAN_SIGN;
  36933. break;
  36934. }
  36935. case CODE_POINTS.NULL: {
  36936. this._err(ERR.unexpectedNullCharacter);
  36937. this._emitChars(REPLACEMENT_CHARACTER);
  36938. break;
  36939. }
  36940. case CODE_POINTS.EOF: {
  36941. this._emitEOFToken();
  36942. break;
  36943. }
  36944. default: {
  36945. this._emitCodePoint(cp);
  36946. }
  36947. }
  36948. }
  36949. // PLAINTEXT state
  36950. //------------------------------------------------------------------
  36951. _statePlaintext(cp) {
  36952. switch (cp) {
  36953. case CODE_POINTS.NULL: {
  36954. this._err(ERR.unexpectedNullCharacter);
  36955. this._emitChars(REPLACEMENT_CHARACTER);
  36956. break;
  36957. }
  36958. case CODE_POINTS.EOF: {
  36959. this._emitEOFToken();
  36960. break;
  36961. }
  36962. default: {
  36963. this._emitCodePoint(cp);
  36964. }
  36965. }
  36966. }
  36967. // Tag open state
  36968. //------------------------------------------------------------------
  36969. _stateTagOpen(cp) {
  36970. if (isAsciiLetter(cp)) {
  36971. this._createStartTagToken();
  36972. this.state = State.TAG_NAME;
  36973. this._stateTagName(cp);
  36974. } else
  36975. switch (cp) {
  36976. case CODE_POINTS.EXCLAMATION_MARK: {
  36977. this.state = State.MARKUP_DECLARATION_OPEN;
  36978. break;
  36979. }
  36980. case CODE_POINTS.SOLIDUS: {
  36981. this.state = State.END_TAG_OPEN;
  36982. break;
  36983. }
  36984. case CODE_POINTS.QUESTION_MARK: {
  36985. this._err(ERR.unexpectedQuestionMarkInsteadOfTagName);
  36986. this._createCommentToken(1);
  36987. this.state = State.BOGUS_COMMENT;
  36988. this._stateBogusComment(cp);
  36989. break;
  36990. }
  36991. case CODE_POINTS.EOF: {
  36992. this._err(ERR.eofBeforeTagName);
  36993. this._emitChars("<");
  36994. this._emitEOFToken();
  36995. break;
  36996. }
  36997. default: {
  36998. this._err(ERR.invalidFirstCharacterOfTagName);
  36999. this._emitChars("<");
  37000. this.state = State.DATA;
  37001. this._stateData(cp);
  37002. }
  37003. }
  37004. }
  37005. // End tag open state
  37006. //------------------------------------------------------------------
  37007. _stateEndTagOpen(cp) {
  37008. if (isAsciiLetter(cp)) {
  37009. this._createEndTagToken();
  37010. this.state = State.TAG_NAME;
  37011. this._stateTagName(cp);
  37012. } else
  37013. switch (cp) {
  37014. case CODE_POINTS.GREATER_THAN_SIGN: {
  37015. this._err(ERR.missingEndTagName);
  37016. this.state = State.DATA;
  37017. break;
  37018. }
  37019. case CODE_POINTS.EOF: {
  37020. this._err(ERR.eofBeforeTagName);
  37021. this._emitChars("</");
  37022. this._emitEOFToken();
  37023. break;
  37024. }
  37025. default: {
  37026. this._err(ERR.invalidFirstCharacterOfTagName);
  37027. this._createCommentToken(2);
  37028. this.state = State.BOGUS_COMMENT;
  37029. this._stateBogusComment(cp);
  37030. }
  37031. }
  37032. }
  37033. // Tag name state
  37034. //------------------------------------------------------------------
  37035. _stateTagName(cp) {
  37036. const token = this.currentToken;
  37037. switch (cp) {
  37038. case CODE_POINTS.SPACE:
  37039. case CODE_POINTS.LINE_FEED:
  37040. case CODE_POINTS.TABULATION:
  37041. case CODE_POINTS.FORM_FEED: {
  37042. this.state = State.BEFORE_ATTRIBUTE_NAME;
  37043. break;
  37044. }
  37045. case CODE_POINTS.SOLIDUS: {
  37046. this.state = State.SELF_CLOSING_START_TAG;
  37047. break;
  37048. }
  37049. case CODE_POINTS.GREATER_THAN_SIGN: {
  37050. this.state = State.DATA;
  37051. this.emitCurrentTagToken();
  37052. break;
  37053. }
  37054. case CODE_POINTS.NULL: {
  37055. this._err(ERR.unexpectedNullCharacter);
  37056. token.tagName += REPLACEMENT_CHARACTER;
  37057. break;
  37058. }
  37059. case CODE_POINTS.EOF: {
  37060. this._err(ERR.eofInTag);
  37061. this._emitEOFToken();
  37062. break;
  37063. }
  37064. default: {
  37065. token.tagName += String.fromCodePoint(isAsciiUpper(cp) ? toAsciiLower(cp) : cp);
  37066. }
  37067. }
  37068. }
  37069. // RCDATA less-than sign state
  37070. //------------------------------------------------------------------
  37071. _stateRcdataLessThanSign(cp) {
  37072. if (cp === CODE_POINTS.SOLIDUS) {
  37073. this.state = State.RCDATA_END_TAG_OPEN;
  37074. } else {
  37075. this._emitChars("<");
  37076. this.state = State.RCDATA;
  37077. this._stateRcdata(cp);
  37078. }
  37079. }
  37080. // RCDATA end tag open state
  37081. //------------------------------------------------------------------
  37082. _stateRcdataEndTagOpen(cp) {
  37083. if (isAsciiLetter(cp)) {
  37084. this.state = State.RCDATA_END_TAG_NAME;
  37085. this._stateRcdataEndTagName(cp);
  37086. } else {
  37087. this._emitChars("</");
  37088. this.state = State.RCDATA;
  37089. this._stateRcdata(cp);
  37090. }
  37091. }
  37092. handleSpecialEndTag(_cp) {
  37093. if (!this.preprocessor.startsWith(this.lastStartTagName, false)) {
  37094. return !this._ensureHibernation();
  37095. }
  37096. this._createEndTagToken();
  37097. const token = this.currentToken;
  37098. token.tagName = this.lastStartTagName;
  37099. const cp = this.preprocessor.peek(this.lastStartTagName.length);
  37100. switch (cp) {
  37101. case CODE_POINTS.SPACE:
  37102. case CODE_POINTS.LINE_FEED:
  37103. case CODE_POINTS.TABULATION:
  37104. case CODE_POINTS.FORM_FEED: {
  37105. this._advanceBy(this.lastStartTagName.length);
  37106. this.state = State.BEFORE_ATTRIBUTE_NAME;
  37107. return false;
  37108. }
  37109. case CODE_POINTS.SOLIDUS: {
  37110. this._advanceBy(this.lastStartTagName.length);
  37111. this.state = State.SELF_CLOSING_START_TAG;
  37112. return false;
  37113. }
  37114. case CODE_POINTS.GREATER_THAN_SIGN: {
  37115. this._advanceBy(this.lastStartTagName.length);
  37116. this.emitCurrentTagToken();
  37117. this.state = State.DATA;
  37118. return false;
  37119. }
  37120. default: {
  37121. return !this._ensureHibernation();
  37122. }
  37123. }
  37124. }
  37125. // RCDATA end tag name state
  37126. //------------------------------------------------------------------
  37127. _stateRcdataEndTagName(cp) {
  37128. if (this.handleSpecialEndTag(cp)) {
  37129. this._emitChars("</");
  37130. this.state = State.RCDATA;
  37131. this._stateRcdata(cp);
  37132. }
  37133. }
  37134. // RAWTEXT less-than sign state
  37135. //------------------------------------------------------------------
  37136. _stateRawtextLessThanSign(cp) {
  37137. if (cp === CODE_POINTS.SOLIDUS) {
  37138. this.state = State.RAWTEXT_END_TAG_OPEN;
  37139. } else {
  37140. this._emitChars("<");
  37141. this.state = State.RAWTEXT;
  37142. this._stateRawtext(cp);
  37143. }
  37144. }
  37145. // RAWTEXT end tag open state
  37146. //------------------------------------------------------------------
  37147. _stateRawtextEndTagOpen(cp) {
  37148. if (isAsciiLetter(cp)) {
  37149. this.state = State.RAWTEXT_END_TAG_NAME;
  37150. this._stateRawtextEndTagName(cp);
  37151. } else {
  37152. this._emitChars("</");
  37153. this.state = State.RAWTEXT;
  37154. this._stateRawtext(cp);
  37155. }
  37156. }
  37157. // RAWTEXT end tag name state
  37158. //------------------------------------------------------------------
  37159. _stateRawtextEndTagName(cp) {
  37160. if (this.handleSpecialEndTag(cp)) {
  37161. this._emitChars("</");
  37162. this.state = State.RAWTEXT;
  37163. this._stateRawtext(cp);
  37164. }
  37165. }
  37166. // Script data less-than sign state
  37167. //------------------------------------------------------------------
  37168. _stateScriptDataLessThanSign(cp) {
  37169. switch (cp) {
  37170. case CODE_POINTS.SOLIDUS: {
  37171. this.state = State.SCRIPT_DATA_END_TAG_OPEN;
  37172. break;
  37173. }
  37174. case CODE_POINTS.EXCLAMATION_MARK: {
  37175. this.state = State.SCRIPT_DATA_ESCAPE_START;
  37176. this._emitChars("<!");
  37177. break;
  37178. }
  37179. default: {
  37180. this._emitChars("<");
  37181. this.state = State.SCRIPT_DATA;
  37182. this._stateScriptData(cp);
  37183. }
  37184. }
  37185. }
  37186. // Script data end tag open state
  37187. //------------------------------------------------------------------
  37188. _stateScriptDataEndTagOpen(cp) {
  37189. if (isAsciiLetter(cp)) {
  37190. this.state = State.SCRIPT_DATA_END_TAG_NAME;
  37191. this._stateScriptDataEndTagName(cp);
  37192. } else {
  37193. this._emitChars("</");
  37194. this.state = State.SCRIPT_DATA;
  37195. this._stateScriptData(cp);
  37196. }
  37197. }
  37198. // Script data end tag name state
  37199. //------------------------------------------------------------------
  37200. _stateScriptDataEndTagName(cp) {
  37201. if (this.handleSpecialEndTag(cp)) {
  37202. this._emitChars("</");
  37203. this.state = State.SCRIPT_DATA;
  37204. this._stateScriptData(cp);
  37205. }
  37206. }
  37207. // Script data escape start state
  37208. //------------------------------------------------------------------
  37209. _stateScriptDataEscapeStart(cp) {
  37210. if (cp === CODE_POINTS.HYPHEN_MINUS) {
  37211. this.state = State.SCRIPT_DATA_ESCAPE_START_DASH;
  37212. this._emitChars("-");
  37213. } else {
  37214. this.state = State.SCRIPT_DATA;
  37215. this._stateScriptData(cp);
  37216. }
  37217. }
  37218. // Script data escape start dash state
  37219. //------------------------------------------------------------------
  37220. _stateScriptDataEscapeStartDash(cp) {
  37221. if (cp === CODE_POINTS.HYPHEN_MINUS) {
  37222. this.state = State.SCRIPT_DATA_ESCAPED_DASH_DASH;
  37223. this._emitChars("-");
  37224. } else {
  37225. this.state = State.SCRIPT_DATA;
  37226. this._stateScriptData(cp);
  37227. }
  37228. }
  37229. // Script data escaped state
  37230. //------------------------------------------------------------------
  37231. _stateScriptDataEscaped(cp) {
  37232. switch (cp) {
  37233. case CODE_POINTS.HYPHEN_MINUS: {
  37234. this.state = State.SCRIPT_DATA_ESCAPED_DASH;
  37235. this._emitChars("-");
  37236. break;
  37237. }
  37238. case CODE_POINTS.LESS_THAN_SIGN: {
  37239. this.state = State.SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN;
  37240. break;
  37241. }
  37242. case CODE_POINTS.NULL: {
  37243. this._err(ERR.unexpectedNullCharacter);
  37244. this._emitChars(REPLACEMENT_CHARACTER);
  37245. break;
  37246. }
  37247. case CODE_POINTS.EOF: {
  37248. this._err(ERR.eofInScriptHtmlCommentLikeText);
  37249. this._emitEOFToken();
  37250. break;
  37251. }
  37252. default: {
  37253. this._emitCodePoint(cp);
  37254. }
  37255. }
  37256. }
  37257. // Script data escaped dash state
  37258. //------------------------------------------------------------------
  37259. _stateScriptDataEscapedDash(cp) {
  37260. switch (cp) {
  37261. case CODE_POINTS.HYPHEN_MINUS: {
  37262. this.state = State.SCRIPT_DATA_ESCAPED_DASH_DASH;
  37263. this._emitChars("-");
  37264. break;
  37265. }
  37266. case CODE_POINTS.LESS_THAN_SIGN: {
  37267. this.state = State.SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN;
  37268. break;
  37269. }
  37270. case CODE_POINTS.NULL: {
  37271. this._err(ERR.unexpectedNullCharacter);
  37272. this.state = State.SCRIPT_DATA_ESCAPED;
  37273. this._emitChars(REPLACEMENT_CHARACTER);
  37274. break;
  37275. }
  37276. case CODE_POINTS.EOF: {
  37277. this._err(ERR.eofInScriptHtmlCommentLikeText);
  37278. this._emitEOFToken();
  37279. break;
  37280. }
  37281. default: {
  37282. this.state = State.SCRIPT_DATA_ESCAPED;
  37283. this._emitCodePoint(cp);
  37284. }
  37285. }
  37286. }
  37287. // Script data escaped dash dash state
  37288. //------------------------------------------------------------------
  37289. _stateScriptDataEscapedDashDash(cp) {
  37290. switch (cp) {
  37291. case CODE_POINTS.HYPHEN_MINUS: {
  37292. this._emitChars("-");
  37293. break;
  37294. }
  37295. case CODE_POINTS.LESS_THAN_SIGN: {
  37296. this.state = State.SCRIPT_DATA_ESCAPED_LESS_THAN_SIGN;
  37297. break;
  37298. }
  37299. case CODE_POINTS.GREATER_THAN_SIGN: {
  37300. this.state = State.SCRIPT_DATA;
  37301. this._emitChars(">");
  37302. break;
  37303. }
  37304. case CODE_POINTS.NULL: {
  37305. this._err(ERR.unexpectedNullCharacter);
  37306. this.state = State.SCRIPT_DATA_ESCAPED;
  37307. this._emitChars(REPLACEMENT_CHARACTER);
  37308. break;
  37309. }
  37310. case CODE_POINTS.EOF: {
  37311. this._err(ERR.eofInScriptHtmlCommentLikeText);
  37312. this._emitEOFToken();
  37313. break;
  37314. }
  37315. default: {
  37316. this.state = State.SCRIPT_DATA_ESCAPED;
  37317. this._emitCodePoint(cp);
  37318. }
  37319. }
  37320. }
  37321. // Script data escaped less-than sign state
  37322. //------------------------------------------------------------------
  37323. _stateScriptDataEscapedLessThanSign(cp) {
  37324. if (cp === CODE_POINTS.SOLIDUS) {
  37325. this.state = State.SCRIPT_DATA_ESCAPED_END_TAG_OPEN;
  37326. } else if (isAsciiLetter(cp)) {
  37327. this._emitChars("<");
  37328. this.state = State.SCRIPT_DATA_DOUBLE_ESCAPE_START;
  37329. this._stateScriptDataDoubleEscapeStart(cp);
  37330. } else {
  37331. this._emitChars("<");
  37332. this.state = State.SCRIPT_DATA_ESCAPED;
  37333. this._stateScriptDataEscaped(cp);
  37334. }
  37335. }
  37336. // Script data escaped end tag open state
  37337. //------------------------------------------------------------------
  37338. _stateScriptDataEscapedEndTagOpen(cp) {
  37339. if (isAsciiLetter(cp)) {
  37340. this.state = State.SCRIPT_DATA_ESCAPED_END_TAG_NAME;
  37341. this._stateScriptDataEscapedEndTagName(cp);
  37342. } else {
  37343. this._emitChars("</");
  37344. this.state = State.SCRIPT_DATA_ESCAPED;
  37345. this._stateScriptDataEscaped(cp);
  37346. }
  37347. }
  37348. // Script data escaped end tag name state
  37349. //------------------------------------------------------------------
  37350. _stateScriptDataEscapedEndTagName(cp) {
  37351. if (this.handleSpecialEndTag(cp)) {
  37352. this._emitChars("</");
  37353. this.state = State.SCRIPT_DATA_ESCAPED;
  37354. this._stateScriptDataEscaped(cp);
  37355. }
  37356. }
  37357. // Script data double escape start state
  37358. //------------------------------------------------------------------
  37359. _stateScriptDataDoubleEscapeStart(cp) {
  37360. if (this.preprocessor.startsWith(SEQUENCES.SCRIPT, false) && isScriptDataDoubleEscapeSequenceEnd(this.preprocessor.peek(SEQUENCES.SCRIPT.length))) {
  37361. this._emitCodePoint(cp);
  37362. for (let i = 0; i < SEQUENCES.SCRIPT.length; i++) {
  37363. this._emitCodePoint(this._consume());
  37364. }
  37365. this.state = State.SCRIPT_DATA_DOUBLE_ESCAPED;
  37366. } else if (!this._ensureHibernation()) {
  37367. this.state = State.SCRIPT_DATA_ESCAPED;
  37368. this._stateScriptDataEscaped(cp);
  37369. }
  37370. }
  37371. // Script data double escaped state
  37372. //------------------------------------------------------------------
  37373. _stateScriptDataDoubleEscaped(cp) {
  37374. switch (cp) {
  37375. case CODE_POINTS.HYPHEN_MINUS: {
  37376. this.state = State.SCRIPT_DATA_DOUBLE_ESCAPED_DASH;
  37377. this._emitChars("-");
  37378. break;
  37379. }
  37380. case CODE_POINTS.LESS_THAN_SIGN: {
  37381. this.state = State.SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN;
  37382. this._emitChars("<");
  37383. break;
  37384. }
  37385. case CODE_POINTS.NULL: {
  37386. this._err(ERR.unexpectedNullCharacter);
  37387. this._emitChars(REPLACEMENT_CHARACTER);
  37388. break;
  37389. }
  37390. case CODE_POINTS.EOF: {
  37391. this._err(ERR.eofInScriptHtmlCommentLikeText);
  37392. this._emitEOFToken();
  37393. break;
  37394. }
  37395. default: {
  37396. this._emitCodePoint(cp);
  37397. }
  37398. }
  37399. }
  37400. // Script data double escaped dash state
  37401. //------------------------------------------------------------------
  37402. _stateScriptDataDoubleEscapedDash(cp) {
  37403. switch (cp) {
  37404. case CODE_POINTS.HYPHEN_MINUS: {
  37405. this.state = State.SCRIPT_DATA_DOUBLE_ESCAPED_DASH_DASH;
  37406. this._emitChars("-");
  37407. break;
  37408. }
  37409. case CODE_POINTS.LESS_THAN_SIGN: {
  37410. this.state = State.SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN;
  37411. this._emitChars("<");
  37412. break;
  37413. }
  37414. case CODE_POINTS.NULL: {
  37415. this._err(ERR.unexpectedNullCharacter);
  37416. this.state = State.SCRIPT_DATA_DOUBLE_ESCAPED;
  37417. this._emitChars(REPLACEMENT_CHARACTER);
  37418. break;
  37419. }
  37420. case CODE_POINTS.EOF: {
  37421. this._err(ERR.eofInScriptHtmlCommentLikeText);
  37422. this._emitEOFToken();
  37423. break;
  37424. }
  37425. default: {
  37426. this.state = State.SCRIPT_DATA_DOUBLE_ESCAPED;
  37427. this._emitCodePoint(cp);
  37428. }
  37429. }
  37430. }
  37431. // Script data double escaped dash dash state
  37432. //------------------------------------------------------------------
  37433. _stateScriptDataDoubleEscapedDashDash(cp) {
  37434. switch (cp) {
  37435. case CODE_POINTS.HYPHEN_MINUS: {
  37436. this._emitChars("-");
  37437. break;
  37438. }
  37439. case CODE_POINTS.LESS_THAN_SIGN: {
  37440. this.state = State.SCRIPT_DATA_DOUBLE_ESCAPED_LESS_THAN_SIGN;
  37441. this._emitChars("<");
  37442. break;
  37443. }
  37444. case CODE_POINTS.GREATER_THAN_SIGN: {
  37445. this.state = State.SCRIPT_DATA;
  37446. this._emitChars(">");
  37447. break;
  37448. }
  37449. case CODE_POINTS.NULL: {
  37450. this._err(ERR.unexpectedNullCharacter);
  37451. this.state = State.SCRIPT_DATA_DOUBLE_ESCAPED;
  37452. this._emitChars(REPLACEMENT_CHARACTER);
  37453. break;
  37454. }
  37455. case CODE_POINTS.EOF: {
  37456. this._err(ERR.eofInScriptHtmlCommentLikeText);
  37457. this._emitEOFToken();
  37458. break;
  37459. }
  37460. default: {
  37461. this.state = State.SCRIPT_DATA_DOUBLE_ESCAPED;
  37462. this._emitCodePoint(cp);
  37463. }
  37464. }
  37465. }
  37466. // Script data double escaped less-than sign state
  37467. //------------------------------------------------------------------
  37468. _stateScriptDataDoubleEscapedLessThanSign(cp) {
  37469. if (cp === CODE_POINTS.SOLIDUS) {
  37470. this.state = State.SCRIPT_DATA_DOUBLE_ESCAPE_END;
  37471. this._emitChars("/");
  37472. } else {
  37473. this.state = State.SCRIPT_DATA_DOUBLE_ESCAPED;
  37474. this._stateScriptDataDoubleEscaped(cp);
  37475. }
  37476. }
  37477. // Script data double escape end state
  37478. //------------------------------------------------------------------
  37479. _stateScriptDataDoubleEscapeEnd(cp) {
  37480. if (this.preprocessor.startsWith(SEQUENCES.SCRIPT, false) && isScriptDataDoubleEscapeSequenceEnd(this.preprocessor.peek(SEQUENCES.SCRIPT.length))) {
  37481. this._emitCodePoint(cp);
  37482. for (let i = 0; i < SEQUENCES.SCRIPT.length; i++) {
  37483. this._emitCodePoint(this._consume());
  37484. }
  37485. this.state = State.SCRIPT_DATA_ESCAPED;
  37486. } else if (!this._ensureHibernation()) {
  37487. this.state = State.SCRIPT_DATA_DOUBLE_ESCAPED;
  37488. this._stateScriptDataDoubleEscaped(cp);
  37489. }
  37490. }
  37491. // Before attribute name state
  37492. //------------------------------------------------------------------
  37493. _stateBeforeAttributeName(cp) {
  37494. switch (cp) {
  37495. case CODE_POINTS.SPACE:
  37496. case CODE_POINTS.LINE_FEED:
  37497. case CODE_POINTS.TABULATION:
  37498. case CODE_POINTS.FORM_FEED: {
  37499. break;
  37500. }
  37501. case CODE_POINTS.SOLIDUS:
  37502. case CODE_POINTS.GREATER_THAN_SIGN:
  37503. case CODE_POINTS.EOF: {
  37504. this.state = State.AFTER_ATTRIBUTE_NAME;
  37505. this._stateAfterAttributeName(cp);
  37506. break;
  37507. }
  37508. case CODE_POINTS.EQUALS_SIGN: {
  37509. this._err(ERR.unexpectedEqualsSignBeforeAttributeName);
  37510. this._createAttr("=");
  37511. this.state = State.ATTRIBUTE_NAME;
  37512. break;
  37513. }
  37514. default: {
  37515. this._createAttr("");
  37516. this.state = State.ATTRIBUTE_NAME;
  37517. this._stateAttributeName(cp);
  37518. }
  37519. }
  37520. }
  37521. // Attribute name state
  37522. //------------------------------------------------------------------
  37523. _stateAttributeName(cp) {
  37524. switch (cp) {
  37525. case CODE_POINTS.SPACE:
  37526. case CODE_POINTS.LINE_FEED:
  37527. case CODE_POINTS.TABULATION:
  37528. case CODE_POINTS.FORM_FEED:
  37529. case CODE_POINTS.SOLIDUS:
  37530. case CODE_POINTS.GREATER_THAN_SIGN:
  37531. case CODE_POINTS.EOF: {
  37532. this._leaveAttrName();
  37533. this.state = State.AFTER_ATTRIBUTE_NAME;
  37534. this._stateAfterAttributeName(cp);
  37535. break;
  37536. }
  37537. case CODE_POINTS.EQUALS_SIGN: {
  37538. this._leaveAttrName();
  37539. this.state = State.BEFORE_ATTRIBUTE_VALUE;
  37540. break;
  37541. }
  37542. case CODE_POINTS.QUOTATION_MARK:
  37543. case CODE_POINTS.APOSTROPHE:
  37544. case CODE_POINTS.LESS_THAN_SIGN: {
  37545. this._err(ERR.unexpectedCharacterInAttributeName);
  37546. this.currentAttr.name += String.fromCodePoint(cp);
  37547. break;
  37548. }
  37549. case CODE_POINTS.NULL: {
  37550. this._err(ERR.unexpectedNullCharacter);
  37551. this.currentAttr.name += REPLACEMENT_CHARACTER;
  37552. break;
  37553. }
  37554. default: {
  37555. this.currentAttr.name += String.fromCodePoint(isAsciiUpper(cp) ? toAsciiLower(cp) : cp);
  37556. }
  37557. }
  37558. }
  37559. // After attribute name state
  37560. //------------------------------------------------------------------
  37561. _stateAfterAttributeName(cp) {
  37562. switch (cp) {
  37563. case CODE_POINTS.SPACE:
  37564. case CODE_POINTS.LINE_FEED:
  37565. case CODE_POINTS.TABULATION:
  37566. case CODE_POINTS.FORM_FEED: {
  37567. break;
  37568. }
  37569. case CODE_POINTS.SOLIDUS: {
  37570. this.state = State.SELF_CLOSING_START_TAG;
  37571. break;
  37572. }
  37573. case CODE_POINTS.EQUALS_SIGN: {
  37574. this.state = State.BEFORE_ATTRIBUTE_VALUE;
  37575. break;
  37576. }
  37577. case CODE_POINTS.GREATER_THAN_SIGN: {
  37578. this.state = State.DATA;
  37579. this.emitCurrentTagToken();
  37580. break;
  37581. }
  37582. case CODE_POINTS.EOF: {
  37583. this._err(ERR.eofInTag);
  37584. this._emitEOFToken();
  37585. break;
  37586. }
  37587. default: {
  37588. this._createAttr("");
  37589. this.state = State.ATTRIBUTE_NAME;
  37590. this._stateAttributeName(cp);
  37591. }
  37592. }
  37593. }
  37594. // Before attribute value state
  37595. //------------------------------------------------------------------
  37596. _stateBeforeAttributeValue(cp) {
  37597. switch (cp) {
  37598. case CODE_POINTS.SPACE:
  37599. case CODE_POINTS.LINE_FEED:
  37600. case CODE_POINTS.TABULATION:
  37601. case CODE_POINTS.FORM_FEED: {
  37602. break;
  37603. }
  37604. case CODE_POINTS.QUOTATION_MARK: {
  37605. this.state = State.ATTRIBUTE_VALUE_DOUBLE_QUOTED;
  37606. break;
  37607. }
  37608. case CODE_POINTS.APOSTROPHE: {
  37609. this.state = State.ATTRIBUTE_VALUE_SINGLE_QUOTED;
  37610. break;
  37611. }
  37612. case CODE_POINTS.GREATER_THAN_SIGN: {
  37613. this._err(ERR.missingAttributeValue);
  37614. this.state = State.DATA;
  37615. this.emitCurrentTagToken();
  37616. break;
  37617. }
  37618. default: {
  37619. this.state = State.ATTRIBUTE_VALUE_UNQUOTED;
  37620. this._stateAttributeValueUnquoted(cp);
  37621. }
  37622. }
  37623. }
  37624. // Attribute value (double-quoted) state
  37625. //------------------------------------------------------------------
  37626. _stateAttributeValueDoubleQuoted(cp) {
  37627. switch (cp) {
  37628. case CODE_POINTS.QUOTATION_MARK: {
  37629. this.state = State.AFTER_ATTRIBUTE_VALUE_QUOTED;
  37630. break;
  37631. }
  37632. case CODE_POINTS.AMPERSAND: {
  37633. this.returnState = State.ATTRIBUTE_VALUE_DOUBLE_QUOTED;
  37634. this.state = State.CHARACTER_REFERENCE;
  37635. break;
  37636. }
  37637. case CODE_POINTS.NULL: {
  37638. this._err(ERR.unexpectedNullCharacter);
  37639. this.currentAttr.value += REPLACEMENT_CHARACTER;
  37640. break;
  37641. }
  37642. case CODE_POINTS.EOF: {
  37643. this._err(ERR.eofInTag);
  37644. this._emitEOFToken();
  37645. break;
  37646. }
  37647. default: {
  37648. this.currentAttr.value += String.fromCodePoint(cp);
  37649. }
  37650. }
  37651. }
  37652. // Attribute value (single-quoted) state
  37653. //------------------------------------------------------------------
  37654. _stateAttributeValueSingleQuoted(cp) {
  37655. switch (cp) {
  37656. case CODE_POINTS.APOSTROPHE: {
  37657. this.state = State.AFTER_ATTRIBUTE_VALUE_QUOTED;
  37658. break;
  37659. }
  37660. case CODE_POINTS.AMPERSAND: {
  37661. this.returnState = State.ATTRIBUTE_VALUE_SINGLE_QUOTED;
  37662. this.state = State.CHARACTER_REFERENCE;
  37663. break;
  37664. }
  37665. case CODE_POINTS.NULL: {
  37666. this._err(ERR.unexpectedNullCharacter);
  37667. this.currentAttr.value += REPLACEMENT_CHARACTER;
  37668. break;
  37669. }
  37670. case CODE_POINTS.EOF: {
  37671. this._err(ERR.eofInTag);
  37672. this._emitEOFToken();
  37673. break;
  37674. }
  37675. default: {
  37676. this.currentAttr.value += String.fromCodePoint(cp);
  37677. }
  37678. }
  37679. }
  37680. // Attribute value (unquoted) state
  37681. //------------------------------------------------------------------
  37682. _stateAttributeValueUnquoted(cp) {
  37683. switch (cp) {
  37684. case CODE_POINTS.SPACE:
  37685. case CODE_POINTS.LINE_FEED:
  37686. case CODE_POINTS.TABULATION:
  37687. case CODE_POINTS.FORM_FEED: {
  37688. this._leaveAttrValue();
  37689. this.state = State.BEFORE_ATTRIBUTE_NAME;
  37690. break;
  37691. }
  37692. case CODE_POINTS.AMPERSAND: {
  37693. this.returnState = State.ATTRIBUTE_VALUE_UNQUOTED;
  37694. this.state = State.CHARACTER_REFERENCE;
  37695. break;
  37696. }
  37697. case CODE_POINTS.GREATER_THAN_SIGN: {
  37698. this._leaveAttrValue();
  37699. this.state = State.DATA;
  37700. this.emitCurrentTagToken();
  37701. break;
  37702. }
  37703. case CODE_POINTS.NULL: {
  37704. this._err(ERR.unexpectedNullCharacter);
  37705. this.currentAttr.value += REPLACEMENT_CHARACTER;
  37706. break;
  37707. }
  37708. case CODE_POINTS.QUOTATION_MARK:
  37709. case CODE_POINTS.APOSTROPHE:
  37710. case CODE_POINTS.LESS_THAN_SIGN:
  37711. case CODE_POINTS.EQUALS_SIGN:
  37712. case CODE_POINTS.GRAVE_ACCENT: {
  37713. this._err(ERR.unexpectedCharacterInUnquotedAttributeValue);
  37714. this.currentAttr.value += String.fromCodePoint(cp);
  37715. break;
  37716. }
  37717. case CODE_POINTS.EOF: {
  37718. this._err(ERR.eofInTag);
  37719. this._emitEOFToken();
  37720. break;
  37721. }
  37722. default: {
  37723. this.currentAttr.value += String.fromCodePoint(cp);
  37724. }
  37725. }
  37726. }
  37727. // After attribute value (quoted) state
  37728. //------------------------------------------------------------------
  37729. _stateAfterAttributeValueQuoted(cp) {
  37730. switch (cp) {
  37731. case CODE_POINTS.SPACE:
  37732. case CODE_POINTS.LINE_FEED:
  37733. case CODE_POINTS.TABULATION:
  37734. case CODE_POINTS.FORM_FEED: {
  37735. this._leaveAttrValue();
  37736. this.state = State.BEFORE_ATTRIBUTE_NAME;
  37737. break;
  37738. }
  37739. case CODE_POINTS.SOLIDUS: {
  37740. this._leaveAttrValue();
  37741. this.state = State.SELF_CLOSING_START_TAG;
  37742. break;
  37743. }
  37744. case CODE_POINTS.GREATER_THAN_SIGN: {
  37745. this._leaveAttrValue();
  37746. this.state = State.DATA;
  37747. this.emitCurrentTagToken();
  37748. break;
  37749. }
  37750. case CODE_POINTS.EOF: {
  37751. this._err(ERR.eofInTag);
  37752. this._emitEOFToken();
  37753. break;
  37754. }
  37755. default: {
  37756. this._err(ERR.missingWhitespaceBetweenAttributes);
  37757. this.state = State.BEFORE_ATTRIBUTE_NAME;
  37758. this._stateBeforeAttributeName(cp);
  37759. }
  37760. }
  37761. }
  37762. // Self-closing start tag state
  37763. //------------------------------------------------------------------
  37764. _stateSelfClosingStartTag(cp) {
  37765. switch (cp) {
  37766. case CODE_POINTS.GREATER_THAN_SIGN: {
  37767. const token = this.currentToken;
  37768. token.selfClosing = true;
  37769. this.state = State.DATA;
  37770. this.emitCurrentTagToken();
  37771. break;
  37772. }
  37773. case CODE_POINTS.EOF: {
  37774. this._err(ERR.eofInTag);
  37775. this._emitEOFToken();
  37776. break;
  37777. }
  37778. default: {
  37779. this._err(ERR.unexpectedSolidusInTag);
  37780. this.state = State.BEFORE_ATTRIBUTE_NAME;
  37781. this._stateBeforeAttributeName(cp);
  37782. }
  37783. }
  37784. }
  37785. // Bogus comment state
  37786. //------------------------------------------------------------------
  37787. _stateBogusComment(cp) {
  37788. const token = this.currentToken;
  37789. switch (cp) {
  37790. case CODE_POINTS.GREATER_THAN_SIGN: {
  37791. this.state = State.DATA;
  37792. this.emitCurrentComment(token);
  37793. break;
  37794. }
  37795. case CODE_POINTS.EOF: {
  37796. this.emitCurrentComment(token);
  37797. this._emitEOFToken();
  37798. break;
  37799. }
  37800. case CODE_POINTS.NULL: {
  37801. this._err(ERR.unexpectedNullCharacter);
  37802. token.data += REPLACEMENT_CHARACTER;
  37803. break;
  37804. }
  37805. default: {
  37806. token.data += String.fromCodePoint(cp);
  37807. }
  37808. }
  37809. }
  37810. // Markup declaration open state
  37811. //------------------------------------------------------------------
  37812. _stateMarkupDeclarationOpen(cp) {
  37813. if (this._consumeSequenceIfMatch(SEQUENCES.DASH_DASH, true)) {
  37814. this._createCommentToken(SEQUENCES.DASH_DASH.length + 1);
  37815. this.state = State.COMMENT_START;
  37816. } else if (this._consumeSequenceIfMatch(SEQUENCES.DOCTYPE, false)) {
  37817. this.currentLocation = this.getCurrentLocation(SEQUENCES.DOCTYPE.length + 1);
  37818. this.state = State.DOCTYPE;
  37819. } else if (this._consumeSequenceIfMatch(SEQUENCES.CDATA_START, true)) {
  37820. if (this.inForeignNode) {
  37821. this.state = State.CDATA_SECTION;
  37822. } else {
  37823. this._err(ERR.cdataInHtmlContent);
  37824. this._createCommentToken(SEQUENCES.CDATA_START.length + 1);
  37825. this.currentToken.data = "[CDATA[";
  37826. this.state = State.BOGUS_COMMENT;
  37827. }
  37828. } else if (!this._ensureHibernation()) {
  37829. this._err(ERR.incorrectlyOpenedComment);
  37830. this._createCommentToken(2);
  37831. this.state = State.BOGUS_COMMENT;
  37832. this._stateBogusComment(cp);
  37833. }
  37834. }
  37835. // Comment start state
  37836. //------------------------------------------------------------------
  37837. _stateCommentStart(cp) {
  37838. switch (cp) {
  37839. case CODE_POINTS.HYPHEN_MINUS: {
  37840. this.state = State.COMMENT_START_DASH;
  37841. break;
  37842. }
  37843. case CODE_POINTS.GREATER_THAN_SIGN: {
  37844. this._err(ERR.abruptClosingOfEmptyComment);
  37845. this.state = State.DATA;
  37846. const token = this.currentToken;
  37847. this.emitCurrentComment(token);
  37848. break;
  37849. }
  37850. default: {
  37851. this.state = State.COMMENT;
  37852. this._stateComment(cp);
  37853. }
  37854. }
  37855. }
  37856. // Comment start dash state
  37857. //------------------------------------------------------------------
  37858. _stateCommentStartDash(cp) {
  37859. const token = this.currentToken;
  37860. switch (cp) {
  37861. case CODE_POINTS.HYPHEN_MINUS: {
  37862. this.state = State.COMMENT_END;
  37863. break;
  37864. }
  37865. case CODE_POINTS.GREATER_THAN_SIGN: {
  37866. this._err(ERR.abruptClosingOfEmptyComment);
  37867. this.state = State.DATA;
  37868. this.emitCurrentComment(token);
  37869. break;
  37870. }
  37871. case CODE_POINTS.EOF: {
  37872. this._err(ERR.eofInComment);
  37873. this.emitCurrentComment(token);
  37874. this._emitEOFToken();
  37875. break;
  37876. }
  37877. default: {
  37878. token.data += "-";
  37879. this.state = State.COMMENT;
  37880. this._stateComment(cp);
  37881. }
  37882. }
  37883. }
  37884. // Comment state
  37885. //------------------------------------------------------------------
  37886. _stateComment(cp) {
  37887. const token = this.currentToken;
  37888. switch (cp) {
  37889. case CODE_POINTS.HYPHEN_MINUS: {
  37890. this.state = State.COMMENT_END_DASH;
  37891. break;
  37892. }
  37893. case CODE_POINTS.LESS_THAN_SIGN: {
  37894. token.data += "<";
  37895. this.state = State.COMMENT_LESS_THAN_SIGN;
  37896. break;
  37897. }
  37898. case CODE_POINTS.NULL: {
  37899. this._err(ERR.unexpectedNullCharacter);
  37900. token.data += REPLACEMENT_CHARACTER;
  37901. break;
  37902. }
  37903. case CODE_POINTS.EOF: {
  37904. this._err(ERR.eofInComment);
  37905. this.emitCurrentComment(token);
  37906. this._emitEOFToken();
  37907. break;
  37908. }
  37909. default: {
  37910. token.data += String.fromCodePoint(cp);
  37911. }
  37912. }
  37913. }
  37914. // Comment less-than sign state
  37915. //------------------------------------------------------------------
  37916. _stateCommentLessThanSign(cp) {
  37917. const token = this.currentToken;
  37918. switch (cp) {
  37919. case CODE_POINTS.EXCLAMATION_MARK: {
  37920. token.data += "!";
  37921. this.state = State.COMMENT_LESS_THAN_SIGN_BANG;
  37922. break;
  37923. }
  37924. case CODE_POINTS.LESS_THAN_SIGN: {
  37925. token.data += "<";
  37926. break;
  37927. }
  37928. default: {
  37929. this.state = State.COMMENT;
  37930. this._stateComment(cp);
  37931. }
  37932. }
  37933. }
  37934. // Comment less-than sign bang state
  37935. //------------------------------------------------------------------
  37936. _stateCommentLessThanSignBang(cp) {
  37937. if (cp === CODE_POINTS.HYPHEN_MINUS) {
  37938. this.state = State.COMMENT_LESS_THAN_SIGN_BANG_DASH;
  37939. } else {
  37940. this.state = State.COMMENT;
  37941. this._stateComment(cp);
  37942. }
  37943. }
  37944. // Comment less-than sign bang dash state
  37945. //------------------------------------------------------------------
  37946. _stateCommentLessThanSignBangDash(cp) {
  37947. if (cp === CODE_POINTS.HYPHEN_MINUS) {
  37948. this.state = State.COMMENT_LESS_THAN_SIGN_BANG_DASH_DASH;
  37949. } else {
  37950. this.state = State.COMMENT_END_DASH;
  37951. this._stateCommentEndDash(cp);
  37952. }
  37953. }
  37954. // Comment less-than sign bang dash dash state
  37955. //------------------------------------------------------------------
  37956. _stateCommentLessThanSignBangDashDash(cp) {
  37957. if (cp !== CODE_POINTS.GREATER_THAN_SIGN && cp !== CODE_POINTS.EOF) {
  37958. this._err(ERR.nestedComment);
  37959. }
  37960. this.state = State.COMMENT_END;
  37961. this._stateCommentEnd(cp);
  37962. }
  37963. // Comment end dash state
  37964. //------------------------------------------------------------------
  37965. _stateCommentEndDash(cp) {
  37966. const token = this.currentToken;
  37967. switch (cp) {
  37968. case CODE_POINTS.HYPHEN_MINUS: {
  37969. this.state = State.COMMENT_END;
  37970. break;
  37971. }
  37972. case CODE_POINTS.EOF: {
  37973. this._err(ERR.eofInComment);
  37974. this.emitCurrentComment(token);
  37975. this._emitEOFToken();
  37976. break;
  37977. }
  37978. default: {
  37979. token.data += "-";
  37980. this.state = State.COMMENT;
  37981. this._stateComment(cp);
  37982. }
  37983. }
  37984. }
  37985. // Comment end state
  37986. //------------------------------------------------------------------
  37987. _stateCommentEnd(cp) {
  37988. const token = this.currentToken;
  37989. switch (cp) {
  37990. case CODE_POINTS.GREATER_THAN_SIGN: {
  37991. this.state = State.DATA;
  37992. this.emitCurrentComment(token);
  37993. break;
  37994. }
  37995. case CODE_POINTS.EXCLAMATION_MARK: {
  37996. this.state = State.COMMENT_END_BANG;
  37997. break;
  37998. }
  37999. case CODE_POINTS.HYPHEN_MINUS: {
  38000. token.data += "-";
  38001. break;
  38002. }
  38003. case CODE_POINTS.EOF: {
  38004. this._err(ERR.eofInComment);
  38005. this.emitCurrentComment(token);
  38006. this._emitEOFToken();
  38007. break;
  38008. }
  38009. default: {
  38010. token.data += "--";
  38011. this.state = State.COMMENT;
  38012. this._stateComment(cp);
  38013. }
  38014. }
  38015. }
  38016. // Comment end bang state
  38017. //------------------------------------------------------------------
  38018. _stateCommentEndBang(cp) {
  38019. const token = this.currentToken;
  38020. switch (cp) {
  38021. case CODE_POINTS.HYPHEN_MINUS: {
  38022. token.data += "--!";
  38023. this.state = State.COMMENT_END_DASH;
  38024. break;
  38025. }
  38026. case CODE_POINTS.GREATER_THAN_SIGN: {
  38027. this._err(ERR.incorrectlyClosedComment);
  38028. this.state = State.DATA;
  38029. this.emitCurrentComment(token);
  38030. break;
  38031. }
  38032. case CODE_POINTS.EOF: {
  38033. this._err(ERR.eofInComment);
  38034. this.emitCurrentComment(token);
  38035. this._emitEOFToken();
  38036. break;
  38037. }
  38038. default: {
  38039. token.data += "--!";
  38040. this.state = State.COMMENT;
  38041. this._stateComment(cp);
  38042. }
  38043. }
  38044. }
  38045. // DOCTYPE state
  38046. //------------------------------------------------------------------
  38047. _stateDoctype(cp) {
  38048. switch (cp) {
  38049. case CODE_POINTS.SPACE:
  38050. case CODE_POINTS.LINE_FEED:
  38051. case CODE_POINTS.TABULATION:
  38052. case CODE_POINTS.FORM_FEED: {
  38053. this.state = State.BEFORE_DOCTYPE_NAME;
  38054. break;
  38055. }
  38056. case CODE_POINTS.GREATER_THAN_SIGN: {
  38057. this.state = State.BEFORE_DOCTYPE_NAME;
  38058. this._stateBeforeDoctypeName(cp);
  38059. break;
  38060. }
  38061. case CODE_POINTS.EOF: {
  38062. this._err(ERR.eofInDoctype);
  38063. this._createDoctypeToken(null);
  38064. const token = this.currentToken;
  38065. token.forceQuirks = true;
  38066. this.emitCurrentDoctype(token);
  38067. this._emitEOFToken();
  38068. break;
  38069. }
  38070. default: {
  38071. this._err(ERR.missingWhitespaceBeforeDoctypeName);
  38072. this.state = State.BEFORE_DOCTYPE_NAME;
  38073. this._stateBeforeDoctypeName(cp);
  38074. }
  38075. }
  38076. }
  38077. // Before DOCTYPE name state
  38078. //------------------------------------------------------------------
  38079. _stateBeforeDoctypeName(cp) {
  38080. if (isAsciiUpper(cp)) {
  38081. this._createDoctypeToken(String.fromCharCode(toAsciiLower(cp)));
  38082. this.state = State.DOCTYPE_NAME;
  38083. } else
  38084. switch (cp) {
  38085. case CODE_POINTS.SPACE:
  38086. case CODE_POINTS.LINE_FEED:
  38087. case CODE_POINTS.TABULATION:
  38088. case CODE_POINTS.FORM_FEED: {
  38089. break;
  38090. }
  38091. case CODE_POINTS.NULL: {
  38092. this._err(ERR.unexpectedNullCharacter);
  38093. this._createDoctypeToken(REPLACEMENT_CHARACTER);
  38094. this.state = State.DOCTYPE_NAME;
  38095. break;
  38096. }
  38097. case CODE_POINTS.GREATER_THAN_SIGN: {
  38098. this._err(ERR.missingDoctypeName);
  38099. this._createDoctypeToken(null);
  38100. const token = this.currentToken;
  38101. token.forceQuirks = true;
  38102. this.emitCurrentDoctype(token);
  38103. this.state = State.DATA;
  38104. break;
  38105. }
  38106. case CODE_POINTS.EOF: {
  38107. this._err(ERR.eofInDoctype);
  38108. this._createDoctypeToken(null);
  38109. const token = this.currentToken;
  38110. token.forceQuirks = true;
  38111. this.emitCurrentDoctype(token);
  38112. this._emitEOFToken();
  38113. break;
  38114. }
  38115. default: {
  38116. this._createDoctypeToken(String.fromCodePoint(cp));
  38117. this.state = State.DOCTYPE_NAME;
  38118. }
  38119. }
  38120. }
  38121. // DOCTYPE name state
  38122. //------------------------------------------------------------------
  38123. _stateDoctypeName(cp) {
  38124. const token = this.currentToken;
  38125. switch (cp) {
  38126. case CODE_POINTS.SPACE:
  38127. case CODE_POINTS.LINE_FEED:
  38128. case CODE_POINTS.TABULATION:
  38129. case CODE_POINTS.FORM_FEED: {
  38130. this.state = State.AFTER_DOCTYPE_NAME;
  38131. break;
  38132. }
  38133. case CODE_POINTS.GREATER_THAN_SIGN: {
  38134. this.state = State.DATA;
  38135. this.emitCurrentDoctype(token);
  38136. break;
  38137. }
  38138. case CODE_POINTS.NULL: {
  38139. this._err(ERR.unexpectedNullCharacter);
  38140. token.name += REPLACEMENT_CHARACTER;
  38141. break;
  38142. }
  38143. case CODE_POINTS.EOF: {
  38144. this._err(ERR.eofInDoctype);
  38145. token.forceQuirks = true;
  38146. this.emitCurrentDoctype(token);
  38147. this._emitEOFToken();
  38148. break;
  38149. }
  38150. default: {
  38151. token.name += String.fromCodePoint(isAsciiUpper(cp) ? toAsciiLower(cp) : cp);
  38152. }
  38153. }
  38154. }
  38155. // After DOCTYPE name state
  38156. //------------------------------------------------------------------
  38157. _stateAfterDoctypeName(cp) {
  38158. const token = this.currentToken;
  38159. switch (cp) {
  38160. case CODE_POINTS.SPACE:
  38161. case CODE_POINTS.LINE_FEED:
  38162. case CODE_POINTS.TABULATION:
  38163. case CODE_POINTS.FORM_FEED: {
  38164. break;
  38165. }
  38166. case CODE_POINTS.GREATER_THAN_SIGN: {
  38167. this.state = State.DATA;
  38168. this.emitCurrentDoctype(token);
  38169. break;
  38170. }
  38171. case CODE_POINTS.EOF: {
  38172. this._err(ERR.eofInDoctype);
  38173. token.forceQuirks = true;
  38174. this.emitCurrentDoctype(token);
  38175. this._emitEOFToken();
  38176. break;
  38177. }
  38178. default: {
  38179. if (this._consumeSequenceIfMatch(SEQUENCES.PUBLIC, false)) {
  38180. this.state = State.AFTER_DOCTYPE_PUBLIC_KEYWORD;
  38181. } else if (this._consumeSequenceIfMatch(SEQUENCES.SYSTEM, false)) {
  38182. this.state = State.AFTER_DOCTYPE_SYSTEM_KEYWORD;
  38183. } else if (!this._ensureHibernation()) {
  38184. this._err(ERR.invalidCharacterSequenceAfterDoctypeName);
  38185. token.forceQuirks = true;
  38186. this.state = State.BOGUS_DOCTYPE;
  38187. this._stateBogusDoctype(cp);
  38188. }
  38189. }
  38190. }
  38191. }
  38192. // After DOCTYPE public keyword state
  38193. //------------------------------------------------------------------
  38194. _stateAfterDoctypePublicKeyword(cp) {
  38195. const token = this.currentToken;
  38196. switch (cp) {
  38197. case CODE_POINTS.SPACE:
  38198. case CODE_POINTS.LINE_FEED:
  38199. case CODE_POINTS.TABULATION:
  38200. case CODE_POINTS.FORM_FEED: {
  38201. this.state = State.BEFORE_DOCTYPE_PUBLIC_IDENTIFIER;
  38202. break;
  38203. }
  38204. case CODE_POINTS.QUOTATION_MARK: {
  38205. this._err(ERR.missingWhitespaceAfterDoctypePublicKeyword);
  38206. token.publicId = "";
  38207. this.state = State.DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED;
  38208. break;
  38209. }
  38210. case CODE_POINTS.APOSTROPHE: {
  38211. this._err(ERR.missingWhitespaceAfterDoctypePublicKeyword);
  38212. token.publicId = "";
  38213. this.state = State.DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED;
  38214. break;
  38215. }
  38216. case CODE_POINTS.GREATER_THAN_SIGN: {
  38217. this._err(ERR.missingDoctypePublicIdentifier);
  38218. token.forceQuirks = true;
  38219. this.state = State.DATA;
  38220. this.emitCurrentDoctype(token);
  38221. break;
  38222. }
  38223. case CODE_POINTS.EOF: {
  38224. this._err(ERR.eofInDoctype);
  38225. token.forceQuirks = true;
  38226. this.emitCurrentDoctype(token);
  38227. this._emitEOFToken();
  38228. break;
  38229. }
  38230. default: {
  38231. this._err(ERR.missingQuoteBeforeDoctypePublicIdentifier);
  38232. token.forceQuirks = true;
  38233. this.state = State.BOGUS_DOCTYPE;
  38234. this._stateBogusDoctype(cp);
  38235. }
  38236. }
  38237. }
  38238. // Before DOCTYPE public identifier state
  38239. //------------------------------------------------------------------
  38240. _stateBeforeDoctypePublicIdentifier(cp) {
  38241. const token = this.currentToken;
  38242. switch (cp) {
  38243. case CODE_POINTS.SPACE:
  38244. case CODE_POINTS.LINE_FEED:
  38245. case CODE_POINTS.TABULATION:
  38246. case CODE_POINTS.FORM_FEED: {
  38247. break;
  38248. }
  38249. case CODE_POINTS.QUOTATION_MARK: {
  38250. token.publicId = "";
  38251. this.state = State.DOCTYPE_PUBLIC_IDENTIFIER_DOUBLE_QUOTED;
  38252. break;
  38253. }
  38254. case CODE_POINTS.APOSTROPHE: {
  38255. token.publicId = "";
  38256. this.state = State.DOCTYPE_PUBLIC_IDENTIFIER_SINGLE_QUOTED;
  38257. break;
  38258. }
  38259. case CODE_POINTS.GREATER_THAN_SIGN: {
  38260. this._err(ERR.missingDoctypePublicIdentifier);
  38261. token.forceQuirks = true;
  38262. this.state = State.DATA;
  38263. this.emitCurrentDoctype(token);
  38264. break;
  38265. }
  38266. case CODE_POINTS.EOF: {
  38267. this._err(ERR.eofInDoctype);
  38268. token.forceQuirks = true;
  38269. this.emitCurrentDoctype(token);
  38270. this._emitEOFToken();
  38271. break;
  38272. }
  38273. default: {
  38274. this._err(ERR.missingQuoteBeforeDoctypePublicIdentifier);
  38275. token.forceQuirks = true;
  38276. this.state = State.BOGUS_DOCTYPE;
  38277. this._stateBogusDoctype(cp);
  38278. }
  38279. }
  38280. }
  38281. // DOCTYPE public identifier (double-quoted) state
  38282. //------------------------------------------------------------------
  38283. _stateDoctypePublicIdentifierDoubleQuoted(cp) {
  38284. const token = this.currentToken;
  38285. switch (cp) {
  38286. case CODE_POINTS.QUOTATION_MARK: {
  38287. this.state = State.AFTER_DOCTYPE_PUBLIC_IDENTIFIER;
  38288. break;
  38289. }
  38290. case CODE_POINTS.NULL: {
  38291. this._err(ERR.unexpectedNullCharacter);
  38292. token.publicId += REPLACEMENT_CHARACTER;
  38293. break;
  38294. }
  38295. case CODE_POINTS.GREATER_THAN_SIGN: {
  38296. this._err(ERR.abruptDoctypePublicIdentifier);
  38297. token.forceQuirks = true;
  38298. this.emitCurrentDoctype(token);
  38299. this.state = State.DATA;
  38300. break;
  38301. }
  38302. case CODE_POINTS.EOF: {
  38303. this._err(ERR.eofInDoctype);
  38304. token.forceQuirks = true;
  38305. this.emitCurrentDoctype(token);
  38306. this._emitEOFToken();
  38307. break;
  38308. }
  38309. default: {
  38310. token.publicId += String.fromCodePoint(cp);
  38311. }
  38312. }
  38313. }
  38314. // DOCTYPE public identifier (single-quoted) state
  38315. //------------------------------------------------------------------
  38316. _stateDoctypePublicIdentifierSingleQuoted(cp) {
  38317. const token = this.currentToken;
  38318. switch (cp) {
  38319. case CODE_POINTS.APOSTROPHE: {
  38320. this.state = State.AFTER_DOCTYPE_PUBLIC_IDENTIFIER;
  38321. break;
  38322. }
  38323. case CODE_POINTS.NULL: {
  38324. this._err(ERR.unexpectedNullCharacter);
  38325. token.publicId += REPLACEMENT_CHARACTER;
  38326. break;
  38327. }
  38328. case CODE_POINTS.GREATER_THAN_SIGN: {
  38329. this._err(ERR.abruptDoctypePublicIdentifier);
  38330. token.forceQuirks = true;
  38331. this.emitCurrentDoctype(token);
  38332. this.state = State.DATA;
  38333. break;
  38334. }
  38335. case CODE_POINTS.EOF: {
  38336. this._err(ERR.eofInDoctype);
  38337. token.forceQuirks = true;
  38338. this.emitCurrentDoctype(token);
  38339. this._emitEOFToken();
  38340. break;
  38341. }
  38342. default: {
  38343. token.publicId += String.fromCodePoint(cp);
  38344. }
  38345. }
  38346. }
  38347. // After DOCTYPE public identifier state
  38348. //------------------------------------------------------------------
  38349. _stateAfterDoctypePublicIdentifier(cp) {
  38350. const token = this.currentToken;
  38351. switch (cp) {
  38352. case CODE_POINTS.SPACE:
  38353. case CODE_POINTS.LINE_FEED:
  38354. case CODE_POINTS.TABULATION:
  38355. case CODE_POINTS.FORM_FEED: {
  38356. this.state = State.BETWEEN_DOCTYPE_PUBLIC_AND_SYSTEM_IDENTIFIERS;
  38357. break;
  38358. }
  38359. case CODE_POINTS.GREATER_THAN_SIGN: {
  38360. this.state = State.DATA;
  38361. this.emitCurrentDoctype(token);
  38362. break;
  38363. }
  38364. case CODE_POINTS.QUOTATION_MARK: {
  38365. this._err(ERR.missingWhitespaceBetweenDoctypePublicAndSystemIdentifiers);
  38366. token.systemId = "";
  38367. this.state = State.DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED;
  38368. break;
  38369. }
  38370. case CODE_POINTS.APOSTROPHE: {
  38371. this._err(ERR.missingWhitespaceBetweenDoctypePublicAndSystemIdentifiers);
  38372. token.systemId = "";
  38373. this.state = State.DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED;
  38374. break;
  38375. }
  38376. case CODE_POINTS.EOF: {
  38377. this._err(ERR.eofInDoctype);
  38378. token.forceQuirks = true;
  38379. this.emitCurrentDoctype(token);
  38380. this._emitEOFToken();
  38381. break;
  38382. }
  38383. default: {
  38384. this._err(ERR.missingQuoteBeforeDoctypeSystemIdentifier);
  38385. token.forceQuirks = true;
  38386. this.state = State.BOGUS_DOCTYPE;
  38387. this._stateBogusDoctype(cp);
  38388. }
  38389. }
  38390. }
  38391. // Between DOCTYPE public and system identifiers state
  38392. //------------------------------------------------------------------
  38393. _stateBetweenDoctypePublicAndSystemIdentifiers(cp) {
  38394. const token = this.currentToken;
  38395. switch (cp) {
  38396. case CODE_POINTS.SPACE:
  38397. case CODE_POINTS.LINE_FEED:
  38398. case CODE_POINTS.TABULATION:
  38399. case CODE_POINTS.FORM_FEED: {
  38400. break;
  38401. }
  38402. case CODE_POINTS.GREATER_THAN_SIGN: {
  38403. this.emitCurrentDoctype(token);
  38404. this.state = State.DATA;
  38405. break;
  38406. }
  38407. case CODE_POINTS.QUOTATION_MARK: {
  38408. token.systemId = "";
  38409. this.state = State.DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED;
  38410. break;
  38411. }
  38412. case CODE_POINTS.APOSTROPHE: {
  38413. token.systemId = "";
  38414. this.state = State.DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED;
  38415. break;
  38416. }
  38417. case CODE_POINTS.EOF: {
  38418. this._err(ERR.eofInDoctype);
  38419. token.forceQuirks = true;
  38420. this.emitCurrentDoctype(token);
  38421. this._emitEOFToken();
  38422. break;
  38423. }
  38424. default: {
  38425. this._err(ERR.missingQuoteBeforeDoctypeSystemIdentifier);
  38426. token.forceQuirks = true;
  38427. this.state = State.BOGUS_DOCTYPE;
  38428. this._stateBogusDoctype(cp);
  38429. }
  38430. }
  38431. }
  38432. // After DOCTYPE system keyword state
  38433. //------------------------------------------------------------------
  38434. _stateAfterDoctypeSystemKeyword(cp) {
  38435. const token = this.currentToken;
  38436. switch (cp) {
  38437. case CODE_POINTS.SPACE:
  38438. case CODE_POINTS.LINE_FEED:
  38439. case CODE_POINTS.TABULATION:
  38440. case CODE_POINTS.FORM_FEED: {
  38441. this.state = State.BEFORE_DOCTYPE_SYSTEM_IDENTIFIER;
  38442. break;
  38443. }
  38444. case CODE_POINTS.QUOTATION_MARK: {
  38445. this._err(ERR.missingWhitespaceAfterDoctypeSystemKeyword);
  38446. token.systemId = "";
  38447. this.state = State.DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED;
  38448. break;
  38449. }
  38450. case CODE_POINTS.APOSTROPHE: {
  38451. this._err(ERR.missingWhitespaceAfterDoctypeSystemKeyword);
  38452. token.systemId = "";
  38453. this.state = State.DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED;
  38454. break;
  38455. }
  38456. case CODE_POINTS.GREATER_THAN_SIGN: {
  38457. this._err(ERR.missingDoctypeSystemIdentifier);
  38458. token.forceQuirks = true;
  38459. this.state = State.DATA;
  38460. this.emitCurrentDoctype(token);
  38461. break;
  38462. }
  38463. case CODE_POINTS.EOF: {
  38464. this._err(ERR.eofInDoctype);
  38465. token.forceQuirks = true;
  38466. this.emitCurrentDoctype(token);
  38467. this._emitEOFToken();
  38468. break;
  38469. }
  38470. default: {
  38471. this._err(ERR.missingQuoteBeforeDoctypeSystemIdentifier);
  38472. token.forceQuirks = true;
  38473. this.state = State.BOGUS_DOCTYPE;
  38474. this._stateBogusDoctype(cp);
  38475. }
  38476. }
  38477. }
  38478. // Before DOCTYPE system identifier state
  38479. //------------------------------------------------------------------
  38480. _stateBeforeDoctypeSystemIdentifier(cp) {
  38481. const token = this.currentToken;
  38482. switch (cp) {
  38483. case CODE_POINTS.SPACE:
  38484. case CODE_POINTS.LINE_FEED:
  38485. case CODE_POINTS.TABULATION:
  38486. case CODE_POINTS.FORM_FEED: {
  38487. break;
  38488. }
  38489. case CODE_POINTS.QUOTATION_MARK: {
  38490. token.systemId = "";
  38491. this.state = State.DOCTYPE_SYSTEM_IDENTIFIER_DOUBLE_QUOTED;
  38492. break;
  38493. }
  38494. case CODE_POINTS.APOSTROPHE: {
  38495. token.systemId = "";
  38496. this.state = State.DOCTYPE_SYSTEM_IDENTIFIER_SINGLE_QUOTED;
  38497. break;
  38498. }
  38499. case CODE_POINTS.GREATER_THAN_SIGN: {
  38500. this._err(ERR.missingDoctypeSystemIdentifier);
  38501. token.forceQuirks = true;
  38502. this.state = State.DATA;
  38503. this.emitCurrentDoctype(token);
  38504. break;
  38505. }
  38506. case CODE_POINTS.EOF: {
  38507. this._err(ERR.eofInDoctype);
  38508. token.forceQuirks = true;
  38509. this.emitCurrentDoctype(token);
  38510. this._emitEOFToken();
  38511. break;
  38512. }
  38513. default: {
  38514. this._err(ERR.missingQuoteBeforeDoctypeSystemIdentifier);
  38515. token.forceQuirks = true;
  38516. this.state = State.BOGUS_DOCTYPE;
  38517. this._stateBogusDoctype(cp);
  38518. }
  38519. }
  38520. }
  38521. // DOCTYPE system identifier (double-quoted) state
  38522. //------------------------------------------------------------------
  38523. _stateDoctypeSystemIdentifierDoubleQuoted(cp) {
  38524. const token = this.currentToken;
  38525. switch (cp) {
  38526. case CODE_POINTS.QUOTATION_MARK: {
  38527. this.state = State.AFTER_DOCTYPE_SYSTEM_IDENTIFIER;
  38528. break;
  38529. }
  38530. case CODE_POINTS.NULL: {
  38531. this._err(ERR.unexpectedNullCharacter);
  38532. token.systemId += REPLACEMENT_CHARACTER;
  38533. break;
  38534. }
  38535. case CODE_POINTS.GREATER_THAN_SIGN: {
  38536. this._err(ERR.abruptDoctypeSystemIdentifier);
  38537. token.forceQuirks = true;
  38538. this.emitCurrentDoctype(token);
  38539. this.state = State.DATA;
  38540. break;
  38541. }
  38542. case CODE_POINTS.EOF: {
  38543. this._err(ERR.eofInDoctype);
  38544. token.forceQuirks = true;
  38545. this.emitCurrentDoctype(token);
  38546. this._emitEOFToken();
  38547. break;
  38548. }
  38549. default: {
  38550. token.systemId += String.fromCodePoint(cp);
  38551. }
  38552. }
  38553. }
  38554. // DOCTYPE system identifier (single-quoted) state
  38555. //------------------------------------------------------------------
  38556. _stateDoctypeSystemIdentifierSingleQuoted(cp) {
  38557. const token = this.currentToken;
  38558. switch (cp) {
  38559. case CODE_POINTS.APOSTROPHE: {
  38560. this.state = State.AFTER_DOCTYPE_SYSTEM_IDENTIFIER;
  38561. break;
  38562. }
  38563. case CODE_POINTS.NULL: {
  38564. this._err(ERR.unexpectedNullCharacter);
  38565. token.systemId += REPLACEMENT_CHARACTER;
  38566. break;
  38567. }
  38568. case CODE_POINTS.GREATER_THAN_SIGN: {
  38569. this._err(ERR.abruptDoctypeSystemIdentifier);
  38570. token.forceQuirks = true;
  38571. this.emitCurrentDoctype(token);
  38572. this.state = State.DATA;
  38573. break;
  38574. }
  38575. case CODE_POINTS.EOF: {
  38576. this._err(ERR.eofInDoctype);
  38577. token.forceQuirks = true;
  38578. this.emitCurrentDoctype(token);
  38579. this._emitEOFToken();
  38580. break;
  38581. }
  38582. default: {
  38583. token.systemId += String.fromCodePoint(cp);
  38584. }
  38585. }
  38586. }
  38587. // After DOCTYPE system identifier state
  38588. //------------------------------------------------------------------
  38589. _stateAfterDoctypeSystemIdentifier(cp) {
  38590. const token = this.currentToken;
  38591. switch (cp) {
  38592. case CODE_POINTS.SPACE:
  38593. case CODE_POINTS.LINE_FEED:
  38594. case CODE_POINTS.TABULATION:
  38595. case CODE_POINTS.FORM_FEED: {
  38596. break;
  38597. }
  38598. case CODE_POINTS.GREATER_THAN_SIGN: {
  38599. this.emitCurrentDoctype(token);
  38600. this.state = State.DATA;
  38601. break;
  38602. }
  38603. case CODE_POINTS.EOF: {
  38604. this._err(ERR.eofInDoctype);
  38605. token.forceQuirks = true;
  38606. this.emitCurrentDoctype(token);
  38607. this._emitEOFToken();
  38608. break;
  38609. }
  38610. default: {
  38611. this._err(ERR.unexpectedCharacterAfterDoctypeSystemIdentifier);
  38612. this.state = State.BOGUS_DOCTYPE;
  38613. this._stateBogusDoctype(cp);
  38614. }
  38615. }
  38616. }
  38617. // Bogus DOCTYPE state
  38618. //------------------------------------------------------------------
  38619. _stateBogusDoctype(cp) {
  38620. const token = this.currentToken;
  38621. switch (cp) {
  38622. case CODE_POINTS.GREATER_THAN_SIGN: {
  38623. this.emitCurrentDoctype(token);
  38624. this.state = State.DATA;
  38625. break;
  38626. }
  38627. case CODE_POINTS.NULL: {
  38628. this._err(ERR.unexpectedNullCharacter);
  38629. break;
  38630. }
  38631. case CODE_POINTS.EOF: {
  38632. this.emitCurrentDoctype(token);
  38633. this._emitEOFToken();
  38634. break;
  38635. }
  38636. default:
  38637. }
  38638. }
  38639. // CDATA section state
  38640. //------------------------------------------------------------------
  38641. _stateCdataSection(cp) {
  38642. switch (cp) {
  38643. case CODE_POINTS.RIGHT_SQUARE_BRACKET: {
  38644. this.state = State.CDATA_SECTION_BRACKET;
  38645. break;
  38646. }
  38647. case CODE_POINTS.EOF: {
  38648. this._err(ERR.eofInCdata);
  38649. this._emitEOFToken();
  38650. break;
  38651. }
  38652. default: {
  38653. this._emitCodePoint(cp);
  38654. }
  38655. }
  38656. }
  38657. // CDATA section bracket state
  38658. //------------------------------------------------------------------
  38659. _stateCdataSectionBracket(cp) {
  38660. if (cp === CODE_POINTS.RIGHT_SQUARE_BRACKET) {
  38661. this.state = State.CDATA_SECTION_END;
  38662. } else {
  38663. this._emitChars("]");
  38664. this.state = State.CDATA_SECTION;
  38665. this._stateCdataSection(cp);
  38666. }
  38667. }
  38668. // CDATA section end state
  38669. //------------------------------------------------------------------
  38670. _stateCdataSectionEnd(cp) {
  38671. switch (cp) {
  38672. case CODE_POINTS.GREATER_THAN_SIGN: {
  38673. this.state = State.DATA;
  38674. break;
  38675. }
  38676. case CODE_POINTS.RIGHT_SQUARE_BRACKET: {
  38677. this._emitChars("]");
  38678. break;
  38679. }
  38680. default: {
  38681. this._emitChars("]]");
  38682. this.state = State.CDATA_SECTION;
  38683. this._stateCdataSection(cp);
  38684. }
  38685. }
  38686. }
  38687. // Character reference state
  38688. //------------------------------------------------------------------
  38689. _stateCharacterReference(cp) {
  38690. if (cp === CODE_POINTS.NUMBER_SIGN) {
  38691. this.state = State.NUMERIC_CHARACTER_REFERENCE;
  38692. } else if (isAsciiAlphaNumeric2(cp)) {
  38693. this.state = State.NAMED_CHARACTER_REFERENCE;
  38694. this._stateNamedCharacterReference(cp);
  38695. } else {
  38696. this._flushCodePointConsumedAsCharacterReference(CODE_POINTS.AMPERSAND);
  38697. this._reconsumeInState(this.returnState, cp);
  38698. }
  38699. }
  38700. // Named character reference state
  38701. //------------------------------------------------------------------
  38702. _stateNamedCharacterReference(cp) {
  38703. const matchResult = this._matchNamedCharacterReference(cp);
  38704. if (this._ensureHibernation()) {
  38705. } else if (matchResult) {
  38706. for (let i = 0; i < matchResult.length; i++) {
  38707. this._flushCodePointConsumedAsCharacterReference(matchResult[i]);
  38708. }
  38709. this.state = this.returnState;
  38710. } else {
  38711. this._flushCodePointConsumedAsCharacterReference(CODE_POINTS.AMPERSAND);
  38712. this.state = State.AMBIGUOUS_AMPERSAND;
  38713. }
  38714. }
  38715. // Ambiguos ampersand state
  38716. //------------------------------------------------------------------
  38717. _stateAmbiguousAmpersand(cp) {
  38718. if (isAsciiAlphaNumeric2(cp)) {
  38719. this._flushCodePointConsumedAsCharacterReference(cp);
  38720. } else {
  38721. if (cp === CODE_POINTS.SEMICOLON) {
  38722. this._err(ERR.unknownNamedCharacterReference);
  38723. }
  38724. this._reconsumeInState(this.returnState, cp);
  38725. }
  38726. }
  38727. // Numeric character reference state
  38728. //------------------------------------------------------------------
  38729. _stateNumericCharacterReference(cp) {
  38730. this.charRefCode = 0;
  38731. if (cp === CODE_POINTS.LATIN_SMALL_X || cp === CODE_POINTS.LATIN_CAPITAL_X) {
  38732. this.state = State.HEXADEMICAL_CHARACTER_REFERENCE_START;
  38733. } else if (isAsciiDigit(cp)) {
  38734. this.state = State.DECIMAL_CHARACTER_REFERENCE;
  38735. this._stateDecimalCharacterReference(cp);
  38736. } else {
  38737. this._err(ERR.absenceOfDigitsInNumericCharacterReference);
  38738. this._flushCodePointConsumedAsCharacterReference(CODE_POINTS.AMPERSAND);
  38739. this._flushCodePointConsumedAsCharacterReference(CODE_POINTS.NUMBER_SIGN);
  38740. this._reconsumeInState(this.returnState, cp);
  38741. }
  38742. }
  38743. // Hexademical character reference start state
  38744. //------------------------------------------------------------------
  38745. _stateHexademicalCharacterReferenceStart(cp) {
  38746. if (isAsciiHexDigit(cp)) {
  38747. this.state = State.HEXADEMICAL_CHARACTER_REFERENCE;
  38748. this._stateHexademicalCharacterReference(cp);
  38749. } else {
  38750. this._err(ERR.absenceOfDigitsInNumericCharacterReference);
  38751. this._flushCodePointConsumedAsCharacterReference(CODE_POINTS.AMPERSAND);
  38752. this._flushCodePointConsumedAsCharacterReference(CODE_POINTS.NUMBER_SIGN);
  38753. this._unconsume(2);
  38754. this.state = this.returnState;
  38755. }
  38756. }
  38757. // Hexademical character reference state
  38758. //------------------------------------------------------------------
  38759. _stateHexademicalCharacterReference(cp) {
  38760. if (isAsciiUpperHexDigit(cp)) {
  38761. this.charRefCode = this.charRefCode * 16 + cp - 55;
  38762. } else if (isAsciiLowerHexDigit(cp)) {
  38763. this.charRefCode = this.charRefCode * 16 + cp - 87;
  38764. } else if (isAsciiDigit(cp)) {
  38765. this.charRefCode = this.charRefCode * 16 + cp - 48;
  38766. } else if (cp === CODE_POINTS.SEMICOLON) {
  38767. this.state = State.NUMERIC_CHARACTER_REFERENCE_END;
  38768. } else {
  38769. this._err(ERR.missingSemicolonAfterCharacterReference);
  38770. this.state = State.NUMERIC_CHARACTER_REFERENCE_END;
  38771. this._stateNumericCharacterReferenceEnd(cp);
  38772. }
  38773. }
  38774. // Decimal character reference state
  38775. //------------------------------------------------------------------
  38776. _stateDecimalCharacterReference(cp) {
  38777. if (isAsciiDigit(cp)) {
  38778. this.charRefCode = this.charRefCode * 10 + cp - 48;
  38779. } else if (cp === CODE_POINTS.SEMICOLON) {
  38780. this.state = State.NUMERIC_CHARACTER_REFERENCE_END;
  38781. } else {
  38782. this._err(ERR.missingSemicolonAfterCharacterReference);
  38783. this.state = State.NUMERIC_CHARACTER_REFERENCE_END;
  38784. this._stateNumericCharacterReferenceEnd(cp);
  38785. }
  38786. }
  38787. // Numeric character reference end state
  38788. //------------------------------------------------------------------
  38789. _stateNumericCharacterReferenceEnd(cp) {
  38790. if (this.charRefCode === CODE_POINTS.NULL) {
  38791. this._err(ERR.nullCharacterReference);
  38792. this.charRefCode = CODE_POINTS.REPLACEMENT_CHARACTER;
  38793. } else if (this.charRefCode > 1114111) {
  38794. this._err(ERR.characterReferenceOutsideUnicodeRange);
  38795. this.charRefCode = CODE_POINTS.REPLACEMENT_CHARACTER;
  38796. } else if (isSurrogate(this.charRefCode)) {
  38797. this._err(ERR.surrogateCharacterReference);
  38798. this.charRefCode = CODE_POINTS.REPLACEMENT_CHARACTER;
  38799. } else if (isUndefinedCodePoint(this.charRefCode)) {
  38800. this._err(ERR.noncharacterCharacterReference);
  38801. } else if (isControlCodePoint(this.charRefCode) || this.charRefCode === CODE_POINTS.CARRIAGE_RETURN) {
  38802. this._err(ERR.controlCharacterReference);
  38803. const replacement = C1_CONTROLS_REFERENCE_REPLACEMENTS.get(this.charRefCode);
  38804. if (replacement !== void 0) {
  38805. this.charRefCode = replacement;
  38806. }
  38807. }
  38808. this._flushCodePointConsumedAsCharacterReference(this.charRefCode);
  38809. this._reconsumeInState(this.returnState, cp);
  38810. }
  38811. };
  38812. // node_modules/parse5/dist/parser/open-element-stack.js
  38813. 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]);
  38814. var IMPLICIT_END_TAG_REQUIRED_THOROUGHLY = /* @__PURE__ */ new Set([
  38815. ...IMPLICIT_END_TAG_REQUIRED,
  38816. TAG_ID.CAPTION,
  38817. TAG_ID.COLGROUP,
  38818. TAG_ID.TBODY,
  38819. TAG_ID.TD,
  38820. TAG_ID.TFOOT,
  38821. TAG_ID.TH,
  38822. TAG_ID.THEAD,
  38823. TAG_ID.TR
  38824. ]);
  38825. var SCOPING_ELEMENT_NS = /* @__PURE__ */ new Map([
  38826. [TAG_ID.APPLET, NS.HTML],
  38827. [TAG_ID.CAPTION, NS.HTML],
  38828. [TAG_ID.HTML, NS.HTML],
  38829. [TAG_ID.MARQUEE, NS.HTML],
  38830. [TAG_ID.OBJECT, NS.HTML],
  38831. [TAG_ID.TABLE, NS.HTML],
  38832. [TAG_ID.TD, NS.HTML],
  38833. [TAG_ID.TEMPLATE, NS.HTML],
  38834. [TAG_ID.TH, NS.HTML],
  38835. [TAG_ID.ANNOTATION_XML, NS.MATHML],
  38836. [TAG_ID.MI, NS.MATHML],
  38837. [TAG_ID.MN, NS.MATHML],
  38838. [TAG_ID.MO, NS.MATHML],
  38839. [TAG_ID.MS, NS.MATHML],
  38840. [TAG_ID.MTEXT, NS.MATHML],
  38841. [TAG_ID.DESC, NS.SVG],
  38842. [TAG_ID.FOREIGN_OBJECT, NS.SVG],
  38843. [TAG_ID.TITLE, NS.SVG]
  38844. ]);
  38845. var NAMED_HEADERS = [TAG_ID.H1, TAG_ID.H2, TAG_ID.H3, TAG_ID.H4, TAG_ID.H5, TAG_ID.H6];
  38846. var TABLE_ROW_CONTEXT = [TAG_ID.TR, TAG_ID.TEMPLATE, TAG_ID.HTML];
  38847. var TABLE_BODY_CONTEXT = [TAG_ID.TBODY, TAG_ID.TFOOT, TAG_ID.THEAD, TAG_ID.TEMPLATE, TAG_ID.HTML];
  38848. var TABLE_CONTEXT = [TAG_ID.TABLE, TAG_ID.TEMPLATE, TAG_ID.HTML];
  38849. var TABLE_CELLS = [TAG_ID.TD, TAG_ID.TH];
  38850. var OpenElementStack = class {
  38851. get currentTmplContentOrNode() {
  38852. return this._isInTemplate() ? this.treeAdapter.getTemplateContent(this.current) : this.current;
  38853. }
  38854. constructor(document, treeAdapter, handler) {
  38855. this.treeAdapter = treeAdapter;
  38856. this.handler = handler;
  38857. this.items = [];
  38858. this.tagIDs = [];
  38859. this.stackTop = -1;
  38860. this.tmplCount = 0;
  38861. this.currentTagId = TAG_ID.UNKNOWN;
  38862. this.current = document;
  38863. }
  38864. //Index of element
  38865. _indexOf(element) {
  38866. return this.items.lastIndexOf(element, this.stackTop);
  38867. }
  38868. //Update current element
  38869. _isInTemplate() {
  38870. return this.currentTagId === TAG_ID.TEMPLATE && this.treeAdapter.getNamespaceURI(this.current) === NS.HTML;
  38871. }
  38872. _updateCurrentElement() {
  38873. this.current = this.items[this.stackTop];
  38874. this.currentTagId = this.tagIDs[this.stackTop];
  38875. }
  38876. //Mutations
  38877. push(element, tagID) {
  38878. this.stackTop++;
  38879. this.items[this.stackTop] = element;
  38880. this.current = element;
  38881. this.tagIDs[this.stackTop] = tagID;
  38882. this.currentTagId = tagID;
  38883. if (this._isInTemplate()) {
  38884. this.tmplCount++;
  38885. }
  38886. this.handler.onItemPush(element, tagID, true);
  38887. }
  38888. pop() {
  38889. const popped = this.current;
  38890. if (this.tmplCount > 0 && this._isInTemplate()) {
  38891. this.tmplCount--;
  38892. }
  38893. this.stackTop--;
  38894. this._updateCurrentElement();
  38895. this.handler.onItemPop(popped, true);
  38896. }
  38897. replace(oldElement, newElement) {
  38898. const idx = this._indexOf(oldElement);
  38899. this.items[idx] = newElement;
  38900. if (idx === this.stackTop) {
  38901. this.current = newElement;
  38902. }
  38903. }
  38904. insertAfter(referenceElement, newElement, newElementID) {
  38905. const insertionIdx = this._indexOf(referenceElement) + 1;
  38906. this.items.splice(insertionIdx, 0, newElement);
  38907. this.tagIDs.splice(insertionIdx, 0, newElementID);
  38908. this.stackTop++;
  38909. if (insertionIdx === this.stackTop) {
  38910. this._updateCurrentElement();
  38911. }
  38912. this.handler.onItemPush(this.current, this.currentTagId, insertionIdx === this.stackTop);
  38913. }
  38914. popUntilTagNamePopped(tagName) {
  38915. let targetIdx = this.stackTop + 1;
  38916. do {
  38917. targetIdx = this.tagIDs.lastIndexOf(tagName, targetIdx - 1);
  38918. } while (targetIdx > 0 && this.treeAdapter.getNamespaceURI(this.items[targetIdx]) !== NS.HTML);
  38919. this.shortenToLength(targetIdx < 0 ? 0 : targetIdx);
  38920. }
  38921. shortenToLength(idx) {
  38922. while (this.stackTop >= idx) {
  38923. const popped = this.current;
  38924. if (this.tmplCount > 0 && this._isInTemplate()) {
  38925. this.tmplCount -= 1;
  38926. }
  38927. this.stackTop--;
  38928. this._updateCurrentElement();
  38929. this.handler.onItemPop(popped, this.stackTop < idx);
  38930. }
  38931. }
  38932. popUntilElementPopped(element) {
  38933. const idx = this._indexOf(element);
  38934. this.shortenToLength(idx < 0 ? 0 : idx);
  38935. }
  38936. popUntilPopped(tagNames, targetNS) {
  38937. const idx = this._indexOfTagNames(tagNames, targetNS);
  38938. this.shortenToLength(idx < 0 ? 0 : idx);
  38939. }
  38940. popUntilNumberedHeaderPopped() {
  38941. this.popUntilPopped(NAMED_HEADERS, NS.HTML);
  38942. }
  38943. popUntilTableCellPopped() {
  38944. this.popUntilPopped(TABLE_CELLS, NS.HTML);
  38945. }
  38946. popAllUpToHtmlElement() {
  38947. this.tmplCount = 0;
  38948. this.shortenToLength(1);
  38949. }
  38950. _indexOfTagNames(tagNames, namespace) {
  38951. for (let i = this.stackTop; i >= 0; i--) {
  38952. if (tagNames.includes(this.tagIDs[i]) && this.treeAdapter.getNamespaceURI(this.items[i]) === namespace) {
  38953. return i;
  38954. }
  38955. }
  38956. return -1;
  38957. }
  38958. clearBackTo(tagNames, targetNS) {
  38959. const idx = this._indexOfTagNames(tagNames, targetNS);
  38960. this.shortenToLength(idx + 1);
  38961. }
  38962. clearBackToTableContext() {
  38963. this.clearBackTo(TABLE_CONTEXT, NS.HTML);
  38964. }
  38965. clearBackToTableBodyContext() {
  38966. this.clearBackTo(TABLE_BODY_CONTEXT, NS.HTML);
  38967. }
  38968. clearBackToTableRowContext() {
  38969. this.clearBackTo(TABLE_ROW_CONTEXT, NS.HTML);
  38970. }
  38971. remove(element) {
  38972. const idx = this._indexOf(element);
  38973. if (idx >= 0) {
  38974. if (idx === this.stackTop) {
  38975. this.pop();
  38976. } else {
  38977. this.items.splice(idx, 1);
  38978. this.tagIDs.splice(idx, 1);
  38979. this.stackTop--;
  38980. this._updateCurrentElement();
  38981. this.handler.onItemPop(element, false);
  38982. }
  38983. }
  38984. }
  38985. //Search
  38986. tryPeekProperlyNestedBodyElement() {
  38987. return this.stackTop >= 1 && this.tagIDs[1] === TAG_ID.BODY ? this.items[1] : null;
  38988. }
  38989. contains(element) {
  38990. return this._indexOf(element) > -1;
  38991. }
  38992. getCommonAncestor(element) {
  38993. const elementIdx = this._indexOf(element) - 1;
  38994. return elementIdx >= 0 ? this.items[elementIdx] : null;
  38995. }
  38996. isRootHtmlElementCurrent() {
  38997. return this.stackTop === 0 && this.tagIDs[0] === TAG_ID.HTML;
  38998. }
  38999. //Element in scope
  39000. hasInScope(tagName) {
  39001. for (let i = this.stackTop; i >= 0; i--) {
  39002. const tn = this.tagIDs[i];
  39003. const ns = this.treeAdapter.getNamespaceURI(this.items[i]);
  39004. if (tn === tagName && ns === NS.HTML) {
  39005. return true;
  39006. }
  39007. if (SCOPING_ELEMENT_NS.get(tn) === ns) {
  39008. return false;
  39009. }
  39010. }
  39011. return true;
  39012. }
  39013. hasNumberedHeaderInScope() {
  39014. for (let i = this.stackTop; i >= 0; i--) {
  39015. const tn = this.tagIDs[i];
  39016. const ns = this.treeAdapter.getNamespaceURI(this.items[i]);
  39017. if (isNumberedHeader(tn) && ns === NS.HTML) {
  39018. return true;
  39019. }
  39020. if (SCOPING_ELEMENT_NS.get(tn) === ns) {
  39021. return false;
  39022. }
  39023. }
  39024. return true;
  39025. }
  39026. hasInListItemScope(tagName) {
  39027. for (let i = this.stackTop; i >= 0; i--) {
  39028. const tn = this.tagIDs[i];
  39029. const ns = this.treeAdapter.getNamespaceURI(this.items[i]);
  39030. if (tn === tagName && ns === NS.HTML) {
  39031. return true;
  39032. }
  39033. if ((tn === TAG_ID.UL || tn === TAG_ID.OL) && ns === NS.HTML || SCOPING_ELEMENT_NS.get(tn) === ns) {
  39034. return false;
  39035. }
  39036. }
  39037. return true;
  39038. }
  39039. hasInButtonScope(tagName) {
  39040. for (let i = this.stackTop; i >= 0; i--) {
  39041. const tn = this.tagIDs[i];
  39042. const ns = this.treeAdapter.getNamespaceURI(this.items[i]);
  39043. if (tn === tagName && ns === NS.HTML) {
  39044. return true;
  39045. }
  39046. if (tn === TAG_ID.BUTTON && ns === NS.HTML || SCOPING_ELEMENT_NS.get(tn) === ns) {
  39047. return false;
  39048. }
  39049. }
  39050. return true;
  39051. }
  39052. hasInTableScope(tagName) {
  39053. for (let i = this.stackTop; i >= 0; i--) {
  39054. const tn = this.tagIDs[i];
  39055. const ns = this.treeAdapter.getNamespaceURI(this.items[i]);
  39056. if (ns !== NS.HTML) {
  39057. continue;
  39058. }
  39059. if (tn === tagName) {
  39060. return true;
  39061. }
  39062. if (tn === TAG_ID.TABLE || tn === TAG_ID.TEMPLATE || tn === TAG_ID.HTML) {
  39063. return false;
  39064. }
  39065. }
  39066. return true;
  39067. }
  39068. hasTableBodyContextInTableScope() {
  39069. for (let i = this.stackTop; i >= 0; i--) {
  39070. const tn = this.tagIDs[i];
  39071. const ns = this.treeAdapter.getNamespaceURI(this.items[i]);
  39072. if (ns !== NS.HTML) {
  39073. continue;
  39074. }
  39075. if (tn === TAG_ID.TBODY || tn === TAG_ID.THEAD || tn === TAG_ID.TFOOT) {
  39076. return true;
  39077. }
  39078. if (tn === TAG_ID.TABLE || tn === TAG_ID.HTML) {
  39079. return false;
  39080. }
  39081. }
  39082. return true;
  39083. }
  39084. hasInSelectScope(tagName) {
  39085. for (let i = this.stackTop; i >= 0; i--) {
  39086. const tn = this.tagIDs[i];
  39087. const ns = this.treeAdapter.getNamespaceURI(this.items[i]);
  39088. if (ns !== NS.HTML) {
  39089. continue;
  39090. }
  39091. if (tn === tagName) {
  39092. return true;
  39093. }
  39094. if (tn !== TAG_ID.OPTION && tn !== TAG_ID.OPTGROUP) {
  39095. return false;
  39096. }
  39097. }
  39098. return true;
  39099. }
  39100. //Implied end tags
  39101. generateImpliedEndTags() {
  39102. while (IMPLICIT_END_TAG_REQUIRED.has(this.currentTagId)) {
  39103. this.pop();
  39104. }
  39105. }
  39106. generateImpliedEndTagsThoroughly() {
  39107. while (IMPLICIT_END_TAG_REQUIRED_THOROUGHLY.has(this.currentTagId)) {
  39108. this.pop();
  39109. }
  39110. }
  39111. generateImpliedEndTagsWithExclusion(exclusionId) {
  39112. while (this.currentTagId !== exclusionId && IMPLICIT_END_TAG_REQUIRED_THOROUGHLY.has(this.currentTagId)) {
  39113. this.pop();
  39114. }
  39115. }
  39116. };
  39117. // node_modules/parse5/dist/parser/formatting-element-list.js
  39118. var NOAH_ARK_CAPACITY = 3;
  39119. var EntryType;
  39120. (function(EntryType2) {
  39121. EntryType2[EntryType2["Marker"] = 0] = "Marker";
  39122. EntryType2[EntryType2["Element"] = 1] = "Element";
  39123. })(EntryType = EntryType || (EntryType = {}));
  39124. var MARKER = { type: EntryType.Marker };
  39125. var FormattingElementList = class {
  39126. constructor(treeAdapter) {
  39127. this.treeAdapter = treeAdapter;
  39128. this.entries = [];
  39129. this.bookmark = null;
  39130. }
  39131. //Noah Ark's condition
  39132. //OPTIMIZATION: at first we try to find possible candidates for exclusion using
  39133. //lightweight heuristics without thorough attributes check.
  39134. _getNoahArkConditionCandidates(newElement, neAttrs) {
  39135. const candidates = [];
  39136. const neAttrsLength = neAttrs.length;
  39137. const neTagName = this.treeAdapter.getTagName(newElement);
  39138. const neNamespaceURI = this.treeAdapter.getNamespaceURI(newElement);
  39139. for (let i = 0; i < this.entries.length; i++) {
  39140. const entry = this.entries[i];
  39141. if (entry.type === EntryType.Marker) {
  39142. break;
  39143. }
  39144. const { element } = entry;
  39145. if (this.treeAdapter.getTagName(element) === neTagName && this.treeAdapter.getNamespaceURI(element) === neNamespaceURI) {
  39146. const elementAttrs = this.treeAdapter.getAttrList(element);
  39147. if (elementAttrs.length === neAttrsLength) {
  39148. candidates.push({ idx: i, attrs: elementAttrs });
  39149. }
  39150. }
  39151. }
  39152. return candidates;
  39153. }
  39154. _ensureNoahArkCondition(newElement) {
  39155. if (this.entries.length < NOAH_ARK_CAPACITY)
  39156. return;
  39157. const neAttrs = this.treeAdapter.getAttrList(newElement);
  39158. const candidates = this._getNoahArkConditionCandidates(newElement, neAttrs);
  39159. if (candidates.length < NOAH_ARK_CAPACITY)
  39160. return;
  39161. const neAttrsMap = new Map(neAttrs.map((neAttr) => [neAttr.name, neAttr.value]));
  39162. let validCandidates = 0;
  39163. for (let i = 0; i < candidates.length; i++) {
  39164. const candidate = candidates[i];
  39165. if (candidate.attrs.every((cAttr) => neAttrsMap.get(cAttr.name) === cAttr.value)) {
  39166. validCandidates += 1;
  39167. if (validCandidates >= NOAH_ARK_CAPACITY) {
  39168. this.entries.splice(candidate.idx, 1);
  39169. }
  39170. }
  39171. }
  39172. }
  39173. //Mutations
  39174. insertMarker() {
  39175. this.entries.unshift(MARKER);
  39176. }
  39177. pushElement(element, token) {
  39178. this._ensureNoahArkCondition(element);
  39179. this.entries.unshift({
  39180. type: EntryType.Element,
  39181. element,
  39182. token
  39183. });
  39184. }
  39185. insertElementAfterBookmark(element, token) {
  39186. const bookmarkIdx = this.entries.indexOf(this.bookmark);
  39187. this.entries.splice(bookmarkIdx, 0, {
  39188. type: EntryType.Element,
  39189. element,
  39190. token
  39191. });
  39192. }
  39193. removeEntry(entry) {
  39194. const entryIndex = this.entries.indexOf(entry);
  39195. if (entryIndex >= 0) {
  39196. this.entries.splice(entryIndex, 1);
  39197. }
  39198. }
  39199. /**
  39200. * Clears the list of formatting elements up to the last marker.
  39201. *
  39202. * @see https://html.spec.whatwg.org/multipage/parsing.html#clear-the-list-of-active-formatting-elements-up-to-the-last-marker
  39203. */
  39204. clearToLastMarker() {
  39205. const markerIdx = this.entries.indexOf(MARKER);
  39206. if (markerIdx >= 0) {
  39207. this.entries.splice(0, markerIdx + 1);
  39208. } else {
  39209. this.entries.length = 0;
  39210. }
  39211. }
  39212. //Search
  39213. getElementEntryInScopeWithTagName(tagName) {
  39214. const entry = this.entries.find((entry2) => entry2.type === EntryType.Marker || this.treeAdapter.getTagName(entry2.element) === tagName);
  39215. return entry && entry.type === EntryType.Element ? entry : null;
  39216. }
  39217. getElementEntry(element) {
  39218. return this.entries.find((entry) => entry.type === EntryType.Element && entry.element === element);
  39219. }
  39220. };
  39221. // node_modules/parse5/dist/tree-adapters/default.js
  39222. function createTextNode(value) {
  39223. return {
  39224. nodeName: "#text",
  39225. value,
  39226. parentNode: null
  39227. };
  39228. }
  39229. var defaultTreeAdapter = {
  39230. //Node construction
  39231. createDocument() {
  39232. return {
  39233. nodeName: "#document",
  39234. mode: DOCUMENT_MODE.NO_QUIRKS,
  39235. childNodes: []
  39236. };
  39237. },
  39238. createDocumentFragment() {
  39239. return {
  39240. nodeName: "#document-fragment",
  39241. childNodes: []
  39242. };
  39243. },
  39244. createElement(tagName, namespaceURI, attrs) {
  39245. return {
  39246. nodeName: tagName,
  39247. tagName,
  39248. attrs,
  39249. namespaceURI,
  39250. childNodes: [],
  39251. parentNode: null
  39252. };
  39253. },
  39254. createCommentNode(data) {
  39255. return {
  39256. nodeName: "#comment",
  39257. data,
  39258. parentNode: null
  39259. };
  39260. },
  39261. //Tree mutation
  39262. appendChild(parentNode, newNode) {
  39263. parentNode.childNodes.push(newNode);
  39264. newNode.parentNode = parentNode;
  39265. },
  39266. insertBefore(parentNode, newNode, referenceNode) {
  39267. const insertionIdx = parentNode.childNodes.indexOf(referenceNode);
  39268. parentNode.childNodes.splice(insertionIdx, 0, newNode);
  39269. newNode.parentNode = parentNode;
  39270. },
  39271. setTemplateContent(templateElement, contentElement) {
  39272. templateElement.content = contentElement;
  39273. },
  39274. getTemplateContent(templateElement) {
  39275. return templateElement.content;
  39276. },
  39277. setDocumentType(document, name, publicId, systemId) {
  39278. const doctypeNode = document.childNodes.find((node) => node.nodeName === "#documentType");
  39279. if (doctypeNode) {
  39280. doctypeNode.name = name;
  39281. doctypeNode.publicId = publicId;
  39282. doctypeNode.systemId = systemId;
  39283. } else {
  39284. const node = {
  39285. nodeName: "#documentType",
  39286. name,
  39287. publicId,
  39288. systemId,
  39289. parentNode: null
  39290. };
  39291. defaultTreeAdapter.appendChild(document, node);
  39292. }
  39293. },
  39294. setDocumentMode(document, mode) {
  39295. document.mode = mode;
  39296. },
  39297. getDocumentMode(document) {
  39298. return document.mode;
  39299. },
  39300. detachNode(node) {
  39301. if (node.parentNode) {
  39302. const idx = node.parentNode.childNodes.indexOf(node);
  39303. node.parentNode.childNodes.splice(idx, 1);
  39304. node.parentNode = null;
  39305. }
  39306. },
  39307. insertText(parentNode, text) {
  39308. if (parentNode.childNodes.length > 0) {
  39309. const prevNode = parentNode.childNodes[parentNode.childNodes.length - 1];
  39310. if (defaultTreeAdapter.isTextNode(prevNode)) {
  39311. prevNode.value += text;
  39312. return;
  39313. }
  39314. }
  39315. defaultTreeAdapter.appendChild(parentNode, createTextNode(text));
  39316. },
  39317. insertTextBefore(parentNode, text, referenceNode) {
  39318. const prevNode = parentNode.childNodes[parentNode.childNodes.indexOf(referenceNode) - 1];
  39319. if (prevNode && defaultTreeAdapter.isTextNode(prevNode)) {
  39320. prevNode.value += text;
  39321. } else {
  39322. defaultTreeAdapter.insertBefore(parentNode, createTextNode(text), referenceNode);
  39323. }
  39324. },
  39325. adoptAttributes(recipient, attrs) {
  39326. const recipientAttrsMap = new Set(recipient.attrs.map((attr) => attr.name));
  39327. for (let j = 0; j < attrs.length; j++) {
  39328. if (!recipientAttrsMap.has(attrs[j].name)) {
  39329. recipient.attrs.push(attrs[j]);
  39330. }
  39331. }
  39332. },
  39333. //Tree traversing
  39334. getFirstChild(node) {
  39335. return node.childNodes[0];
  39336. },
  39337. getChildNodes(node) {
  39338. return node.childNodes;
  39339. },
  39340. getParentNode(node) {
  39341. return node.parentNode;
  39342. },
  39343. getAttrList(element) {
  39344. return element.attrs;
  39345. },
  39346. //Node data
  39347. getTagName(element) {
  39348. return element.tagName;
  39349. },
  39350. getNamespaceURI(element) {
  39351. return element.namespaceURI;
  39352. },
  39353. getTextNodeContent(textNode) {
  39354. return textNode.value;
  39355. },
  39356. getCommentNodeContent(commentNode) {
  39357. return commentNode.data;
  39358. },
  39359. getDocumentTypeNodeName(doctypeNode) {
  39360. return doctypeNode.name;
  39361. },
  39362. getDocumentTypeNodePublicId(doctypeNode) {
  39363. return doctypeNode.publicId;
  39364. },
  39365. getDocumentTypeNodeSystemId(doctypeNode) {
  39366. return doctypeNode.systemId;
  39367. },
  39368. //Node types
  39369. isTextNode(node) {
  39370. return node.nodeName === "#text";
  39371. },
  39372. isCommentNode(node) {
  39373. return node.nodeName === "#comment";
  39374. },
  39375. isDocumentTypeNode(node) {
  39376. return node.nodeName === "#documentType";
  39377. },
  39378. isElementNode(node) {
  39379. return Object.prototype.hasOwnProperty.call(node, "tagName");
  39380. },
  39381. // Source code location
  39382. setNodeSourceCodeLocation(node, location2) {
  39383. node.sourceCodeLocation = location2;
  39384. },
  39385. getNodeSourceCodeLocation(node) {
  39386. return node.sourceCodeLocation;
  39387. },
  39388. updateNodeSourceCodeLocation(node, endLocation) {
  39389. node.sourceCodeLocation = { ...node.sourceCodeLocation, ...endLocation };
  39390. }
  39391. };
  39392. // node_modules/parse5/dist/common/doctype.js
  39393. var VALID_DOCTYPE_NAME = "html";
  39394. var VALID_SYSTEM_ID = "about:legacy-compat";
  39395. var QUIRKS_MODE_SYSTEM_ID = "http://www.ibm.com/data/dtd/v11/ibmxhtml1-transitional.dtd";
  39396. var QUIRKS_MODE_PUBLIC_ID_PREFIXES = [
  39397. "+//silmaril//dtd html pro v0r11 19970101//",
  39398. "-//as//dtd html 3.0 aswedit + extensions//",
  39399. "-//advasoft ltd//dtd html 3.0 aswedit + extensions//",
  39400. "-//ietf//dtd html 2.0 level 1//",
  39401. "-//ietf//dtd html 2.0 level 2//",
  39402. "-//ietf//dtd html 2.0 strict level 1//",
  39403. "-//ietf//dtd html 2.0 strict level 2//",
  39404. "-//ietf//dtd html 2.0 strict//",
  39405. "-//ietf//dtd html 2.0//",
  39406. "-//ietf//dtd html 2.1e//",
  39407. "-//ietf//dtd html 3.0//",
  39408. "-//ietf//dtd html 3.2 final//",
  39409. "-//ietf//dtd html 3.2//",
  39410. "-//ietf//dtd html 3//",
  39411. "-//ietf//dtd html level 0//",
  39412. "-//ietf//dtd html level 1//",
  39413. "-//ietf//dtd html level 2//",
  39414. "-//ietf//dtd html level 3//",
  39415. "-//ietf//dtd html strict level 0//",
  39416. "-//ietf//dtd html strict level 1//",
  39417. "-//ietf//dtd html strict level 2//",
  39418. "-//ietf//dtd html strict level 3//",
  39419. "-//ietf//dtd html strict//",
  39420. "-//ietf//dtd html//",
  39421. "-//metrius//dtd metrius presentational//",
  39422. "-//microsoft//dtd internet explorer 2.0 html strict//",
  39423. "-//microsoft//dtd internet explorer 2.0 html//",
  39424. "-//microsoft//dtd internet explorer 2.0 tables//",
  39425. "-//microsoft//dtd internet explorer 3.0 html strict//",
  39426. "-//microsoft//dtd internet explorer 3.0 html//",
  39427. "-//microsoft//dtd internet explorer 3.0 tables//",
  39428. "-//netscape comm. corp.//dtd html//",
  39429. "-//netscape comm. corp.//dtd strict html//",
  39430. "-//o'reilly and associates//dtd html 2.0//",
  39431. "-//o'reilly and associates//dtd html extended 1.0//",
  39432. "-//o'reilly and associates//dtd html extended relaxed 1.0//",
  39433. "-//sq//dtd html 2.0 hotmetal + extensions//",
  39434. "-//softquad software//dtd hotmetal pro 6.0::19990601::extensions to html 4.0//",
  39435. "-//softquad//dtd hotmetal pro 4.0::19971010::extensions to html 4.0//",
  39436. "-//spyglass//dtd html 2.0 extended//",
  39437. "-//sun microsystems corp.//dtd hotjava html//",
  39438. "-//sun microsystems corp.//dtd hotjava strict html//",
  39439. "-//w3c//dtd html 3 1995-03-24//",
  39440. "-//w3c//dtd html 3.2 draft//",
  39441. "-//w3c//dtd html 3.2 final//",
  39442. "-//w3c//dtd html 3.2//",
  39443. "-//w3c//dtd html 3.2s draft//",
  39444. "-//w3c//dtd html 4.0 frameset//",
  39445. "-//w3c//dtd html 4.0 transitional//",
  39446. "-//w3c//dtd html experimental 19960712//",
  39447. "-//w3c//dtd html experimental 970421//",
  39448. "-//w3c//dtd w3 html//",
  39449. "-//w3o//dtd w3 html 3.0//",
  39450. "-//webtechs//dtd mozilla html 2.0//",
  39451. "-//webtechs//dtd mozilla html//"
  39452. ];
  39453. var QUIRKS_MODE_NO_SYSTEM_ID_PUBLIC_ID_PREFIXES = [
  39454. ...QUIRKS_MODE_PUBLIC_ID_PREFIXES,
  39455. "-//w3c//dtd html 4.01 frameset//",
  39456. "-//w3c//dtd html 4.01 transitional//"
  39457. ];
  39458. var QUIRKS_MODE_PUBLIC_IDS = /* @__PURE__ */ new Set([
  39459. "-//w3o//dtd w3 html strict 3.0//en//",
  39460. "-/w3c/dtd html 4.0 transitional/en",
  39461. "html"
  39462. ]);
  39463. var LIMITED_QUIRKS_PUBLIC_ID_PREFIXES = ["-//w3c//dtd xhtml 1.0 frameset//", "-//w3c//dtd xhtml 1.0 transitional//"];
  39464. var LIMITED_QUIRKS_WITH_SYSTEM_ID_PUBLIC_ID_PREFIXES = [
  39465. ...LIMITED_QUIRKS_PUBLIC_ID_PREFIXES,
  39466. "-//w3c//dtd html 4.01 frameset//",
  39467. "-//w3c//dtd html 4.01 transitional//"
  39468. ];
  39469. function hasPrefix(publicId, prefixes) {
  39470. return prefixes.some((prefix) => publicId.startsWith(prefix));
  39471. }
  39472. function isConforming(token) {
  39473. return token.name === VALID_DOCTYPE_NAME && token.publicId === null && (token.systemId === null || token.systemId === VALID_SYSTEM_ID);
  39474. }
  39475. function getDocumentMode(token) {
  39476. if (token.name !== VALID_DOCTYPE_NAME) {
  39477. return DOCUMENT_MODE.QUIRKS;
  39478. }
  39479. const { systemId } = token;
  39480. if (systemId && systemId.toLowerCase() === QUIRKS_MODE_SYSTEM_ID) {
  39481. return DOCUMENT_MODE.QUIRKS;
  39482. }
  39483. let { publicId } = token;
  39484. if (publicId !== null) {
  39485. publicId = publicId.toLowerCase();
  39486. if (QUIRKS_MODE_PUBLIC_IDS.has(publicId)) {
  39487. return DOCUMENT_MODE.QUIRKS;
  39488. }
  39489. let prefixes = systemId === null ? QUIRKS_MODE_NO_SYSTEM_ID_PUBLIC_ID_PREFIXES : QUIRKS_MODE_PUBLIC_ID_PREFIXES;
  39490. if (hasPrefix(publicId, prefixes)) {
  39491. return DOCUMENT_MODE.QUIRKS;
  39492. }
  39493. prefixes = systemId === null ? LIMITED_QUIRKS_PUBLIC_ID_PREFIXES : LIMITED_QUIRKS_WITH_SYSTEM_ID_PUBLIC_ID_PREFIXES;
  39494. if (hasPrefix(publicId, prefixes)) {
  39495. return DOCUMENT_MODE.LIMITED_QUIRKS;
  39496. }
  39497. }
  39498. return DOCUMENT_MODE.NO_QUIRKS;
  39499. }
  39500. // node_modules/parse5/dist/common/foreign-content.js
  39501. var foreign_content_exports = {};
  39502. __export(foreign_content_exports, {
  39503. SVG_TAG_NAMES_ADJUSTMENT_MAP: () => SVG_TAG_NAMES_ADJUSTMENT_MAP,
  39504. adjustTokenMathMLAttrs: () => adjustTokenMathMLAttrs,
  39505. adjustTokenSVGAttrs: () => adjustTokenSVGAttrs,
  39506. adjustTokenSVGTagName: () => adjustTokenSVGTagName,
  39507. adjustTokenXMLAttrs: () => adjustTokenXMLAttrs,
  39508. causesExit: () => causesExit,
  39509. isIntegrationPoint: () => isIntegrationPoint
  39510. });
  39511. var MIME_TYPES = {
  39512. TEXT_HTML: "text/html",
  39513. APPLICATION_XML: "application/xhtml+xml"
  39514. };
  39515. var DEFINITION_URL_ATTR = "definitionurl";
  39516. var ADJUSTED_DEFINITION_URL_ATTR = "definitionURL";
  39517. var SVG_ATTRS_ADJUSTMENT_MAP = new Map([
  39518. "attributeName",
  39519. "attributeType",
  39520. "baseFrequency",
  39521. "baseProfile",
  39522. "calcMode",
  39523. "clipPathUnits",
  39524. "diffuseConstant",
  39525. "edgeMode",
  39526. "filterUnits",
  39527. "glyphRef",
  39528. "gradientTransform",
  39529. "gradientUnits",
  39530. "kernelMatrix",
  39531. "kernelUnitLength",
  39532. "keyPoints",
  39533. "keySplines",
  39534. "keyTimes",
  39535. "lengthAdjust",
  39536. "limitingConeAngle",
  39537. "markerHeight",
  39538. "markerUnits",
  39539. "markerWidth",
  39540. "maskContentUnits",
  39541. "maskUnits",
  39542. "numOctaves",
  39543. "pathLength",
  39544. "patternContentUnits",
  39545. "patternTransform",
  39546. "patternUnits",
  39547. "pointsAtX",
  39548. "pointsAtY",
  39549. "pointsAtZ",
  39550. "preserveAlpha",
  39551. "preserveAspectRatio",
  39552. "primitiveUnits",
  39553. "refX",
  39554. "refY",
  39555. "repeatCount",
  39556. "repeatDur",
  39557. "requiredExtensions",
  39558. "requiredFeatures",
  39559. "specularConstant",
  39560. "specularExponent",
  39561. "spreadMethod",
  39562. "startOffset",
  39563. "stdDeviation",
  39564. "stitchTiles",
  39565. "surfaceScale",
  39566. "systemLanguage",
  39567. "tableValues",
  39568. "targetX",
  39569. "targetY",
  39570. "textLength",
  39571. "viewBox",
  39572. "viewTarget",
  39573. "xChannelSelector",
  39574. "yChannelSelector",
  39575. "zoomAndPan"
  39576. ].map((attr) => [attr.toLowerCase(), attr]));
  39577. var XML_ATTRS_ADJUSTMENT_MAP = /* @__PURE__ */ new Map([
  39578. ["xlink:actuate", { prefix: "xlink", name: "actuate", namespace: NS.XLINK }],
  39579. ["xlink:arcrole", { prefix: "xlink", name: "arcrole", namespace: NS.XLINK }],
  39580. ["xlink:href", { prefix: "xlink", name: "href", namespace: NS.XLINK }],
  39581. ["xlink:role", { prefix: "xlink", name: "role", namespace: NS.XLINK }],
  39582. ["xlink:show", { prefix: "xlink", name: "show", namespace: NS.XLINK }],
  39583. ["xlink:title", { prefix: "xlink", name: "title", namespace: NS.XLINK }],
  39584. ["xlink:type", { prefix: "xlink", name: "type", namespace: NS.XLINK }],
  39585. ["xml:base", { prefix: "xml", name: "base", namespace: NS.XML }],
  39586. ["xml:lang", { prefix: "xml", name: "lang", namespace: NS.XML }],
  39587. ["xml:space", { prefix: "xml", name: "space", namespace: NS.XML }],
  39588. ["xmlns", { prefix: "", name: "xmlns", namespace: NS.XMLNS }],
  39589. ["xmlns:xlink", { prefix: "xmlns", name: "xlink", namespace: NS.XMLNS }]
  39590. ]);
  39591. var SVG_TAG_NAMES_ADJUSTMENT_MAP = new Map([
  39592. "altGlyph",
  39593. "altGlyphDef",
  39594. "altGlyphItem",
  39595. "animateColor",
  39596. "animateMotion",
  39597. "animateTransform",
  39598. "clipPath",
  39599. "feBlend",
  39600. "feColorMatrix",
  39601. "feComponentTransfer",
  39602. "feComposite",
  39603. "feConvolveMatrix",
  39604. "feDiffuseLighting",
  39605. "feDisplacementMap",
  39606. "feDistantLight",
  39607. "feFlood",
  39608. "feFuncA",
  39609. "feFuncB",
  39610. "feFuncG",
  39611. "feFuncR",
  39612. "feGaussianBlur",
  39613. "feImage",
  39614. "feMerge",
  39615. "feMergeNode",
  39616. "feMorphology",
  39617. "feOffset",
  39618. "fePointLight",
  39619. "feSpecularLighting",
  39620. "feSpotLight",
  39621. "feTile",
  39622. "feTurbulence",
  39623. "foreignObject",
  39624. "glyphRef",
  39625. "linearGradient",
  39626. "radialGradient",
  39627. "textPath"
  39628. ].map((tn) => [tn.toLowerCase(), tn]));
  39629. var EXITS_FOREIGN_CONTENT = /* @__PURE__ */ new Set([
  39630. TAG_ID.B,
  39631. TAG_ID.BIG,
  39632. TAG_ID.BLOCKQUOTE,
  39633. TAG_ID.BODY,
  39634. TAG_ID.BR,
  39635. TAG_ID.CENTER,
  39636. TAG_ID.CODE,
  39637. TAG_ID.DD,
  39638. TAG_ID.DIV,
  39639. TAG_ID.DL,
  39640. TAG_ID.DT,
  39641. TAG_ID.EM,
  39642. TAG_ID.EMBED,
  39643. TAG_ID.H1,
  39644. TAG_ID.H2,
  39645. TAG_ID.H3,
  39646. TAG_ID.H4,
  39647. TAG_ID.H5,
  39648. TAG_ID.H6,
  39649. TAG_ID.HEAD,
  39650. TAG_ID.HR,
  39651. TAG_ID.I,
  39652. TAG_ID.IMG,
  39653. TAG_ID.LI,
  39654. TAG_ID.LISTING,
  39655. TAG_ID.MENU,
  39656. TAG_ID.META,
  39657. TAG_ID.NOBR,
  39658. TAG_ID.OL,
  39659. TAG_ID.P,
  39660. TAG_ID.PRE,
  39661. TAG_ID.RUBY,
  39662. TAG_ID.S,
  39663. TAG_ID.SMALL,
  39664. TAG_ID.SPAN,
  39665. TAG_ID.STRONG,
  39666. TAG_ID.STRIKE,
  39667. TAG_ID.SUB,
  39668. TAG_ID.SUP,
  39669. TAG_ID.TABLE,
  39670. TAG_ID.TT,
  39671. TAG_ID.U,
  39672. TAG_ID.UL,
  39673. TAG_ID.VAR
  39674. ]);
  39675. function causesExit(startTagToken) {
  39676. const tn = startTagToken.tagID;
  39677. const isFontWithAttrs = tn === TAG_ID.FONT && startTagToken.attrs.some(({ name }) => name === ATTRS.COLOR || name === ATTRS.SIZE || name === ATTRS.FACE);
  39678. return isFontWithAttrs || EXITS_FOREIGN_CONTENT.has(tn);
  39679. }
  39680. function adjustTokenMathMLAttrs(token) {
  39681. for (let i = 0; i < token.attrs.length; i++) {
  39682. if (token.attrs[i].name === DEFINITION_URL_ATTR) {
  39683. token.attrs[i].name = ADJUSTED_DEFINITION_URL_ATTR;
  39684. break;
  39685. }
  39686. }
  39687. }
  39688. function adjustTokenSVGAttrs(token) {
  39689. for (let i = 0; i < token.attrs.length; i++) {
  39690. const adjustedAttrName = SVG_ATTRS_ADJUSTMENT_MAP.get(token.attrs[i].name);
  39691. if (adjustedAttrName != null) {
  39692. token.attrs[i].name = adjustedAttrName;
  39693. }
  39694. }
  39695. }
  39696. function adjustTokenXMLAttrs(token) {
  39697. for (let i = 0; i < token.attrs.length; i++) {
  39698. const adjustedAttrEntry = XML_ATTRS_ADJUSTMENT_MAP.get(token.attrs[i].name);
  39699. if (adjustedAttrEntry) {
  39700. token.attrs[i].prefix = adjustedAttrEntry.prefix;
  39701. token.attrs[i].name = adjustedAttrEntry.name;
  39702. token.attrs[i].namespace = adjustedAttrEntry.namespace;
  39703. }
  39704. }
  39705. }
  39706. function adjustTokenSVGTagName(token) {
  39707. const adjustedTagName = SVG_TAG_NAMES_ADJUSTMENT_MAP.get(token.tagName);
  39708. if (adjustedTagName != null) {
  39709. token.tagName = adjustedTagName;
  39710. token.tagID = getTagID(token.tagName);
  39711. }
  39712. }
  39713. function isMathMLTextIntegrationPoint(tn, ns) {
  39714. return ns === NS.MATHML && (tn === TAG_ID.MI || tn === TAG_ID.MO || tn === TAG_ID.MN || tn === TAG_ID.MS || tn === TAG_ID.MTEXT);
  39715. }
  39716. function isHtmlIntegrationPoint(tn, ns, attrs) {
  39717. if (ns === NS.MATHML && tn === TAG_ID.ANNOTATION_XML) {
  39718. for (let i = 0; i < attrs.length; i++) {
  39719. if (attrs[i].name === ATTRS.ENCODING) {
  39720. const value = attrs[i].value.toLowerCase();
  39721. return value === MIME_TYPES.TEXT_HTML || value === MIME_TYPES.APPLICATION_XML;
  39722. }
  39723. }
  39724. }
  39725. return ns === NS.SVG && (tn === TAG_ID.FOREIGN_OBJECT || tn === TAG_ID.DESC || tn === TAG_ID.TITLE);
  39726. }
  39727. function isIntegrationPoint(tn, ns, attrs, foreignNS) {
  39728. return (!foreignNS || foreignNS === NS.HTML) && isHtmlIntegrationPoint(tn, ns, attrs) || (!foreignNS || foreignNS === NS.MATHML) && isMathMLTextIntegrationPoint(tn, ns);
  39729. }
  39730. // node_modules/parse5/dist/parser/index.js
  39731. var HIDDEN_INPUT_TYPE = "hidden";
  39732. var AA_OUTER_LOOP_ITER = 8;
  39733. var AA_INNER_LOOP_ITER = 3;
  39734. var InsertionMode;
  39735. (function(InsertionMode2) {
  39736. InsertionMode2[InsertionMode2["INITIAL"] = 0] = "INITIAL";
  39737. InsertionMode2[InsertionMode2["BEFORE_HTML"] = 1] = "BEFORE_HTML";
  39738. InsertionMode2[InsertionMode2["BEFORE_HEAD"] = 2] = "BEFORE_HEAD";
  39739. InsertionMode2[InsertionMode2["IN_HEAD"] = 3] = "IN_HEAD";
  39740. InsertionMode2[InsertionMode2["IN_HEAD_NO_SCRIPT"] = 4] = "IN_HEAD_NO_SCRIPT";
  39741. InsertionMode2[InsertionMode2["AFTER_HEAD"] = 5] = "AFTER_HEAD";
  39742. InsertionMode2[InsertionMode2["IN_BODY"] = 6] = "IN_BODY";
  39743. InsertionMode2[InsertionMode2["TEXT"] = 7] = "TEXT";
  39744. InsertionMode2[InsertionMode2["IN_TABLE"] = 8] = "IN_TABLE";
  39745. InsertionMode2[InsertionMode2["IN_TABLE_TEXT"] = 9] = "IN_TABLE_TEXT";
  39746. InsertionMode2[InsertionMode2["IN_CAPTION"] = 10] = "IN_CAPTION";
  39747. InsertionMode2[InsertionMode2["IN_COLUMN_GROUP"] = 11] = "IN_COLUMN_GROUP";
  39748. InsertionMode2[InsertionMode2["IN_TABLE_BODY"] = 12] = "IN_TABLE_BODY";
  39749. InsertionMode2[InsertionMode2["IN_ROW"] = 13] = "IN_ROW";
  39750. InsertionMode2[InsertionMode2["IN_CELL"] = 14] = "IN_CELL";
  39751. InsertionMode2[InsertionMode2["IN_SELECT"] = 15] = "IN_SELECT";
  39752. InsertionMode2[InsertionMode2["IN_SELECT_IN_TABLE"] = 16] = "IN_SELECT_IN_TABLE";
  39753. InsertionMode2[InsertionMode2["IN_TEMPLATE"] = 17] = "IN_TEMPLATE";
  39754. InsertionMode2[InsertionMode2["AFTER_BODY"] = 18] = "AFTER_BODY";
  39755. InsertionMode2[InsertionMode2["IN_FRAMESET"] = 19] = "IN_FRAMESET";
  39756. InsertionMode2[InsertionMode2["AFTER_FRAMESET"] = 20] = "AFTER_FRAMESET";
  39757. InsertionMode2[InsertionMode2["AFTER_AFTER_BODY"] = 21] = "AFTER_AFTER_BODY";
  39758. InsertionMode2[InsertionMode2["AFTER_AFTER_FRAMESET"] = 22] = "AFTER_AFTER_FRAMESET";
  39759. })(InsertionMode || (InsertionMode = {}));
  39760. var BASE_LOC = {
  39761. startLine: -1,
  39762. startCol: -1,
  39763. startOffset: -1,
  39764. endLine: -1,
  39765. endCol: -1,
  39766. endOffset: -1
  39767. };
  39768. var TABLE_STRUCTURE_TAGS = /* @__PURE__ */ new Set([TAG_ID.TABLE, TAG_ID.TBODY, TAG_ID.TFOOT, TAG_ID.THEAD, TAG_ID.TR]);
  39769. var defaultParserOptions = {
  39770. scriptingEnabled: true,
  39771. sourceCodeLocationInfo: false,
  39772. treeAdapter: defaultTreeAdapter,
  39773. onParseError: null
  39774. };
  39775. var Parser = class {
  39776. constructor(options, document, fragmentContext = null, scriptHandler = null) {
  39777. this.fragmentContext = fragmentContext;
  39778. this.scriptHandler = scriptHandler;
  39779. this.currentToken = null;
  39780. this.stopped = false;
  39781. this.insertionMode = InsertionMode.INITIAL;
  39782. this.originalInsertionMode = InsertionMode.INITIAL;
  39783. this.headElement = null;
  39784. this.formElement = null;
  39785. this.currentNotInHTML = false;
  39786. this.tmplInsertionModeStack = [];
  39787. this.pendingCharacterTokens = [];
  39788. this.hasNonWhitespacePendingCharacterToken = false;
  39789. this.framesetOk = true;
  39790. this.skipNextNewLine = false;
  39791. this.fosterParentingEnabled = false;
  39792. this.options = {
  39793. ...defaultParserOptions,
  39794. ...options
  39795. };
  39796. this.treeAdapter = this.options.treeAdapter;
  39797. this.onParseError = this.options.onParseError;
  39798. if (this.onParseError) {
  39799. this.options.sourceCodeLocationInfo = true;
  39800. }
  39801. this.document = document !== null && document !== void 0 ? document : this.treeAdapter.createDocument();
  39802. this.tokenizer = new Tokenizer(this.options, this);
  39803. this.activeFormattingElements = new FormattingElementList(this.treeAdapter);
  39804. this.fragmentContextID = fragmentContext ? getTagID(this.treeAdapter.getTagName(fragmentContext)) : TAG_ID.UNKNOWN;
  39805. this._setContextModes(fragmentContext !== null && fragmentContext !== void 0 ? fragmentContext : this.document, this.fragmentContextID);
  39806. this.openElements = new OpenElementStack(this.document, this.treeAdapter, this);
  39807. }
  39808. // API
  39809. static parse(html, options) {
  39810. const parser = new this(options);
  39811. parser.tokenizer.write(html, true);
  39812. return parser.document;
  39813. }
  39814. static getFragmentParser(fragmentContext, options) {
  39815. const opts = {
  39816. ...defaultParserOptions,
  39817. ...options
  39818. };
  39819. fragmentContext !== null && fragmentContext !== void 0 ? fragmentContext : fragmentContext = opts.treeAdapter.createElement(TAG_NAMES.TEMPLATE, NS.HTML, []);
  39820. const documentMock = opts.treeAdapter.createElement("documentmock", NS.HTML, []);
  39821. const parser = new this(opts, documentMock, fragmentContext);
  39822. if (parser.fragmentContextID === TAG_ID.TEMPLATE) {
  39823. parser.tmplInsertionModeStack.unshift(InsertionMode.IN_TEMPLATE);
  39824. }
  39825. parser._initTokenizerForFragmentParsing();
  39826. parser._insertFakeRootElement();
  39827. parser._resetInsertionMode();
  39828. parser._findFormInFragmentContext();
  39829. return parser;
  39830. }
  39831. getFragment() {
  39832. const rootElement = this.treeAdapter.getFirstChild(this.document);
  39833. const fragment = this.treeAdapter.createDocumentFragment();
  39834. this._adoptNodes(rootElement, fragment);
  39835. return fragment;
  39836. }
  39837. //Errors
  39838. _err(token, code, beforeToken) {
  39839. var _a2;
  39840. if (!this.onParseError)
  39841. return;
  39842. const loc = (_a2 = token.location) !== null && _a2 !== void 0 ? _a2 : BASE_LOC;
  39843. const err2 = {
  39844. code,
  39845. startLine: loc.startLine,
  39846. startCol: loc.startCol,
  39847. startOffset: loc.startOffset,
  39848. endLine: beforeToken ? loc.startLine : loc.endLine,
  39849. endCol: beforeToken ? loc.startCol : loc.endCol,
  39850. endOffset: beforeToken ? loc.startOffset : loc.endOffset
  39851. };
  39852. this.onParseError(err2);
  39853. }
  39854. //Stack events
  39855. onItemPush(node, tid, isTop) {
  39856. var _a2, _b;
  39857. (_b = (_a2 = this.treeAdapter).onItemPush) === null || _b === void 0 ? void 0 : _b.call(_a2, node);
  39858. if (isTop && this.openElements.stackTop > 0)
  39859. this._setContextModes(node, tid);
  39860. }
  39861. onItemPop(node, isTop) {
  39862. var _a2, _b;
  39863. if (this.options.sourceCodeLocationInfo) {
  39864. this._setEndLocation(node, this.currentToken);
  39865. }
  39866. (_b = (_a2 = this.treeAdapter).onItemPop) === null || _b === void 0 ? void 0 : _b.call(_a2, node, this.openElements.current);
  39867. if (isTop) {
  39868. let current;
  39869. let currentTagId;
  39870. if (this.openElements.stackTop === 0 && this.fragmentContext) {
  39871. current = this.fragmentContext;
  39872. currentTagId = this.fragmentContextID;
  39873. } else {
  39874. ({ current, currentTagId } = this.openElements);
  39875. }
  39876. this._setContextModes(current, currentTagId);
  39877. }
  39878. }
  39879. _setContextModes(current, tid) {
  39880. const isHTML = current === this.document || this.treeAdapter.getNamespaceURI(current) === NS.HTML;
  39881. this.currentNotInHTML = !isHTML;
  39882. this.tokenizer.inForeignNode = !isHTML && !this._isIntegrationPoint(tid, current);
  39883. }
  39884. _switchToTextParsing(currentToken, nextTokenizerState) {
  39885. this._insertElement(currentToken, NS.HTML);
  39886. this.tokenizer.state = nextTokenizerState;
  39887. this.originalInsertionMode = this.insertionMode;
  39888. this.insertionMode = InsertionMode.TEXT;
  39889. }
  39890. switchToPlaintextParsing() {
  39891. this.insertionMode = InsertionMode.TEXT;
  39892. this.originalInsertionMode = InsertionMode.IN_BODY;
  39893. this.tokenizer.state = TokenizerMode.PLAINTEXT;
  39894. }
  39895. //Fragment parsing
  39896. _getAdjustedCurrentElement() {
  39897. return this.openElements.stackTop === 0 && this.fragmentContext ? this.fragmentContext : this.openElements.current;
  39898. }
  39899. _findFormInFragmentContext() {
  39900. let node = this.fragmentContext;
  39901. while (node) {
  39902. if (this.treeAdapter.getTagName(node) === TAG_NAMES.FORM) {
  39903. this.formElement = node;
  39904. break;
  39905. }
  39906. node = this.treeAdapter.getParentNode(node);
  39907. }
  39908. }
  39909. _initTokenizerForFragmentParsing() {
  39910. if (!this.fragmentContext || this.treeAdapter.getNamespaceURI(this.fragmentContext) !== NS.HTML) {
  39911. return;
  39912. }
  39913. switch (this.fragmentContextID) {
  39914. case TAG_ID.TITLE:
  39915. case TAG_ID.TEXTAREA: {
  39916. this.tokenizer.state = TokenizerMode.RCDATA;
  39917. break;
  39918. }
  39919. case TAG_ID.STYLE:
  39920. case TAG_ID.XMP:
  39921. case TAG_ID.IFRAME:
  39922. case TAG_ID.NOEMBED:
  39923. case TAG_ID.NOFRAMES:
  39924. case TAG_ID.NOSCRIPT: {
  39925. this.tokenizer.state = TokenizerMode.RAWTEXT;
  39926. break;
  39927. }
  39928. case TAG_ID.SCRIPT: {
  39929. this.tokenizer.state = TokenizerMode.SCRIPT_DATA;
  39930. break;
  39931. }
  39932. case TAG_ID.PLAINTEXT: {
  39933. this.tokenizer.state = TokenizerMode.PLAINTEXT;
  39934. break;
  39935. }
  39936. default:
  39937. }
  39938. }
  39939. //Tree mutation
  39940. _setDocumentType(token) {
  39941. const name = token.name || "";
  39942. const publicId = token.publicId || "";
  39943. const systemId = token.systemId || "";
  39944. this.treeAdapter.setDocumentType(this.document, name, publicId, systemId);
  39945. if (token.location) {
  39946. const documentChildren = this.treeAdapter.getChildNodes(this.document);
  39947. const docTypeNode = documentChildren.find((node) => this.treeAdapter.isDocumentTypeNode(node));
  39948. if (docTypeNode) {
  39949. this.treeAdapter.setNodeSourceCodeLocation(docTypeNode, token.location);
  39950. }
  39951. }
  39952. }
  39953. _attachElementToTree(element, location2) {
  39954. if (this.options.sourceCodeLocationInfo) {
  39955. const loc = location2 && {
  39956. ...location2,
  39957. startTag: location2
  39958. };
  39959. this.treeAdapter.setNodeSourceCodeLocation(element, loc);
  39960. }
  39961. if (this._shouldFosterParentOnInsertion()) {
  39962. this._fosterParentElement(element);
  39963. } else {
  39964. const parent = this.openElements.currentTmplContentOrNode;
  39965. this.treeAdapter.appendChild(parent, element);
  39966. }
  39967. }
  39968. _appendElement(token, namespaceURI) {
  39969. const element = this.treeAdapter.createElement(token.tagName, namespaceURI, token.attrs);
  39970. this._attachElementToTree(element, token.location);
  39971. }
  39972. _insertElement(token, namespaceURI) {
  39973. const element = this.treeAdapter.createElement(token.tagName, namespaceURI, token.attrs);
  39974. this._attachElementToTree(element, token.location);
  39975. this.openElements.push(element, token.tagID);
  39976. }
  39977. _insertFakeElement(tagName, tagID) {
  39978. const element = this.treeAdapter.createElement(tagName, NS.HTML, []);
  39979. this._attachElementToTree(element, null);
  39980. this.openElements.push(element, tagID);
  39981. }
  39982. _insertTemplate(token) {
  39983. const tmpl = this.treeAdapter.createElement(token.tagName, NS.HTML, token.attrs);
  39984. const content = this.treeAdapter.createDocumentFragment();
  39985. this.treeAdapter.setTemplateContent(tmpl, content);
  39986. this._attachElementToTree(tmpl, token.location);
  39987. this.openElements.push(tmpl, token.tagID);
  39988. if (this.options.sourceCodeLocationInfo)
  39989. this.treeAdapter.setNodeSourceCodeLocation(content, null);
  39990. }
  39991. _insertFakeRootElement() {
  39992. const element = this.treeAdapter.createElement(TAG_NAMES.HTML, NS.HTML, []);
  39993. if (this.options.sourceCodeLocationInfo)
  39994. this.treeAdapter.setNodeSourceCodeLocation(element, null);
  39995. this.treeAdapter.appendChild(this.openElements.current, element);
  39996. this.openElements.push(element, TAG_ID.HTML);
  39997. }
  39998. _appendCommentNode(token, parent) {
  39999. const commentNode = this.treeAdapter.createCommentNode(token.data);
  40000. this.treeAdapter.appendChild(parent, commentNode);
  40001. if (this.options.sourceCodeLocationInfo) {
  40002. this.treeAdapter.setNodeSourceCodeLocation(commentNode, token.location);
  40003. }
  40004. }
  40005. _insertCharacters(token) {
  40006. let parent;
  40007. let beforeElement;
  40008. if (this._shouldFosterParentOnInsertion()) {
  40009. ({ parent, beforeElement } = this._findFosterParentingLocation());
  40010. if (beforeElement) {
  40011. this.treeAdapter.insertTextBefore(parent, token.chars, beforeElement);
  40012. } else {
  40013. this.treeAdapter.insertText(parent, token.chars);
  40014. }
  40015. } else {
  40016. parent = this.openElements.currentTmplContentOrNode;
  40017. this.treeAdapter.insertText(parent, token.chars);
  40018. }
  40019. if (!token.location)
  40020. return;
  40021. const siblings = this.treeAdapter.getChildNodes(parent);
  40022. const textNodeIdx = beforeElement ? siblings.lastIndexOf(beforeElement) : siblings.length;
  40023. const textNode = siblings[textNodeIdx - 1];
  40024. const tnLoc = this.treeAdapter.getNodeSourceCodeLocation(textNode);
  40025. if (tnLoc) {
  40026. const { endLine, endCol, endOffset } = token.location;
  40027. this.treeAdapter.updateNodeSourceCodeLocation(textNode, { endLine, endCol, endOffset });
  40028. } else if (this.options.sourceCodeLocationInfo) {
  40029. this.treeAdapter.setNodeSourceCodeLocation(textNode, token.location);
  40030. }
  40031. }
  40032. _adoptNodes(donor, recipient) {
  40033. for (let child = this.treeAdapter.getFirstChild(donor); child; child = this.treeAdapter.getFirstChild(donor)) {
  40034. this.treeAdapter.detachNode(child);
  40035. this.treeAdapter.appendChild(recipient, child);
  40036. }
  40037. }
  40038. _setEndLocation(element, closingToken) {
  40039. if (this.treeAdapter.getNodeSourceCodeLocation(element) && closingToken.location) {
  40040. const ctLoc = closingToken.location;
  40041. const tn = this.treeAdapter.getTagName(element);
  40042. const endLoc = (
  40043. // NOTE: For cases like <p> <p> </p> - First 'p' closes without a closing
  40044. // tag and for cases like <td> <p> </td> - 'p' closes without a closing tag.
  40045. closingToken.type === TokenType.END_TAG && tn === closingToken.tagName ? {
  40046. endTag: { ...ctLoc },
  40047. endLine: ctLoc.endLine,
  40048. endCol: ctLoc.endCol,
  40049. endOffset: ctLoc.endOffset
  40050. } : {
  40051. endLine: ctLoc.startLine,
  40052. endCol: ctLoc.startCol,
  40053. endOffset: ctLoc.startOffset
  40054. }
  40055. );
  40056. this.treeAdapter.updateNodeSourceCodeLocation(element, endLoc);
  40057. }
  40058. }
  40059. //Token processing
  40060. shouldProcessStartTagTokenInForeignContent(token) {
  40061. if (!this.currentNotInHTML)
  40062. return false;
  40063. let current;
  40064. let currentTagId;
  40065. if (this.openElements.stackTop === 0 && this.fragmentContext) {
  40066. current = this.fragmentContext;
  40067. currentTagId = this.fragmentContextID;
  40068. } else {
  40069. ({ current, currentTagId } = this.openElements);
  40070. }
  40071. if (token.tagID === TAG_ID.SVG && this.treeAdapter.getTagName(current) === TAG_NAMES.ANNOTATION_XML && this.treeAdapter.getNamespaceURI(current) === NS.MATHML) {
  40072. return false;
  40073. }
  40074. return (
  40075. // Check that `current` is not an integration point for HTML or MathML elements.
  40076. this.tokenizer.inForeignNode || // If it _is_ an integration point, then we might have to check that it is not an HTML
  40077. // integration point.
  40078. (token.tagID === TAG_ID.MGLYPH || token.tagID === TAG_ID.MALIGNMARK) && !this._isIntegrationPoint(currentTagId, current, NS.HTML)
  40079. );
  40080. }
  40081. _processToken(token) {
  40082. switch (token.type) {
  40083. case TokenType.CHARACTER: {
  40084. this.onCharacter(token);
  40085. break;
  40086. }
  40087. case TokenType.NULL_CHARACTER: {
  40088. this.onNullCharacter(token);
  40089. break;
  40090. }
  40091. case TokenType.COMMENT: {
  40092. this.onComment(token);
  40093. break;
  40094. }
  40095. case TokenType.DOCTYPE: {
  40096. this.onDoctype(token);
  40097. break;
  40098. }
  40099. case TokenType.START_TAG: {
  40100. this._processStartTag(token);
  40101. break;
  40102. }
  40103. case TokenType.END_TAG: {
  40104. this.onEndTag(token);
  40105. break;
  40106. }
  40107. case TokenType.EOF: {
  40108. this.onEof(token);
  40109. break;
  40110. }
  40111. case TokenType.WHITESPACE_CHARACTER: {
  40112. this.onWhitespaceCharacter(token);
  40113. break;
  40114. }
  40115. }
  40116. }
  40117. //Integration points
  40118. _isIntegrationPoint(tid, element, foreignNS) {
  40119. const ns = this.treeAdapter.getNamespaceURI(element);
  40120. const attrs = this.treeAdapter.getAttrList(element);
  40121. return isIntegrationPoint(tid, ns, attrs, foreignNS);
  40122. }
  40123. //Active formatting elements reconstruction
  40124. _reconstructActiveFormattingElements() {
  40125. const listLength = this.activeFormattingElements.entries.length;
  40126. if (listLength) {
  40127. const endIndex = this.activeFormattingElements.entries.findIndex((entry) => entry.type === EntryType.Marker || this.openElements.contains(entry.element));
  40128. const unopenIdx = endIndex < 0 ? listLength - 1 : endIndex - 1;
  40129. for (let i = unopenIdx; i >= 0; i--) {
  40130. const entry = this.activeFormattingElements.entries[i];
  40131. this._insertElement(entry.token, this.treeAdapter.getNamespaceURI(entry.element));
  40132. entry.element = this.openElements.current;
  40133. }
  40134. }
  40135. }
  40136. //Close elements
  40137. _closeTableCell() {
  40138. this.openElements.generateImpliedEndTags();
  40139. this.openElements.popUntilTableCellPopped();
  40140. this.activeFormattingElements.clearToLastMarker();
  40141. this.insertionMode = InsertionMode.IN_ROW;
  40142. }
  40143. _closePElement() {
  40144. this.openElements.generateImpliedEndTagsWithExclusion(TAG_ID.P);
  40145. this.openElements.popUntilTagNamePopped(TAG_ID.P);
  40146. }
  40147. //Insertion modes
  40148. _resetInsertionMode() {
  40149. for (let i = this.openElements.stackTop; i >= 0; i--) {
  40150. switch (i === 0 && this.fragmentContext ? this.fragmentContextID : this.openElements.tagIDs[i]) {
  40151. case TAG_ID.TR: {
  40152. this.insertionMode = InsertionMode.IN_ROW;
  40153. return;
  40154. }
  40155. case TAG_ID.TBODY:
  40156. case TAG_ID.THEAD:
  40157. case TAG_ID.TFOOT: {
  40158. this.insertionMode = InsertionMode.IN_TABLE_BODY;
  40159. return;
  40160. }
  40161. case TAG_ID.CAPTION: {
  40162. this.insertionMode = InsertionMode.IN_CAPTION;
  40163. return;
  40164. }
  40165. case TAG_ID.COLGROUP: {
  40166. this.insertionMode = InsertionMode.IN_COLUMN_GROUP;
  40167. return;
  40168. }
  40169. case TAG_ID.TABLE: {
  40170. this.insertionMode = InsertionMode.IN_TABLE;
  40171. return;
  40172. }
  40173. case TAG_ID.BODY: {
  40174. this.insertionMode = InsertionMode.IN_BODY;
  40175. return;
  40176. }
  40177. case TAG_ID.FRAMESET: {
  40178. this.insertionMode = InsertionMode.IN_FRAMESET;
  40179. return;
  40180. }
  40181. case TAG_ID.SELECT: {
  40182. this._resetInsertionModeForSelect(i);
  40183. return;
  40184. }
  40185. case TAG_ID.TEMPLATE: {
  40186. this.insertionMode = this.tmplInsertionModeStack[0];
  40187. return;
  40188. }
  40189. case TAG_ID.HTML: {
  40190. this.insertionMode = this.headElement ? InsertionMode.AFTER_HEAD : InsertionMode.BEFORE_HEAD;
  40191. return;
  40192. }
  40193. case TAG_ID.TD:
  40194. case TAG_ID.TH: {
  40195. if (i > 0) {
  40196. this.insertionMode = InsertionMode.IN_CELL;
  40197. return;
  40198. }
  40199. break;
  40200. }
  40201. case TAG_ID.HEAD: {
  40202. if (i > 0) {
  40203. this.insertionMode = InsertionMode.IN_HEAD;
  40204. return;
  40205. }
  40206. break;
  40207. }
  40208. }
  40209. }
  40210. this.insertionMode = InsertionMode.IN_BODY;
  40211. }
  40212. _resetInsertionModeForSelect(selectIdx) {
  40213. if (selectIdx > 0) {
  40214. for (let i = selectIdx - 1; i > 0; i--) {
  40215. const tn = this.openElements.tagIDs[i];
  40216. if (tn === TAG_ID.TEMPLATE) {
  40217. break;
  40218. } else if (tn === TAG_ID.TABLE) {
  40219. this.insertionMode = InsertionMode.IN_SELECT_IN_TABLE;
  40220. return;
  40221. }
  40222. }
  40223. }
  40224. this.insertionMode = InsertionMode.IN_SELECT;
  40225. }
  40226. //Foster parenting
  40227. _isElementCausesFosterParenting(tn) {
  40228. return TABLE_STRUCTURE_TAGS.has(tn);
  40229. }
  40230. _shouldFosterParentOnInsertion() {
  40231. return this.fosterParentingEnabled && this._isElementCausesFosterParenting(this.openElements.currentTagId);
  40232. }
  40233. _findFosterParentingLocation() {
  40234. for (let i = this.openElements.stackTop; i >= 0; i--) {
  40235. const openElement = this.openElements.items[i];
  40236. switch (this.openElements.tagIDs[i]) {
  40237. case TAG_ID.TEMPLATE: {
  40238. if (this.treeAdapter.getNamespaceURI(openElement) === NS.HTML) {
  40239. return { parent: this.treeAdapter.getTemplateContent(openElement), beforeElement: null };
  40240. }
  40241. break;
  40242. }
  40243. case TAG_ID.TABLE: {
  40244. const parent = this.treeAdapter.getParentNode(openElement);
  40245. if (parent) {
  40246. return { parent, beforeElement: openElement };
  40247. }
  40248. return { parent: this.openElements.items[i - 1], beforeElement: null };
  40249. }
  40250. default:
  40251. }
  40252. }
  40253. return { parent: this.openElements.items[0], beforeElement: null };
  40254. }
  40255. _fosterParentElement(element) {
  40256. const location2 = this._findFosterParentingLocation();
  40257. if (location2.beforeElement) {
  40258. this.treeAdapter.insertBefore(location2.parent, element, location2.beforeElement);
  40259. } else {
  40260. this.treeAdapter.appendChild(location2.parent, element);
  40261. }
  40262. }
  40263. //Special elements
  40264. _isSpecialElement(element, id) {
  40265. const ns = this.treeAdapter.getNamespaceURI(element);
  40266. return SPECIAL_ELEMENTS[ns].has(id);
  40267. }
  40268. onCharacter(token) {
  40269. this.skipNextNewLine = false;
  40270. if (this.tokenizer.inForeignNode) {
  40271. characterInForeignContent(this, token);
  40272. return;
  40273. }
  40274. switch (this.insertionMode) {
  40275. case InsertionMode.INITIAL: {
  40276. tokenInInitialMode(this, token);
  40277. break;
  40278. }
  40279. case InsertionMode.BEFORE_HTML: {
  40280. tokenBeforeHtml(this, token);
  40281. break;
  40282. }
  40283. case InsertionMode.BEFORE_HEAD: {
  40284. tokenBeforeHead(this, token);
  40285. break;
  40286. }
  40287. case InsertionMode.IN_HEAD: {
  40288. tokenInHead(this, token);
  40289. break;
  40290. }
  40291. case InsertionMode.IN_HEAD_NO_SCRIPT: {
  40292. tokenInHeadNoScript(this, token);
  40293. break;
  40294. }
  40295. case InsertionMode.AFTER_HEAD: {
  40296. tokenAfterHead(this, token);
  40297. break;
  40298. }
  40299. case InsertionMode.IN_BODY:
  40300. case InsertionMode.IN_CAPTION:
  40301. case InsertionMode.IN_CELL:
  40302. case InsertionMode.IN_TEMPLATE: {
  40303. characterInBody(this, token);
  40304. break;
  40305. }
  40306. case InsertionMode.TEXT:
  40307. case InsertionMode.IN_SELECT:
  40308. case InsertionMode.IN_SELECT_IN_TABLE: {
  40309. this._insertCharacters(token);
  40310. break;
  40311. }
  40312. case InsertionMode.IN_TABLE:
  40313. case InsertionMode.IN_TABLE_BODY:
  40314. case InsertionMode.IN_ROW: {
  40315. characterInTable(this, token);
  40316. break;
  40317. }
  40318. case InsertionMode.IN_TABLE_TEXT: {
  40319. characterInTableText(this, token);
  40320. break;
  40321. }
  40322. case InsertionMode.IN_COLUMN_GROUP: {
  40323. tokenInColumnGroup(this, token);
  40324. break;
  40325. }
  40326. case InsertionMode.AFTER_BODY: {
  40327. tokenAfterBody(this, token);
  40328. break;
  40329. }
  40330. case InsertionMode.AFTER_AFTER_BODY: {
  40331. tokenAfterAfterBody(this, token);
  40332. break;
  40333. }
  40334. default:
  40335. }
  40336. }
  40337. onNullCharacter(token) {
  40338. this.skipNextNewLine = false;
  40339. if (this.tokenizer.inForeignNode) {
  40340. nullCharacterInForeignContent(this, token);
  40341. return;
  40342. }
  40343. switch (this.insertionMode) {
  40344. case InsertionMode.INITIAL: {
  40345. tokenInInitialMode(this, token);
  40346. break;
  40347. }
  40348. case InsertionMode.BEFORE_HTML: {
  40349. tokenBeforeHtml(this, token);
  40350. break;
  40351. }
  40352. case InsertionMode.BEFORE_HEAD: {
  40353. tokenBeforeHead(this, token);
  40354. break;
  40355. }
  40356. case InsertionMode.IN_HEAD: {
  40357. tokenInHead(this, token);
  40358. break;
  40359. }
  40360. case InsertionMode.IN_HEAD_NO_SCRIPT: {
  40361. tokenInHeadNoScript(this, token);
  40362. break;
  40363. }
  40364. case InsertionMode.AFTER_HEAD: {
  40365. tokenAfterHead(this, token);
  40366. break;
  40367. }
  40368. case InsertionMode.TEXT: {
  40369. this._insertCharacters(token);
  40370. break;
  40371. }
  40372. case InsertionMode.IN_TABLE:
  40373. case InsertionMode.IN_TABLE_BODY:
  40374. case InsertionMode.IN_ROW: {
  40375. characterInTable(this, token);
  40376. break;
  40377. }
  40378. case InsertionMode.IN_COLUMN_GROUP: {
  40379. tokenInColumnGroup(this, token);
  40380. break;
  40381. }
  40382. case InsertionMode.AFTER_BODY: {
  40383. tokenAfterBody(this, token);
  40384. break;
  40385. }
  40386. case InsertionMode.AFTER_AFTER_BODY: {
  40387. tokenAfterAfterBody(this, token);
  40388. break;
  40389. }
  40390. default:
  40391. }
  40392. }
  40393. onComment(token) {
  40394. this.skipNextNewLine = false;
  40395. if (this.currentNotInHTML) {
  40396. appendComment(this, token);
  40397. return;
  40398. }
  40399. switch (this.insertionMode) {
  40400. case InsertionMode.INITIAL:
  40401. case InsertionMode.BEFORE_HTML:
  40402. case InsertionMode.BEFORE_HEAD:
  40403. case InsertionMode.IN_HEAD:
  40404. case InsertionMode.IN_HEAD_NO_SCRIPT:
  40405. case InsertionMode.AFTER_HEAD:
  40406. case InsertionMode.IN_BODY:
  40407. case InsertionMode.IN_TABLE:
  40408. case InsertionMode.IN_CAPTION:
  40409. case InsertionMode.IN_COLUMN_GROUP:
  40410. case InsertionMode.IN_TABLE_BODY:
  40411. case InsertionMode.IN_ROW:
  40412. case InsertionMode.IN_CELL:
  40413. case InsertionMode.IN_SELECT:
  40414. case InsertionMode.IN_SELECT_IN_TABLE:
  40415. case InsertionMode.IN_TEMPLATE:
  40416. case InsertionMode.IN_FRAMESET:
  40417. case InsertionMode.AFTER_FRAMESET: {
  40418. appendComment(this, token);
  40419. break;
  40420. }
  40421. case InsertionMode.IN_TABLE_TEXT: {
  40422. tokenInTableText(this, token);
  40423. break;
  40424. }
  40425. case InsertionMode.AFTER_BODY: {
  40426. appendCommentToRootHtmlElement(this, token);
  40427. break;
  40428. }
  40429. case InsertionMode.AFTER_AFTER_BODY:
  40430. case InsertionMode.AFTER_AFTER_FRAMESET: {
  40431. appendCommentToDocument(this, token);
  40432. break;
  40433. }
  40434. default:
  40435. }
  40436. }
  40437. onDoctype(token) {
  40438. this.skipNextNewLine = false;
  40439. switch (this.insertionMode) {
  40440. case InsertionMode.INITIAL: {
  40441. doctypeInInitialMode(this, token);
  40442. break;
  40443. }
  40444. case InsertionMode.BEFORE_HEAD:
  40445. case InsertionMode.IN_HEAD:
  40446. case InsertionMode.IN_HEAD_NO_SCRIPT:
  40447. case InsertionMode.AFTER_HEAD: {
  40448. this._err(token, ERR.misplacedDoctype);
  40449. break;
  40450. }
  40451. case InsertionMode.IN_TABLE_TEXT: {
  40452. tokenInTableText(this, token);
  40453. break;
  40454. }
  40455. default:
  40456. }
  40457. }
  40458. onStartTag(token) {
  40459. this.skipNextNewLine = false;
  40460. this.currentToken = token;
  40461. this._processStartTag(token);
  40462. if (token.selfClosing && !token.ackSelfClosing) {
  40463. this._err(token, ERR.nonVoidHtmlElementStartTagWithTrailingSolidus);
  40464. }
  40465. }
  40466. /**
  40467. * Processes a given start tag.
  40468. *
  40469. * `onStartTag` checks if a self-closing tag was recognized. When a token
  40470. * is moved inbetween multiple insertion modes, this check for self-closing
  40471. * could lead to false positives. To avoid this, `_processStartTag` is used
  40472. * for nested calls.
  40473. *
  40474. * @param token The token to process.
  40475. */
  40476. _processStartTag(token) {
  40477. if (this.shouldProcessStartTagTokenInForeignContent(token)) {
  40478. startTagInForeignContent(this, token);
  40479. } else {
  40480. this._startTagOutsideForeignContent(token);
  40481. }
  40482. }
  40483. _startTagOutsideForeignContent(token) {
  40484. switch (this.insertionMode) {
  40485. case InsertionMode.INITIAL: {
  40486. tokenInInitialMode(this, token);
  40487. break;
  40488. }
  40489. case InsertionMode.BEFORE_HTML: {
  40490. startTagBeforeHtml(this, token);
  40491. break;
  40492. }
  40493. case InsertionMode.BEFORE_HEAD: {
  40494. startTagBeforeHead(this, token);
  40495. break;
  40496. }
  40497. case InsertionMode.IN_HEAD: {
  40498. startTagInHead(this, token);
  40499. break;
  40500. }
  40501. case InsertionMode.IN_HEAD_NO_SCRIPT: {
  40502. startTagInHeadNoScript(this, token);
  40503. break;
  40504. }
  40505. case InsertionMode.AFTER_HEAD: {
  40506. startTagAfterHead(this, token);
  40507. break;
  40508. }
  40509. case InsertionMode.IN_BODY: {
  40510. startTagInBody(this, token);
  40511. break;
  40512. }
  40513. case InsertionMode.IN_TABLE: {
  40514. startTagInTable(this, token);
  40515. break;
  40516. }
  40517. case InsertionMode.IN_TABLE_TEXT: {
  40518. tokenInTableText(this, token);
  40519. break;
  40520. }
  40521. case InsertionMode.IN_CAPTION: {
  40522. startTagInCaption(this, token);
  40523. break;
  40524. }
  40525. case InsertionMode.IN_COLUMN_GROUP: {
  40526. startTagInColumnGroup(this, token);
  40527. break;
  40528. }
  40529. case InsertionMode.IN_TABLE_BODY: {
  40530. startTagInTableBody(this, token);
  40531. break;
  40532. }
  40533. case InsertionMode.IN_ROW: {
  40534. startTagInRow(this, token);
  40535. break;
  40536. }
  40537. case InsertionMode.IN_CELL: {
  40538. startTagInCell(this, token);
  40539. break;
  40540. }
  40541. case InsertionMode.IN_SELECT: {
  40542. startTagInSelect(this, token);
  40543. break;
  40544. }
  40545. case InsertionMode.IN_SELECT_IN_TABLE: {
  40546. startTagInSelectInTable(this, token);
  40547. break;
  40548. }
  40549. case InsertionMode.IN_TEMPLATE: {
  40550. startTagInTemplate(this, token);
  40551. break;
  40552. }
  40553. case InsertionMode.AFTER_BODY: {
  40554. startTagAfterBody(this, token);
  40555. break;
  40556. }
  40557. case InsertionMode.IN_FRAMESET: {
  40558. startTagInFrameset(this, token);
  40559. break;
  40560. }
  40561. case InsertionMode.AFTER_FRAMESET: {
  40562. startTagAfterFrameset(this, token);
  40563. break;
  40564. }
  40565. case InsertionMode.AFTER_AFTER_BODY: {
  40566. startTagAfterAfterBody(this, token);
  40567. break;
  40568. }
  40569. case InsertionMode.AFTER_AFTER_FRAMESET: {
  40570. startTagAfterAfterFrameset(this, token);
  40571. break;
  40572. }
  40573. default:
  40574. }
  40575. }
  40576. onEndTag(token) {
  40577. this.skipNextNewLine = false;
  40578. this.currentToken = token;
  40579. if (this.currentNotInHTML) {
  40580. endTagInForeignContent(this, token);
  40581. } else {
  40582. this._endTagOutsideForeignContent(token);
  40583. }
  40584. }
  40585. _endTagOutsideForeignContent(token) {
  40586. switch (this.insertionMode) {
  40587. case InsertionMode.INITIAL: {
  40588. tokenInInitialMode(this, token);
  40589. break;
  40590. }
  40591. case InsertionMode.BEFORE_HTML: {
  40592. endTagBeforeHtml(this, token);
  40593. break;
  40594. }
  40595. case InsertionMode.BEFORE_HEAD: {
  40596. endTagBeforeHead(this, token);
  40597. break;
  40598. }
  40599. case InsertionMode.IN_HEAD: {
  40600. endTagInHead(this, token);
  40601. break;
  40602. }
  40603. case InsertionMode.IN_HEAD_NO_SCRIPT: {
  40604. endTagInHeadNoScript(this, token);
  40605. break;
  40606. }
  40607. case InsertionMode.AFTER_HEAD: {
  40608. endTagAfterHead(this, token);
  40609. break;
  40610. }
  40611. case InsertionMode.IN_BODY: {
  40612. endTagInBody(this, token);
  40613. break;
  40614. }
  40615. case InsertionMode.TEXT: {
  40616. endTagInText(this, token);
  40617. break;
  40618. }
  40619. case InsertionMode.IN_TABLE: {
  40620. endTagInTable(this, token);
  40621. break;
  40622. }
  40623. case InsertionMode.IN_TABLE_TEXT: {
  40624. tokenInTableText(this, token);
  40625. break;
  40626. }
  40627. case InsertionMode.IN_CAPTION: {
  40628. endTagInCaption(this, token);
  40629. break;
  40630. }
  40631. case InsertionMode.IN_COLUMN_GROUP: {
  40632. endTagInColumnGroup(this, token);
  40633. break;
  40634. }
  40635. case InsertionMode.IN_TABLE_BODY: {
  40636. endTagInTableBody(this, token);
  40637. break;
  40638. }
  40639. case InsertionMode.IN_ROW: {
  40640. endTagInRow(this, token);
  40641. break;
  40642. }
  40643. case InsertionMode.IN_CELL: {
  40644. endTagInCell(this, token);
  40645. break;
  40646. }
  40647. case InsertionMode.IN_SELECT: {
  40648. endTagInSelect(this, token);
  40649. break;
  40650. }
  40651. case InsertionMode.IN_SELECT_IN_TABLE: {
  40652. endTagInSelectInTable(this, token);
  40653. break;
  40654. }
  40655. case InsertionMode.IN_TEMPLATE: {
  40656. endTagInTemplate(this, token);
  40657. break;
  40658. }
  40659. case InsertionMode.AFTER_BODY: {
  40660. endTagAfterBody(this, token);
  40661. break;
  40662. }
  40663. case InsertionMode.IN_FRAMESET: {
  40664. endTagInFrameset(this, token);
  40665. break;
  40666. }
  40667. case InsertionMode.AFTER_FRAMESET: {
  40668. endTagAfterFrameset(this, token);
  40669. break;
  40670. }
  40671. case InsertionMode.AFTER_AFTER_BODY: {
  40672. tokenAfterAfterBody(this, token);
  40673. break;
  40674. }
  40675. default:
  40676. }
  40677. }
  40678. onEof(token) {
  40679. switch (this.insertionMode) {
  40680. case InsertionMode.INITIAL: {
  40681. tokenInInitialMode(this, token);
  40682. break;
  40683. }
  40684. case InsertionMode.BEFORE_HTML: {
  40685. tokenBeforeHtml(this, token);
  40686. break;
  40687. }
  40688. case InsertionMode.BEFORE_HEAD: {
  40689. tokenBeforeHead(this, token);
  40690. break;
  40691. }
  40692. case InsertionMode.IN_HEAD: {
  40693. tokenInHead(this, token);
  40694. break;
  40695. }
  40696. case InsertionMode.IN_HEAD_NO_SCRIPT: {
  40697. tokenInHeadNoScript(this, token);
  40698. break;
  40699. }
  40700. case InsertionMode.AFTER_HEAD: {
  40701. tokenAfterHead(this, token);
  40702. break;
  40703. }
  40704. case InsertionMode.IN_BODY:
  40705. case InsertionMode.IN_TABLE:
  40706. case InsertionMode.IN_CAPTION:
  40707. case InsertionMode.IN_COLUMN_GROUP:
  40708. case InsertionMode.IN_TABLE_BODY:
  40709. case InsertionMode.IN_ROW:
  40710. case InsertionMode.IN_CELL:
  40711. case InsertionMode.IN_SELECT:
  40712. case InsertionMode.IN_SELECT_IN_TABLE: {
  40713. eofInBody(this, token);
  40714. break;
  40715. }
  40716. case InsertionMode.TEXT: {
  40717. eofInText(this, token);
  40718. break;
  40719. }
  40720. case InsertionMode.IN_TABLE_TEXT: {
  40721. tokenInTableText(this, token);
  40722. break;
  40723. }
  40724. case InsertionMode.IN_TEMPLATE: {
  40725. eofInTemplate(this, token);
  40726. break;
  40727. }
  40728. case InsertionMode.AFTER_BODY:
  40729. case InsertionMode.IN_FRAMESET:
  40730. case InsertionMode.AFTER_FRAMESET:
  40731. case InsertionMode.AFTER_AFTER_BODY:
  40732. case InsertionMode.AFTER_AFTER_FRAMESET: {
  40733. stopParsing(this, token);
  40734. break;
  40735. }
  40736. default:
  40737. }
  40738. }
  40739. onWhitespaceCharacter(token) {
  40740. if (this.skipNextNewLine) {
  40741. this.skipNextNewLine = false;
  40742. if (token.chars.charCodeAt(0) === CODE_POINTS.LINE_FEED) {
  40743. if (token.chars.length === 1) {
  40744. return;
  40745. }
  40746. token.chars = token.chars.substr(1);
  40747. }
  40748. }
  40749. if (this.tokenizer.inForeignNode) {
  40750. this._insertCharacters(token);
  40751. return;
  40752. }
  40753. switch (this.insertionMode) {
  40754. case InsertionMode.IN_HEAD:
  40755. case InsertionMode.IN_HEAD_NO_SCRIPT:
  40756. case InsertionMode.AFTER_HEAD:
  40757. case InsertionMode.TEXT:
  40758. case InsertionMode.IN_COLUMN_GROUP:
  40759. case InsertionMode.IN_SELECT:
  40760. case InsertionMode.IN_SELECT_IN_TABLE:
  40761. case InsertionMode.IN_FRAMESET:
  40762. case InsertionMode.AFTER_FRAMESET: {
  40763. this._insertCharacters(token);
  40764. break;
  40765. }
  40766. case InsertionMode.IN_BODY:
  40767. case InsertionMode.IN_CAPTION:
  40768. case InsertionMode.IN_CELL:
  40769. case InsertionMode.IN_TEMPLATE:
  40770. case InsertionMode.AFTER_BODY:
  40771. case InsertionMode.AFTER_AFTER_BODY:
  40772. case InsertionMode.AFTER_AFTER_FRAMESET: {
  40773. whitespaceCharacterInBody(this, token);
  40774. break;
  40775. }
  40776. case InsertionMode.IN_TABLE:
  40777. case InsertionMode.IN_TABLE_BODY:
  40778. case InsertionMode.IN_ROW: {
  40779. characterInTable(this, token);
  40780. break;
  40781. }
  40782. case InsertionMode.IN_TABLE_TEXT: {
  40783. whitespaceCharacterInTableText(this, token);
  40784. break;
  40785. }
  40786. default:
  40787. }
  40788. }
  40789. };
  40790. function aaObtainFormattingElementEntry(p, token) {
  40791. let formattingElementEntry = p.activeFormattingElements.getElementEntryInScopeWithTagName(token.tagName);
  40792. if (formattingElementEntry) {
  40793. if (!p.openElements.contains(formattingElementEntry.element)) {
  40794. p.activeFormattingElements.removeEntry(formattingElementEntry);
  40795. formattingElementEntry = null;
  40796. } else if (!p.openElements.hasInScope(token.tagID)) {
  40797. formattingElementEntry = null;
  40798. }
  40799. } else {
  40800. genericEndTagInBody(p, token);
  40801. }
  40802. return formattingElementEntry;
  40803. }
  40804. function aaObtainFurthestBlock(p, formattingElementEntry) {
  40805. let furthestBlock = null;
  40806. let idx = p.openElements.stackTop;
  40807. for (; idx >= 0; idx--) {
  40808. const element = p.openElements.items[idx];
  40809. if (element === formattingElementEntry.element) {
  40810. break;
  40811. }
  40812. if (p._isSpecialElement(element, p.openElements.tagIDs[idx])) {
  40813. furthestBlock = element;
  40814. }
  40815. }
  40816. if (!furthestBlock) {
  40817. p.openElements.shortenToLength(idx < 0 ? 0 : idx);
  40818. p.activeFormattingElements.removeEntry(formattingElementEntry);
  40819. }
  40820. return furthestBlock;
  40821. }
  40822. function aaInnerLoop(p, furthestBlock, formattingElement) {
  40823. let lastElement = furthestBlock;
  40824. let nextElement = p.openElements.getCommonAncestor(furthestBlock);
  40825. for (let i = 0, element = nextElement; element !== formattingElement; i++, element = nextElement) {
  40826. nextElement = p.openElements.getCommonAncestor(element);
  40827. const elementEntry = p.activeFormattingElements.getElementEntry(element);
  40828. const counterOverflow = elementEntry && i >= AA_INNER_LOOP_ITER;
  40829. const shouldRemoveFromOpenElements = !elementEntry || counterOverflow;
  40830. if (shouldRemoveFromOpenElements) {
  40831. if (counterOverflow) {
  40832. p.activeFormattingElements.removeEntry(elementEntry);
  40833. }
  40834. p.openElements.remove(element);
  40835. } else {
  40836. element = aaRecreateElementFromEntry(p, elementEntry);
  40837. if (lastElement === furthestBlock) {
  40838. p.activeFormattingElements.bookmark = elementEntry;
  40839. }
  40840. p.treeAdapter.detachNode(lastElement);
  40841. p.treeAdapter.appendChild(element, lastElement);
  40842. lastElement = element;
  40843. }
  40844. }
  40845. return lastElement;
  40846. }
  40847. function aaRecreateElementFromEntry(p, elementEntry) {
  40848. const ns = p.treeAdapter.getNamespaceURI(elementEntry.element);
  40849. const newElement = p.treeAdapter.createElement(elementEntry.token.tagName, ns, elementEntry.token.attrs);
  40850. p.openElements.replace(elementEntry.element, newElement);
  40851. elementEntry.element = newElement;
  40852. return newElement;
  40853. }
  40854. function aaInsertLastNodeInCommonAncestor(p, commonAncestor, lastElement) {
  40855. const tn = p.treeAdapter.getTagName(commonAncestor);
  40856. const tid = getTagID(tn);
  40857. if (p._isElementCausesFosterParenting(tid)) {
  40858. p._fosterParentElement(lastElement);
  40859. } else {
  40860. const ns = p.treeAdapter.getNamespaceURI(commonAncestor);
  40861. if (tid === TAG_ID.TEMPLATE && ns === NS.HTML) {
  40862. commonAncestor = p.treeAdapter.getTemplateContent(commonAncestor);
  40863. }
  40864. p.treeAdapter.appendChild(commonAncestor, lastElement);
  40865. }
  40866. }
  40867. function aaReplaceFormattingElement(p, furthestBlock, formattingElementEntry) {
  40868. const ns = p.treeAdapter.getNamespaceURI(formattingElementEntry.element);
  40869. const { token } = formattingElementEntry;
  40870. const newElement = p.treeAdapter.createElement(token.tagName, ns, token.attrs);
  40871. p._adoptNodes(furthestBlock, newElement);
  40872. p.treeAdapter.appendChild(furthestBlock, newElement);
  40873. p.activeFormattingElements.insertElementAfterBookmark(newElement, token);
  40874. p.activeFormattingElements.removeEntry(formattingElementEntry);
  40875. p.openElements.remove(formattingElementEntry.element);
  40876. p.openElements.insertAfter(furthestBlock, newElement, token.tagID);
  40877. }
  40878. function callAdoptionAgency(p, token) {
  40879. for (let i = 0; i < AA_OUTER_LOOP_ITER; i++) {
  40880. const formattingElementEntry = aaObtainFormattingElementEntry(p, token);
  40881. if (!formattingElementEntry) {
  40882. break;
  40883. }
  40884. const furthestBlock = aaObtainFurthestBlock(p, formattingElementEntry);
  40885. if (!furthestBlock) {
  40886. break;
  40887. }
  40888. p.activeFormattingElements.bookmark = formattingElementEntry;
  40889. const lastElement = aaInnerLoop(p, furthestBlock, formattingElementEntry.element);
  40890. const commonAncestor = p.openElements.getCommonAncestor(formattingElementEntry.element);
  40891. p.treeAdapter.detachNode(lastElement);
  40892. if (commonAncestor)
  40893. aaInsertLastNodeInCommonAncestor(p, commonAncestor, lastElement);
  40894. aaReplaceFormattingElement(p, furthestBlock, formattingElementEntry);
  40895. }
  40896. }
  40897. function appendComment(p, token) {
  40898. p._appendCommentNode(token, p.openElements.currentTmplContentOrNode);
  40899. }
  40900. function appendCommentToRootHtmlElement(p, token) {
  40901. p._appendCommentNode(token, p.openElements.items[0]);
  40902. }
  40903. function appendCommentToDocument(p, token) {
  40904. p._appendCommentNode(token, p.document);
  40905. }
  40906. function stopParsing(p, token) {
  40907. p.stopped = true;
  40908. if (token.location) {
  40909. const target = p.fragmentContext ? 0 : 2;
  40910. for (let i = p.openElements.stackTop; i >= target; i--) {
  40911. p._setEndLocation(p.openElements.items[i], token);
  40912. }
  40913. if (!p.fragmentContext && p.openElements.stackTop >= 0) {
  40914. const htmlElement = p.openElements.items[0];
  40915. const htmlLocation = p.treeAdapter.getNodeSourceCodeLocation(htmlElement);
  40916. if (htmlLocation && !htmlLocation.endTag) {
  40917. p._setEndLocation(htmlElement, token);
  40918. if (p.openElements.stackTop >= 1) {
  40919. const bodyElement = p.openElements.items[1];
  40920. const bodyLocation = p.treeAdapter.getNodeSourceCodeLocation(bodyElement);
  40921. if (bodyLocation && !bodyLocation.endTag) {
  40922. p._setEndLocation(bodyElement, token);
  40923. }
  40924. }
  40925. }
  40926. }
  40927. }
  40928. }
  40929. function doctypeInInitialMode(p, token) {
  40930. p._setDocumentType(token);
  40931. const mode = token.forceQuirks ? DOCUMENT_MODE.QUIRKS : getDocumentMode(token);
  40932. if (!isConforming(token)) {
  40933. p._err(token, ERR.nonConformingDoctype);
  40934. }
  40935. p.treeAdapter.setDocumentMode(p.document, mode);
  40936. p.insertionMode = InsertionMode.BEFORE_HTML;
  40937. }
  40938. function tokenInInitialMode(p, token) {
  40939. p._err(token, ERR.missingDoctype, true);
  40940. p.treeAdapter.setDocumentMode(p.document, DOCUMENT_MODE.QUIRKS);
  40941. p.insertionMode = InsertionMode.BEFORE_HTML;
  40942. p._processToken(token);
  40943. }
  40944. function startTagBeforeHtml(p, token) {
  40945. if (token.tagID === TAG_ID.HTML) {
  40946. p._insertElement(token, NS.HTML);
  40947. p.insertionMode = InsertionMode.BEFORE_HEAD;
  40948. } else {
  40949. tokenBeforeHtml(p, token);
  40950. }
  40951. }
  40952. function endTagBeforeHtml(p, token) {
  40953. const tn = token.tagID;
  40954. if (tn === TAG_ID.HTML || tn === TAG_ID.HEAD || tn === TAG_ID.BODY || tn === TAG_ID.BR) {
  40955. tokenBeforeHtml(p, token);
  40956. }
  40957. }
  40958. function tokenBeforeHtml(p, token) {
  40959. p._insertFakeRootElement();
  40960. p.insertionMode = InsertionMode.BEFORE_HEAD;
  40961. p._processToken(token);
  40962. }
  40963. function startTagBeforeHead(p, token) {
  40964. switch (token.tagID) {
  40965. case TAG_ID.HTML: {
  40966. startTagInBody(p, token);
  40967. break;
  40968. }
  40969. case TAG_ID.HEAD: {
  40970. p._insertElement(token, NS.HTML);
  40971. p.headElement = p.openElements.current;
  40972. p.insertionMode = InsertionMode.IN_HEAD;
  40973. break;
  40974. }
  40975. default: {
  40976. tokenBeforeHead(p, token);
  40977. }
  40978. }
  40979. }
  40980. function endTagBeforeHead(p, token) {
  40981. const tn = token.tagID;
  40982. if (tn === TAG_ID.HEAD || tn === TAG_ID.BODY || tn === TAG_ID.HTML || tn === TAG_ID.BR) {
  40983. tokenBeforeHead(p, token);
  40984. } else {
  40985. p._err(token, ERR.endTagWithoutMatchingOpenElement);
  40986. }
  40987. }
  40988. function tokenBeforeHead(p, token) {
  40989. p._insertFakeElement(TAG_NAMES.HEAD, TAG_ID.HEAD);
  40990. p.headElement = p.openElements.current;
  40991. p.insertionMode = InsertionMode.IN_HEAD;
  40992. p._processToken(token);
  40993. }
  40994. function startTagInHead(p, token) {
  40995. switch (token.tagID) {
  40996. case TAG_ID.HTML: {
  40997. startTagInBody(p, token);
  40998. break;
  40999. }
  41000. case TAG_ID.BASE:
  41001. case TAG_ID.BASEFONT:
  41002. case TAG_ID.BGSOUND:
  41003. case TAG_ID.LINK:
  41004. case TAG_ID.META: {
  41005. p._appendElement(token, NS.HTML);
  41006. token.ackSelfClosing = true;
  41007. break;
  41008. }
  41009. case TAG_ID.TITLE: {
  41010. p._switchToTextParsing(token, TokenizerMode.RCDATA);
  41011. break;
  41012. }
  41013. case TAG_ID.NOSCRIPT: {
  41014. if (p.options.scriptingEnabled) {
  41015. p._switchToTextParsing(token, TokenizerMode.RAWTEXT);
  41016. } else {
  41017. p._insertElement(token, NS.HTML);
  41018. p.insertionMode = InsertionMode.IN_HEAD_NO_SCRIPT;
  41019. }
  41020. break;
  41021. }
  41022. case TAG_ID.NOFRAMES:
  41023. case TAG_ID.STYLE: {
  41024. p._switchToTextParsing(token, TokenizerMode.RAWTEXT);
  41025. break;
  41026. }
  41027. case TAG_ID.SCRIPT: {
  41028. p._switchToTextParsing(token, TokenizerMode.SCRIPT_DATA);
  41029. break;
  41030. }
  41031. case TAG_ID.TEMPLATE: {
  41032. p._insertTemplate(token);
  41033. p.activeFormattingElements.insertMarker();
  41034. p.framesetOk = false;
  41035. p.insertionMode = InsertionMode.IN_TEMPLATE;
  41036. p.tmplInsertionModeStack.unshift(InsertionMode.IN_TEMPLATE);
  41037. break;
  41038. }
  41039. case TAG_ID.HEAD: {
  41040. p._err(token, ERR.misplacedStartTagForHeadElement);
  41041. break;
  41042. }
  41043. default: {
  41044. tokenInHead(p, token);
  41045. }
  41046. }
  41047. }
  41048. function endTagInHead(p, token) {
  41049. switch (token.tagID) {
  41050. case TAG_ID.HEAD: {
  41051. p.openElements.pop();
  41052. p.insertionMode = InsertionMode.AFTER_HEAD;
  41053. break;
  41054. }
  41055. case TAG_ID.BODY:
  41056. case TAG_ID.BR:
  41057. case TAG_ID.HTML: {
  41058. tokenInHead(p, token);
  41059. break;
  41060. }
  41061. case TAG_ID.TEMPLATE: {
  41062. templateEndTagInHead(p, token);
  41063. break;
  41064. }
  41065. default: {
  41066. p._err(token, ERR.endTagWithoutMatchingOpenElement);
  41067. }
  41068. }
  41069. }
  41070. function templateEndTagInHead(p, token) {
  41071. if (p.openElements.tmplCount > 0) {
  41072. p.openElements.generateImpliedEndTagsThoroughly();
  41073. if (p.openElements.currentTagId !== TAG_ID.TEMPLATE) {
  41074. p._err(token, ERR.closingOfElementWithOpenChildElements);
  41075. }
  41076. p.openElements.popUntilTagNamePopped(TAG_ID.TEMPLATE);
  41077. p.activeFormattingElements.clearToLastMarker();
  41078. p.tmplInsertionModeStack.shift();
  41079. p._resetInsertionMode();
  41080. } else {
  41081. p._err(token, ERR.endTagWithoutMatchingOpenElement);
  41082. }
  41083. }
  41084. function tokenInHead(p, token) {
  41085. p.openElements.pop();
  41086. p.insertionMode = InsertionMode.AFTER_HEAD;
  41087. p._processToken(token);
  41088. }
  41089. function startTagInHeadNoScript(p, token) {
  41090. switch (token.tagID) {
  41091. case TAG_ID.HTML: {
  41092. startTagInBody(p, token);
  41093. break;
  41094. }
  41095. case TAG_ID.BASEFONT:
  41096. case TAG_ID.BGSOUND:
  41097. case TAG_ID.HEAD:
  41098. case TAG_ID.LINK:
  41099. case TAG_ID.META:
  41100. case TAG_ID.NOFRAMES:
  41101. case TAG_ID.STYLE: {
  41102. startTagInHead(p, token);
  41103. break;
  41104. }
  41105. case TAG_ID.NOSCRIPT: {
  41106. p._err(token, ERR.nestedNoscriptInHead);
  41107. break;
  41108. }
  41109. default: {
  41110. tokenInHeadNoScript(p, token);
  41111. }
  41112. }
  41113. }
  41114. function endTagInHeadNoScript(p, token) {
  41115. switch (token.tagID) {
  41116. case TAG_ID.NOSCRIPT: {
  41117. p.openElements.pop();
  41118. p.insertionMode = InsertionMode.IN_HEAD;
  41119. break;
  41120. }
  41121. case TAG_ID.BR: {
  41122. tokenInHeadNoScript(p, token);
  41123. break;
  41124. }
  41125. default: {
  41126. p._err(token, ERR.endTagWithoutMatchingOpenElement);
  41127. }
  41128. }
  41129. }
  41130. function tokenInHeadNoScript(p, token) {
  41131. const errCode = token.type === TokenType.EOF ? ERR.openElementsLeftAfterEof : ERR.disallowedContentInNoscriptInHead;
  41132. p._err(token, errCode);
  41133. p.openElements.pop();
  41134. p.insertionMode = InsertionMode.IN_HEAD;
  41135. p._processToken(token);
  41136. }
  41137. function startTagAfterHead(p, token) {
  41138. switch (token.tagID) {
  41139. case TAG_ID.HTML: {
  41140. startTagInBody(p, token);
  41141. break;
  41142. }
  41143. case TAG_ID.BODY: {
  41144. p._insertElement(token, NS.HTML);
  41145. p.framesetOk = false;
  41146. p.insertionMode = InsertionMode.IN_BODY;
  41147. break;
  41148. }
  41149. case TAG_ID.FRAMESET: {
  41150. p._insertElement(token, NS.HTML);
  41151. p.insertionMode = InsertionMode.IN_FRAMESET;
  41152. break;
  41153. }
  41154. case TAG_ID.BASE:
  41155. case TAG_ID.BASEFONT:
  41156. case TAG_ID.BGSOUND:
  41157. case TAG_ID.LINK:
  41158. case TAG_ID.META:
  41159. case TAG_ID.NOFRAMES:
  41160. case TAG_ID.SCRIPT:
  41161. case TAG_ID.STYLE:
  41162. case TAG_ID.TEMPLATE:
  41163. case TAG_ID.TITLE: {
  41164. p._err(token, ERR.abandonedHeadElementChild);
  41165. p.openElements.push(p.headElement, TAG_ID.HEAD);
  41166. startTagInHead(p, token);
  41167. p.openElements.remove(p.headElement);
  41168. break;
  41169. }
  41170. case TAG_ID.HEAD: {
  41171. p._err(token, ERR.misplacedStartTagForHeadElement);
  41172. break;
  41173. }
  41174. default: {
  41175. tokenAfterHead(p, token);
  41176. }
  41177. }
  41178. }
  41179. function endTagAfterHead(p, token) {
  41180. switch (token.tagID) {
  41181. case TAG_ID.BODY:
  41182. case TAG_ID.HTML:
  41183. case TAG_ID.BR: {
  41184. tokenAfterHead(p, token);
  41185. break;
  41186. }
  41187. case TAG_ID.TEMPLATE: {
  41188. templateEndTagInHead(p, token);
  41189. break;
  41190. }
  41191. default: {
  41192. p._err(token, ERR.endTagWithoutMatchingOpenElement);
  41193. }
  41194. }
  41195. }
  41196. function tokenAfterHead(p, token) {
  41197. p._insertFakeElement(TAG_NAMES.BODY, TAG_ID.BODY);
  41198. p.insertionMode = InsertionMode.IN_BODY;
  41199. modeInBody(p, token);
  41200. }
  41201. function modeInBody(p, token) {
  41202. switch (token.type) {
  41203. case TokenType.CHARACTER: {
  41204. characterInBody(p, token);
  41205. break;
  41206. }
  41207. case TokenType.WHITESPACE_CHARACTER: {
  41208. whitespaceCharacterInBody(p, token);
  41209. break;
  41210. }
  41211. case TokenType.COMMENT: {
  41212. appendComment(p, token);
  41213. break;
  41214. }
  41215. case TokenType.START_TAG: {
  41216. startTagInBody(p, token);
  41217. break;
  41218. }
  41219. case TokenType.END_TAG: {
  41220. endTagInBody(p, token);
  41221. break;
  41222. }
  41223. case TokenType.EOF: {
  41224. eofInBody(p, token);
  41225. break;
  41226. }
  41227. default:
  41228. }
  41229. }
  41230. function whitespaceCharacterInBody(p, token) {
  41231. p._reconstructActiveFormattingElements();
  41232. p._insertCharacters(token);
  41233. }
  41234. function characterInBody(p, token) {
  41235. p._reconstructActiveFormattingElements();
  41236. p._insertCharacters(token);
  41237. p.framesetOk = false;
  41238. }
  41239. function htmlStartTagInBody(p, token) {
  41240. if (p.openElements.tmplCount === 0) {
  41241. p.treeAdapter.adoptAttributes(p.openElements.items[0], token.attrs);
  41242. }
  41243. }
  41244. function bodyStartTagInBody(p, token) {
  41245. const bodyElement = p.openElements.tryPeekProperlyNestedBodyElement();
  41246. if (bodyElement && p.openElements.tmplCount === 0) {
  41247. p.framesetOk = false;
  41248. p.treeAdapter.adoptAttributes(bodyElement, token.attrs);
  41249. }
  41250. }
  41251. function framesetStartTagInBody(p, token) {
  41252. const bodyElement = p.openElements.tryPeekProperlyNestedBodyElement();
  41253. if (p.framesetOk && bodyElement) {
  41254. p.treeAdapter.detachNode(bodyElement);
  41255. p.openElements.popAllUpToHtmlElement();
  41256. p._insertElement(token, NS.HTML);
  41257. p.insertionMode = InsertionMode.IN_FRAMESET;
  41258. }
  41259. }
  41260. function addressStartTagInBody(p, token) {
  41261. if (p.openElements.hasInButtonScope(TAG_ID.P)) {
  41262. p._closePElement();
  41263. }
  41264. p._insertElement(token, NS.HTML);
  41265. }
  41266. function numberedHeaderStartTagInBody(p, token) {
  41267. if (p.openElements.hasInButtonScope(TAG_ID.P)) {
  41268. p._closePElement();
  41269. }
  41270. if (isNumberedHeader(p.openElements.currentTagId)) {
  41271. p.openElements.pop();
  41272. }
  41273. p._insertElement(token, NS.HTML);
  41274. }
  41275. function preStartTagInBody(p, token) {
  41276. if (p.openElements.hasInButtonScope(TAG_ID.P)) {
  41277. p._closePElement();
  41278. }
  41279. p._insertElement(token, NS.HTML);
  41280. p.skipNextNewLine = true;
  41281. p.framesetOk = false;
  41282. }
  41283. function formStartTagInBody(p, token) {
  41284. const inTemplate = p.openElements.tmplCount > 0;
  41285. if (!p.formElement || inTemplate) {
  41286. if (p.openElements.hasInButtonScope(TAG_ID.P)) {
  41287. p._closePElement();
  41288. }
  41289. p._insertElement(token, NS.HTML);
  41290. if (!inTemplate) {
  41291. p.formElement = p.openElements.current;
  41292. }
  41293. }
  41294. }
  41295. function listItemStartTagInBody(p, token) {
  41296. p.framesetOk = false;
  41297. const tn = token.tagID;
  41298. for (let i = p.openElements.stackTop; i >= 0; i--) {
  41299. const elementId = p.openElements.tagIDs[i];
  41300. 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)) {
  41301. p.openElements.generateImpliedEndTagsWithExclusion(elementId);
  41302. p.openElements.popUntilTagNamePopped(elementId);
  41303. break;
  41304. }
  41305. if (elementId !== TAG_ID.ADDRESS && elementId !== TAG_ID.DIV && elementId !== TAG_ID.P && p._isSpecialElement(p.openElements.items[i], elementId)) {
  41306. break;
  41307. }
  41308. }
  41309. if (p.openElements.hasInButtonScope(TAG_ID.P)) {
  41310. p._closePElement();
  41311. }
  41312. p._insertElement(token, NS.HTML);
  41313. }
  41314. function plaintextStartTagInBody(p, token) {
  41315. if (p.openElements.hasInButtonScope(TAG_ID.P)) {
  41316. p._closePElement();
  41317. }
  41318. p._insertElement(token, NS.HTML);
  41319. p.tokenizer.state = TokenizerMode.PLAINTEXT;
  41320. }
  41321. function buttonStartTagInBody(p, token) {
  41322. if (p.openElements.hasInScope(TAG_ID.BUTTON)) {
  41323. p.openElements.generateImpliedEndTags();
  41324. p.openElements.popUntilTagNamePopped(TAG_ID.BUTTON);
  41325. }
  41326. p._reconstructActiveFormattingElements();
  41327. p._insertElement(token, NS.HTML);
  41328. p.framesetOk = false;
  41329. }
  41330. function aStartTagInBody(p, token) {
  41331. const activeElementEntry = p.activeFormattingElements.getElementEntryInScopeWithTagName(TAG_NAMES.A);
  41332. if (activeElementEntry) {
  41333. callAdoptionAgency(p, token);
  41334. p.openElements.remove(activeElementEntry.element);
  41335. p.activeFormattingElements.removeEntry(activeElementEntry);
  41336. }
  41337. p._reconstructActiveFormattingElements();
  41338. p._insertElement(token, NS.HTML);
  41339. p.activeFormattingElements.pushElement(p.openElements.current, token);
  41340. }
  41341. function bStartTagInBody(p, token) {
  41342. p._reconstructActiveFormattingElements();
  41343. p._insertElement(token, NS.HTML);
  41344. p.activeFormattingElements.pushElement(p.openElements.current, token);
  41345. }
  41346. function nobrStartTagInBody(p, token) {
  41347. p._reconstructActiveFormattingElements();
  41348. if (p.openElements.hasInScope(TAG_ID.NOBR)) {
  41349. callAdoptionAgency(p, token);
  41350. p._reconstructActiveFormattingElements();
  41351. }
  41352. p._insertElement(token, NS.HTML);
  41353. p.activeFormattingElements.pushElement(p.openElements.current, token);
  41354. }
  41355. function appletStartTagInBody(p, token) {
  41356. p._reconstructActiveFormattingElements();
  41357. p._insertElement(token, NS.HTML);
  41358. p.activeFormattingElements.insertMarker();
  41359. p.framesetOk = false;
  41360. }
  41361. function tableStartTagInBody(p, token) {
  41362. if (p.treeAdapter.getDocumentMode(p.document) !== DOCUMENT_MODE.QUIRKS && p.openElements.hasInButtonScope(TAG_ID.P)) {
  41363. p._closePElement();
  41364. }
  41365. p._insertElement(token, NS.HTML);
  41366. p.framesetOk = false;
  41367. p.insertionMode = InsertionMode.IN_TABLE;
  41368. }
  41369. function areaStartTagInBody(p, token) {
  41370. p._reconstructActiveFormattingElements();
  41371. p._appendElement(token, NS.HTML);
  41372. p.framesetOk = false;
  41373. token.ackSelfClosing = true;
  41374. }
  41375. function isHiddenInput(token) {
  41376. const inputType = getTokenAttr(token, ATTRS.TYPE);
  41377. return inputType != null && inputType.toLowerCase() === HIDDEN_INPUT_TYPE;
  41378. }
  41379. function inputStartTagInBody(p, token) {
  41380. p._reconstructActiveFormattingElements();
  41381. p._appendElement(token, NS.HTML);
  41382. if (!isHiddenInput(token)) {
  41383. p.framesetOk = false;
  41384. }
  41385. token.ackSelfClosing = true;
  41386. }
  41387. function paramStartTagInBody(p, token) {
  41388. p._appendElement(token, NS.HTML);
  41389. token.ackSelfClosing = true;
  41390. }
  41391. function hrStartTagInBody(p, token) {
  41392. if (p.openElements.hasInButtonScope(TAG_ID.P)) {
  41393. p._closePElement();
  41394. }
  41395. p._appendElement(token, NS.HTML);
  41396. p.framesetOk = false;
  41397. token.ackSelfClosing = true;
  41398. }
  41399. function imageStartTagInBody(p, token) {
  41400. token.tagName = TAG_NAMES.IMG;
  41401. token.tagID = TAG_ID.IMG;
  41402. areaStartTagInBody(p, token);
  41403. }
  41404. function textareaStartTagInBody(p, token) {
  41405. p._insertElement(token, NS.HTML);
  41406. p.skipNextNewLine = true;
  41407. p.tokenizer.state = TokenizerMode.RCDATA;
  41408. p.originalInsertionMode = p.insertionMode;
  41409. p.framesetOk = false;
  41410. p.insertionMode = InsertionMode.TEXT;
  41411. }
  41412. function xmpStartTagInBody(p, token) {
  41413. if (p.openElements.hasInButtonScope(TAG_ID.P)) {
  41414. p._closePElement();
  41415. }
  41416. p._reconstructActiveFormattingElements();
  41417. p.framesetOk = false;
  41418. p._switchToTextParsing(token, TokenizerMode.RAWTEXT);
  41419. }
  41420. function iframeStartTagInBody(p, token) {
  41421. p.framesetOk = false;
  41422. p._switchToTextParsing(token, TokenizerMode.RAWTEXT);
  41423. }
  41424. function noembedStartTagInBody(p, token) {
  41425. p._switchToTextParsing(token, TokenizerMode.RAWTEXT);
  41426. }
  41427. function selectStartTagInBody(p, token) {
  41428. p._reconstructActiveFormattingElements();
  41429. p._insertElement(token, NS.HTML);
  41430. p.framesetOk = false;
  41431. 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;
  41432. }
  41433. function optgroupStartTagInBody(p, token) {
  41434. if (p.openElements.currentTagId === TAG_ID.OPTION) {
  41435. p.openElements.pop();
  41436. }
  41437. p._reconstructActiveFormattingElements();
  41438. p._insertElement(token, NS.HTML);
  41439. }
  41440. function rbStartTagInBody(p, token) {
  41441. if (p.openElements.hasInScope(TAG_ID.RUBY)) {
  41442. p.openElements.generateImpliedEndTags();
  41443. }
  41444. p._insertElement(token, NS.HTML);
  41445. }
  41446. function rtStartTagInBody(p, token) {
  41447. if (p.openElements.hasInScope(TAG_ID.RUBY)) {
  41448. p.openElements.generateImpliedEndTagsWithExclusion(TAG_ID.RTC);
  41449. }
  41450. p._insertElement(token, NS.HTML);
  41451. }
  41452. function mathStartTagInBody(p, token) {
  41453. p._reconstructActiveFormattingElements();
  41454. adjustTokenMathMLAttrs(token);
  41455. adjustTokenXMLAttrs(token);
  41456. if (token.selfClosing) {
  41457. p._appendElement(token, NS.MATHML);
  41458. } else {
  41459. p._insertElement(token, NS.MATHML);
  41460. }
  41461. token.ackSelfClosing = true;
  41462. }
  41463. function svgStartTagInBody(p, token) {
  41464. p._reconstructActiveFormattingElements();
  41465. adjustTokenSVGAttrs(token);
  41466. adjustTokenXMLAttrs(token);
  41467. if (token.selfClosing) {
  41468. p._appendElement(token, NS.SVG);
  41469. } else {
  41470. p._insertElement(token, NS.SVG);
  41471. }
  41472. token.ackSelfClosing = true;
  41473. }
  41474. function genericStartTagInBody(p, token) {
  41475. p._reconstructActiveFormattingElements();
  41476. p._insertElement(token, NS.HTML);
  41477. }
  41478. function startTagInBody(p, token) {
  41479. switch (token.tagID) {
  41480. case TAG_ID.I:
  41481. case TAG_ID.S:
  41482. case TAG_ID.B:
  41483. case TAG_ID.U:
  41484. case TAG_ID.EM:
  41485. case TAG_ID.TT:
  41486. case TAG_ID.BIG:
  41487. case TAG_ID.CODE:
  41488. case TAG_ID.FONT:
  41489. case TAG_ID.SMALL:
  41490. case TAG_ID.STRIKE:
  41491. case TAG_ID.STRONG: {
  41492. bStartTagInBody(p, token);
  41493. break;
  41494. }
  41495. case TAG_ID.A: {
  41496. aStartTagInBody(p, token);
  41497. break;
  41498. }
  41499. case TAG_ID.H1:
  41500. case TAG_ID.H2:
  41501. case TAG_ID.H3:
  41502. case TAG_ID.H4:
  41503. case TAG_ID.H5:
  41504. case TAG_ID.H6: {
  41505. numberedHeaderStartTagInBody(p, token);
  41506. break;
  41507. }
  41508. case TAG_ID.P:
  41509. case TAG_ID.DL:
  41510. case TAG_ID.OL:
  41511. case TAG_ID.UL:
  41512. case TAG_ID.DIV:
  41513. case TAG_ID.DIR:
  41514. case TAG_ID.NAV:
  41515. case TAG_ID.MAIN:
  41516. case TAG_ID.MENU:
  41517. case TAG_ID.ASIDE:
  41518. case TAG_ID.CENTER:
  41519. case TAG_ID.FIGURE:
  41520. case TAG_ID.FOOTER:
  41521. case TAG_ID.HEADER:
  41522. case TAG_ID.HGROUP:
  41523. case TAG_ID.DIALOG:
  41524. case TAG_ID.DETAILS:
  41525. case TAG_ID.ADDRESS:
  41526. case TAG_ID.ARTICLE:
  41527. case TAG_ID.SECTION:
  41528. case TAG_ID.SUMMARY:
  41529. case TAG_ID.FIELDSET:
  41530. case TAG_ID.BLOCKQUOTE:
  41531. case TAG_ID.FIGCAPTION: {
  41532. addressStartTagInBody(p, token);
  41533. break;
  41534. }
  41535. case TAG_ID.LI:
  41536. case TAG_ID.DD:
  41537. case TAG_ID.DT: {
  41538. listItemStartTagInBody(p, token);
  41539. break;
  41540. }
  41541. case TAG_ID.BR:
  41542. case TAG_ID.IMG:
  41543. case TAG_ID.WBR:
  41544. case TAG_ID.AREA:
  41545. case TAG_ID.EMBED:
  41546. case TAG_ID.KEYGEN: {
  41547. areaStartTagInBody(p, token);
  41548. break;
  41549. }
  41550. case TAG_ID.HR: {
  41551. hrStartTagInBody(p, token);
  41552. break;
  41553. }
  41554. case TAG_ID.RB:
  41555. case TAG_ID.RTC: {
  41556. rbStartTagInBody(p, token);
  41557. break;
  41558. }
  41559. case TAG_ID.RT:
  41560. case TAG_ID.RP: {
  41561. rtStartTagInBody(p, token);
  41562. break;
  41563. }
  41564. case TAG_ID.PRE:
  41565. case TAG_ID.LISTING: {
  41566. preStartTagInBody(p, token);
  41567. break;
  41568. }
  41569. case TAG_ID.XMP: {
  41570. xmpStartTagInBody(p, token);
  41571. break;
  41572. }
  41573. case TAG_ID.SVG: {
  41574. svgStartTagInBody(p, token);
  41575. break;
  41576. }
  41577. case TAG_ID.HTML: {
  41578. htmlStartTagInBody(p, token);
  41579. break;
  41580. }
  41581. case TAG_ID.BASE:
  41582. case TAG_ID.LINK:
  41583. case TAG_ID.META:
  41584. case TAG_ID.STYLE:
  41585. case TAG_ID.TITLE:
  41586. case TAG_ID.SCRIPT:
  41587. case TAG_ID.BGSOUND:
  41588. case TAG_ID.BASEFONT:
  41589. case TAG_ID.TEMPLATE: {
  41590. startTagInHead(p, token);
  41591. break;
  41592. }
  41593. case TAG_ID.BODY: {
  41594. bodyStartTagInBody(p, token);
  41595. break;
  41596. }
  41597. case TAG_ID.FORM: {
  41598. formStartTagInBody(p, token);
  41599. break;
  41600. }
  41601. case TAG_ID.NOBR: {
  41602. nobrStartTagInBody(p, token);
  41603. break;
  41604. }
  41605. case TAG_ID.MATH: {
  41606. mathStartTagInBody(p, token);
  41607. break;
  41608. }
  41609. case TAG_ID.TABLE: {
  41610. tableStartTagInBody(p, token);
  41611. break;
  41612. }
  41613. case TAG_ID.INPUT: {
  41614. inputStartTagInBody(p, token);
  41615. break;
  41616. }
  41617. case TAG_ID.PARAM:
  41618. case TAG_ID.TRACK:
  41619. case TAG_ID.SOURCE: {
  41620. paramStartTagInBody(p, token);
  41621. break;
  41622. }
  41623. case TAG_ID.IMAGE: {
  41624. imageStartTagInBody(p, token);
  41625. break;
  41626. }
  41627. case TAG_ID.BUTTON: {
  41628. buttonStartTagInBody(p, token);
  41629. break;
  41630. }
  41631. case TAG_ID.APPLET:
  41632. case TAG_ID.OBJECT:
  41633. case TAG_ID.MARQUEE: {
  41634. appletStartTagInBody(p, token);
  41635. break;
  41636. }
  41637. case TAG_ID.IFRAME: {
  41638. iframeStartTagInBody(p, token);
  41639. break;
  41640. }
  41641. case TAG_ID.SELECT: {
  41642. selectStartTagInBody(p, token);
  41643. break;
  41644. }
  41645. case TAG_ID.OPTION:
  41646. case TAG_ID.OPTGROUP: {
  41647. optgroupStartTagInBody(p, token);
  41648. break;
  41649. }
  41650. case TAG_ID.NOEMBED: {
  41651. noembedStartTagInBody(p, token);
  41652. break;
  41653. }
  41654. case TAG_ID.FRAMESET: {
  41655. framesetStartTagInBody(p, token);
  41656. break;
  41657. }
  41658. case TAG_ID.TEXTAREA: {
  41659. textareaStartTagInBody(p, token);
  41660. break;
  41661. }
  41662. case TAG_ID.NOSCRIPT: {
  41663. if (p.options.scriptingEnabled) {
  41664. noembedStartTagInBody(p, token);
  41665. } else {
  41666. genericStartTagInBody(p, token);
  41667. }
  41668. break;
  41669. }
  41670. case TAG_ID.PLAINTEXT: {
  41671. plaintextStartTagInBody(p, token);
  41672. break;
  41673. }
  41674. case TAG_ID.COL:
  41675. case TAG_ID.TH:
  41676. case TAG_ID.TD:
  41677. case TAG_ID.TR:
  41678. case TAG_ID.HEAD:
  41679. case TAG_ID.FRAME:
  41680. case TAG_ID.TBODY:
  41681. case TAG_ID.TFOOT:
  41682. case TAG_ID.THEAD:
  41683. case TAG_ID.CAPTION:
  41684. case TAG_ID.COLGROUP: {
  41685. break;
  41686. }
  41687. default: {
  41688. genericStartTagInBody(p, token);
  41689. }
  41690. }
  41691. }
  41692. function bodyEndTagInBody(p, token) {
  41693. if (p.openElements.hasInScope(TAG_ID.BODY)) {
  41694. p.insertionMode = InsertionMode.AFTER_BODY;
  41695. if (p.options.sourceCodeLocationInfo) {
  41696. const bodyElement = p.openElements.tryPeekProperlyNestedBodyElement();
  41697. if (bodyElement) {
  41698. p._setEndLocation(bodyElement, token);
  41699. }
  41700. }
  41701. }
  41702. }
  41703. function htmlEndTagInBody(p, token) {
  41704. if (p.openElements.hasInScope(TAG_ID.BODY)) {
  41705. p.insertionMode = InsertionMode.AFTER_BODY;
  41706. endTagAfterBody(p, token);
  41707. }
  41708. }
  41709. function addressEndTagInBody(p, token) {
  41710. const tn = token.tagID;
  41711. if (p.openElements.hasInScope(tn)) {
  41712. p.openElements.generateImpliedEndTags();
  41713. p.openElements.popUntilTagNamePopped(tn);
  41714. }
  41715. }
  41716. function formEndTagInBody(p) {
  41717. const inTemplate = p.openElements.tmplCount > 0;
  41718. const { formElement } = p;
  41719. if (!inTemplate) {
  41720. p.formElement = null;
  41721. }
  41722. if ((formElement || inTemplate) && p.openElements.hasInScope(TAG_ID.FORM)) {
  41723. p.openElements.generateImpliedEndTags();
  41724. if (inTemplate) {
  41725. p.openElements.popUntilTagNamePopped(TAG_ID.FORM);
  41726. } else if (formElement) {
  41727. p.openElements.remove(formElement);
  41728. }
  41729. }
  41730. }
  41731. function pEndTagInBody(p) {
  41732. if (!p.openElements.hasInButtonScope(TAG_ID.P)) {
  41733. p._insertFakeElement(TAG_NAMES.P, TAG_ID.P);
  41734. }
  41735. p._closePElement();
  41736. }
  41737. function liEndTagInBody(p) {
  41738. if (p.openElements.hasInListItemScope(TAG_ID.LI)) {
  41739. p.openElements.generateImpliedEndTagsWithExclusion(TAG_ID.LI);
  41740. p.openElements.popUntilTagNamePopped(TAG_ID.LI);
  41741. }
  41742. }
  41743. function ddEndTagInBody(p, token) {
  41744. const tn = token.tagID;
  41745. if (p.openElements.hasInScope(tn)) {
  41746. p.openElements.generateImpliedEndTagsWithExclusion(tn);
  41747. p.openElements.popUntilTagNamePopped(tn);
  41748. }
  41749. }
  41750. function numberedHeaderEndTagInBody(p) {
  41751. if (p.openElements.hasNumberedHeaderInScope()) {
  41752. p.openElements.generateImpliedEndTags();
  41753. p.openElements.popUntilNumberedHeaderPopped();
  41754. }
  41755. }
  41756. function appletEndTagInBody(p, token) {
  41757. const tn = token.tagID;
  41758. if (p.openElements.hasInScope(tn)) {
  41759. p.openElements.generateImpliedEndTags();
  41760. p.openElements.popUntilTagNamePopped(tn);
  41761. p.activeFormattingElements.clearToLastMarker();
  41762. }
  41763. }
  41764. function brEndTagInBody(p) {
  41765. p._reconstructActiveFormattingElements();
  41766. p._insertFakeElement(TAG_NAMES.BR, TAG_ID.BR);
  41767. p.openElements.pop();
  41768. p.framesetOk = false;
  41769. }
  41770. function genericEndTagInBody(p, token) {
  41771. const tn = token.tagName;
  41772. const tid = token.tagID;
  41773. for (let i = p.openElements.stackTop; i > 0; i--) {
  41774. const element = p.openElements.items[i];
  41775. const elementId = p.openElements.tagIDs[i];
  41776. if (tid === elementId && (tid !== TAG_ID.UNKNOWN || p.treeAdapter.getTagName(element) === tn)) {
  41777. p.openElements.generateImpliedEndTagsWithExclusion(tid);
  41778. if (p.openElements.stackTop >= i)
  41779. p.openElements.shortenToLength(i);
  41780. break;
  41781. }
  41782. if (p._isSpecialElement(element, elementId)) {
  41783. break;
  41784. }
  41785. }
  41786. }
  41787. function endTagInBody(p, token) {
  41788. switch (token.tagID) {
  41789. case TAG_ID.A:
  41790. case TAG_ID.B:
  41791. case TAG_ID.I:
  41792. case TAG_ID.S:
  41793. case TAG_ID.U:
  41794. case TAG_ID.EM:
  41795. case TAG_ID.TT:
  41796. case TAG_ID.BIG:
  41797. case TAG_ID.CODE:
  41798. case TAG_ID.FONT:
  41799. case TAG_ID.NOBR:
  41800. case TAG_ID.SMALL:
  41801. case TAG_ID.STRIKE:
  41802. case TAG_ID.STRONG: {
  41803. callAdoptionAgency(p, token);
  41804. break;
  41805. }
  41806. case TAG_ID.P: {
  41807. pEndTagInBody(p);
  41808. break;
  41809. }
  41810. case TAG_ID.DL:
  41811. case TAG_ID.UL:
  41812. case TAG_ID.OL:
  41813. case TAG_ID.DIR:
  41814. case TAG_ID.DIV:
  41815. case TAG_ID.NAV:
  41816. case TAG_ID.PRE:
  41817. case TAG_ID.MAIN:
  41818. case TAG_ID.MENU:
  41819. case TAG_ID.ASIDE:
  41820. case TAG_ID.BUTTON:
  41821. case TAG_ID.CENTER:
  41822. case TAG_ID.FIGURE:
  41823. case TAG_ID.FOOTER:
  41824. case TAG_ID.HEADER:
  41825. case TAG_ID.HGROUP:
  41826. case TAG_ID.DIALOG:
  41827. case TAG_ID.ADDRESS:
  41828. case TAG_ID.ARTICLE:
  41829. case TAG_ID.DETAILS:
  41830. case TAG_ID.SECTION:
  41831. case TAG_ID.SUMMARY:
  41832. case TAG_ID.LISTING:
  41833. case TAG_ID.FIELDSET:
  41834. case TAG_ID.BLOCKQUOTE:
  41835. case TAG_ID.FIGCAPTION: {
  41836. addressEndTagInBody(p, token);
  41837. break;
  41838. }
  41839. case TAG_ID.LI: {
  41840. liEndTagInBody(p);
  41841. break;
  41842. }
  41843. case TAG_ID.DD:
  41844. case TAG_ID.DT: {
  41845. ddEndTagInBody(p, token);
  41846. break;
  41847. }
  41848. case TAG_ID.H1:
  41849. case TAG_ID.H2:
  41850. case TAG_ID.H3:
  41851. case TAG_ID.H4:
  41852. case TAG_ID.H5:
  41853. case TAG_ID.H6: {
  41854. numberedHeaderEndTagInBody(p);
  41855. break;
  41856. }
  41857. case TAG_ID.BR: {
  41858. brEndTagInBody(p);
  41859. break;
  41860. }
  41861. case TAG_ID.BODY: {
  41862. bodyEndTagInBody(p, token);
  41863. break;
  41864. }
  41865. case TAG_ID.HTML: {
  41866. htmlEndTagInBody(p, token);
  41867. break;
  41868. }
  41869. case TAG_ID.FORM: {
  41870. formEndTagInBody(p);
  41871. break;
  41872. }
  41873. case TAG_ID.APPLET:
  41874. case TAG_ID.OBJECT:
  41875. case TAG_ID.MARQUEE: {
  41876. appletEndTagInBody(p, token);
  41877. break;
  41878. }
  41879. case TAG_ID.TEMPLATE: {
  41880. templateEndTagInHead(p, token);
  41881. break;
  41882. }
  41883. default: {
  41884. genericEndTagInBody(p, token);
  41885. }
  41886. }
  41887. }
  41888. function eofInBody(p, token) {
  41889. if (p.tmplInsertionModeStack.length > 0) {
  41890. eofInTemplate(p, token);
  41891. } else {
  41892. stopParsing(p, token);
  41893. }
  41894. }
  41895. function endTagInText(p, token) {
  41896. var _a2;
  41897. if (token.tagID === TAG_ID.SCRIPT) {
  41898. (_a2 = p.scriptHandler) === null || _a2 === void 0 ? void 0 : _a2.call(p, p.openElements.current);
  41899. }
  41900. p.openElements.pop();
  41901. p.insertionMode = p.originalInsertionMode;
  41902. }
  41903. function eofInText(p, token) {
  41904. p._err(token, ERR.eofInElementThatCanContainOnlyText);
  41905. p.openElements.pop();
  41906. p.insertionMode = p.originalInsertionMode;
  41907. p.onEof(token);
  41908. }
  41909. function characterInTable(p, token) {
  41910. if (TABLE_STRUCTURE_TAGS.has(p.openElements.currentTagId)) {
  41911. p.pendingCharacterTokens.length = 0;
  41912. p.hasNonWhitespacePendingCharacterToken = false;
  41913. p.originalInsertionMode = p.insertionMode;
  41914. p.insertionMode = InsertionMode.IN_TABLE_TEXT;
  41915. switch (token.type) {
  41916. case TokenType.CHARACTER: {
  41917. characterInTableText(p, token);
  41918. break;
  41919. }
  41920. case TokenType.WHITESPACE_CHARACTER: {
  41921. whitespaceCharacterInTableText(p, token);
  41922. break;
  41923. }
  41924. }
  41925. } else {
  41926. tokenInTable(p, token);
  41927. }
  41928. }
  41929. function captionStartTagInTable(p, token) {
  41930. p.openElements.clearBackToTableContext();
  41931. p.activeFormattingElements.insertMarker();
  41932. p._insertElement(token, NS.HTML);
  41933. p.insertionMode = InsertionMode.IN_CAPTION;
  41934. }
  41935. function colgroupStartTagInTable(p, token) {
  41936. p.openElements.clearBackToTableContext();
  41937. p._insertElement(token, NS.HTML);
  41938. p.insertionMode = InsertionMode.IN_COLUMN_GROUP;
  41939. }
  41940. function colStartTagInTable(p, token) {
  41941. p.openElements.clearBackToTableContext();
  41942. p._insertFakeElement(TAG_NAMES.COLGROUP, TAG_ID.COLGROUP);
  41943. p.insertionMode = InsertionMode.IN_COLUMN_GROUP;
  41944. startTagInColumnGroup(p, token);
  41945. }
  41946. function tbodyStartTagInTable(p, token) {
  41947. p.openElements.clearBackToTableContext();
  41948. p._insertElement(token, NS.HTML);
  41949. p.insertionMode = InsertionMode.IN_TABLE_BODY;
  41950. }
  41951. function tdStartTagInTable(p, token) {
  41952. p.openElements.clearBackToTableContext();
  41953. p._insertFakeElement(TAG_NAMES.TBODY, TAG_ID.TBODY);
  41954. p.insertionMode = InsertionMode.IN_TABLE_BODY;
  41955. startTagInTableBody(p, token);
  41956. }
  41957. function tableStartTagInTable(p, token) {
  41958. if (p.openElements.hasInTableScope(TAG_ID.TABLE)) {
  41959. p.openElements.popUntilTagNamePopped(TAG_ID.TABLE);
  41960. p._resetInsertionMode();
  41961. p._processStartTag(token);
  41962. }
  41963. }
  41964. function inputStartTagInTable(p, token) {
  41965. if (isHiddenInput(token)) {
  41966. p._appendElement(token, NS.HTML);
  41967. } else {
  41968. tokenInTable(p, token);
  41969. }
  41970. token.ackSelfClosing = true;
  41971. }
  41972. function formStartTagInTable(p, token) {
  41973. if (!p.formElement && p.openElements.tmplCount === 0) {
  41974. p._insertElement(token, NS.HTML);
  41975. p.formElement = p.openElements.current;
  41976. p.openElements.pop();
  41977. }
  41978. }
  41979. function startTagInTable(p, token) {
  41980. switch (token.tagID) {
  41981. case TAG_ID.TD:
  41982. case TAG_ID.TH:
  41983. case TAG_ID.TR: {
  41984. tdStartTagInTable(p, token);
  41985. break;
  41986. }
  41987. case TAG_ID.STYLE:
  41988. case TAG_ID.SCRIPT:
  41989. case TAG_ID.TEMPLATE: {
  41990. startTagInHead(p, token);
  41991. break;
  41992. }
  41993. case TAG_ID.COL: {
  41994. colStartTagInTable(p, token);
  41995. break;
  41996. }
  41997. case TAG_ID.FORM: {
  41998. formStartTagInTable(p, token);
  41999. break;
  42000. }
  42001. case TAG_ID.TABLE: {
  42002. tableStartTagInTable(p, token);
  42003. break;
  42004. }
  42005. case TAG_ID.TBODY:
  42006. case TAG_ID.TFOOT:
  42007. case TAG_ID.THEAD: {
  42008. tbodyStartTagInTable(p, token);
  42009. break;
  42010. }
  42011. case TAG_ID.INPUT: {
  42012. inputStartTagInTable(p, token);
  42013. break;
  42014. }
  42015. case TAG_ID.CAPTION: {
  42016. captionStartTagInTable(p, token);
  42017. break;
  42018. }
  42019. case TAG_ID.COLGROUP: {
  42020. colgroupStartTagInTable(p, token);
  42021. break;
  42022. }
  42023. default: {
  42024. tokenInTable(p, token);
  42025. }
  42026. }
  42027. }
  42028. function endTagInTable(p, token) {
  42029. switch (token.tagID) {
  42030. case TAG_ID.TABLE: {
  42031. if (p.openElements.hasInTableScope(TAG_ID.TABLE)) {
  42032. p.openElements.popUntilTagNamePopped(TAG_ID.TABLE);
  42033. p._resetInsertionMode();
  42034. }
  42035. break;
  42036. }
  42037. case TAG_ID.TEMPLATE: {
  42038. templateEndTagInHead(p, token);
  42039. break;
  42040. }
  42041. case TAG_ID.BODY:
  42042. case TAG_ID.CAPTION:
  42043. case TAG_ID.COL:
  42044. case TAG_ID.COLGROUP:
  42045. case TAG_ID.HTML:
  42046. case TAG_ID.TBODY:
  42047. case TAG_ID.TD:
  42048. case TAG_ID.TFOOT:
  42049. case TAG_ID.TH:
  42050. case TAG_ID.THEAD:
  42051. case TAG_ID.TR: {
  42052. break;
  42053. }
  42054. default: {
  42055. tokenInTable(p, token);
  42056. }
  42057. }
  42058. }
  42059. function tokenInTable(p, token) {
  42060. const savedFosterParentingState = p.fosterParentingEnabled;
  42061. p.fosterParentingEnabled = true;
  42062. modeInBody(p, token);
  42063. p.fosterParentingEnabled = savedFosterParentingState;
  42064. }
  42065. function whitespaceCharacterInTableText(p, token) {
  42066. p.pendingCharacterTokens.push(token);
  42067. }
  42068. function characterInTableText(p, token) {
  42069. p.pendingCharacterTokens.push(token);
  42070. p.hasNonWhitespacePendingCharacterToken = true;
  42071. }
  42072. function tokenInTableText(p, token) {
  42073. let i = 0;
  42074. if (p.hasNonWhitespacePendingCharacterToken) {
  42075. for (; i < p.pendingCharacterTokens.length; i++) {
  42076. tokenInTable(p, p.pendingCharacterTokens[i]);
  42077. }
  42078. } else {
  42079. for (; i < p.pendingCharacterTokens.length; i++) {
  42080. p._insertCharacters(p.pendingCharacterTokens[i]);
  42081. }
  42082. }
  42083. p.insertionMode = p.originalInsertionMode;
  42084. p._processToken(token);
  42085. }
  42086. 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]);
  42087. function startTagInCaption(p, token) {
  42088. const tn = token.tagID;
  42089. if (TABLE_VOID_ELEMENTS.has(tn)) {
  42090. if (p.openElements.hasInTableScope(TAG_ID.CAPTION)) {
  42091. p.openElements.generateImpliedEndTags();
  42092. p.openElements.popUntilTagNamePopped(TAG_ID.CAPTION);
  42093. p.activeFormattingElements.clearToLastMarker();
  42094. p.insertionMode = InsertionMode.IN_TABLE;
  42095. startTagInTable(p, token);
  42096. }
  42097. } else {
  42098. startTagInBody(p, token);
  42099. }
  42100. }
  42101. function endTagInCaption(p, token) {
  42102. const tn = token.tagID;
  42103. switch (tn) {
  42104. case TAG_ID.CAPTION:
  42105. case TAG_ID.TABLE: {
  42106. if (p.openElements.hasInTableScope(TAG_ID.CAPTION)) {
  42107. p.openElements.generateImpliedEndTags();
  42108. p.openElements.popUntilTagNamePopped(TAG_ID.CAPTION);
  42109. p.activeFormattingElements.clearToLastMarker();
  42110. p.insertionMode = InsertionMode.IN_TABLE;
  42111. if (tn === TAG_ID.TABLE) {
  42112. endTagInTable(p, token);
  42113. }
  42114. }
  42115. break;
  42116. }
  42117. case TAG_ID.BODY:
  42118. case TAG_ID.COL:
  42119. case TAG_ID.COLGROUP:
  42120. case TAG_ID.HTML:
  42121. case TAG_ID.TBODY:
  42122. case TAG_ID.TD:
  42123. case TAG_ID.TFOOT:
  42124. case TAG_ID.TH:
  42125. case TAG_ID.THEAD:
  42126. case TAG_ID.TR: {
  42127. break;
  42128. }
  42129. default: {
  42130. endTagInBody(p, token);
  42131. }
  42132. }
  42133. }
  42134. function startTagInColumnGroup(p, token) {
  42135. switch (token.tagID) {
  42136. case TAG_ID.HTML: {
  42137. startTagInBody(p, token);
  42138. break;
  42139. }
  42140. case TAG_ID.COL: {
  42141. p._appendElement(token, NS.HTML);
  42142. token.ackSelfClosing = true;
  42143. break;
  42144. }
  42145. case TAG_ID.TEMPLATE: {
  42146. startTagInHead(p, token);
  42147. break;
  42148. }
  42149. default: {
  42150. tokenInColumnGroup(p, token);
  42151. }
  42152. }
  42153. }
  42154. function endTagInColumnGroup(p, token) {
  42155. switch (token.tagID) {
  42156. case TAG_ID.COLGROUP: {
  42157. if (p.openElements.currentTagId === TAG_ID.COLGROUP) {
  42158. p.openElements.pop();
  42159. p.insertionMode = InsertionMode.IN_TABLE;
  42160. }
  42161. break;
  42162. }
  42163. case TAG_ID.TEMPLATE: {
  42164. templateEndTagInHead(p, token);
  42165. break;
  42166. }
  42167. case TAG_ID.COL: {
  42168. break;
  42169. }
  42170. default: {
  42171. tokenInColumnGroup(p, token);
  42172. }
  42173. }
  42174. }
  42175. function tokenInColumnGroup(p, token) {
  42176. if (p.openElements.currentTagId === TAG_ID.COLGROUP) {
  42177. p.openElements.pop();
  42178. p.insertionMode = InsertionMode.IN_TABLE;
  42179. p._processToken(token);
  42180. }
  42181. }
  42182. function startTagInTableBody(p, token) {
  42183. switch (token.tagID) {
  42184. case TAG_ID.TR: {
  42185. p.openElements.clearBackToTableBodyContext();
  42186. p._insertElement(token, NS.HTML);
  42187. p.insertionMode = InsertionMode.IN_ROW;
  42188. break;
  42189. }
  42190. case TAG_ID.TH:
  42191. case TAG_ID.TD: {
  42192. p.openElements.clearBackToTableBodyContext();
  42193. p._insertFakeElement(TAG_NAMES.TR, TAG_ID.TR);
  42194. p.insertionMode = InsertionMode.IN_ROW;
  42195. startTagInRow(p, token);
  42196. break;
  42197. }
  42198. case TAG_ID.CAPTION:
  42199. case TAG_ID.COL:
  42200. case TAG_ID.COLGROUP:
  42201. case TAG_ID.TBODY:
  42202. case TAG_ID.TFOOT:
  42203. case TAG_ID.THEAD: {
  42204. if (p.openElements.hasTableBodyContextInTableScope()) {
  42205. p.openElements.clearBackToTableBodyContext();
  42206. p.openElements.pop();
  42207. p.insertionMode = InsertionMode.IN_TABLE;
  42208. startTagInTable(p, token);
  42209. }
  42210. break;
  42211. }
  42212. default: {
  42213. startTagInTable(p, token);
  42214. }
  42215. }
  42216. }
  42217. function endTagInTableBody(p, token) {
  42218. const tn = token.tagID;
  42219. switch (token.tagID) {
  42220. case TAG_ID.TBODY:
  42221. case TAG_ID.TFOOT:
  42222. case TAG_ID.THEAD: {
  42223. if (p.openElements.hasInTableScope(tn)) {
  42224. p.openElements.clearBackToTableBodyContext();
  42225. p.openElements.pop();
  42226. p.insertionMode = InsertionMode.IN_TABLE;
  42227. }
  42228. break;
  42229. }
  42230. case TAG_ID.TABLE: {
  42231. if (p.openElements.hasTableBodyContextInTableScope()) {
  42232. p.openElements.clearBackToTableBodyContext();
  42233. p.openElements.pop();
  42234. p.insertionMode = InsertionMode.IN_TABLE;
  42235. endTagInTable(p, token);
  42236. }
  42237. break;
  42238. }
  42239. case TAG_ID.BODY:
  42240. case TAG_ID.CAPTION:
  42241. case TAG_ID.COL:
  42242. case TAG_ID.COLGROUP:
  42243. case TAG_ID.HTML:
  42244. case TAG_ID.TD:
  42245. case TAG_ID.TH:
  42246. case TAG_ID.TR: {
  42247. break;
  42248. }
  42249. default: {
  42250. endTagInTable(p, token);
  42251. }
  42252. }
  42253. }
  42254. function startTagInRow(p, token) {
  42255. switch (token.tagID) {
  42256. case TAG_ID.TH:
  42257. case TAG_ID.TD: {
  42258. p.openElements.clearBackToTableRowContext();
  42259. p._insertElement(token, NS.HTML);
  42260. p.insertionMode = InsertionMode.IN_CELL;
  42261. p.activeFormattingElements.insertMarker();
  42262. break;
  42263. }
  42264. case TAG_ID.CAPTION:
  42265. case TAG_ID.COL:
  42266. case TAG_ID.COLGROUP:
  42267. case TAG_ID.TBODY:
  42268. case TAG_ID.TFOOT:
  42269. case TAG_ID.THEAD:
  42270. case TAG_ID.TR: {
  42271. if (p.openElements.hasInTableScope(TAG_ID.TR)) {
  42272. p.openElements.clearBackToTableRowContext();
  42273. p.openElements.pop();
  42274. p.insertionMode = InsertionMode.IN_TABLE_BODY;
  42275. startTagInTableBody(p, token);
  42276. }
  42277. break;
  42278. }
  42279. default: {
  42280. startTagInTable(p, token);
  42281. }
  42282. }
  42283. }
  42284. function endTagInRow(p, token) {
  42285. switch (token.tagID) {
  42286. case TAG_ID.TR: {
  42287. if (p.openElements.hasInTableScope(TAG_ID.TR)) {
  42288. p.openElements.clearBackToTableRowContext();
  42289. p.openElements.pop();
  42290. p.insertionMode = InsertionMode.IN_TABLE_BODY;
  42291. }
  42292. break;
  42293. }
  42294. case TAG_ID.TABLE: {
  42295. if (p.openElements.hasInTableScope(TAG_ID.TR)) {
  42296. p.openElements.clearBackToTableRowContext();
  42297. p.openElements.pop();
  42298. p.insertionMode = InsertionMode.IN_TABLE_BODY;
  42299. endTagInTableBody(p, token);
  42300. }
  42301. break;
  42302. }
  42303. case TAG_ID.TBODY:
  42304. case TAG_ID.TFOOT:
  42305. case TAG_ID.THEAD: {
  42306. if (p.openElements.hasInTableScope(token.tagID) || p.openElements.hasInTableScope(TAG_ID.TR)) {
  42307. p.openElements.clearBackToTableRowContext();
  42308. p.openElements.pop();
  42309. p.insertionMode = InsertionMode.IN_TABLE_BODY;
  42310. endTagInTableBody(p, token);
  42311. }
  42312. break;
  42313. }
  42314. case TAG_ID.BODY:
  42315. case TAG_ID.CAPTION:
  42316. case TAG_ID.COL:
  42317. case TAG_ID.COLGROUP:
  42318. case TAG_ID.HTML:
  42319. case TAG_ID.TD:
  42320. case TAG_ID.TH: {
  42321. break;
  42322. }
  42323. default: {
  42324. endTagInTable(p, token);
  42325. }
  42326. }
  42327. }
  42328. function startTagInCell(p, token) {
  42329. const tn = token.tagID;
  42330. if (TABLE_VOID_ELEMENTS.has(tn)) {
  42331. if (p.openElements.hasInTableScope(TAG_ID.TD) || p.openElements.hasInTableScope(TAG_ID.TH)) {
  42332. p._closeTableCell();
  42333. startTagInRow(p, token);
  42334. }
  42335. } else {
  42336. startTagInBody(p, token);
  42337. }
  42338. }
  42339. function endTagInCell(p, token) {
  42340. const tn = token.tagID;
  42341. switch (tn) {
  42342. case TAG_ID.TD:
  42343. case TAG_ID.TH: {
  42344. if (p.openElements.hasInTableScope(tn)) {
  42345. p.openElements.generateImpliedEndTags();
  42346. p.openElements.popUntilTagNamePopped(tn);
  42347. p.activeFormattingElements.clearToLastMarker();
  42348. p.insertionMode = InsertionMode.IN_ROW;
  42349. }
  42350. break;
  42351. }
  42352. case TAG_ID.TABLE:
  42353. case TAG_ID.TBODY:
  42354. case TAG_ID.TFOOT:
  42355. case TAG_ID.THEAD:
  42356. case TAG_ID.TR: {
  42357. if (p.openElements.hasInTableScope(tn)) {
  42358. p._closeTableCell();
  42359. endTagInRow(p, token);
  42360. }
  42361. break;
  42362. }
  42363. case TAG_ID.BODY:
  42364. case TAG_ID.CAPTION:
  42365. case TAG_ID.COL:
  42366. case TAG_ID.COLGROUP:
  42367. case TAG_ID.HTML: {
  42368. break;
  42369. }
  42370. default: {
  42371. endTagInBody(p, token);
  42372. }
  42373. }
  42374. }
  42375. function startTagInSelect(p, token) {
  42376. switch (token.tagID) {
  42377. case TAG_ID.HTML: {
  42378. startTagInBody(p, token);
  42379. break;
  42380. }
  42381. case TAG_ID.OPTION: {
  42382. if (p.openElements.currentTagId === TAG_ID.OPTION) {
  42383. p.openElements.pop();
  42384. }
  42385. p._insertElement(token, NS.HTML);
  42386. break;
  42387. }
  42388. case TAG_ID.OPTGROUP: {
  42389. if (p.openElements.currentTagId === TAG_ID.OPTION) {
  42390. p.openElements.pop();
  42391. }
  42392. if (p.openElements.currentTagId === TAG_ID.OPTGROUP) {
  42393. p.openElements.pop();
  42394. }
  42395. p._insertElement(token, NS.HTML);
  42396. break;
  42397. }
  42398. case TAG_ID.INPUT:
  42399. case TAG_ID.KEYGEN:
  42400. case TAG_ID.TEXTAREA:
  42401. case TAG_ID.SELECT: {
  42402. if (p.openElements.hasInSelectScope(TAG_ID.SELECT)) {
  42403. p.openElements.popUntilTagNamePopped(TAG_ID.SELECT);
  42404. p._resetInsertionMode();
  42405. if (token.tagID !== TAG_ID.SELECT) {
  42406. p._processStartTag(token);
  42407. }
  42408. }
  42409. break;
  42410. }
  42411. case TAG_ID.SCRIPT:
  42412. case TAG_ID.TEMPLATE: {
  42413. startTagInHead(p, token);
  42414. break;
  42415. }
  42416. default:
  42417. }
  42418. }
  42419. function endTagInSelect(p, token) {
  42420. switch (token.tagID) {
  42421. case TAG_ID.OPTGROUP: {
  42422. if (p.openElements.stackTop > 0 && p.openElements.currentTagId === TAG_ID.OPTION && p.openElements.tagIDs[p.openElements.stackTop - 1] === TAG_ID.OPTGROUP) {
  42423. p.openElements.pop();
  42424. }
  42425. if (p.openElements.currentTagId === TAG_ID.OPTGROUP) {
  42426. p.openElements.pop();
  42427. }
  42428. break;
  42429. }
  42430. case TAG_ID.OPTION: {
  42431. if (p.openElements.currentTagId === TAG_ID.OPTION) {
  42432. p.openElements.pop();
  42433. }
  42434. break;
  42435. }
  42436. case TAG_ID.SELECT: {
  42437. if (p.openElements.hasInSelectScope(TAG_ID.SELECT)) {
  42438. p.openElements.popUntilTagNamePopped(TAG_ID.SELECT);
  42439. p._resetInsertionMode();
  42440. }
  42441. break;
  42442. }
  42443. case TAG_ID.TEMPLATE: {
  42444. templateEndTagInHead(p, token);
  42445. break;
  42446. }
  42447. default:
  42448. }
  42449. }
  42450. function startTagInSelectInTable(p, token) {
  42451. const tn = token.tagID;
  42452. 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) {
  42453. p.openElements.popUntilTagNamePopped(TAG_ID.SELECT);
  42454. p._resetInsertionMode();
  42455. p._processStartTag(token);
  42456. } else {
  42457. startTagInSelect(p, token);
  42458. }
  42459. }
  42460. function endTagInSelectInTable(p, token) {
  42461. const tn = token.tagID;
  42462. 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) {
  42463. if (p.openElements.hasInTableScope(tn)) {
  42464. p.openElements.popUntilTagNamePopped(TAG_ID.SELECT);
  42465. p._resetInsertionMode();
  42466. p.onEndTag(token);
  42467. }
  42468. } else {
  42469. endTagInSelect(p, token);
  42470. }
  42471. }
  42472. function startTagInTemplate(p, token) {
  42473. switch (token.tagID) {
  42474. case TAG_ID.BASE:
  42475. case TAG_ID.BASEFONT:
  42476. case TAG_ID.BGSOUND:
  42477. case TAG_ID.LINK:
  42478. case TAG_ID.META:
  42479. case TAG_ID.NOFRAMES:
  42480. case TAG_ID.SCRIPT:
  42481. case TAG_ID.STYLE:
  42482. case TAG_ID.TEMPLATE:
  42483. case TAG_ID.TITLE: {
  42484. startTagInHead(p, token);
  42485. break;
  42486. }
  42487. case TAG_ID.CAPTION:
  42488. case TAG_ID.COLGROUP:
  42489. case TAG_ID.TBODY:
  42490. case TAG_ID.TFOOT:
  42491. case TAG_ID.THEAD: {
  42492. p.tmplInsertionModeStack[0] = InsertionMode.IN_TABLE;
  42493. p.insertionMode = InsertionMode.IN_TABLE;
  42494. startTagInTable(p, token);
  42495. break;
  42496. }
  42497. case TAG_ID.COL: {
  42498. p.tmplInsertionModeStack[0] = InsertionMode.IN_COLUMN_GROUP;
  42499. p.insertionMode = InsertionMode.IN_COLUMN_GROUP;
  42500. startTagInColumnGroup(p, token);
  42501. break;
  42502. }
  42503. case TAG_ID.TR: {
  42504. p.tmplInsertionModeStack[0] = InsertionMode.IN_TABLE_BODY;
  42505. p.insertionMode = InsertionMode.IN_TABLE_BODY;
  42506. startTagInTableBody(p, token);
  42507. break;
  42508. }
  42509. case TAG_ID.TD:
  42510. case TAG_ID.TH: {
  42511. p.tmplInsertionModeStack[0] = InsertionMode.IN_ROW;
  42512. p.insertionMode = InsertionMode.IN_ROW;
  42513. startTagInRow(p, token);
  42514. break;
  42515. }
  42516. default: {
  42517. p.tmplInsertionModeStack[0] = InsertionMode.IN_BODY;
  42518. p.insertionMode = InsertionMode.IN_BODY;
  42519. startTagInBody(p, token);
  42520. }
  42521. }
  42522. }
  42523. function endTagInTemplate(p, token) {
  42524. if (token.tagID === TAG_ID.TEMPLATE) {
  42525. templateEndTagInHead(p, token);
  42526. }
  42527. }
  42528. function eofInTemplate(p, token) {
  42529. if (p.openElements.tmplCount > 0) {
  42530. p.openElements.popUntilTagNamePopped(TAG_ID.TEMPLATE);
  42531. p.activeFormattingElements.clearToLastMarker();
  42532. p.tmplInsertionModeStack.shift();
  42533. p._resetInsertionMode();
  42534. p.onEof(token);
  42535. } else {
  42536. stopParsing(p, token);
  42537. }
  42538. }
  42539. function startTagAfterBody(p, token) {
  42540. if (token.tagID === TAG_ID.HTML) {
  42541. startTagInBody(p, token);
  42542. } else {
  42543. tokenAfterBody(p, token);
  42544. }
  42545. }
  42546. function endTagAfterBody(p, token) {
  42547. var _a2;
  42548. if (token.tagID === TAG_ID.HTML) {
  42549. if (!p.fragmentContext) {
  42550. p.insertionMode = InsertionMode.AFTER_AFTER_BODY;
  42551. }
  42552. if (p.options.sourceCodeLocationInfo && p.openElements.tagIDs[0] === TAG_ID.HTML) {
  42553. p._setEndLocation(p.openElements.items[0], token);
  42554. const bodyElement = p.openElements.items[1];
  42555. if (bodyElement && !((_a2 = p.treeAdapter.getNodeSourceCodeLocation(bodyElement)) === null || _a2 === void 0 ? void 0 : _a2.endTag)) {
  42556. p._setEndLocation(bodyElement, token);
  42557. }
  42558. }
  42559. } else {
  42560. tokenAfterBody(p, token);
  42561. }
  42562. }
  42563. function tokenAfterBody(p, token) {
  42564. p.insertionMode = InsertionMode.IN_BODY;
  42565. modeInBody(p, token);
  42566. }
  42567. function startTagInFrameset(p, token) {
  42568. switch (token.tagID) {
  42569. case TAG_ID.HTML: {
  42570. startTagInBody(p, token);
  42571. break;
  42572. }
  42573. case TAG_ID.FRAMESET: {
  42574. p._insertElement(token, NS.HTML);
  42575. break;
  42576. }
  42577. case TAG_ID.FRAME: {
  42578. p._appendElement(token, NS.HTML);
  42579. token.ackSelfClosing = true;
  42580. break;
  42581. }
  42582. case TAG_ID.NOFRAMES: {
  42583. startTagInHead(p, token);
  42584. break;
  42585. }
  42586. default:
  42587. }
  42588. }
  42589. function endTagInFrameset(p, token) {
  42590. if (token.tagID === TAG_ID.FRAMESET && !p.openElements.isRootHtmlElementCurrent()) {
  42591. p.openElements.pop();
  42592. if (!p.fragmentContext && p.openElements.currentTagId !== TAG_ID.FRAMESET) {
  42593. p.insertionMode = InsertionMode.AFTER_FRAMESET;
  42594. }
  42595. }
  42596. }
  42597. function startTagAfterFrameset(p, token) {
  42598. switch (token.tagID) {
  42599. case TAG_ID.HTML: {
  42600. startTagInBody(p, token);
  42601. break;
  42602. }
  42603. case TAG_ID.NOFRAMES: {
  42604. startTagInHead(p, token);
  42605. break;
  42606. }
  42607. default:
  42608. }
  42609. }
  42610. function endTagAfterFrameset(p, token) {
  42611. if (token.tagID === TAG_ID.HTML) {
  42612. p.insertionMode = InsertionMode.AFTER_AFTER_FRAMESET;
  42613. }
  42614. }
  42615. function startTagAfterAfterBody(p, token) {
  42616. if (token.tagID === TAG_ID.HTML) {
  42617. startTagInBody(p, token);
  42618. } else {
  42619. tokenAfterAfterBody(p, token);
  42620. }
  42621. }
  42622. function tokenAfterAfterBody(p, token) {
  42623. p.insertionMode = InsertionMode.IN_BODY;
  42624. modeInBody(p, token);
  42625. }
  42626. function startTagAfterAfterFrameset(p, token) {
  42627. switch (token.tagID) {
  42628. case TAG_ID.HTML: {
  42629. startTagInBody(p, token);
  42630. break;
  42631. }
  42632. case TAG_ID.NOFRAMES: {
  42633. startTagInHead(p, token);
  42634. break;
  42635. }
  42636. default:
  42637. }
  42638. }
  42639. function nullCharacterInForeignContent(p, token) {
  42640. token.chars = REPLACEMENT_CHARACTER;
  42641. p._insertCharacters(token);
  42642. }
  42643. function characterInForeignContent(p, token) {
  42644. p._insertCharacters(token);
  42645. p.framesetOk = false;
  42646. }
  42647. function popUntilHtmlOrIntegrationPoint(p) {
  42648. while (p.treeAdapter.getNamespaceURI(p.openElements.current) !== NS.HTML && !p._isIntegrationPoint(p.openElements.currentTagId, p.openElements.current)) {
  42649. p.openElements.pop();
  42650. }
  42651. }
  42652. function startTagInForeignContent(p, token) {
  42653. if (causesExit(token)) {
  42654. popUntilHtmlOrIntegrationPoint(p);
  42655. p._startTagOutsideForeignContent(token);
  42656. } else {
  42657. const current = p._getAdjustedCurrentElement();
  42658. const currentNs = p.treeAdapter.getNamespaceURI(current);
  42659. if (currentNs === NS.MATHML) {
  42660. adjustTokenMathMLAttrs(token);
  42661. } else if (currentNs === NS.SVG) {
  42662. adjustTokenSVGTagName(token);
  42663. adjustTokenSVGAttrs(token);
  42664. }
  42665. adjustTokenXMLAttrs(token);
  42666. if (token.selfClosing) {
  42667. p._appendElement(token, currentNs);
  42668. } else {
  42669. p._insertElement(token, currentNs);
  42670. }
  42671. token.ackSelfClosing = true;
  42672. }
  42673. }
  42674. function endTagInForeignContent(p, token) {
  42675. if (token.tagID === TAG_ID.P || token.tagID === TAG_ID.BR) {
  42676. popUntilHtmlOrIntegrationPoint(p);
  42677. p._endTagOutsideForeignContent(token);
  42678. return;
  42679. }
  42680. for (let i = p.openElements.stackTop; i > 0; i--) {
  42681. const element = p.openElements.items[i];
  42682. if (p.treeAdapter.getNamespaceURI(element) === NS.HTML) {
  42683. p._endTagOutsideForeignContent(token);
  42684. break;
  42685. }
  42686. const tagName = p.treeAdapter.getTagName(element);
  42687. if (tagName.toLowerCase() === token.tagName) {
  42688. token.tagName = tagName;
  42689. p.openElements.shortenToLength(i);
  42690. break;
  42691. }
  42692. }
  42693. }
  42694. // node_modules/entities/lib/esm/escape.js
  42695. var xmlCodeMap = /* @__PURE__ */ new Map([
  42696. [34, "&quot;"],
  42697. [38, "&amp;"],
  42698. [39, "&apos;"],
  42699. [60, "&lt;"],
  42700. [62, "&gt;"]
  42701. ]);
  42702. var getCodePoint = (
  42703. // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
  42704. String.prototype.codePointAt != null ? (str, index) => str.codePointAt(index) : (
  42705. // http://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae
  42706. (c, index) => (c.charCodeAt(index) & 64512) === 55296 ? (c.charCodeAt(index) - 55296) * 1024 + c.charCodeAt(index + 1) - 56320 + 65536 : c.charCodeAt(index)
  42707. )
  42708. );
  42709. function getEscaper(regex, map2) {
  42710. return function escape(data) {
  42711. let match;
  42712. let lastIdx = 0;
  42713. let result = "";
  42714. while (match = regex.exec(data)) {
  42715. if (lastIdx !== match.index) {
  42716. result += data.substring(lastIdx, match.index);
  42717. }
  42718. result += map2.get(match[0].charCodeAt(0));
  42719. lastIdx = match.index + 1;
  42720. }
  42721. return result + data.substring(lastIdx);
  42722. };
  42723. }
  42724. var escapeUTF8 = getEscaper(/[&<>'"]/g, xmlCodeMap);
  42725. var escapeAttribute = getEscaper(/["&\u00A0]/g, /* @__PURE__ */ new Map([
  42726. [34, "&quot;"],
  42727. [38, "&amp;"],
  42728. [160, "&nbsp;"]
  42729. ]));
  42730. var escapeText = getEscaper(/[&<>\u00A0]/g, /* @__PURE__ */ new Map([
  42731. [38, "&amp;"],
  42732. [60, "&lt;"],
  42733. [62, "&gt;"],
  42734. [160, "&nbsp;"]
  42735. ]));
  42736. // node_modules/parse5/dist/serializer/index.js
  42737. var VOID_ELEMENTS = /* @__PURE__ */ new Set([
  42738. TAG_NAMES.AREA,
  42739. TAG_NAMES.BASE,
  42740. TAG_NAMES.BASEFONT,
  42741. TAG_NAMES.BGSOUND,
  42742. TAG_NAMES.BR,
  42743. TAG_NAMES.COL,
  42744. TAG_NAMES.EMBED,
  42745. TAG_NAMES.FRAME,
  42746. TAG_NAMES.HR,
  42747. TAG_NAMES.IMG,
  42748. TAG_NAMES.INPUT,
  42749. TAG_NAMES.KEYGEN,
  42750. TAG_NAMES.LINK,
  42751. TAG_NAMES.META,
  42752. TAG_NAMES.PARAM,
  42753. TAG_NAMES.SOURCE,
  42754. TAG_NAMES.TRACK,
  42755. TAG_NAMES.WBR
  42756. ]);
  42757. // node_modules/parse5/dist/index.js
  42758. function parse(html, options) {
  42759. return Parser.parse(html, options);
  42760. }
  42761. function parseFragment(fragmentContext, html, options) {
  42762. if (typeof fragmentContext === "string") {
  42763. options = html;
  42764. html = fragmentContext;
  42765. fragmentContext = null;
  42766. }
  42767. const parser = Parser.getFragmentParser(fragmentContext, options);
  42768. parser.tokenizer.write(html, true);
  42769. return parser.getFragment();
  42770. }
  42771. // src/mock-doc/parse-util.ts
  42772. var docParser = /* @__PURE__ */ new WeakMap();
  42773. function parseDocumentUtil(ownerDocument, html) {
  42774. const doc = parse(html.trim(), getParser(ownerDocument));
  42775. doc.documentElement = doc.firstElementChild;
  42776. doc.head = doc.documentElement.firstElementChild;
  42777. doc.body = doc.head.nextElementSibling;
  42778. return doc;
  42779. }
  42780. function parseFragmentUtil(ownerDocument, html) {
  42781. if (typeof html === "string") {
  42782. html = html.trim();
  42783. } else {
  42784. html = "";
  42785. }
  42786. const frag = parseFragment(html, getParser(ownerDocument));
  42787. return frag;
  42788. }
  42789. function getParser(ownerDocument) {
  42790. let parseOptions = docParser.get(ownerDocument);
  42791. if (parseOptions != null) {
  42792. return parseOptions;
  42793. }
  42794. const treeAdapter = {
  42795. createDocument() {
  42796. const doc = ownerDocument.createElement("#document" /* DOCUMENT_NODE */);
  42797. doc["x-mode"] = "no-quirks";
  42798. return doc;
  42799. },
  42800. setNodeSourceCodeLocation(node, location2) {
  42801. node.sourceCodeLocation = location2;
  42802. },
  42803. getNodeSourceCodeLocation(node) {
  42804. return node.sourceCodeLocation;
  42805. },
  42806. createDocumentFragment() {
  42807. return ownerDocument.createDocumentFragment();
  42808. },
  42809. createElement(tagName, namespaceURI, attrs) {
  42810. const elm = ownerDocument.createElementNS(namespaceURI, tagName);
  42811. for (let i = 0; i < attrs.length; i++) {
  42812. const attr = attrs[i];
  42813. if (attr.namespace == null || attr.namespace === "http://www.w3.org/1999/xhtml") {
  42814. elm.setAttribute(attr.name, attr.value);
  42815. } else {
  42816. elm.setAttributeNS(attr.namespace, attr.name, attr.value);
  42817. }
  42818. }
  42819. return elm;
  42820. },
  42821. createCommentNode(data) {
  42822. return ownerDocument.createComment(data);
  42823. },
  42824. appendChild(parentNode, newNode) {
  42825. parentNode.appendChild(newNode);
  42826. },
  42827. insertBefore(parentNode, newNode, referenceNode) {
  42828. parentNode.insertBefore(newNode, referenceNode);
  42829. },
  42830. setTemplateContent(templateElement, contentElement) {
  42831. templateElement.content = contentElement;
  42832. },
  42833. getTemplateContent(templateElement) {
  42834. return templateElement.content;
  42835. },
  42836. setDocumentType(doc, name, publicId, systemId) {
  42837. let doctypeNode = doc.childNodes.find((n) => n.nodeType === 10 /* DOCUMENT_TYPE_NODE */);
  42838. if (doctypeNode == null) {
  42839. doctypeNode = ownerDocument.createDocumentTypeNode();
  42840. doc.insertBefore(doctypeNode, doc.firstChild);
  42841. }
  42842. doctypeNode.nodeValue = "!DOCTYPE";
  42843. doctypeNode["x-name"] = name;
  42844. doctypeNode["x-publicId"] = publicId;
  42845. doctypeNode["x-systemId"] = systemId;
  42846. },
  42847. setDocumentMode(doc, mode) {
  42848. doc["x-mode"] = mode;
  42849. },
  42850. getDocumentMode(doc) {
  42851. return doc["x-mode"];
  42852. },
  42853. detachNode(node) {
  42854. node.remove();
  42855. },
  42856. insertText(parentNode, text) {
  42857. const lastChild = parentNode.lastChild;
  42858. if (lastChild != null && lastChild.nodeType === 3 /* TEXT_NODE */) {
  42859. lastChild.nodeValue += text;
  42860. } else {
  42861. parentNode.appendChild(ownerDocument.createTextNode(text));
  42862. }
  42863. },
  42864. insertTextBefore(parentNode, text, referenceNode) {
  42865. const prevNode = parentNode.childNodes[parentNode.childNodes.indexOf(referenceNode) - 1];
  42866. if (prevNode != null && prevNode.nodeType === 3 /* TEXT_NODE */) {
  42867. prevNode.nodeValue += text;
  42868. } else {
  42869. parentNode.insertBefore(ownerDocument.createTextNode(text), referenceNode);
  42870. }
  42871. },
  42872. adoptAttributes(recipient, attrs) {
  42873. for (let i = 0; i < attrs.length; i++) {
  42874. const attr = attrs[i];
  42875. if (recipient.hasAttributeNS(attr.namespace, attr.name) === false) {
  42876. recipient.setAttributeNS(attr.namespace, attr.name, attr.value);
  42877. }
  42878. }
  42879. },
  42880. getFirstChild(node) {
  42881. return node.childNodes[0];
  42882. },
  42883. getChildNodes(node) {
  42884. return node.childNodes;
  42885. },
  42886. getParentNode(node) {
  42887. return node.parentNode;
  42888. },
  42889. getAttrList(element) {
  42890. const attrs = element.attributes.__items.map((attr) => {
  42891. return {
  42892. name: attr.name,
  42893. value: attr.value,
  42894. namespace: attr.namespaceURI,
  42895. prefix: null
  42896. };
  42897. });
  42898. return attrs;
  42899. },
  42900. getTagName(element) {
  42901. if (element.namespaceURI === "http://www.w3.org/1999/xhtml") {
  42902. return element.nodeName.toLowerCase();
  42903. } else {
  42904. return element.nodeName;
  42905. }
  42906. },
  42907. getNamespaceURI(element) {
  42908. return element.namespaceURI;
  42909. },
  42910. getTextNodeContent(textNode) {
  42911. return textNode.nodeValue;
  42912. },
  42913. getCommentNodeContent(commentNode) {
  42914. return commentNode.nodeValue;
  42915. },
  42916. getDocumentTypeNodeName(doctypeNode) {
  42917. return doctypeNode["x-name"];
  42918. },
  42919. getDocumentTypeNodePublicId(doctypeNode) {
  42920. return doctypeNode["x-publicId"];
  42921. },
  42922. getDocumentTypeNodeSystemId(doctypeNode) {
  42923. return doctypeNode["x-systemId"];
  42924. },
  42925. // @ts-ignore - a `MockNode` will never be assignable to a `TreeAdapterTypeMap['text']`. As a result, we cannot
  42926. // complete this function signature
  42927. isTextNode(node) {
  42928. return node.nodeType === 3 /* TEXT_NODE */;
  42929. },
  42930. // @ts-ignore - a `MockNode` will never be assignable to a `TreeAdapterTypeMap['comment']`. As a result, we cannot
  42931. // complete this function signature (which requires its return type to be a type predicate)
  42932. isCommentNode(node) {
  42933. return node.nodeType === 8 /* COMMENT_NODE */;
  42934. },
  42935. // @ts-ignore - a `MockNode` will never be assignable to a `TreeAdapterTypeMap['document']`. As a result, we cannot
  42936. // complete this function signature (which requires its return type to be a type predicate)
  42937. isDocumentTypeNode(node) {
  42938. return node.nodeType === 10 /* DOCUMENT_TYPE_NODE */;
  42939. },
  42940. // @ts-ignore - a `MockNode` will never be assignable to a `TreeAdapterTypeMap['element']`. As a result, we cannot
  42941. // complete this function signature (which requires its return type to be a type predicate)
  42942. isElementNode(node) {
  42943. return node.nodeType === 1 /* ELEMENT_NODE */;
  42944. }
  42945. };
  42946. parseOptions = {
  42947. treeAdapter
  42948. };
  42949. docParser.set(ownerDocument, parseOptions);
  42950. return parseOptions;
  42951. }
  42952. // src/mock-doc/third-party/jquery.ts
  42953. var jquery_default = (
  42954. /*!
  42955. * jQuery JavaScript Library v4.0.0-pre+9352011a7.dirty +selector
  42956. * https://jquery.com/
  42957. *
  42958. * Copyright OpenJS Foundation and other contributors
  42959. * Released under the MIT license
  42960. * https://jquery.org/license
  42961. *
  42962. * Date: 2023-12-11T17:55Z
  42963. */
  42964. function(global2, factory) {
  42965. "use strict";
  42966. if (true) {
  42967. return factory(global2, true);
  42968. } else {
  42969. factory(global2);
  42970. }
  42971. }({
  42972. document: {
  42973. createElement() {
  42974. return {};
  42975. },
  42976. nodeType: 9,
  42977. documentElement: {
  42978. nodeType: 1,
  42979. nodeName: "HTML"
  42980. }
  42981. }
  42982. }, function(window, noGlobal) {
  42983. "use strict";
  42984. if (!window.document) {
  42985. throw new Error("jQuery requires a window with a document");
  42986. }
  42987. var arr = [];
  42988. var getProto = Object.getPrototypeOf;
  42989. var slice = arr.slice;
  42990. var flat = arr.flat ? function(array) {
  42991. return arr.flat.call(array);
  42992. } : function(array) {
  42993. return arr.concat.apply([], array);
  42994. };
  42995. var push = arr.push;
  42996. var indexOf = arr.indexOf;
  42997. var class2type = {};
  42998. var toString = class2type.toString;
  42999. var hasOwn = class2type.hasOwnProperty;
  43000. var fnToString = hasOwn.toString;
  43001. var ObjectFunctionString = fnToString.call(Object);
  43002. var support = {};
  43003. function toType(obj) {
  43004. if (obj == null) {
  43005. return obj + "";
  43006. }
  43007. return typeof obj === "object" ? class2type[toString.call(obj)] || "object" : typeof obj;
  43008. }
  43009. function isWindow(obj) {
  43010. return obj != null && obj === obj.window;
  43011. }
  43012. function isArrayLike(obj) {
  43013. var length = !!obj && obj.length, type = toType(obj);
  43014. if (typeof obj === "function" || isWindow(obj)) {
  43015. return false;
  43016. }
  43017. return type === "array" || length === 0 || typeof length === "number" && length > 0 && length - 1 in obj;
  43018. }
  43019. var document = window.document;
  43020. var preservedScriptAttributes = {
  43021. type: true,
  43022. src: true,
  43023. nonce: true,
  43024. noModule: true
  43025. };
  43026. function DOMEval(code, node, doc) {
  43027. doc = doc || document;
  43028. var i2, script = doc.createElement("script");
  43029. script.text = code;
  43030. if (node) {
  43031. for (i2 in preservedScriptAttributes) {
  43032. if (node[i2]) {
  43033. script[i2] = node[i2];
  43034. }
  43035. }
  43036. }
  43037. doc.head.appendChild(script).parentNode.removeChild(script);
  43038. }
  43039. const jQuery = {};
  43040. var version = "4.0.0-pre+9352011a7.dirty +selector", rhtmlSuffix = /HTML$/i, jQueryOrig = function(selector, context) {
  43041. return new jQuery.fn.init(selector, context);
  43042. };
  43043. jQuery.fn = jQuery.prototype = {
  43044. // The current version of jQuery being used
  43045. jquery: version,
  43046. constructor: jQuery,
  43047. // The default length of a jQuery object is 0
  43048. length: 0,
  43049. toArray: function() {
  43050. return slice.call(this);
  43051. },
  43052. // Get the Nth element in the matched element set OR
  43053. // Get the whole matched element set as a clean array
  43054. get: function(num) {
  43055. if (num == null) {
  43056. return slice.call(this);
  43057. }
  43058. return num < 0 ? this[num + this.length] : this[num];
  43059. },
  43060. // Take an array of elements and push it onto the stack
  43061. // (returning the new matched element set)
  43062. pushStack: function(elems) {
  43063. var ret = jQuery.merge(this.constructor(), elems);
  43064. ret.prevObject = this;
  43065. return ret;
  43066. },
  43067. // Execute a callback for every element in the matched set.
  43068. each: function(callback) {
  43069. return jQuery.each(this, callback);
  43070. },
  43071. map: function(callback) {
  43072. return this.pushStack(jQuery.map(this, function(elem, i2) {
  43073. return callback.call(elem, i2, elem);
  43074. }));
  43075. },
  43076. slice: function() {
  43077. return this.pushStack(slice.apply(this, arguments));
  43078. },
  43079. first: function() {
  43080. return this.eq(0);
  43081. },
  43082. last: function() {
  43083. return this.eq(-1);
  43084. },
  43085. even: function() {
  43086. return this.pushStack(jQuery.grep(this, function(_elem, i2) {
  43087. return (i2 + 1) % 2;
  43088. }));
  43089. },
  43090. odd: function() {
  43091. return this.pushStack(jQuery.grep(this, function(_elem, i2) {
  43092. return i2 % 2;
  43093. }));
  43094. },
  43095. eq: function(i2) {
  43096. var len = this.length, j = +i2 + (i2 < 0 ? len : 0);
  43097. return this.pushStack(j >= 0 && j < len ? [this[j]] : []);
  43098. },
  43099. end: function() {
  43100. return this.prevObject || this.constructor();
  43101. }
  43102. };
  43103. jQuery.extend = jQuery.fn.extend = function() {
  43104. var options, name, src, copy, copyIsArray, clone, target = arguments[0] || {}, i2 = 1, length = arguments.length, deep = false;
  43105. if (typeof target === "boolean") {
  43106. deep = target;
  43107. target = arguments[i2] || {};
  43108. i2++;
  43109. }
  43110. if (typeof target !== "object" && typeof target !== "function") {
  43111. target = {};
  43112. }
  43113. if (i2 === length) {
  43114. target = this;
  43115. i2--;
  43116. }
  43117. for (; i2 < length; i2++) {
  43118. if ((options = arguments[i2]) != null) {
  43119. for (name in options) {
  43120. copy = options[name];
  43121. if (name === "__proto__" || target === copy) {
  43122. continue;
  43123. }
  43124. if (deep && copy && (jQuery.isPlainObject(copy) || (copyIsArray = Array.isArray(copy)))) {
  43125. src = target[name];
  43126. if (copyIsArray && !Array.isArray(src)) {
  43127. clone = [];
  43128. } else if (!copyIsArray && !jQuery.isPlainObject(src)) {
  43129. clone = {};
  43130. } else {
  43131. clone = src;
  43132. }
  43133. copyIsArray = false;
  43134. target[name] = jQuery.extend(deep, clone, copy);
  43135. } else if (copy !== void 0) {
  43136. target[name] = copy;
  43137. }
  43138. }
  43139. }
  43140. }
  43141. return target;
  43142. };
  43143. jQuery.extend({
  43144. // Unique for each copy of jQuery on the page
  43145. expando: "jQuery" + (version + Math.random()).replace(/\D/g, ""),
  43146. // Assume jQuery is ready without the ready module
  43147. isReady: true,
  43148. error: function(msg) {
  43149. throw new Error(msg);
  43150. },
  43151. noop: function() {
  43152. },
  43153. isPlainObject: function(obj) {
  43154. var proto, Ctor;
  43155. if (!obj || toString.call(obj) !== "[object Object]") {
  43156. return false;
  43157. }
  43158. proto = getProto(obj);
  43159. if (!proto) {
  43160. return true;
  43161. }
  43162. Ctor = hasOwn.call(proto, "constructor") && proto.constructor;
  43163. return typeof Ctor === "function" && fnToString.call(Ctor) === ObjectFunctionString;
  43164. },
  43165. isEmptyObject: function(obj) {
  43166. var name;
  43167. for (name in obj) {
  43168. return false;
  43169. }
  43170. return true;
  43171. },
  43172. // Evaluates a script in a provided context; falls back to the global one
  43173. // if not specified.
  43174. globalEval: function(code, options, doc) {
  43175. DOMEval(code, { nonce: options && options.nonce }, doc);
  43176. },
  43177. each: function(obj, callback) {
  43178. var length, i2 = 0;
  43179. if (isArrayLike(obj)) {
  43180. length = obj.length;
  43181. for (; i2 < length; i2++) {
  43182. if (callback.call(obj[i2], i2, obj[i2]) === false) {
  43183. break;
  43184. }
  43185. }
  43186. } else {
  43187. for (i2 in obj) {
  43188. if (callback.call(obj[i2], i2, obj[i2]) === false) {
  43189. break;
  43190. }
  43191. }
  43192. }
  43193. return obj;
  43194. },
  43195. // Retrieve the text value of an array of DOM nodes
  43196. text: function(elem) {
  43197. var node, ret = "", i2 = 0, nodeType = elem.nodeType;
  43198. if (!nodeType) {
  43199. while (node = elem[i2++]) {
  43200. ret += jQuery.text(node);
  43201. }
  43202. }
  43203. if (nodeType === 1 || nodeType === 11) {
  43204. return elem.textContent;
  43205. }
  43206. if (nodeType === 9) {
  43207. return elem.documentElement.textContent;
  43208. }
  43209. if (nodeType === 3 || nodeType === 4) {
  43210. return elem.nodeValue;
  43211. }
  43212. return ret;
  43213. },
  43214. // results is for internal usage only
  43215. makeArray: function(arr2, results) {
  43216. var ret = results || [];
  43217. if (arr2 != null) {
  43218. if (isArrayLike(Object(arr2))) {
  43219. jQuery.merge(
  43220. ret,
  43221. typeof arr2 === "string" ? [arr2] : arr2
  43222. );
  43223. } else {
  43224. push.call(ret, arr2);
  43225. }
  43226. }
  43227. return ret;
  43228. },
  43229. inArray: function(elem, arr2, i2) {
  43230. return arr2 == null ? -1 : indexOf.call(arr2, elem, i2);
  43231. },
  43232. isXMLDoc: function(elem) {
  43233. var namespace = elem && elem.namespaceURI, docElem = elem && (elem.ownerDocument || elem).documentElement;
  43234. return !rhtmlSuffix.test(namespace || docElem && docElem.nodeName || "HTML");
  43235. },
  43236. // Note: an element does not contain itself
  43237. contains: function(a, b) {
  43238. var bup = b && b.parentNode;
  43239. return a === bup || !!(bup && bup.nodeType === 1 && // Support: IE 9 - 11+
  43240. // IE doesn't have `contains` on SVG.
  43241. (a.contains ? a.contains(bup) : a.compareDocumentPosition && a.compareDocumentPosition(bup) & 16));
  43242. },
  43243. merge: function(first, second) {
  43244. var len = +second.length, j = 0, i2 = first.length;
  43245. for (; j < len; j++) {
  43246. first[i2++] = second[j];
  43247. }
  43248. first.length = i2;
  43249. return first;
  43250. },
  43251. grep: function(elems, callback, invert) {
  43252. var callbackInverse, matches3 = [], i2 = 0, length = elems.length, callbackExpect = !invert;
  43253. for (; i2 < length; i2++) {
  43254. callbackInverse = !callback(elems[i2], i2);
  43255. if (callbackInverse !== callbackExpect) {
  43256. matches3.push(elems[i2]);
  43257. }
  43258. }
  43259. return matches3;
  43260. },
  43261. // arg is for internal usage only
  43262. map: function(elems, callback, arg) {
  43263. var length, value, i2 = 0, ret = [];
  43264. if (isArrayLike(elems)) {
  43265. length = elems.length;
  43266. for (; i2 < length; i2++) {
  43267. value = callback(elems[i2], i2, arg);
  43268. if (value != null) {
  43269. ret.push(value);
  43270. }
  43271. }
  43272. } else {
  43273. for (i2 in elems) {
  43274. value = callback(elems[i2], i2, arg);
  43275. if (value != null) {
  43276. ret.push(value);
  43277. }
  43278. }
  43279. }
  43280. return flat(ret);
  43281. },
  43282. // A global GUID counter for objects
  43283. guid: 1,
  43284. // jQuery.support is not used in Core but other projects attach their
  43285. // properties to it so it needs to exist.
  43286. support
  43287. });
  43288. if (typeof Symbol === "function") {
  43289. jQuery.fn[Symbol.iterator] = arr[Symbol.iterator];
  43290. }
  43291. jQuery.each(
  43292. "Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),
  43293. function(_i, name) {
  43294. class2type["[object " + name + "]"] = name.toLowerCase();
  43295. }
  43296. );
  43297. function nodeName(elem, name) {
  43298. return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
  43299. }
  43300. var pop = arr.pop;
  43301. var whitespace = "[\\x20\\t\\r\\n\\f]";
  43302. var isIE = document.documentMode;
  43303. try {
  43304. document.querySelector(":has(*,:jqfake)");
  43305. support.cssHas = false;
  43306. } catch (e) {
  43307. support.cssHas = true;
  43308. }
  43309. var rbuggyQSA = [];
  43310. if (isIE) {
  43311. rbuggyQSA.push(
  43312. // Support: IE 9 - 11+
  43313. // IE's :disabled selector does not pick up the children of disabled fieldsets
  43314. ":enabled",
  43315. ":disabled",
  43316. // Support: IE 11+
  43317. // IE 11 doesn't find elements on a `[name='']` query in some cases.
  43318. // Adding a temporary attribute to the document before the selection works
  43319. // around the issue.
  43320. "\\[" + whitespace + "*name" + whitespace + "*=" + whitespace + `*(?:''|"")`
  43321. );
  43322. }
  43323. if (!support.cssHas) {
  43324. rbuggyQSA.push(":has");
  43325. }
  43326. rbuggyQSA = rbuggyQSA.length && new RegExp(rbuggyQSA.join("|"));
  43327. var rtrimCSS = new RegExp(
  43328. "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$",
  43329. "g"
  43330. );
  43331. var identifier = "(?:\\\\[\\da-fA-F]{1,6}" + whitespace + "?|\\\\[^\\r\\n\\f]|[\\w-]|[^\0-\\x7f])+";
  43332. var booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped";
  43333. var rleadingCombinator = new RegExp("^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*");
  43334. var rdescend = new RegExp(whitespace + "|>");
  43335. var rsibling = /[+~]/;
  43336. var documentElement = document.documentElement;
  43337. var matches2 = documentElement.matches || documentElement.msMatchesSelector;
  43338. function createCache() {
  43339. var keys = [];
  43340. function cache(key, value) {
  43341. if (keys.push(key + " ") > jQuery.expr.cacheLength) {
  43342. delete cache[keys.shift()];
  43343. }
  43344. return cache[key + " "] = value;
  43345. }
  43346. return cache;
  43347. }
  43348. function testContext(context) {
  43349. return context && typeof context.getElementsByTagName !== "undefined" && context;
  43350. }
  43351. var attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace + // Operator (capture 2)
  43352. "*([*^$|!~]?=)" + whitespace + // "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]"
  43353. `*(?:'((?:\\\\.|[^\\\\'])*)'|"((?:\\\\.|[^\\\\"])*)"|(` + identifier + "))|)" + whitespace + "*\\]";
  43354. var pseudos = ":(" + identifier + `)(?:\\((('((?:\\\\.|[^\\\\'])*)'|"((?:\\\\.|[^\\\\"])*)")|((?:\\\\.|[^\\\\()[\\]]|` + attributes + ")*)|.*)\\)|)";
  43355. var filterMatchExpr = {
  43356. ID: new RegExp("^#(" + identifier + ")"),
  43357. CLASS: new RegExp("^\\.(" + identifier + ")"),
  43358. TAG: new RegExp("^(" + identifier + "|[*])"),
  43359. ATTR: new RegExp("^" + attributes),
  43360. PSEUDO: new RegExp("^" + pseudos),
  43361. CHILD: new RegExp(
  43362. "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace + "*(\\d+)|))" + whitespace + "*\\)|)",
  43363. "i"
  43364. )
  43365. };
  43366. var rpseudo = new RegExp(pseudos);
  43367. var runescape = new RegExp("\\\\[\\da-fA-F]{1,6}" + whitespace + "?|\\\\([^\\r\\n\\f])", "g"), funescape = function(escape, nonHex) {
  43368. var high = "0x" + escape.slice(1) - 65536;
  43369. if (nonHex) {
  43370. return nonHex;
  43371. }
  43372. return high < 0 ? String.fromCharCode(high + 65536) : String.fromCharCode(high >> 10 | 55296, high & 1023 | 56320);
  43373. };
  43374. function unescapeSelector(sel) {
  43375. return sel.replace(runescape, funescape);
  43376. }
  43377. function selectorError(msg) {
  43378. jQuery.error("Syntax error, unrecognized expression: " + msg);
  43379. }
  43380. var rcomma = new RegExp("^" + whitespace + "*," + whitespace + "*");
  43381. var tokenCache = createCache();
  43382. function tokenize(selector, parseOnly) {
  43383. var matched, match, tokens, type, soFar, groups, preFilters, cached = tokenCache[selector + " "];
  43384. if (cached) {
  43385. return parseOnly ? 0 : cached.slice(0);
  43386. }
  43387. soFar = selector;
  43388. groups = [];
  43389. preFilters = jQuery.expr.preFilter;
  43390. while (soFar) {
  43391. if (!matched || (match = rcomma.exec(soFar))) {
  43392. if (match) {
  43393. soFar = soFar.slice(match[0].length) || soFar;
  43394. }
  43395. groups.push(tokens = []);
  43396. }
  43397. matched = false;
  43398. if (match = rleadingCombinator.exec(soFar)) {
  43399. matched = match.shift();
  43400. tokens.push({
  43401. value: matched,
  43402. // Cast descendant combinators to space
  43403. type: match[0].replace(rtrimCSS, " ")
  43404. });
  43405. soFar = soFar.slice(matched.length);
  43406. }
  43407. for (type in filterMatchExpr) {
  43408. if ((match = jQuery.expr.match[type].exec(soFar)) && (!preFilters[type] || (match = preFilters[type](match)))) {
  43409. matched = match.shift();
  43410. tokens.push({
  43411. value: matched,
  43412. type,
  43413. matches: match
  43414. });
  43415. soFar = soFar.slice(matched.length);
  43416. }
  43417. }
  43418. if (!matched) {
  43419. break;
  43420. }
  43421. }
  43422. if (parseOnly) {
  43423. return soFar.length;
  43424. }
  43425. return soFar ? selectorError(selector) : (
  43426. // Cache the tokens
  43427. tokenCache(selector, groups).slice(0)
  43428. );
  43429. }
  43430. var preFilter = {
  43431. ATTR: function(match) {
  43432. match[1] = unescapeSelector(match[1]);
  43433. match[3] = unescapeSelector(match[3] || match[4] || match[5] || "");
  43434. if (match[2] === "~=") {
  43435. match[3] = " " + match[3] + " ";
  43436. }
  43437. return match.slice(0, 4);
  43438. },
  43439. CHILD: function(match) {
  43440. match[1] = match[1].toLowerCase();
  43441. if (match[1].slice(0, 3) === "nth") {
  43442. if (!match[3]) {
  43443. selectorError(match[0]);
  43444. }
  43445. match[4] = +(match[4] ? match[5] + (match[6] || 1) : 2 * (match[3] === "even" || match[3] === "odd"));
  43446. match[5] = +(match[7] + match[8] || match[3] === "odd");
  43447. } else if (match[3]) {
  43448. selectorError(match[0]);
  43449. }
  43450. return match;
  43451. },
  43452. PSEUDO: function(match) {
  43453. var excess, unquoted = !match[6] && match[2];
  43454. if (filterMatchExpr.CHILD.test(match[0])) {
  43455. return null;
  43456. }
  43457. if (match[3]) {
  43458. match[2] = match[4] || match[5] || "";
  43459. } else if (unquoted && rpseudo.test(unquoted) && // Get excess from tokenize (recursively)
  43460. (excess = tokenize(unquoted, true)) && // advance to the next closing parenthesis
  43461. (excess = unquoted.indexOf(")", unquoted.length - excess) - unquoted.length)) {
  43462. match[0] = match[0].slice(0, excess);
  43463. match[2] = unquoted.slice(0, excess);
  43464. }
  43465. return match.slice(0, 3);
  43466. }
  43467. };
  43468. function toSelector(tokens) {
  43469. var i2 = 0, len = tokens.length, selector = "";
  43470. for (; i2 < len; i2++) {
  43471. selector += tokens[i2].value;
  43472. }
  43473. return selector;
  43474. }
  43475. var rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\x80-\uFFFF\w-]/g;
  43476. function fcssescape(ch, asCodePoint) {
  43477. if (asCodePoint) {
  43478. if (ch === "\0") {
  43479. return "\uFFFD";
  43480. }
  43481. return ch.slice(0, -1) + "\\" + ch.charCodeAt(ch.length - 1).toString(16) + " ";
  43482. }
  43483. return "\\" + ch;
  43484. }
  43485. jQuery.escapeSelector = function(sel) {
  43486. return (sel + "").replace(rcssescape, fcssescape);
  43487. };
  43488. var sort = arr.sort;
  43489. var splice = arr.splice;
  43490. var hasDuplicate;
  43491. function sortOrder(a, b) {
  43492. if (a === b) {
  43493. hasDuplicate = true;
  43494. return 0;
  43495. }
  43496. var compare = !a.compareDocumentPosition - !b.compareDocumentPosition;
  43497. if (compare) {
  43498. return compare;
  43499. }
  43500. compare = (a.ownerDocument || a) == (b.ownerDocument || b) ? a.compareDocumentPosition(b) : (
  43501. // Otherwise we know they are disconnected
  43502. 1
  43503. );
  43504. if (compare & 1) {
  43505. if (a == document || a.ownerDocument == document && jQuery.contains(document, a)) {
  43506. return -1;
  43507. }
  43508. if (b == document || b.ownerDocument == document && jQuery.contains(document, b)) {
  43509. return 1;
  43510. }
  43511. return 0;
  43512. }
  43513. return compare & 4 ? -1 : 1;
  43514. }
  43515. jQuery.uniqueSort = function(results) {
  43516. var elem, duplicates = [], j = 0, i2 = 0;
  43517. hasDuplicate = false;
  43518. sort.call(results, sortOrder);
  43519. if (hasDuplicate) {
  43520. while (elem = results[i2++]) {
  43521. if (elem === results[i2]) {
  43522. j = duplicates.push(i2);
  43523. }
  43524. }
  43525. while (j--) {
  43526. splice.call(results, duplicates[j], 1);
  43527. }
  43528. }
  43529. return results;
  43530. };
  43531. jQuery.fn.uniqueSort = function() {
  43532. return this.pushStack(jQuery.uniqueSort(slice.apply(this)));
  43533. };
  43534. 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({
  43535. bool: new RegExp("^(?:" + booleans + ")$", "i"),
  43536. // For use in libraries implementing .is()
  43537. // We use this for POS matching in `select`
  43538. needsContext: new RegExp("^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i")
  43539. }, filterMatchExpr), rinputs = /^(?:input|select|textarea|button)$/i, rheader = /^h\d$/i, rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, unloadHandler = function() {
  43540. setDocument();
  43541. }, inDisabledFieldset = addCombinator(
  43542. function(elem) {
  43543. return elem.disabled === true && nodeName(elem, "fieldset");
  43544. },
  43545. { dir: "parentNode", next: "legend" }
  43546. );
  43547. function find(selector, context, results, seed) {
  43548. var m, i2, elem, nid, match, groups, newSelector, newContext = context && context.ownerDocument, nodeType = context ? context.nodeType : 9;
  43549. results = results || [];
  43550. if (typeof selector !== "string" || !selector || nodeType !== 1 && nodeType !== 9 && nodeType !== 11) {
  43551. return results;
  43552. }
  43553. if (false) {
  43554. setDocument(context);
  43555. context = context || document$1;
  43556. if (documentIsHTML) {
  43557. if (nodeType !== 11 && (match = rquickExpr.exec(selector))) {
  43558. if (m = match[1]) {
  43559. if (nodeType === 9) {
  43560. if (elem = context.getElementById(m)) {
  43561. push.call(results, elem);
  43562. }
  43563. return results;
  43564. } else {
  43565. if (newContext && (elem = newContext.getElementById(m)) && jQuery.contains(context, elem)) {
  43566. push.call(results, elem);
  43567. return results;
  43568. }
  43569. }
  43570. } else if (match[2]) {
  43571. push.apply(results, context.getElementsByTagName(selector));
  43572. return results;
  43573. } else if ((m = match[3]) && context.getElementsByClassName) {
  43574. push.apply(results, context.getElementsByClassName(m));
  43575. return results;
  43576. }
  43577. }
  43578. if (!nonnativeSelectorCache[selector + " "] && (!rbuggyQSA || !rbuggyQSA.test(selector))) {
  43579. newSelector = selector;
  43580. newContext = context;
  43581. if (nodeType === 1 && (rdescend.test(selector) || rleadingCombinator.test(selector))) {
  43582. newContext = rsibling.test(selector) && testContext(context.parentNode) || context;
  43583. if (newContext != context || isIE) {
  43584. if (nid = context.getAttribute("id")) {
  43585. nid = jQuery.escapeSelector(nid);
  43586. } else {
  43587. context.setAttribute("id", nid = jQuery.expando);
  43588. }
  43589. }
  43590. groups = tokenize(selector);
  43591. i2 = groups.length;
  43592. while (i2--) {
  43593. groups[i2] = (nid ? "#" + nid : ":scope") + " " + toSelector(groups[i2]);
  43594. }
  43595. newSelector = groups.join(",");
  43596. }
  43597. try {
  43598. push.apply(
  43599. results,
  43600. newContext.querySelectorAll(newSelector)
  43601. );
  43602. return results;
  43603. } catch (qsaError) {
  43604. nonnativeSelectorCache(selector, true);
  43605. } finally {
  43606. if (nid === jQuery.expando) {
  43607. context.removeAttribute("id");
  43608. }
  43609. }
  43610. }
  43611. }
  43612. }
  43613. return select(selector.replace(rtrimCSS, "$1"), context, results, seed);
  43614. }
  43615. function markFunction(fn) {
  43616. fn[jQuery.expando] = true;
  43617. return fn;
  43618. }
  43619. function createInputPseudo(type) {
  43620. return function(elem) {
  43621. return nodeName(elem, "input") && elem.type === type;
  43622. };
  43623. }
  43624. function createButtonPseudo(type) {
  43625. return function(elem) {
  43626. return (nodeName(elem, "input") || nodeName(elem, "button")) && elem.type === type;
  43627. };
  43628. }
  43629. function createDisabledPseudo(disabled) {
  43630. return function(elem) {
  43631. if ("form" in elem) {
  43632. if (elem.parentNode && elem.disabled === false) {
  43633. if ("label" in elem) {
  43634. if ("label" in elem.parentNode) {
  43635. return elem.parentNode.disabled === disabled;
  43636. } else {
  43637. return elem.disabled === disabled;
  43638. }
  43639. }
  43640. return elem.isDisabled === disabled || // Where there is no isDisabled, check manually
  43641. elem.isDisabled !== !disabled && inDisabledFieldset(elem) === disabled;
  43642. }
  43643. return elem.disabled === disabled;
  43644. } else if ("label" in elem) {
  43645. return elem.disabled === disabled;
  43646. }
  43647. return false;
  43648. };
  43649. }
  43650. function createPositionalPseudo(fn) {
  43651. return markFunction(function(argument) {
  43652. argument = +argument;
  43653. return markFunction(function(seed, matches3) {
  43654. var j, matchIndexes = fn([], seed.length, argument), i2 = matchIndexes.length;
  43655. while (i2--) {
  43656. if (seed[j = matchIndexes[i2]]) {
  43657. seed[j] = !(matches3[j] = seed[j]);
  43658. }
  43659. }
  43660. });
  43661. });
  43662. }
  43663. function setDocument(node) {
  43664. var subWindow, doc = node ? node.ownerDocument || node : document;
  43665. if (doc == document$1 || doc.nodeType !== 9) {
  43666. return;
  43667. }
  43668. document$1 = doc;
  43669. documentElement$1 = document$1.documentElement;
  43670. documentIsHTML = !jQuery.isXMLDoc(document$1);
  43671. if (isIE && document != document$1 && (subWindow = document$1.defaultView) && subWindow.top !== subWindow) {
  43672. subWindow.addEventListener("unload", unloadHandler);
  43673. }
  43674. }
  43675. find.matches = function(expr, elements) {
  43676. return find(expr, null, null, elements);
  43677. };
  43678. find.matchesSelector = function(elem, expr) {
  43679. setDocument(elem);
  43680. if (documentIsHTML && !nonnativeSelectorCache[expr + " "] && (!rbuggyQSA || !rbuggyQSA.test(expr))) {
  43681. try {
  43682. return matches2.call(elem, expr);
  43683. } catch (e) {
  43684. nonnativeSelectorCache(expr, true);
  43685. }
  43686. }
  43687. return find(expr, document$1, null, [elem]).length > 0;
  43688. };
  43689. jQuery.expr = {
  43690. // Can be adjusted by the user
  43691. cacheLength: 50,
  43692. createPseudo: markFunction,
  43693. match: matchExpr,
  43694. find: {
  43695. ID: function(id, context) {
  43696. if (typeof context.getElementById !== "undefined" && documentIsHTML) {
  43697. var elem = context.getElementById(id);
  43698. return elem ? [elem] : [];
  43699. }
  43700. },
  43701. TAG: function(tag, context) {
  43702. if (typeof context.getElementsByTagName !== "undefined") {
  43703. return context.getElementsByTagName(tag);
  43704. } else {
  43705. return context.querySelectorAll(tag);
  43706. }
  43707. },
  43708. CLASS: function(className, context) {
  43709. if (typeof context.getElementsByClassName !== "undefined" && documentIsHTML) {
  43710. return context.getElementsByClassName(className);
  43711. }
  43712. }
  43713. },
  43714. relative: {
  43715. ">": { dir: "parentNode", first: true },
  43716. " ": { dir: "parentNode" },
  43717. "+": { dir: "previousSibling", first: true },
  43718. "~": { dir: "previousSibling" }
  43719. },
  43720. preFilter,
  43721. filter: {
  43722. ID: function(id) {
  43723. var attrId = unescapeSelector(id);
  43724. return function(elem) {
  43725. return elem.getAttribute("id") === attrId;
  43726. };
  43727. },
  43728. TAG: function(nodeNameSelector) {
  43729. var expectedNodeName = unescapeSelector(nodeNameSelector).toLowerCase();
  43730. return nodeNameSelector === "*" ? function() {
  43731. return true;
  43732. } : function(elem) {
  43733. return nodeName(elem, expectedNodeName);
  43734. };
  43735. },
  43736. CLASS: function(className) {
  43737. var pattern = classCache[className + " "];
  43738. return pattern || (pattern = new RegExp("(^|" + whitespace + ")" + className + "(" + whitespace + "|$)")) && classCache(className, function(elem) {
  43739. return pattern.test(
  43740. typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== "undefined" && elem.getAttribute("class") || ""
  43741. );
  43742. });
  43743. },
  43744. ATTR: function(name, operator, check) {
  43745. return function(elem) {
  43746. var result = elem.getAttribute(name);
  43747. if (result == null) {
  43748. return operator === "!=";
  43749. }
  43750. if (!operator) {
  43751. return true;
  43752. }
  43753. result += "";
  43754. if (operator === "=") {
  43755. return result === check;
  43756. }
  43757. if (operator === "!=") {
  43758. return result !== check;
  43759. }
  43760. if (operator === "^=") {
  43761. return check && result.indexOf(check) === 0;
  43762. }
  43763. if (operator === "*=") {
  43764. return check && result.indexOf(check) > -1;
  43765. }
  43766. if (operator === "$=") {
  43767. return check && result.slice(-check.length) === check;
  43768. }
  43769. if (operator === "~=") {
  43770. return (" " + result.replace(rwhitespace, " ") + " ").indexOf(check) > -1;
  43771. }
  43772. if (operator === "|=") {
  43773. return result === check || result.slice(0, check.length + 1) === check + "-";
  43774. }
  43775. return false;
  43776. };
  43777. },
  43778. CHILD: function(type, what, _argument, first, last) {
  43779. var simple = type.slice(0, 3) !== "nth", forward = type.slice(-4) !== "last", ofType = what === "of-type";
  43780. return first === 1 && last === 0 ? (
  43781. // Shortcut for :nth-*(n)
  43782. function(elem) {
  43783. return !!elem.parentNode;
  43784. }
  43785. ) : function(elem, _context, xml) {
  43786. var cache, outerCache, node, nodeIndex, start, dir = simple !== forward ? "nextSibling" : "previousSibling", parent = elem.parentNode, name = ofType && elem.nodeName.toLowerCase(), useCache = !xml && !ofType, diff = false;
  43787. if (parent) {
  43788. if (simple) {
  43789. while (dir) {
  43790. node = elem;
  43791. while (node = node[dir]) {
  43792. if (ofType ? nodeName(node, name) : node.nodeType === 1) {
  43793. return false;
  43794. }
  43795. }
  43796. start = dir = type === "only" && !start && "nextSibling";
  43797. }
  43798. return true;
  43799. }
  43800. start = [forward ? parent.firstChild : parent.lastChild];
  43801. if (forward && useCache) {
  43802. outerCache = parent[jQuery.expando] || (parent[jQuery.expando] = {});
  43803. cache = outerCache[type] || [];
  43804. nodeIndex = cache[0] === dirruns && cache[1];
  43805. diff = nodeIndex && cache[2];
  43806. node = nodeIndex && parent.childNodes[nodeIndex];
  43807. while (node = ++nodeIndex && node && node[dir] || // Fallback to seeking `elem` from the start
  43808. (diff = nodeIndex = 0) || start.pop()) {
  43809. if (node.nodeType === 1 && ++diff && node === elem) {
  43810. outerCache[type] = [dirruns, nodeIndex, diff];
  43811. break;
  43812. }
  43813. }
  43814. } else {
  43815. if (useCache) {
  43816. outerCache = elem[jQuery.expando] || (elem[jQuery.expando] = {});
  43817. cache = outerCache[type] || [];
  43818. nodeIndex = cache[0] === dirruns && cache[1];
  43819. diff = nodeIndex;
  43820. }
  43821. if (diff === false) {
  43822. while (node = ++nodeIndex && node && node[dir] || (diff = nodeIndex = 0) || start.pop()) {
  43823. if ((ofType ? nodeName(node, name) : node.nodeType === 1) && ++diff) {
  43824. if (useCache) {
  43825. outerCache = node[jQuery.expando] || (node[jQuery.expando] = {});
  43826. outerCache[type] = [dirruns, diff];
  43827. }
  43828. if (node === elem) {
  43829. break;
  43830. }
  43831. }
  43832. }
  43833. }
  43834. }
  43835. diff -= last;
  43836. return diff === first || diff % first === 0 && diff / first >= 0;
  43837. }
  43838. };
  43839. },
  43840. PSEUDO: function(pseudo, argument) {
  43841. var fn = jQuery.expr.pseudos[pseudo] || jQuery.expr.setFilters[pseudo.toLowerCase()] || selectorError("unsupported pseudo: " + pseudo);
  43842. if (fn[jQuery.expando]) {
  43843. return fn(argument);
  43844. }
  43845. return fn;
  43846. }
  43847. },
  43848. pseudos: {
  43849. // Potentially complex pseudos
  43850. not: markFunction(function(selector) {
  43851. var input = [], results = [], matcher = compile(selector.replace(rtrimCSS, "$1"));
  43852. return matcher[jQuery.expando] ? markFunction(function(seed, matches3, _context, xml) {
  43853. var elem, unmatched = matcher(seed, null, xml, []), i2 = seed.length;
  43854. while (i2--) {
  43855. if (elem = unmatched[i2]) {
  43856. seed[i2] = !(matches3[i2] = elem);
  43857. }
  43858. }
  43859. }) : function(elem, _context, xml) {
  43860. input[0] = elem;
  43861. matcher(input, null, xml, results);
  43862. input[0] = null;
  43863. return !results.pop();
  43864. };
  43865. }),
  43866. has: markFunction(function(selector) {
  43867. return function(elem) {
  43868. return find(selector, elem).length > 0;
  43869. };
  43870. }),
  43871. contains: markFunction(function(text) {
  43872. text = unescapeSelector(text);
  43873. return function(elem) {
  43874. return (elem.textContent || jQuery.text(elem)).indexOf(text) > -1;
  43875. };
  43876. }),
  43877. // "Whether an element is represented by a :lang() selector
  43878. // is based solely on the element's language value
  43879. // being equal to the identifier C,
  43880. // or beginning with the identifier C immediately followed by "-".
  43881. // The matching of C against the element's language value is performed case-insensitively.
  43882. // The identifier C does not have to be a valid language name."
  43883. // https://www.w3.org/TR/selectors/#lang-pseudo
  43884. lang: markFunction(function(lang) {
  43885. if (!ridentifier.test(lang || "")) {
  43886. selectorError("unsupported lang: " + lang);
  43887. }
  43888. lang = unescapeSelector(lang).toLowerCase();
  43889. return function(elem) {
  43890. var elemLang;
  43891. do {
  43892. if (elemLang = documentIsHTML ? elem.lang : elem.getAttribute("xml:lang") || elem.getAttribute("lang")) {
  43893. elemLang = elemLang.toLowerCase();
  43894. return elemLang === lang || elemLang.indexOf(lang + "-") === 0;
  43895. }
  43896. } while ((elem = elem.parentNode) && elem.nodeType === 1);
  43897. return false;
  43898. };
  43899. }),
  43900. // Miscellaneous
  43901. target: function(elem) {
  43902. var hash = window.location && window.location.hash;
  43903. return hash && hash.slice(1) === elem.id;
  43904. },
  43905. root: function(elem) {
  43906. return elem === documentElement$1;
  43907. },
  43908. focus: function(elem) {
  43909. return elem === document$1.activeElement && document$1.hasFocus() && !!(elem.type || elem.href || ~elem.tabIndex);
  43910. },
  43911. // Boolean properties
  43912. enabled: createDisabledPseudo(false),
  43913. disabled: createDisabledPseudo(true),
  43914. checked: function(elem) {
  43915. return nodeName(elem, "input") && !!elem.checked || nodeName(elem, "option") && !!elem.selected;
  43916. },
  43917. selected: function(elem) {
  43918. if (isIE && elem.parentNode) {
  43919. elem.parentNode.selectedIndex;
  43920. }
  43921. return elem.selected === true;
  43922. },
  43923. // Contents
  43924. empty: function(elem) {
  43925. for (elem = elem.firstChild; elem; elem = elem.nextSibling) {
  43926. if (elem.nodeType < 6) {
  43927. return false;
  43928. }
  43929. }
  43930. return true;
  43931. },
  43932. parent: function(elem) {
  43933. return !jQuery.expr.pseudos.empty(elem);
  43934. },
  43935. // Element/input types
  43936. header: function(elem) {
  43937. return rheader.test(elem.nodeName);
  43938. },
  43939. input: function(elem) {
  43940. return rinputs.test(elem.nodeName);
  43941. },
  43942. button: function(elem) {
  43943. return nodeName(elem, "input") && elem.type === "button" || nodeName(elem, "button");
  43944. },
  43945. text: function(elem) {
  43946. return nodeName(elem, "input") && elem.type === "text";
  43947. },
  43948. // Position-in-collection
  43949. first: createPositionalPseudo(function() {
  43950. return [0];
  43951. }),
  43952. last: createPositionalPseudo(function(_matchIndexes, length) {
  43953. return [length - 1];
  43954. }),
  43955. eq: createPositionalPseudo(function(_matchIndexes, length, argument) {
  43956. return [argument < 0 ? argument + length : argument];
  43957. }),
  43958. even: createPositionalPseudo(function(matchIndexes, length) {
  43959. var i2 = 0;
  43960. for (; i2 < length; i2 += 2) {
  43961. matchIndexes.push(i2);
  43962. }
  43963. return matchIndexes;
  43964. }),
  43965. odd: createPositionalPseudo(function(matchIndexes, length) {
  43966. var i2 = 1;
  43967. for (; i2 < length; i2 += 2) {
  43968. matchIndexes.push(i2);
  43969. }
  43970. return matchIndexes;
  43971. }),
  43972. lt: createPositionalPseudo(function(matchIndexes, length, argument) {
  43973. var i2;
  43974. if (argument < 0) {
  43975. i2 = argument + length;
  43976. } else if (argument > length) {
  43977. i2 = length;
  43978. } else {
  43979. i2 = argument;
  43980. }
  43981. for (; --i2 >= 0; ) {
  43982. matchIndexes.push(i2);
  43983. }
  43984. return matchIndexes;
  43985. }),
  43986. gt: createPositionalPseudo(function(matchIndexes, length, argument) {
  43987. var i2 = argument < 0 ? argument + length : argument;
  43988. for (; ++i2 < length; ) {
  43989. matchIndexes.push(i2);
  43990. }
  43991. return matchIndexes;
  43992. })
  43993. }
  43994. };
  43995. jQuery.expr.pseudos.nth = jQuery.expr.pseudos.eq;
  43996. for (i in { radio: true, checkbox: true, file: true, password: true, image: true }) {
  43997. jQuery.expr.pseudos[i] = createInputPseudo(i);
  43998. }
  43999. for (i in { submit: true, reset: true }) {
  44000. jQuery.expr.pseudos[i] = createButtonPseudo(i);
  44001. }
  44002. function setFilters() {
  44003. }
  44004. setFilters.prototype = jQuery.expr.filters = jQuery.expr.pseudos;
  44005. jQuery.expr.setFilters = new setFilters();
  44006. function addCombinator(matcher, combinator, base) {
  44007. var dir = combinator.dir, skip = combinator.next, key = skip || dir, checkNonElements = base && key === "parentNode", doneName = done++;
  44008. return combinator.first ? (
  44009. // Check against closest ancestor/preceding element
  44010. function(elem, context, xml) {
  44011. while (elem = elem[dir]) {
  44012. if (elem.nodeType === 1 || checkNonElements) {
  44013. return matcher(elem, context, xml);
  44014. }
  44015. }
  44016. return false;
  44017. }
  44018. ) : (
  44019. // Check against all ancestor/preceding elements
  44020. function(elem, context, xml) {
  44021. var oldCache, outerCache, newCache = [dirruns, doneName];
  44022. if (xml) {
  44023. while (elem = elem[dir]) {
  44024. if (elem.nodeType === 1 || checkNonElements) {
  44025. if (matcher(elem, context, xml)) {
  44026. return true;
  44027. }
  44028. }
  44029. }
  44030. } else {
  44031. while (elem = elem[dir]) {
  44032. if (elem.nodeType === 1 || checkNonElements) {
  44033. outerCache = elem[jQuery.expando] || (elem[jQuery.expando] = {});
  44034. if (skip && nodeName(elem, skip)) {
  44035. elem = elem[dir] || elem;
  44036. } else if ((oldCache = outerCache[key]) && oldCache[0] === dirruns && oldCache[1] === doneName) {
  44037. return newCache[2] = oldCache[2];
  44038. } else {
  44039. outerCache[key] = newCache;
  44040. if (newCache[2] = matcher(elem, context, xml)) {
  44041. return true;
  44042. }
  44043. }
  44044. }
  44045. }
  44046. }
  44047. return false;
  44048. }
  44049. );
  44050. }
  44051. function elementMatcher(matchers) {
  44052. return matchers.length > 1 ? function(elem, context, xml) {
  44053. var i2 = matchers.length;
  44054. while (i2--) {
  44055. if (!matchers[i2](elem, context, xml)) {
  44056. return false;
  44057. }
  44058. }
  44059. return true;
  44060. } : matchers[0];
  44061. }
  44062. function multipleContexts(selector, contexts, results) {
  44063. var i2 = 0, len = contexts.length;
  44064. for (; i2 < len; i2++) {
  44065. find(selector, contexts[i2], results);
  44066. }
  44067. return results;
  44068. }
  44069. function condense(unmatched, map2, filter, context, xml) {
  44070. var elem, newUnmatched = [], i2 = 0, len = unmatched.length, mapped = map2 != null;
  44071. for (; i2 < len; i2++) {
  44072. if (elem = unmatched[i2]) {
  44073. if (!filter || filter(elem, context, xml)) {
  44074. newUnmatched.push(elem);
  44075. if (mapped) {
  44076. map2.push(i2);
  44077. }
  44078. }
  44079. }
  44080. }
  44081. return newUnmatched;
  44082. }
  44083. function setMatcher(preFilter2, selector, matcher, postFilter, postFinder, postSelector) {
  44084. if (postFilter && !postFilter[jQuery.expando]) {
  44085. postFilter = setMatcher(postFilter);
  44086. }
  44087. if (postFinder && !postFinder[jQuery.expando]) {
  44088. postFinder = setMatcher(postFinder, postSelector);
  44089. }
  44090. return markFunction(function(seed, results, context, xml) {
  44091. var temp, i2, elem, matcherOut, preMap = [], postMap = [], preexisting = results.length, elems = seed || multipleContexts(
  44092. selector || "*",
  44093. context.nodeType ? [context] : context,
  44094. []
  44095. ), matcherIn = preFilter2 && (seed || !selector) ? condense(elems, preMap, preFilter2, context, xml) : elems;
  44096. if (matcher) {
  44097. matcherOut = postFinder || (seed ? preFilter2 : preexisting || postFilter) ? (
  44098. // ...intermediate processing is necessary
  44099. []
  44100. ) : (
  44101. // ...otherwise use results directly
  44102. results
  44103. );
  44104. matcher(matcherIn, matcherOut, context, xml);
  44105. } else {
  44106. matcherOut = matcherIn;
  44107. }
  44108. if (postFilter) {
  44109. temp = condense(matcherOut, postMap);
  44110. postFilter(temp, [], context, xml);
  44111. i2 = temp.length;
  44112. while (i2--) {
  44113. if (elem = temp[i2]) {
  44114. matcherOut[postMap[i2]] = !(matcherIn[postMap[i2]] = elem);
  44115. }
  44116. }
  44117. }
  44118. if (seed) {
  44119. if (postFinder || preFilter2) {
  44120. if (postFinder) {
  44121. temp = [];
  44122. i2 = matcherOut.length;
  44123. while (i2--) {
  44124. if (elem = matcherOut[i2]) {
  44125. temp.push(matcherIn[i2] = elem);
  44126. }
  44127. }
  44128. postFinder(null, matcherOut = [], temp, xml);
  44129. }
  44130. i2 = matcherOut.length;
  44131. while (i2--) {
  44132. if ((elem = matcherOut[i2]) && (temp = postFinder ? indexOf.call(seed, elem) : preMap[i2]) > -1) {
  44133. seed[temp] = !(results[temp] = elem);
  44134. }
  44135. }
  44136. }
  44137. } else {
  44138. matcherOut = condense(
  44139. matcherOut === results ? matcherOut.splice(preexisting, matcherOut.length) : matcherOut
  44140. );
  44141. if (postFinder) {
  44142. postFinder(null, results, matcherOut, xml);
  44143. } else {
  44144. push.apply(results, matcherOut);
  44145. }
  44146. }
  44147. });
  44148. }
  44149. function matcherFromTokens(tokens) {
  44150. 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) {
  44151. return elem === checkContext;
  44152. }, implicitRelative, true), matchAnyContext = addCombinator(function(elem) {
  44153. return indexOf.call(checkContext, elem) > -1;
  44154. }, implicitRelative, true), matchers = [function(elem, context, xml) {
  44155. var ret = !leadingRelative && (xml || context != outermostContext) || ((checkContext = context).nodeType ? matchContext(elem, context, xml) : matchAnyContext(elem, context, xml));
  44156. checkContext = null;
  44157. return ret;
  44158. }];
  44159. for (; i2 < len; i2++) {
  44160. if (matcher = jQuery.expr.relative[tokens[i2].type]) {
  44161. matchers = [addCombinator(elementMatcher(matchers), matcher)];
  44162. } else {
  44163. matcher = jQuery.expr.filter[tokens[i2].type].apply(null, tokens[i2].matches);
  44164. if (matcher[jQuery.expando]) {
  44165. j = ++i2;
  44166. for (; j < len; j++) {
  44167. if (jQuery.expr.relative[tokens[j].type]) {
  44168. break;
  44169. }
  44170. }
  44171. return setMatcher(
  44172. i2 > 1 && elementMatcher(matchers),
  44173. i2 > 1 && toSelector(
  44174. // If the preceding token was a descendant combinator, insert an implicit any-element `*`
  44175. tokens.slice(0, i2 - 1).concat({ value: tokens[i2 - 2].type === " " ? "*" : "" })
  44176. ).replace(rtrimCSS, "$1"),
  44177. matcher,
  44178. i2 < j && matcherFromTokens(tokens.slice(i2, j)),
  44179. j < len && matcherFromTokens(tokens = tokens.slice(j)),
  44180. j < len && toSelector(tokens)
  44181. );
  44182. }
  44183. matchers.push(matcher);
  44184. }
  44185. }
  44186. return elementMatcher(matchers);
  44187. }
  44188. function matcherFromGroupMatchers(elementMatchers, setMatchers) {
  44189. var bySet = setMatchers.length > 0, byElement = elementMatchers.length > 0, superMatcher = function(seed, context, xml, results, outermost) {
  44190. 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;
  44191. if (outermost) {
  44192. outermostContext = context == document$1 || context || outermost;
  44193. }
  44194. for (; (elem = elems[i2]) != null; i2++) {
  44195. if (byElement && elem) {
  44196. j = 0;
  44197. if (!context && elem.ownerDocument != document$1) {
  44198. setDocument(elem);
  44199. xml = !documentIsHTML;
  44200. }
  44201. while (matcher = elementMatchers[j++]) {
  44202. if (matcher(elem, context || document$1, xml)) {
  44203. push.call(results, elem);
  44204. break;
  44205. }
  44206. }
  44207. if (outermost) {
  44208. dirruns = dirrunsUnique;
  44209. }
  44210. }
  44211. if (bySet) {
  44212. if (elem = !matcher && elem) {
  44213. matchedCount--;
  44214. }
  44215. if (seed) {
  44216. unmatched.push(elem);
  44217. }
  44218. }
  44219. }
  44220. matchedCount += i2;
  44221. if (bySet && i2 !== matchedCount) {
  44222. j = 0;
  44223. while (matcher = setMatchers[j++]) {
  44224. matcher(unmatched, setMatched, context, xml);
  44225. }
  44226. if (seed) {
  44227. if (matchedCount > 0) {
  44228. while (i2--) {
  44229. if (!(unmatched[i2] || setMatched[i2])) {
  44230. setMatched[i2] = pop.call(results);
  44231. }
  44232. }
  44233. }
  44234. setMatched = condense(setMatched);
  44235. }
  44236. push.apply(results, setMatched);
  44237. if (outermost && !seed && setMatched.length > 0 && matchedCount + setMatchers.length > 1) {
  44238. jQuery.uniqueSort(results);
  44239. }
  44240. }
  44241. if (outermost) {
  44242. dirruns = dirrunsUnique;
  44243. outermostContext = contextBackup;
  44244. }
  44245. return unmatched;
  44246. };
  44247. return bySet ? markFunction(superMatcher) : superMatcher;
  44248. }
  44249. function compile(selector, match) {
  44250. var i2, setMatchers = [], elementMatchers = [], cached = compilerCache[selector + " "];
  44251. if (!cached) {
  44252. if (!match) {
  44253. match = tokenize(selector);
  44254. }
  44255. i2 = match.length;
  44256. while (i2--) {
  44257. cached = matcherFromTokens(match[i2]);
  44258. if (cached[jQuery.expando]) {
  44259. setMatchers.push(cached);
  44260. } else {
  44261. elementMatchers.push(cached);
  44262. }
  44263. }
  44264. cached = compilerCache(
  44265. selector,
  44266. matcherFromGroupMatchers(elementMatchers, setMatchers)
  44267. );
  44268. cached.selector = selector;
  44269. }
  44270. return cached;
  44271. }
  44272. function select(selector, context, results, seed) {
  44273. var i2, tokens, token, type, find2, compiled = typeof selector === "function" && selector, match = !seed && tokenize(selector = compiled.selector || selector);
  44274. results = results || [];
  44275. if (match.length === 1) {
  44276. tokens = match[0] = match[0].slice(0);
  44277. if (tokens.length > 2 && (token = tokens[0]).type === "ID" && context.nodeType === 9 && documentIsHTML && jQuery.expr.relative[tokens[1].type]) {
  44278. context = (jQuery.expr.find.ID(
  44279. unescapeSelector(token.matches[0]),
  44280. context
  44281. ) || [])[0];
  44282. if (!context) {
  44283. return results;
  44284. } else if (compiled) {
  44285. context = context.parentNode;
  44286. }
  44287. selector = selector.slice(tokens.shift().value.length);
  44288. }
  44289. i2 = matchExpr.needsContext.test(selector) ? 0 : tokens.length;
  44290. while (i2--) {
  44291. token = tokens[i2];
  44292. if (jQuery.expr.relative[type = token.type]) {
  44293. break;
  44294. }
  44295. if (find2 = jQuery.expr.find[type]) {
  44296. if (seed = find2(
  44297. unescapeSelector(token.matches[0]),
  44298. rsibling.test(tokens[0].type) && testContext(context.parentNode) || context
  44299. )) {
  44300. tokens.splice(i2, 1);
  44301. selector = seed.length && toSelector(tokens);
  44302. if (!selector) {
  44303. push.apply(results, seed);
  44304. return results;
  44305. }
  44306. break;
  44307. }
  44308. }
  44309. }
  44310. }
  44311. (compiled || compile(selector, match))(
  44312. seed,
  44313. context,
  44314. !documentIsHTML,
  44315. results,
  44316. !context || rsibling.test(selector) && testContext(context.parentNode) || context
  44317. );
  44318. return results;
  44319. }
  44320. setDocument();
  44321. jQuery.find = find;
  44322. find.compile = compile;
  44323. find.select = select;
  44324. find.setDocument = setDocument;
  44325. find.tokenize = tokenize;
  44326. return jQuery;
  44327. })
  44328. );
  44329. // src/mock-doc/selector.ts
  44330. function matches(selector, elm) {
  44331. try {
  44332. const r = jquery_default.find(selector, void 0, void 0, [elm]);
  44333. return r.length > 0;
  44334. } catch (e) {
  44335. updateSelectorError(selector, e);
  44336. throw e;
  44337. }
  44338. }
  44339. function selectOne(selector, elm) {
  44340. try {
  44341. const r = jquery_default.find(selector, elm, void 0, void 0);
  44342. return r[0] || null;
  44343. } catch (e) {
  44344. updateSelectorError(selector, e);
  44345. throw e;
  44346. }
  44347. }
  44348. function selectAll(selector, elm) {
  44349. try {
  44350. return jquery_default.find(selector, elm, void 0, void 0);
  44351. } catch (e) {
  44352. updateSelectorError(selector, e);
  44353. throw e;
  44354. }
  44355. }
  44356. var PROBLEMATIC_SELECTORS = [":scope", ":where", ":is"];
  44357. function updateSelectorError(selector, e) {
  44358. const selectorsPresent = PROBLEMATIC_SELECTORS.filter((s) => selector.includes(s));
  44359. if (selectorsPresent.length > 0 && e.message) {
  44360. e.message = `At present jQuery does not support the ${humanReadableList(selectorsPresent)} ${selectorsPresent.length === 1 ? "selector" : "selectors"}.
  44361. If you need this in your test, consider writing an end-to-end test instead.
  44362. ` + e.message;
  44363. }
  44364. }
  44365. function humanReadableList(items) {
  44366. if (items.length <= 1) {
  44367. return items.join("");
  44368. }
  44369. return `${items.slice(0, items.length - 1).join(", ")} and ${items[items.length - 1]}`;
  44370. }
  44371. // src/mock-doc/serialize-node.ts
  44372. function normalizeSerializationOptions(opts = {}) {
  44373. return {
  44374. ...opts,
  44375. outerHtml: typeof opts.outerHtml !== "boolean" ? false : opts.outerHtml,
  44376. ...opts.prettyHtml ? {
  44377. indentSpaces: typeof opts.indentSpaces !== "number" ? 2 : opts.indentSpaces,
  44378. newLines: typeof opts.newLines !== "boolean" ? true : opts.newLines
  44379. } : {
  44380. prettyHtml: false,
  44381. indentSpaces: typeof opts.indentSpaces !== "number" ? 0 : opts.indentSpaces,
  44382. newLines: typeof opts.newLines !== "boolean" ? false : opts.newLines
  44383. },
  44384. approximateLineWidth: typeof opts.approximateLineWidth !== "number" ? -1 : opts.approximateLineWidth,
  44385. removeEmptyAttributes: typeof opts.removeEmptyAttributes !== "boolean" ? true : opts.removeEmptyAttributes,
  44386. removeAttributeQuotes: typeof opts.removeAttributeQuotes !== "boolean" ? false : opts.removeAttributeQuotes,
  44387. removeBooleanAttributeQuotes: typeof opts.removeBooleanAttributeQuotes !== "boolean" ? false : opts.removeBooleanAttributeQuotes,
  44388. removeHtmlComments: typeof opts.removeHtmlComments !== "boolean" ? false : opts.removeHtmlComments,
  44389. serializeShadowRoot: typeof opts.serializeShadowRoot !== "boolean" ? true : opts.serializeShadowRoot,
  44390. fullDocument: typeof opts.fullDocument !== "boolean" ? true : opts.fullDocument
  44391. };
  44392. }
  44393. function serializeNodeToHtml(elm, serializationOptions = {}) {
  44394. const opts = normalizeSerializationOptions(serializationOptions);
  44395. const output = {
  44396. currentLineWidth: 0,
  44397. indent: 0,
  44398. isWithinBody: false,
  44399. text: []
  44400. };
  44401. let renderedNode = "";
  44402. const children = !opts.fullDocument && elm.body ? Array.from(elm.body.childNodes) : opts.outerHtml ? [elm] : Array.from(elm.childNodes);
  44403. for (let i = 0, ii = children.length; i < ii; i++) {
  44404. const child = children[i];
  44405. const chunks = Array.from(streamToHtml(child, opts, output));
  44406. renderedNode += chunks.join("");
  44407. }
  44408. return renderedNode.trim();
  44409. }
  44410. var shadowRootTag = "mock:shadow-root";
  44411. function* streamToHtml(node, opts, output) {
  44412. var _a2, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p;
  44413. const isShadowRoot = node.nodeType === 11 /* DOCUMENT_FRAGMENT_NODE */;
  44414. if (node.nodeType === 1 /* ELEMENT_NODE */ || isShadowRoot) {
  44415. const tagName = isShadowRoot ? shadowRootTag : getTagName(node);
  44416. if (tagName === "body") {
  44417. output.isWithinBody = true;
  44418. }
  44419. const ignoreTag = opts.excludeTags != null && opts.excludeTags.includes(tagName);
  44420. if (ignoreTag === false) {
  44421. const isWithinWhitespaceSensitiveNode = opts.newLines || ((_a2 = opts.indentSpaces) != null ? _a2 : 0) > 0 ? isWithinWhitespaceSensitive(node) : false;
  44422. if (opts.newLines && !isWithinWhitespaceSensitiveNode) {
  44423. yield "\n";
  44424. output.currentLineWidth = 0;
  44425. }
  44426. if (((_b = opts.indentSpaces) != null ? _b : 0) > 0 && !isWithinWhitespaceSensitiveNode) {
  44427. for (let i = 0; i < output.indent; i++) {
  44428. yield " ";
  44429. }
  44430. output.currentLineWidth += output.indent;
  44431. }
  44432. const tag = tagName === shadowRootTag ? "template" : tagName;
  44433. yield "<" + tag;
  44434. output.currentLineWidth += tag.length + 1;
  44435. if (tag === "template") {
  44436. const mode = ` shadowrootmode="open"`;
  44437. yield mode;
  44438. output.currentLineWidth += mode.length;
  44439. }
  44440. const attrsLength = node.attributes.length;
  44441. const attributes = opts.prettyHtml && attrsLength > 1 ? cloneAttributes(node.attributes, true) : node.attributes;
  44442. for (let i = 0; i < attrsLength; i++) {
  44443. const attr = attributes.item(i);
  44444. const attrName = attr.name;
  44445. if (attrName === "style") {
  44446. continue;
  44447. }
  44448. let attrValue = attr.value;
  44449. if (opts.removeEmptyAttributes && attrValue === "" && REMOVE_EMPTY_ATTR.has(attrName)) {
  44450. continue;
  44451. }
  44452. const attrNamespaceURI = attr.namespaceURI;
  44453. if (attrNamespaceURI == null) {
  44454. output.currentLineWidth += attrName.length + 1;
  44455. if (opts.approximateLineWidth && opts.approximateLineWidth > 0 && output.currentLineWidth > opts.approximateLineWidth) {
  44456. yield "\n" + attrName;
  44457. output.currentLineWidth = 0;
  44458. } else {
  44459. yield " " + attrName;
  44460. }
  44461. } else if (attrNamespaceURI === "http://www.w3.org/XML/1998/namespace") {
  44462. yield " xml:" + attrName;
  44463. output.currentLineWidth += attrName.length + 5;
  44464. } else if (attrNamespaceURI === "http://www.w3.org/2000/xmlns/") {
  44465. if (attrName !== "xmlns") {
  44466. yield " xmlns:" + attrName;
  44467. output.currentLineWidth += attrName.length + 7;
  44468. } else {
  44469. yield " " + attrName;
  44470. output.currentLineWidth += attrName.length + 1;
  44471. }
  44472. } else if (attrNamespaceURI === XLINK_NS) {
  44473. yield " xlink:" + attrName;
  44474. output.currentLineWidth += attrName.length + 7;
  44475. } else {
  44476. yield " " + attrNamespaceURI + ":" + attrName;
  44477. output.currentLineWidth += attrNamespaceURI.length + attrName.length + 2;
  44478. }
  44479. if (opts.prettyHtml && attrName === "class") {
  44480. attrValue = attr.value = attrValue.split(" ").filter((t) => t !== "").sort().join(" ").trim();
  44481. }
  44482. if (attrValue === "") {
  44483. if (opts.removeBooleanAttributeQuotes && BOOLEAN_ATTR.has(attrName)) {
  44484. continue;
  44485. }
  44486. if (opts.removeEmptyAttributes && attrName.startsWith("data-")) {
  44487. continue;
  44488. }
  44489. }
  44490. if (opts.removeAttributeQuotes && CAN_REMOVE_ATTR_QUOTES.test(attrValue)) {
  44491. yield "=" + escapeString(attrValue, true);
  44492. output.currentLineWidth += attrValue.length + 1;
  44493. } else {
  44494. yield '="' + escapeString(attrValue, true) + '"';
  44495. output.currentLineWidth += attrValue.length + 3;
  44496. }
  44497. }
  44498. if (node.hasAttribute("style")) {
  44499. const cssText = node.style.cssText;
  44500. if (opts.approximateLineWidth && opts.approximateLineWidth > 0 && output.currentLineWidth + cssText.length + 10 > opts.approximateLineWidth) {
  44501. yield `
  44502. style="${cssText}">`;
  44503. output.currentLineWidth = 0;
  44504. } else {
  44505. yield ` style="${cssText}">`;
  44506. output.currentLineWidth += cssText.length + 10;
  44507. }
  44508. } else {
  44509. yield ">";
  44510. output.currentLineWidth += 1;
  44511. }
  44512. }
  44513. if (EMPTY_ELEMENTS.has(tagName) === false) {
  44514. const shadowRoot = node.shadowRoot;
  44515. if (shadowRoot != null && opts.serializeShadowRoot) {
  44516. output.indent = output.indent + ((_c = opts.indentSpaces) != null ? _c : 0);
  44517. yield* streamToHtml(shadowRoot, opts, output);
  44518. output.indent = output.indent - ((_d = opts.indentSpaces) != null ? _d : 0);
  44519. 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()) === "")) {
  44520. yield "\n";
  44521. output.currentLineWidth = 0;
  44522. for (let i = 0; i < output.indent; i++) {
  44523. yield " ";
  44524. }
  44525. output.currentLineWidth += output.indent;
  44526. }
  44527. }
  44528. if (opts.excludeTagContent == null || opts.excludeTagContent.includes(tagName) === false) {
  44529. const tag = tagName === shadowRootTag ? "template" : tagName;
  44530. const childNodes = tagName === "template" ? node.content.childNodes : node.childNodes;
  44531. const childNodeLength = childNodes.length;
  44532. if (childNodeLength > 0) {
  44533. if (childNodeLength === 1 && childNodes[0].nodeType === 3 /* TEXT_NODE */ && (typeof childNodes[0].nodeValue !== "string" || childNodes[0].nodeValue.trim() === "")) {
  44534. } else {
  44535. const isWithinWhitespaceSensitiveNode = opts.newLines || ((_f = opts.indentSpaces) != null ? _f : 0) > 0 ? isWithinWhitespaceSensitive(node) : false;
  44536. if (!isWithinWhitespaceSensitiveNode && ((_g = opts.indentSpaces) != null ? _g : 0) > 0 && ignoreTag === false) {
  44537. output.indent = output.indent + ((_h = opts.indentSpaces) != null ? _h : 0);
  44538. }
  44539. for (let i = 0; i < childNodeLength; i++) {
  44540. yield* streamToHtml(childNodes[i], opts, output);
  44541. }
  44542. if (ignoreTag === false) {
  44543. if (opts.newLines && !isWithinWhitespaceSensitiveNode) {
  44544. yield "\n";
  44545. output.currentLineWidth = 0;
  44546. }
  44547. if (((_i = opts.indentSpaces) != null ? _i : 0) > 0 && !isWithinWhitespaceSensitiveNode) {
  44548. output.indent = output.indent - ((_j = opts.indentSpaces) != null ? _j : 0);
  44549. for (let i = 0; i < output.indent; i++) {
  44550. yield " ";
  44551. }
  44552. output.currentLineWidth += output.indent;
  44553. }
  44554. }
  44555. }
  44556. }
  44557. if (ignoreTag === false) {
  44558. yield "</" + tag + ">";
  44559. output.currentLineWidth += tag.length + 3;
  44560. }
  44561. }
  44562. }
  44563. if (((_k = opts.approximateLineWidth) != null ? _k : 0) > 0 && STRUCTURE_ELEMENTS.has(tagName)) {
  44564. yield "\n";
  44565. output.currentLineWidth = 0;
  44566. }
  44567. if (tagName === "body") {
  44568. output.isWithinBody = false;
  44569. }
  44570. } else if (node.nodeType === 3 /* TEXT_NODE */) {
  44571. let textContent = node.nodeValue;
  44572. if (typeof textContent === "string") {
  44573. const trimmedTextContent = textContent.trim();
  44574. if (trimmedTextContent === "") {
  44575. if (isWithinWhitespaceSensitive(node)) {
  44576. yield textContent;
  44577. output.currentLineWidth += textContent.length;
  44578. } else if (((_l = opts.approximateLineWidth) != null ? _l : 0) > 0 && !output.isWithinBody) {
  44579. } else if (!opts.prettyHtml) {
  44580. output.currentLineWidth += 1;
  44581. if (opts.approximateLineWidth && opts.approximateLineWidth > 0 && output.currentLineWidth > opts.approximateLineWidth) {
  44582. yield "\n";
  44583. output.currentLineWidth = 0;
  44584. } else {
  44585. yield " ";
  44586. }
  44587. }
  44588. } else {
  44589. const isWithinWhitespaceSensitiveNode = opts.newLines || ((_m = opts.indentSpaces) != null ? _m : 0) > 0 || opts.prettyHtml ? isWithinWhitespaceSensitive(node) : false;
  44590. if (opts.newLines && !isWithinWhitespaceSensitiveNode) {
  44591. yield "\n";
  44592. output.currentLineWidth = 0;
  44593. }
  44594. if (((_n = opts.indentSpaces) != null ? _n : 0) > 0 && !isWithinWhitespaceSensitiveNode) {
  44595. for (let i = 0; i < output.indent; i++) {
  44596. yield " ";
  44597. }
  44598. output.currentLineWidth += output.indent;
  44599. }
  44600. let textContentLength = textContent.length;
  44601. if (textContentLength > 0) {
  44602. const parentTagName = node.parentNode != null && node.parentNode.nodeType === 1 /* ELEMENT_NODE */ ? node.parentNode.nodeName : null;
  44603. if (typeof parentTagName === "string" && NON_ESCAPABLE_CONTENT.has(parentTagName)) {
  44604. if (isWithinWhitespaceSensitive(node)) {
  44605. yield textContent;
  44606. } else {
  44607. yield trimmedTextContent;
  44608. textContentLength = trimmedTextContent.length;
  44609. }
  44610. output.currentLineWidth += textContentLength;
  44611. } else {
  44612. if (opts.prettyHtml && !isWithinWhitespaceSensitiveNode) {
  44613. yield escapeString(textContent.replace(/\s\s+/g, " ").trim(), false);
  44614. output.currentLineWidth += textContentLength;
  44615. } else {
  44616. if (isWithinWhitespaceSensitive(node)) {
  44617. output.currentLineWidth += textContentLength;
  44618. } else {
  44619. if (/\s/.test(textContent.charAt(0))) {
  44620. textContent = " " + textContent.trimLeft();
  44621. }
  44622. textContentLength = textContent.length;
  44623. if (textContentLength > 1) {
  44624. if (/\s/.test(textContent.charAt(textContentLength - 1))) {
  44625. if (opts.approximateLineWidth && opts.approximateLineWidth > 0 && output.currentLineWidth + textContentLength > opts.approximateLineWidth) {
  44626. textContent = textContent.trimRight() + "\n";
  44627. output.currentLineWidth = 0;
  44628. } else {
  44629. textContent = textContent.trimRight() + " ";
  44630. }
  44631. }
  44632. }
  44633. output.currentLineWidth += textContentLength;
  44634. }
  44635. yield escapeString(textContent, false);
  44636. }
  44637. }
  44638. }
  44639. }
  44640. }
  44641. } else if (node.nodeType === 8 /* COMMENT_NODE */) {
  44642. const nodeValue = node.nodeValue;
  44643. 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 + "."));
  44644. if (opts.removeHtmlComments && !isHydrateAnnotation) {
  44645. return;
  44646. }
  44647. const isWithinWhitespaceSensitiveNode = opts.newLines || ((_o = opts.indentSpaces) != null ? _o : 0) > 0 ? isWithinWhitespaceSensitive(node) : false;
  44648. if (opts.newLines && !isWithinWhitespaceSensitiveNode) {
  44649. yield "\n";
  44650. output.currentLineWidth = 0;
  44651. }
  44652. if (((_p = opts.indentSpaces) != null ? _p : 0) > 0 && !isWithinWhitespaceSensitiveNode) {
  44653. for (let i = 0; i < output.indent; i++) {
  44654. yield " ";
  44655. }
  44656. output.currentLineWidth += output.indent;
  44657. }
  44658. yield "<!--" + nodeValue + "-->";
  44659. if (nodeValue) {
  44660. output.currentLineWidth += nodeValue.length + 7;
  44661. }
  44662. } else if (node.nodeType === 10 /* DOCUMENT_TYPE_NODE */) {
  44663. yield "<!doctype html>";
  44664. }
  44665. }
  44666. var AMP_REGEX = /&/g;
  44667. var NBSP_REGEX = /\u00a0/g;
  44668. var DOUBLE_QUOTE_REGEX = /"/g;
  44669. var LT_REGEX = /</g;
  44670. var GT_REGEX = />/g;
  44671. var CAN_REMOVE_ATTR_QUOTES = /^[^ \t\n\f\r"'`=<>\/\\-]+$/;
  44672. function getTagName(element) {
  44673. if (element.namespaceURI === "http://www.w3.org/1999/xhtml") {
  44674. return element.nodeName.toLowerCase();
  44675. } else {
  44676. return element.nodeName;
  44677. }
  44678. }
  44679. function escapeString(str, attrMode) {
  44680. str = str.replace(AMP_REGEX, "&amp;").replace(NBSP_REGEX, "&nbsp;");
  44681. if (attrMode) {
  44682. return str.replace(DOUBLE_QUOTE_REGEX, "&quot;");
  44683. }
  44684. return str.replace(LT_REGEX, "&lt;").replace(GT_REGEX, "&gt;");
  44685. }
  44686. function isWithinWhitespaceSensitive(node) {
  44687. let _node = node;
  44688. while (_node == null ? void 0 : _node.nodeName) {
  44689. if (WHITESPACE_SENSITIVE.has(_node.nodeName)) {
  44690. return true;
  44691. }
  44692. _node = _node.parentNode;
  44693. }
  44694. return false;
  44695. }
  44696. var NON_ESCAPABLE_CONTENT = /* @__PURE__ */ new Set([
  44697. "STYLE",
  44698. "SCRIPT",
  44699. "IFRAME",
  44700. "NOSCRIPT",
  44701. "XMP",
  44702. "NOEMBED",
  44703. "NOFRAMES",
  44704. "PLAINTEXT"
  44705. ]);
  44706. var WHITESPACE_SENSITIVE = /* @__PURE__ */ new Set([
  44707. "CODE",
  44708. "OUTPUT",
  44709. "PLAINTEXT",
  44710. "PRE",
  44711. "SCRIPT",
  44712. "TEMPLATE",
  44713. "TEXTAREA"
  44714. ]);
  44715. var EMPTY_ELEMENTS = /* @__PURE__ */ new Set([
  44716. "area",
  44717. "base",
  44718. "basefont",
  44719. "bgsound",
  44720. "br",
  44721. "col",
  44722. "embed",
  44723. "frame",
  44724. "hr",
  44725. "img",
  44726. "input",
  44727. "keygen",
  44728. "link",
  44729. "meta",
  44730. "param",
  44731. "source",
  44732. "trace",
  44733. "track",
  44734. "wbr"
  44735. ]);
  44736. var REMOVE_EMPTY_ATTR = /* @__PURE__ */ new Set(["class", "dir", "id", "lang", "name", "title"]);
  44737. var BOOLEAN_ATTR = /* @__PURE__ */ new Set([
  44738. "allowfullscreen",
  44739. "async",
  44740. "autofocus",
  44741. "autoplay",
  44742. "checked",
  44743. "compact",
  44744. "controls",
  44745. "declare",
  44746. "default",
  44747. "defaultchecked",
  44748. "defaultmuted",
  44749. "defaultselected",
  44750. "defer",
  44751. "disabled",
  44752. "enabled",
  44753. "formnovalidate",
  44754. "hidden",
  44755. "indeterminate",
  44756. "inert",
  44757. "ismap",
  44758. "itemscope",
  44759. "loop",
  44760. "multiple",
  44761. "muted",
  44762. "nohref",
  44763. "nomodule",
  44764. "noresize",
  44765. "noshade",
  44766. "novalidate",
  44767. "nowrap",
  44768. "open",
  44769. "pauseonexit",
  44770. "readonly",
  44771. "required",
  44772. "reversed",
  44773. "scoped",
  44774. "seamless",
  44775. "selected",
  44776. "sortable",
  44777. "truespeed",
  44778. "typemustmatch",
  44779. "visible"
  44780. ]);
  44781. var STRUCTURE_ELEMENTS = /* @__PURE__ */ new Set([
  44782. "html",
  44783. "body",
  44784. "head",
  44785. "iframe",
  44786. "meta",
  44787. "link",
  44788. "base",
  44789. "title",
  44790. "script",
  44791. "style"
  44792. ]);
  44793. // src/mock-doc/node.ts
  44794. var MockNode2 = class {
  44795. constructor(ownerDocument, nodeType, nodeName, nodeValue) {
  44796. this.ownerDocument = ownerDocument;
  44797. this.nodeType = nodeType;
  44798. this.nodeName = nodeName;
  44799. this._nodeValue = nodeValue;
  44800. this.parentNode = null;
  44801. this.childNodes = [];
  44802. }
  44803. appendChild(newNode) {
  44804. if (newNode.nodeType === 11 /* DOCUMENT_FRAGMENT_NODE */) {
  44805. const nodes = newNode.childNodes.slice();
  44806. for (const child of nodes) {
  44807. this.appendChild(child);
  44808. }
  44809. } else {
  44810. newNode.remove();
  44811. newNode.parentNode = this;
  44812. this.childNodes.push(newNode);
  44813. connectNode(this.ownerDocument, newNode);
  44814. }
  44815. return newNode;
  44816. }
  44817. append(...items) {
  44818. items.forEach((item) => {
  44819. const isNode = typeof item === "object" && item !== null && "nodeType" in item;
  44820. this.appendChild(isNode ? item : this.ownerDocument.createTextNode(String(item)));
  44821. });
  44822. }
  44823. prepend(...items) {
  44824. const firstChild = this.firstChild;
  44825. items.forEach((item) => {
  44826. const isNode = typeof item === "object" && item !== null && "nodeType" in item;
  44827. if (firstChild) {
  44828. this.insertBefore(isNode ? item : this.ownerDocument.createTextNode(String(item)), firstChild);
  44829. }
  44830. });
  44831. }
  44832. cloneNode(deep) {
  44833. throw new Error(`invalid node type to clone: ${this.nodeType}, deep: ${deep}`);
  44834. }
  44835. compareDocumentPosition(_other) {
  44836. return -1;
  44837. }
  44838. get firstChild() {
  44839. return this.childNodes[0] || null;
  44840. }
  44841. insertBefore(newNode, referenceNode) {
  44842. if (newNode.nodeType === 11 /* DOCUMENT_FRAGMENT_NODE */) {
  44843. for (let i = 0, ii = newNode.childNodes.length; i < ii; i++) {
  44844. insertBefore(this, newNode.childNodes[i], referenceNode);
  44845. }
  44846. } else {
  44847. insertBefore(this, newNode, referenceNode);
  44848. }
  44849. return newNode;
  44850. }
  44851. get isConnected() {
  44852. let node = this;
  44853. while (node != null) {
  44854. if (node.nodeType === 9 /* DOCUMENT_NODE */) {
  44855. return true;
  44856. }
  44857. node = node.parentNode;
  44858. if (node != null && node.nodeType === 11 /* DOCUMENT_FRAGMENT_NODE */) {
  44859. node = node.host;
  44860. }
  44861. }
  44862. return false;
  44863. }
  44864. isSameNode(node) {
  44865. return this === node;
  44866. }
  44867. get lastChild() {
  44868. return this.childNodes[this.childNodes.length - 1] || null;
  44869. }
  44870. get nextSibling() {
  44871. if (this.parentNode != null) {
  44872. const index = this.parentNode.childNodes.indexOf(this) + 1;
  44873. return this.parentNode.childNodes[index] || null;
  44874. }
  44875. return null;
  44876. }
  44877. get nodeValue() {
  44878. var _a2;
  44879. return (_a2 = this._nodeValue) != null ? _a2 : "";
  44880. }
  44881. set nodeValue(value) {
  44882. this._nodeValue = value;
  44883. }
  44884. get parentElement() {
  44885. return this.parentNode || null;
  44886. }
  44887. set parentElement(value) {
  44888. this.parentNode = value;
  44889. }
  44890. get previousSibling() {
  44891. if (this.parentNode != null) {
  44892. const index = this.parentNode.childNodes.indexOf(this) - 1;
  44893. return this.parentNode.childNodes[index] || null;
  44894. }
  44895. return null;
  44896. }
  44897. contains(otherNode) {
  44898. if (otherNode === this) {
  44899. return true;
  44900. }
  44901. const childNodes = Array.from(this.childNodes);
  44902. if (childNodes.includes(otherNode)) {
  44903. return true;
  44904. }
  44905. return childNodes.some((node) => this.contains.bind(node)(otherNode));
  44906. }
  44907. removeChild(childNode) {
  44908. const index = this.childNodes.indexOf(childNode);
  44909. if (index > -1) {
  44910. this.childNodes.splice(index, 1);
  44911. if (this.nodeType === 1 /* ELEMENT_NODE */) {
  44912. const wasConnected = this.isConnected;
  44913. childNode.parentNode = null;
  44914. if (wasConnected === true) {
  44915. disconnectNode(childNode);
  44916. }
  44917. } else {
  44918. childNode.parentNode = null;
  44919. }
  44920. } else {
  44921. throw new Error(`node not found within childNodes during removeChild`);
  44922. }
  44923. return childNode;
  44924. }
  44925. remove() {
  44926. if (this.parentNode != null) {
  44927. this.parentNode.removeChild(this);
  44928. }
  44929. }
  44930. replaceChild(newChild, oldChild) {
  44931. if (oldChild.parentNode === this) {
  44932. this.insertBefore(newChild, oldChild);
  44933. oldChild.remove();
  44934. return newChild;
  44935. }
  44936. return null;
  44937. }
  44938. get textContent() {
  44939. var _a2;
  44940. return (_a2 = this._nodeValue) != null ? _a2 : "";
  44941. }
  44942. set textContent(value) {
  44943. this._nodeValue = String(value);
  44944. }
  44945. };
  44946. MockNode2.ELEMENT_NODE = 1;
  44947. MockNode2.TEXT_NODE = 3;
  44948. MockNode2.PROCESSING_INSTRUCTION_NODE = 7;
  44949. MockNode2.COMMENT_NODE = 8;
  44950. MockNode2.DOCUMENT_NODE = 9;
  44951. MockNode2.DOCUMENT_TYPE_NODE = 10;
  44952. MockNode2.DOCUMENT_FRAGMENT_NODE = 11;
  44953. var MockNodeList = class {
  44954. constructor(ownerDocument, childNodes, length) {
  44955. this.ownerDocument = ownerDocument;
  44956. this.childNodes = childNodes;
  44957. this.length = length;
  44958. }
  44959. };
  44960. var MockElement = class extends MockNode2 {
  44961. attachInternals() {
  44962. return new Proxy({}, {
  44963. get: function(_target, prop, _receiver) {
  44964. console.error(
  44965. `NOTE: Property ${String(prop)} was accessed on ElementInternals, but this property is not implemented.
  44966. Testing components with ElementInternals is fully supported in e2e tests.`
  44967. );
  44968. }
  44969. });
  44970. }
  44971. constructor(ownerDocument, nodeName, namespaceURI = null) {
  44972. super(ownerDocument, 1 /* ELEMENT_NODE */, typeof nodeName === "string" ? nodeName : null, null);
  44973. this.__namespaceURI = namespaceURI;
  44974. this.__shadowRoot = null;
  44975. this.__attributeMap = null;
  44976. }
  44977. addEventListener(type, handler) {
  44978. addEventListener(this, type, handler);
  44979. }
  44980. attachShadow(_opts) {
  44981. const shadowRoot = this.ownerDocument.createDocumentFragment();
  44982. this.shadowRoot = shadowRoot;
  44983. return shadowRoot;
  44984. }
  44985. blur() {
  44986. dispatchEvent(
  44987. this,
  44988. new MockFocusEvent("blur", { relatedTarget: null, bubbles: true, cancelable: true, composed: true })
  44989. );
  44990. }
  44991. get localName() {
  44992. if (!this.nodeName) {
  44993. throw new Error(`Can't compute elements localName without nodeName`);
  44994. }
  44995. return this.nodeName.toLocaleLowerCase();
  44996. }
  44997. get namespaceURI() {
  44998. return this.__namespaceURI;
  44999. }
  45000. get shadowRoot() {
  45001. return this.__shadowRoot || null;
  45002. }
  45003. /**
  45004. * Set shadow root for element
  45005. * @param shadowRoot - ShadowRoot to set
  45006. */
  45007. set shadowRoot(shadowRoot) {
  45008. if (shadowRoot != null) {
  45009. shadowRoot.host = this;
  45010. this.__shadowRoot = shadowRoot;
  45011. } else {
  45012. delete this.__shadowRoot;
  45013. }
  45014. }
  45015. get attributes() {
  45016. if (this.__attributeMap == null) {
  45017. const attrMap = createAttributeProxy(false);
  45018. this.__attributeMap = attrMap;
  45019. return attrMap;
  45020. }
  45021. return this.__attributeMap;
  45022. }
  45023. set attributes(attrs) {
  45024. this.__attributeMap = attrs;
  45025. }
  45026. get children() {
  45027. return this.childNodes.filter((n) => n.nodeType === 1 /* ELEMENT_NODE */);
  45028. }
  45029. get childElementCount() {
  45030. return this.childNodes.filter((n) => n.nodeType === 1 /* ELEMENT_NODE */).length;
  45031. }
  45032. get className() {
  45033. return this.getAttributeNS(null, "class") || "";
  45034. }
  45035. set className(value) {
  45036. this.setAttributeNS(null, "class", value);
  45037. }
  45038. get classList() {
  45039. return new MockClassList(this);
  45040. }
  45041. click() {
  45042. dispatchEvent(this, new MockEvent("click", { bubbles: true, cancelable: true, composed: true }));
  45043. }
  45044. cloneNode(_deep) {
  45045. return null;
  45046. }
  45047. closest(selector) {
  45048. let elm = this;
  45049. while (elm != null) {
  45050. if (elm.matches(selector)) {
  45051. return elm;
  45052. }
  45053. elm = elm.parentNode;
  45054. }
  45055. return null;
  45056. }
  45057. get dataset() {
  45058. return dataset(this);
  45059. }
  45060. get dir() {
  45061. return this.getAttributeNS(null, "dir") || "";
  45062. }
  45063. set dir(value) {
  45064. this.setAttributeNS(null, "dir", value);
  45065. }
  45066. dispatchEvent(ev) {
  45067. return dispatchEvent(this, ev);
  45068. }
  45069. get firstElementChild() {
  45070. return this.children[0] || null;
  45071. }
  45072. focus(_options) {
  45073. dispatchEvent(
  45074. this,
  45075. new MockFocusEvent("focus", { relatedTarget: null, bubbles: true, cancelable: true, composed: true })
  45076. );
  45077. }
  45078. getAttribute(attrName) {
  45079. if (attrName === "style") {
  45080. if (this.__style != null && this.__style.length > 0) {
  45081. return this.style.cssText;
  45082. }
  45083. return null;
  45084. }
  45085. const attr = this.attributes.getNamedItem(attrName);
  45086. if (attr != null) {
  45087. return attr.value;
  45088. }
  45089. return null;
  45090. }
  45091. getAttributeNS(namespaceURI, attrName) {
  45092. const attr = this.attributes.getNamedItemNS(namespaceURI, attrName);
  45093. if (attr != null) {
  45094. return attr.value;
  45095. }
  45096. return null;
  45097. }
  45098. getAttributeNode(attrName) {
  45099. if (!this.hasAttribute(attrName)) {
  45100. return null;
  45101. }
  45102. return new MockAttr(attrName, this.getAttribute(attrName));
  45103. }
  45104. getBoundingClientRect() {
  45105. return { bottom: 0, height: 0, left: 0, right: 0, top: 0, width: 0, x: 0, y: 0 };
  45106. }
  45107. getRootNode(opts) {
  45108. const isComposed = opts != null && opts.composed === true;
  45109. let node = this;
  45110. while (node.parentNode != null) {
  45111. node = node.parentNode;
  45112. if (isComposed === true && node.parentNode == null && node.host != null) {
  45113. node = node.host;
  45114. }
  45115. }
  45116. return node;
  45117. }
  45118. get draggable() {
  45119. return this.getAttributeNS(null, "draggable") === "true";
  45120. }
  45121. set draggable(value) {
  45122. this.setAttributeNS(null, "draggable", value);
  45123. }
  45124. hasChildNodes() {
  45125. return this.childNodes.length > 0;
  45126. }
  45127. get id() {
  45128. return this.getAttributeNS(null, "id") || "";
  45129. }
  45130. set id(value) {
  45131. this.setAttributeNS(null, "id", value);
  45132. }
  45133. get innerHTML() {
  45134. if (this.childNodes.length === 0) {
  45135. return "";
  45136. }
  45137. return serializeNodeToHtml(this, {
  45138. newLines: false,
  45139. indentSpaces: 0
  45140. });
  45141. }
  45142. set innerHTML(html) {
  45143. var _a2;
  45144. if (NON_ESCAPABLE_CONTENT.has((_a2 = this.nodeName) != null ? _a2 : "") === true) {
  45145. setTextContent(this, html);
  45146. } else {
  45147. for (let i = this.childNodes.length - 1; i >= 0; i--) {
  45148. this.removeChild(this.childNodes[i]);
  45149. }
  45150. if (typeof html === "string") {
  45151. const frag = parseFragmentUtil(this.ownerDocument, html);
  45152. while (frag.childNodes.length > 0) {
  45153. this.appendChild(frag.childNodes[0]);
  45154. }
  45155. }
  45156. }
  45157. }
  45158. get innerText() {
  45159. const text = [];
  45160. getTextContent(this.childNodes, text);
  45161. return text.join("");
  45162. }
  45163. set innerText(value) {
  45164. setTextContent(this, value);
  45165. }
  45166. insertAdjacentElement(position, elm) {
  45167. if (position === "beforebegin" && this.parentNode) {
  45168. insertBefore(this.parentNode, elm, this);
  45169. } else if (position === "afterbegin") {
  45170. this.prepend(elm);
  45171. } else if (position === "beforeend") {
  45172. this.appendChild(elm);
  45173. } else if (position === "afterend" && this.parentNode) {
  45174. insertBefore(this.parentNode, elm, this.nextSibling);
  45175. }
  45176. return elm;
  45177. }
  45178. insertAdjacentHTML(position, html) {
  45179. const frag = parseFragmentUtil(this.ownerDocument, html);
  45180. if (position === "beforebegin") {
  45181. while (frag.childNodes.length > 0) {
  45182. if (this.parentNode) {
  45183. insertBefore(this.parentNode, frag.childNodes[0], this);
  45184. }
  45185. }
  45186. } else if (position === "afterbegin") {
  45187. while (frag.childNodes.length > 0) {
  45188. this.prepend(frag.childNodes[frag.childNodes.length - 1]);
  45189. }
  45190. } else if (position === "beforeend") {
  45191. while (frag.childNodes.length > 0) {
  45192. this.appendChild(frag.childNodes[0]);
  45193. }
  45194. } else if (position === "afterend") {
  45195. while (frag.childNodes.length > 0) {
  45196. if (this.parentNode) {
  45197. insertBefore(this.parentNode, frag.childNodes[frag.childNodes.length - 1], this.nextSibling);
  45198. }
  45199. }
  45200. }
  45201. }
  45202. insertAdjacentText(position, text) {
  45203. const elm = this.ownerDocument.createTextNode(text);
  45204. if (position === "beforebegin" && this.parentNode) {
  45205. insertBefore(this.parentNode, elm, this);
  45206. } else if (position === "afterbegin") {
  45207. this.prepend(elm);
  45208. } else if (position === "beforeend") {
  45209. this.appendChild(elm);
  45210. } else if (position === "afterend" && this.parentNode) {
  45211. insertBefore(this.parentNode, elm, this.nextSibling);
  45212. }
  45213. }
  45214. hasAttribute(attrName) {
  45215. if (attrName === "style") {
  45216. return this.__style != null && this.__style.length > 0;
  45217. }
  45218. return this.getAttribute(attrName) !== null;
  45219. }
  45220. hasAttributeNS(namespaceURI, name) {
  45221. return this.getAttributeNS(namespaceURI, name) !== null;
  45222. }
  45223. get hidden() {
  45224. return this.hasAttributeNS(null, "hidden");
  45225. }
  45226. set hidden(isHidden) {
  45227. if (isHidden === true) {
  45228. this.setAttributeNS(null, "hidden", "");
  45229. } else {
  45230. this.removeAttributeNS(null, "hidden");
  45231. }
  45232. }
  45233. get lang() {
  45234. return this.getAttributeNS(null, "lang") || "";
  45235. }
  45236. set lang(value) {
  45237. this.setAttributeNS(null, "lang", value);
  45238. }
  45239. get lastElementChild() {
  45240. const children = this.children;
  45241. return children[children.length - 1] || null;
  45242. }
  45243. matches(selector) {
  45244. return matches(selector, this);
  45245. }
  45246. get nextElementSibling() {
  45247. const parentElement = this.parentElement;
  45248. if (parentElement != null && (parentElement.nodeType === 1 /* ELEMENT_NODE */ || parentElement.nodeType === 11 /* DOCUMENT_FRAGMENT_NODE */ || parentElement.nodeType === 9 /* DOCUMENT_NODE */)) {
  45249. const children = parentElement.children;
  45250. const index = children.indexOf(this) + 1;
  45251. return parentElement.children[index] || null;
  45252. }
  45253. return null;
  45254. }
  45255. get outerHTML() {
  45256. return serializeNodeToHtml(this, {
  45257. newLines: false,
  45258. outerHtml: true,
  45259. indentSpaces: 0
  45260. });
  45261. }
  45262. get previousElementSibling() {
  45263. const parentElement = this.parentElement;
  45264. if (parentElement != null && (parentElement.nodeType === 1 /* ELEMENT_NODE */ || parentElement.nodeType === 11 /* DOCUMENT_FRAGMENT_NODE */ || parentElement.nodeType === 9 /* DOCUMENT_NODE */)) {
  45265. const children = parentElement.children;
  45266. const index = children.indexOf(this) - 1;
  45267. return parentElement.children[index] || null;
  45268. }
  45269. return null;
  45270. }
  45271. getElementsByClassName(classNames) {
  45272. const classes = classNames.trim().split(" ").filter((c) => c.length > 0);
  45273. const results = [];
  45274. getElementsByClassName(this, classes, results);
  45275. return results;
  45276. }
  45277. getElementsByTagName(tagName) {
  45278. const results = [];
  45279. getElementsByTagName(this, tagName.toLowerCase(), results);
  45280. return results;
  45281. }
  45282. querySelector(selector) {
  45283. return selectOne(selector, this);
  45284. }
  45285. querySelectorAll(selector) {
  45286. return selectAll(selector, this);
  45287. }
  45288. removeAttribute(attrName) {
  45289. if (attrName === "style") {
  45290. delete this.__style;
  45291. } else {
  45292. const attr = this.attributes.getNamedItem(attrName);
  45293. if (attr != null) {
  45294. this.attributes.removeNamedItemNS(attr);
  45295. if (checkAttributeChanged(this) === true) {
  45296. attributeChanged(this, attrName, attr.value, null);
  45297. }
  45298. }
  45299. }
  45300. }
  45301. removeAttributeNS(namespaceURI, attrName) {
  45302. const attr = this.attributes.getNamedItemNS(namespaceURI, attrName);
  45303. if (attr != null) {
  45304. this.attributes.removeNamedItemNS(attr);
  45305. if (checkAttributeChanged(this) === true) {
  45306. attributeChanged(this, attrName, attr.value, null);
  45307. }
  45308. }
  45309. }
  45310. removeEventListener(type, handler) {
  45311. removeEventListener(this, type, handler);
  45312. }
  45313. setAttribute(attrName, value) {
  45314. if (attrName === "style") {
  45315. this.style = value;
  45316. } else {
  45317. const attributes = this.attributes;
  45318. let attr = attributes.getNamedItem(attrName);
  45319. const checkAttrChanged = checkAttributeChanged(this);
  45320. if (attr != null) {
  45321. if (checkAttrChanged === true) {
  45322. const oldValue = attr.value;
  45323. attr.value = value;
  45324. if (oldValue !== attr.value) {
  45325. attributeChanged(this, attr.name, oldValue, attr.value);
  45326. }
  45327. } else {
  45328. attr.value = value;
  45329. }
  45330. } else {
  45331. if (attributes.caseInsensitive) {
  45332. attrName = attrName.toLowerCase();
  45333. }
  45334. attr = new MockAttr(attrName, value);
  45335. attributes.__items.push(attr);
  45336. if (checkAttrChanged === true) {
  45337. attributeChanged(this, attrName, null, attr.value);
  45338. }
  45339. }
  45340. }
  45341. }
  45342. setAttributeNS(namespaceURI, attrName, value) {
  45343. const attributes = this.attributes;
  45344. let attr = attributes.getNamedItemNS(namespaceURI, attrName);
  45345. const checkAttrChanged = checkAttributeChanged(this);
  45346. if (attr != null) {
  45347. if (checkAttrChanged === true) {
  45348. const oldValue = attr.value;
  45349. attr.value = value;
  45350. if (oldValue !== attr.value) {
  45351. attributeChanged(this, attr.name, oldValue, attr.value);
  45352. }
  45353. } else {
  45354. attr.value = value;
  45355. }
  45356. } else {
  45357. attr = new MockAttr(attrName, value, namespaceURI);
  45358. attributes.__items.push(attr);
  45359. if (checkAttrChanged === true) {
  45360. attributeChanged(this, attrName, null, attr.value);
  45361. }
  45362. }
  45363. }
  45364. get style() {
  45365. if (this.__style == null) {
  45366. this.__style = createCSSStyleDeclaration();
  45367. }
  45368. return this.__style;
  45369. }
  45370. set style(val) {
  45371. if (typeof val === "string") {
  45372. if (this.__style == null) {
  45373. this.__style = createCSSStyleDeclaration();
  45374. }
  45375. this.__style.cssText = val;
  45376. } else {
  45377. this.__style = val;
  45378. }
  45379. }
  45380. get tabIndex() {
  45381. return parseInt(this.getAttributeNS(null, "tabindex") || "-1", 10);
  45382. }
  45383. set tabIndex(value) {
  45384. this.setAttributeNS(null, "tabindex", value);
  45385. }
  45386. get tagName() {
  45387. var _a2;
  45388. return (_a2 = this.nodeName) != null ? _a2 : "";
  45389. }
  45390. set tagName(value) {
  45391. this.nodeName = value;
  45392. }
  45393. get textContent() {
  45394. const text = [];
  45395. getTextContent(this.childNodes, text);
  45396. return text.join("");
  45397. }
  45398. set textContent(value) {
  45399. setTextContent(this, value);
  45400. }
  45401. get title() {
  45402. return this.getAttributeNS(null, "title") || "";
  45403. }
  45404. set title(value) {
  45405. this.setAttributeNS(null, "title", value);
  45406. }
  45407. animate() {
  45408. }
  45409. onanimationstart() {
  45410. }
  45411. onanimationend() {
  45412. }
  45413. onanimationiteration() {
  45414. }
  45415. onabort() {
  45416. }
  45417. onauxclick() {
  45418. }
  45419. onbeforecopy() {
  45420. }
  45421. onbeforecut() {
  45422. }
  45423. onbeforepaste() {
  45424. }
  45425. onblur() {
  45426. }
  45427. oncancel() {
  45428. }
  45429. oncanplay() {
  45430. }
  45431. oncanplaythrough() {
  45432. }
  45433. onchange() {
  45434. }
  45435. onclick() {
  45436. }
  45437. onclose() {
  45438. }
  45439. oncontextmenu() {
  45440. }
  45441. oncopy() {
  45442. }
  45443. oncuechange() {
  45444. }
  45445. oncut() {
  45446. }
  45447. ondblclick() {
  45448. }
  45449. ondrag() {
  45450. }
  45451. ondragend() {
  45452. }
  45453. ondragenter() {
  45454. }
  45455. ondragleave() {
  45456. }
  45457. ondragover() {
  45458. }
  45459. ondragstart() {
  45460. }
  45461. ondrop() {
  45462. }
  45463. ondurationchange() {
  45464. }
  45465. onemptied() {
  45466. }
  45467. onended() {
  45468. }
  45469. onerror() {
  45470. }
  45471. onfocus() {
  45472. }
  45473. onfocusin() {
  45474. }
  45475. onfocusout() {
  45476. }
  45477. onformdata() {
  45478. }
  45479. onfullscreenchange() {
  45480. }
  45481. onfullscreenerror() {
  45482. }
  45483. ongotpointercapture() {
  45484. }
  45485. oninput() {
  45486. }
  45487. oninvalid() {
  45488. }
  45489. onkeydown() {
  45490. }
  45491. onkeypress() {
  45492. }
  45493. onkeyup() {
  45494. }
  45495. onload() {
  45496. }
  45497. onloadeddata() {
  45498. }
  45499. onloadedmetadata() {
  45500. }
  45501. onloadstart() {
  45502. }
  45503. onlostpointercapture() {
  45504. }
  45505. onmousedown() {
  45506. }
  45507. onmouseenter() {
  45508. }
  45509. onmouseleave() {
  45510. }
  45511. onmousemove() {
  45512. }
  45513. onmouseout() {
  45514. }
  45515. onmouseover() {
  45516. }
  45517. onmouseup() {
  45518. }
  45519. onmousewheel() {
  45520. }
  45521. onpaste() {
  45522. }
  45523. onpause() {
  45524. }
  45525. onplay() {
  45526. }
  45527. onplaying() {
  45528. }
  45529. onpointercancel() {
  45530. }
  45531. onpointerdown() {
  45532. }
  45533. onpointerenter() {
  45534. }
  45535. onpointerleave() {
  45536. }
  45537. onpointermove() {
  45538. }
  45539. onpointerout() {
  45540. }
  45541. onpointerover() {
  45542. }
  45543. onpointerup() {
  45544. }
  45545. onprogress() {
  45546. }
  45547. onratechange() {
  45548. }
  45549. onreset() {
  45550. }
  45551. onresize() {
  45552. }
  45553. onscroll() {
  45554. }
  45555. onsearch() {
  45556. }
  45557. onseeked() {
  45558. }
  45559. onseeking() {
  45560. }
  45561. onselect() {
  45562. }
  45563. onselectstart() {
  45564. }
  45565. onstalled() {
  45566. }
  45567. onsubmit() {
  45568. }
  45569. onsuspend() {
  45570. }
  45571. ontimeupdate() {
  45572. }
  45573. ontoggle() {
  45574. }
  45575. onvolumechange() {
  45576. }
  45577. onwaiting() {
  45578. }
  45579. onwebkitfullscreenchange() {
  45580. }
  45581. onwebkitfullscreenerror() {
  45582. }
  45583. onwheel() {
  45584. }
  45585. requestFullscreen() {
  45586. }
  45587. scrollBy() {
  45588. }
  45589. scrollTo() {
  45590. }
  45591. scrollIntoView() {
  45592. }
  45593. toString(opts) {
  45594. return serializeNodeToHtml(this, opts);
  45595. }
  45596. };
  45597. function getElementsByClassName(elm, classNames, foundElms) {
  45598. const children = elm.children;
  45599. for (let i = 0, ii = children.length; i < ii; i++) {
  45600. const childElm = children[i];
  45601. for (let j = 0, jj = classNames.length; j < jj; j++) {
  45602. if (childElm.classList.contains(classNames[j])) {
  45603. foundElms.push(childElm);
  45604. }
  45605. }
  45606. getElementsByClassName(childElm, classNames, foundElms);
  45607. }
  45608. }
  45609. function getElementsByTagName(elm, tagName, foundElms) {
  45610. var _a2;
  45611. const children = elm.children;
  45612. for (let i = 0, ii = children.length; i < ii; i++) {
  45613. const childElm = children[i];
  45614. if (tagName === "*" || ((_a2 = childElm.nodeName) != null ? _a2 : "").toLowerCase() === tagName) {
  45615. foundElms.push(childElm);
  45616. }
  45617. getElementsByTagName(childElm, tagName, foundElms);
  45618. }
  45619. }
  45620. function resetElement(elm) {
  45621. resetEventListeners(elm);
  45622. delete elm.__attributeMap;
  45623. delete elm.__shadowRoot;
  45624. delete elm.__style;
  45625. }
  45626. function insertBefore(parentNode, newNode, referenceNode) {
  45627. if (newNode !== referenceNode) {
  45628. newNode.remove();
  45629. newNode.parentNode = parentNode;
  45630. newNode.ownerDocument = parentNode.ownerDocument;
  45631. if (referenceNode != null) {
  45632. const index = parentNode.childNodes.indexOf(referenceNode);
  45633. if (index > -1) {
  45634. parentNode.childNodes.splice(index, 0, newNode);
  45635. } else {
  45636. throw new Error(`referenceNode not found in parentNode.childNodes`);
  45637. }
  45638. } else {
  45639. parentNode.childNodes.push(newNode);
  45640. }
  45641. connectNode(parentNode.ownerDocument, newNode);
  45642. }
  45643. return newNode;
  45644. }
  45645. var MockHTMLElement = class extends MockElement {
  45646. constructor(ownerDocument, nodeName) {
  45647. super(ownerDocument, typeof nodeName === "string" ? nodeName.toUpperCase() : null);
  45648. this.__namespaceURI = "http://www.w3.org/1999/xhtml";
  45649. }
  45650. get tagName() {
  45651. var _a2;
  45652. return (_a2 = this.nodeName) != null ? _a2 : "";
  45653. }
  45654. set tagName(value) {
  45655. this.nodeName = value;
  45656. }
  45657. /**
  45658. * A node’s parent of type Element is known as its parent element.
  45659. * If the node has a parent of a different type, its parent element
  45660. * is null.
  45661. * @returns MockElement
  45662. */
  45663. get parentElement() {
  45664. if (this.nodeName === "HTML") {
  45665. return null;
  45666. }
  45667. return super.parentElement;
  45668. }
  45669. get attributes() {
  45670. if (this.__attributeMap == null) {
  45671. const attrMap = createAttributeProxy(true);
  45672. this.__attributeMap = attrMap;
  45673. return attrMap;
  45674. }
  45675. return this.__attributeMap;
  45676. }
  45677. set attributes(attrs) {
  45678. this.__attributeMap = attrs;
  45679. }
  45680. };
  45681. var MockTextNode = class _MockTextNode extends MockNode2 {
  45682. constructor(ownerDocument, text) {
  45683. super(ownerDocument, 3 /* TEXT_NODE */, "#text" /* TEXT_NODE */, text);
  45684. }
  45685. cloneNode(_deep) {
  45686. return new _MockTextNode(null, this.nodeValue);
  45687. }
  45688. get textContent() {
  45689. return this.nodeValue;
  45690. }
  45691. set textContent(text) {
  45692. this.nodeValue = text;
  45693. }
  45694. get data() {
  45695. return this.nodeValue;
  45696. }
  45697. set data(text) {
  45698. this.nodeValue = text;
  45699. }
  45700. get wholeText() {
  45701. if (this.parentNode != null) {
  45702. const text = [];
  45703. for (let i = 0, ii = this.parentNode.childNodes.length; i < ii; i++) {
  45704. const childNode = this.parentNode.childNodes[i];
  45705. if (childNode.nodeType === 3 /* TEXT_NODE */) {
  45706. text.push(childNode.nodeValue);
  45707. }
  45708. }
  45709. return text.join("");
  45710. }
  45711. return this.nodeValue;
  45712. }
  45713. };
  45714. function getTextContent(childNodes, text) {
  45715. for (let i = 0, ii = childNodes.length; i < ii; i++) {
  45716. const childNode = childNodes[i];
  45717. if (childNode.nodeType === 3 /* TEXT_NODE */) {
  45718. text.push(childNode.nodeValue);
  45719. } else if (childNode.nodeType === 1 /* ELEMENT_NODE */) {
  45720. getTextContent(childNode.childNodes, text);
  45721. }
  45722. }
  45723. }
  45724. function setTextContent(elm, text) {
  45725. for (let i = elm.childNodes.length - 1; i >= 0; i--) {
  45726. elm.removeChild(elm.childNodes[i]);
  45727. }
  45728. const textNode = new MockTextNode(elm.ownerDocument, text);
  45729. elm.appendChild(textNode);
  45730. }
  45731. // src/mock-doc/comment-node.ts
  45732. var MockComment = class _MockComment extends MockNode2 {
  45733. constructor(ownerDocument, data) {
  45734. super(ownerDocument, 8 /* COMMENT_NODE */, "#comment" /* COMMENT_NODE */, data);
  45735. }
  45736. cloneNode(_deep) {
  45737. return new _MockComment(null, this.nodeValue);
  45738. }
  45739. get textContent() {
  45740. return this.nodeValue;
  45741. }
  45742. set textContent(text) {
  45743. this.nodeValue = text;
  45744. }
  45745. };
  45746. // src/mock-doc/document-fragment.ts
  45747. var MockDocumentFragment = class _MockDocumentFragment extends MockHTMLElement {
  45748. constructor(ownerDocument) {
  45749. super(ownerDocument, null);
  45750. this.nodeName = "#document-fragment" /* DOCUMENT_FRAGMENT_NODE */;
  45751. this.nodeType = 11 /* DOCUMENT_FRAGMENT_NODE */;
  45752. }
  45753. getElementById(id) {
  45754. return getElementById(this, id);
  45755. }
  45756. cloneNode(deep) {
  45757. const cloned = new _MockDocumentFragment(null);
  45758. if (deep) {
  45759. for (let i = 0, ii = this.childNodes.length; i < ii; i++) {
  45760. const childNode = this.childNodes[i];
  45761. if (childNode.nodeType === 1 /* ELEMENT_NODE */ || childNode.nodeType === 3 /* TEXT_NODE */ || childNode.nodeType === 8 /* COMMENT_NODE */) {
  45762. const clonedChildNode = this.childNodes[i].cloneNode(true);
  45763. cloned.appendChild(clonedChildNode);
  45764. }
  45765. }
  45766. }
  45767. return cloned;
  45768. }
  45769. };
  45770. // src/mock-doc/document-type-node.ts
  45771. var MockDocumentTypeNode = class extends MockHTMLElement {
  45772. constructor(ownerDocument) {
  45773. super(ownerDocument, "!DOCTYPE");
  45774. this.nodeType = 10 /* DOCUMENT_TYPE_NODE */;
  45775. this.setAttribute("html", "");
  45776. }
  45777. };
  45778. // src/mock-doc/css-style-sheet.ts
  45779. var MockCSSRule = class {
  45780. constructor(parentStyleSheet) {
  45781. this.parentStyleSheet = parentStyleSheet;
  45782. this.cssText = "";
  45783. this.type = 0;
  45784. }
  45785. };
  45786. var MockCSSStyleSheet = class {
  45787. constructor(ownerNode) {
  45788. this.type = "text/css";
  45789. this.parentStyleSheet = null;
  45790. this.cssRules = [];
  45791. this.ownerNode = ownerNode;
  45792. }
  45793. get rules() {
  45794. return this.cssRules;
  45795. }
  45796. set rules(rules) {
  45797. this.cssRules = rules;
  45798. }
  45799. deleteRule(index) {
  45800. if (index >= 0 && index < this.cssRules.length) {
  45801. this.cssRules.splice(index, 1);
  45802. updateStyleTextNode(this.ownerNode);
  45803. }
  45804. }
  45805. insertRule(rule, index = 0) {
  45806. if (typeof index !== "number") {
  45807. index = 0;
  45808. }
  45809. if (index < 0) {
  45810. index = 0;
  45811. }
  45812. if (index > this.cssRules.length) {
  45813. index = this.cssRules.length;
  45814. }
  45815. const cssRule = new MockCSSRule(this);
  45816. cssRule.cssText = rule;
  45817. this.cssRules.splice(index, 0, cssRule);
  45818. updateStyleTextNode(this.ownerNode);
  45819. return index;
  45820. }
  45821. };
  45822. function getStyleElementText(styleElm) {
  45823. const output = [];
  45824. for (let i = 0; i < styleElm.childNodes.length; i++) {
  45825. output.push(styleElm.childNodes[i].nodeValue);
  45826. }
  45827. return output.join("");
  45828. }
  45829. function setStyleElementText(styleElm, text) {
  45830. const sheet = styleElm.sheet;
  45831. sheet.cssRules.length = 0;
  45832. sheet.insertRule(text);
  45833. updateStyleTextNode(styleElm);
  45834. }
  45835. function updateStyleTextNode(styleElm) {
  45836. const childNodeLen = styleElm.childNodes.length;
  45837. if (childNodeLen > 1) {
  45838. for (let i = childNodeLen - 1; i >= 1; i--) {
  45839. styleElm.removeChild(styleElm.childNodes[i]);
  45840. }
  45841. } else if (childNodeLen < 1) {
  45842. styleElm.appendChild(styleElm.ownerDocument.createTextNode(""));
  45843. }
  45844. const textNode = styleElm.childNodes[0];
  45845. textNode.nodeValue = styleElm.sheet.cssRules.map((r) => r.cssText).join("\n");
  45846. }
  45847. // src/mock-doc/element.ts
  45848. function createElement(ownerDocument, tagName) {
  45849. if (typeof tagName !== "string" || tagName === "" || !/^[a-z0-9-_:]+$/i.test(tagName)) {
  45850. throw new Error(`The tag name provided (${tagName}) is not a valid name.`);
  45851. }
  45852. tagName = tagName.toLowerCase();
  45853. switch (tagName) {
  45854. case "a":
  45855. return new MockAnchorElement(ownerDocument);
  45856. case "base":
  45857. return new MockBaseElement(ownerDocument);
  45858. case "button":
  45859. return new MockButtonElement(ownerDocument);
  45860. case "canvas":
  45861. return new MockCanvasElement(ownerDocument);
  45862. case "form":
  45863. return new MockFormElement(ownerDocument);
  45864. case "img":
  45865. return new MockImageElement(ownerDocument);
  45866. case "input":
  45867. return new MockInputElement(ownerDocument);
  45868. case "link":
  45869. return new MockLinkElement(ownerDocument);
  45870. case "meta":
  45871. return new MockMetaElement(ownerDocument);
  45872. case "script":
  45873. return new MockScriptElement(ownerDocument);
  45874. case "style":
  45875. return new MockStyleElement(ownerDocument);
  45876. case "template":
  45877. return new MockTemplateElement(ownerDocument);
  45878. case "title":
  45879. return new MockTitleElement(ownerDocument);
  45880. case "ul":
  45881. return new MockUListElement(ownerDocument);
  45882. }
  45883. if (ownerDocument != null && tagName.includes("-")) {
  45884. const win = ownerDocument.defaultView;
  45885. if (win != null && win.customElements != null) {
  45886. return createCustomElement(win.customElements, ownerDocument, tagName);
  45887. }
  45888. }
  45889. return new MockHTMLElement(ownerDocument, tagName);
  45890. }
  45891. function createElementNS(ownerDocument, namespaceURI, tagName) {
  45892. if (namespaceURI === "http://www.w3.org/1999/xhtml") {
  45893. return createElement(ownerDocument, tagName);
  45894. } else if (namespaceURI === "http://www.w3.org/2000/svg") {
  45895. switch (tagName.toLowerCase()) {
  45896. case "text":
  45897. case "tspan":
  45898. case "tref":
  45899. case "altglyph":
  45900. case "textpath":
  45901. return new MockSVGTextContentElement(ownerDocument, tagName);
  45902. case "circle":
  45903. case "ellipse":
  45904. case "image":
  45905. case "line":
  45906. case "path":
  45907. case "polygon":
  45908. case "polyline":
  45909. case "rect":
  45910. case "use":
  45911. return new MockSVGGraphicsElement(ownerDocument, tagName);
  45912. case "svg":
  45913. return new MockSVGSVGElement(ownerDocument, tagName);
  45914. default:
  45915. return new MockSVGElement(ownerDocument, tagName);
  45916. }
  45917. } else {
  45918. return new MockElement(ownerDocument, tagName, namespaceURI);
  45919. }
  45920. }
  45921. var MockAnchorElement = class extends MockHTMLElement {
  45922. constructor(ownerDocument) {
  45923. super(ownerDocument, "a");
  45924. }
  45925. get href() {
  45926. return fullUrl(this, "href");
  45927. }
  45928. set href(value) {
  45929. this.setAttribute("href", value);
  45930. }
  45931. get pathname() {
  45932. return new URL(this.href).pathname;
  45933. }
  45934. };
  45935. var MockButtonElement = class extends MockHTMLElement {
  45936. constructor(ownerDocument) {
  45937. super(ownerDocument, "button");
  45938. }
  45939. };
  45940. patchPropAttributes(
  45941. MockButtonElement.prototype,
  45942. {
  45943. type: String
  45944. },
  45945. {
  45946. type: "submit"
  45947. }
  45948. );
  45949. var MockImageElement = class extends MockHTMLElement {
  45950. constructor(ownerDocument) {
  45951. super(ownerDocument, "img");
  45952. }
  45953. get draggable() {
  45954. return this.getAttributeNS(null, "draggable") !== "false";
  45955. }
  45956. set draggable(value) {
  45957. this.setAttributeNS(null, "draggable", value);
  45958. }
  45959. get src() {
  45960. return fullUrl(this, "src");
  45961. }
  45962. set src(value) {
  45963. this.setAttribute("src", value);
  45964. }
  45965. };
  45966. patchPropAttributes(MockImageElement.prototype, {
  45967. height: Number,
  45968. width: Number
  45969. });
  45970. var MockInputElement = class extends MockHTMLElement {
  45971. constructor(ownerDocument) {
  45972. super(ownerDocument, "input");
  45973. }
  45974. get list() {
  45975. const listId = this.getAttribute("list");
  45976. if (listId) {
  45977. return this.ownerDocument.getElementById(listId);
  45978. }
  45979. return null;
  45980. }
  45981. };
  45982. patchPropAttributes(
  45983. MockInputElement.prototype,
  45984. {
  45985. accept: String,
  45986. autocomplete: String,
  45987. autofocus: Boolean,
  45988. capture: String,
  45989. checked: Boolean,
  45990. disabled: Boolean,
  45991. form: String,
  45992. formaction: String,
  45993. formenctype: String,
  45994. formmethod: String,
  45995. formnovalidate: String,
  45996. formtarget: String,
  45997. height: Number,
  45998. inputmode: String,
  45999. max: String,
  46000. maxLength: Number,
  46001. min: String,
  46002. minLength: Number,
  46003. multiple: Boolean,
  46004. name: String,
  46005. pattern: String,
  46006. placeholder: String,
  46007. required: Boolean,
  46008. readOnly: Boolean,
  46009. size: Number,
  46010. spellCheck: Boolean,
  46011. src: String,
  46012. step: String,
  46013. type: String,
  46014. value: String,
  46015. width: Number
  46016. },
  46017. {
  46018. type: "text"
  46019. }
  46020. );
  46021. var MockFormElement = class extends MockHTMLElement {
  46022. constructor(ownerDocument) {
  46023. super(ownerDocument, "form");
  46024. }
  46025. };
  46026. patchPropAttributes(MockFormElement.prototype, {
  46027. name: String
  46028. });
  46029. var MockLinkElement = class extends MockHTMLElement {
  46030. constructor(ownerDocument) {
  46031. super(ownerDocument, "link");
  46032. }
  46033. get href() {
  46034. return fullUrl(this, "href");
  46035. }
  46036. set href(value) {
  46037. this.setAttribute("href", value);
  46038. }
  46039. };
  46040. patchPropAttributes(MockLinkElement.prototype, {
  46041. crossorigin: String,
  46042. media: String,
  46043. rel: String,
  46044. type: String
  46045. });
  46046. var MockMetaElement = class extends MockHTMLElement {
  46047. constructor(ownerDocument) {
  46048. super(ownerDocument, "meta");
  46049. }
  46050. };
  46051. patchPropAttributes(MockMetaElement.prototype, {
  46052. charset: String,
  46053. content: String,
  46054. name: String
  46055. });
  46056. var MockScriptElement = class extends MockHTMLElement {
  46057. constructor(ownerDocument) {
  46058. super(ownerDocument, "script");
  46059. }
  46060. get src() {
  46061. return fullUrl(this, "src");
  46062. }
  46063. set src(value) {
  46064. this.setAttribute("src", value);
  46065. }
  46066. };
  46067. patchPropAttributes(MockScriptElement.prototype, {
  46068. type: String
  46069. });
  46070. var MockDOMMatrix = class _MockDOMMatrix {
  46071. constructor() {
  46072. this.a = 1;
  46073. this.b = 0;
  46074. this.c = 0;
  46075. this.d = 1;
  46076. this.e = 0;
  46077. this.f = 0;
  46078. this.m11 = 1;
  46079. this.m12 = 0;
  46080. this.m13 = 0;
  46081. this.m14 = 0;
  46082. this.m21 = 0;
  46083. this.m22 = 1;
  46084. this.m23 = 0;
  46085. this.m24 = 0;
  46086. this.m31 = 0;
  46087. this.m32 = 0;
  46088. this.m33 = 1;
  46089. this.m34 = 0;
  46090. this.m41 = 0;
  46091. this.m42 = 0;
  46092. this.m43 = 0;
  46093. this.m44 = 1;
  46094. this.is2D = true;
  46095. this.isIdentity = true;
  46096. }
  46097. static fromMatrix() {
  46098. return new _MockDOMMatrix();
  46099. }
  46100. inverse() {
  46101. return new _MockDOMMatrix();
  46102. }
  46103. flipX() {
  46104. return new _MockDOMMatrix();
  46105. }
  46106. flipY() {
  46107. return new _MockDOMMatrix();
  46108. }
  46109. multiply() {
  46110. return new _MockDOMMatrix();
  46111. }
  46112. rotate() {
  46113. return new _MockDOMMatrix();
  46114. }
  46115. rotateAxisAngle() {
  46116. return new _MockDOMMatrix();
  46117. }
  46118. rotateFromVector() {
  46119. return new _MockDOMMatrix();
  46120. }
  46121. scale() {
  46122. return new _MockDOMMatrix();
  46123. }
  46124. scaleNonUniform() {
  46125. return new _MockDOMMatrix();
  46126. }
  46127. skewX() {
  46128. return new _MockDOMMatrix();
  46129. }
  46130. skewY() {
  46131. return new _MockDOMMatrix();
  46132. }
  46133. toJSON() {
  46134. }
  46135. toString() {
  46136. }
  46137. transformPoint() {
  46138. return new MockDOMPoint();
  46139. }
  46140. translate() {
  46141. return new _MockDOMMatrix();
  46142. }
  46143. };
  46144. var MockDOMPoint = class {
  46145. constructor() {
  46146. this.w = 1;
  46147. this.x = 0;
  46148. this.y = 0;
  46149. this.z = 0;
  46150. }
  46151. toJSON() {
  46152. }
  46153. matrixTransform() {
  46154. return new MockDOMMatrix();
  46155. }
  46156. };
  46157. var MockSVGRect = class {
  46158. constructor() {
  46159. this.height = 10;
  46160. this.width = 10;
  46161. this.x = 0;
  46162. this.y = 0;
  46163. }
  46164. };
  46165. var MockStyleElement = class extends MockHTMLElement {
  46166. constructor(ownerDocument) {
  46167. super(ownerDocument, "style");
  46168. this.sheet = new MockCSSStyleSheet(this);
  46169. }
  46170. get innerHTML() {
  46171. return getStyleElementText(this);
  46172. }
  46173. set innerHTML(value) {
  46174. setStyleElementText(this, value);
  46175. }
  46176. get innerText() {
  46177. return getStyleElementText(this);
  46178. }
  46179. set innerText(value) {
  46180. setStyleElementText(this, value);
  46181. }
  46182. get textContent() {
  46183. return getStyleElementText(this);
  46184. }
  46185. set textContent(value) {
  46186. setStyleElementText(this, value);
  46187. }
  46188. };
  46189. var MockSVGElement = class extends MockElement {
  46190. constructor() {
  46191. super(...arguments);
  46192. this.__namespaceURI = "http://www.w3.org/2000/svg";
  46193. }
  46194. // SVGElement properties and methods
  46195. get ownerSVGElement() {
  46196. return null;
  46197. }
  46198. get viewportElement() {
  46199. return null;
  46200. }
  46201. onunload() {
  46202. }
  46203. // SVGGeometryElement properties and methods
  46204. get pathLength() {
  46205. return 0;
  46206. }
  46207. isPointInFill(_pt) {
  46208. return false;
  46209. }
  46210. isPointInStroke(_pt) {
  46211. return false;
  46212. }
  46213. getTotalLength() {
  46214. return 0;
  46215. }
  46216. };
  46217. var MockSVGGraphicsElement = class extends MockSVGElement {
  46218. getBBox(_options) {
  46219. return new MockSVGRect();
  46220. }
  46221. getCTM() {
  46222. return new MockDOMMatrix();
  46223. }
  46224. getScreenCTM() {
  46225. return new MockDOMMatrix();
  46226. }
  46227. };
  46228. var MockSVGSVGElement = class extends MockSVGGraphicsElement {
  46229. createSVGPoint() {
  46230. return new MockDOMPoint();
  46231. }
  46232. };
  46233. var MockSVGTextContentElement = class extends MockSVGGraphicsElement {
  46234. getComputedTextLength() {
  46235. return 0;
  46236. }
  46237. };
  46238. var MockBaseElement = class extends MockHTMLElement {
  46239. constructor(ownerDocument) {
  46240. super(ownerDocument, "base");
  46241. }
  46242. get href() {
  46243. return fullUrl(this, "href");
  46244. }
  46245. set href(value) {
  46246. this.setAttribute("href", value);
  46247. }
  46248. };
  46249. var MockTemplateElement = class _MockTemplateElement extends MockHTMLElement {
  46250. constructor(ownerDocument) {
  46251. super(ownerDocument, "template");
  46252. this.content = new MockDocumentFragment(ownerDocument);
  46253. }
  46254. get innerHTML() {
  46255. return this.content.innerHTML;
  46256. }
  46257. set innerHTML(html) {
  46258. this.content.innerHTML = html;
  46259. }
  46260. cloneNode(deep) {
  46261. const cloned = new _MockTemplateElement(null);
  46262. cloned.attributes = cloneAttributes(this.attributes);
  46263. const styleCssText = this.getAttribute("style");
  46264. if (styleCssText != null && styleCssText.length > 0) {
  46265. cloned.setAttribute("style", styleCssText);
  46266. }
  46267. cloned.content = this.content.cloneNode(deep);
  46268. if (deep) {
  46269. for (let i = 0, ii = this.childNodes.length; i < ii; i++) {
  46270. const clonedChildNode = this.childNodes[i].cloneNode(true);
  46271. cloned.appendChild(clonedChildNode);
  46272. }
  46273. }
  46274. return cloned;
  46275. }
  46276. };
  46277. var MockTitleElement = class extends MockHTMLElement {
  46278. constructor(ownerDocument) {
  46279. super(ownerDocument, "title");
  46280. }
  46281. get text() {
  46282. return this.textContent;
  46283. }
  46284. set text(value) {
  46285. this.textContent = value;
  46286. }
  46287. };
  46288. var MockUListElement = class extends MockHTMLElement {
  46289. constructor(ownerDocument) {
  46290. super(ownerDocument, "ul");
  46291. }
  46292. };
  46293. var CanvasRenderingContext = class {
  46294. constructor(context, contextAttributes) {
  46295. this.context = context;
  46296. this.contextAttributes = contextAttributes;
  46297. }
  46298. fillRect() {
  46299. return;
  46300. }
  46301. clearRect() {
  46302. }
  46303. getImageData(_, __, w, h) {
  46304. return {
  46305. data: new Array(w * h * 4)
  46306. };
  46307. }
  46308. toDataURL() {
  46309. return "data:,";
  46310. }
  46311. putImageData() {
  46312. }
  46313. createImageData() {
  46314. return {};
  46315. }
  46316. setTransform() {
  46317. }
  46318. drawImage() {
  46319. }
  46320. save() {
  46321. }
  46322. fillText() {
  46323. }
  46324. restore() {
  46325. }
  46326. beginPath() {
  46327. }
  46328. moveTo() {
  46329. }
  46330. lineTo() {
  46331. }
  46332. closePath() {
  46333. }
  46334. stroke() {
  46335. }
  46336. translate() {
  46337. }
  46338. scale() {
  46339. }
  46340. rotate() {
  46341. }
  46342. arc() {
  46343. }
  46344. fill() {
  46345. }
  46346. measureText() {
  46347. return { width: 0 };
  46348. }
  46349. transform() {
  46350. }
  46351. rect() {
  46352. }
  46353. clip() {
  46354. }
  46355. };
  46356. var MockCanvasElement = class extends MockHTMLElement {
  46357. constructor(ownerDocument) {
  46358. super(ownerDocument, "canvas");
  46359. }
  46360. getContext(context, contextAttributes) {
  46361. return new CanvasRenderingContext(context, contextAttributes);
  46362. }
  46363. };
  46364. function fullUrl(elm, attrName) {
  46365. const val = elm.getAttribute(attrName) || "";
  46366. if (elm.ownerDocument != null) {
  46367. const win = elm.ownerDocument.defaultView;
  46368. if (win != null) {
  46369. const loc = win.location;
  46370. if (loc != null) {
  46371. try {
  46372. const url = new URL(val, loc.href);
  46373. return url.href;
  46374. } catch (e) {
  46375. }
  46376. }
  46377. }
  46378. }
  46379. return val.replace(/\'|\"/g, "").trim();
  46380. }
  46381. function patchPropAttributes(prototype, attrs, defaults = {}) {
  46382. Object.keys(attrs).forEach((propName) => {
  46383. const attr = attrs[propName];
  46384. const defaultValue = defaults[propName];
  46385. if (attr === Boolean) {
  46386. Object.defineProperty(prototype, propName, {
  46387. get() {
  46388. return this.hasAttribute(propName);
  46389. },
  46390. set(value) {
  46391. if (value) {
  46392. this.setAttribute(propName, "");
  46393. } else {
  46394. this.removeAttribute(propName);
  46395. }
  46396. }
  46397. });
  46398. } else if (attr === Number) {
  46399. Object.defineProperty(prototype, propName, {
  46400. get() {
  46401. const value = this.getAttribute(propName);
  46402. return value ? parseInt(value, 10) : defaultValue === void 0 ? 0 : defaultValue;
  46403. },
  46404. set(value) {
  46405. this.setAttribute(propName, value);
  46406. }
  46407. });
  46408. } else {
  46409. Object.defineProperty(prototype, propName, {
  46410. get() {
  46411. return this.hasAttribute(propName) ? this.getAttribute(propName) : defaultValue || "";
  46412. },
  46413. set(value) {
  46414. this.setAttribute(propName, value);
  46415. }
  46416. });
  46417. }
  46418. });
  46419. }
  46420. MockElement.prototype.cloneNode = function(deep) {
  46421. const cloned = createElement(this.ownerDocument, this.nodeName);
  46422. cloned.attributes = cloneAttributes(this.attributes);
  46423. const styleCssText = this.getAttribute("style");
  46424. if (styleCssText != null && styleCssText.length > 0) {
  46425. cloned.setAttribute("style", styleCssText);
  46426. }
  46427. if (deep) {
  46428. for (let i = 0, ii = this.childNodes.length; i < ii; i++) {
  46429. const clonedChildNode = this.childNodes[i].cloneNode(true);
  46430. cloned.appendChild(clonedChildNode);
  46431. }
  46432. }
  46433. return cloned;
  46434. };
  46435. // src/mock-doc/parse-html.ts
  46436. var sharedDocument;
  46437. function parseHtmlToDocument(html, ownerDocument = null) {
  46438. if (ownerDocument == null) {
  46439. if (sharedDocument == null) {
  46440. sharedDocument = new MockDocument();
  46441. }
  46442. ownerDocument = sharedDocument;
  46443. }
  46444. return parseDocumentUtil(ownerDocument, html);
  46445. }
  46446. // src/mock-doc/console.ts
  46447. var consoleNoop = () => {
  46448. };
  46449. function createConsole() {
  46450. return {
  46451. debug: consoleNoop,
  46452. error: consoleNoop,
  46453. info: consoleNoop,
  46454. log: consoleNoop,
  46455. warn: consoleNoop,
  46456. dir: consoleNoop,
  46457. dirxml: consoleNoop,
  46458. table: consoleNoop,
  46459. trace: consoleNoop,
  46460. group: consoleNoop,
  46461. groupCollapsed: consoleNoop,
  46462. groupEnd: consoleNoop,
  46463. clear: consoleNoop,
  46464. count: consoleNoop,
  46465. countReset: consoleNoop,
  46466. assert: consoleNoop,
  46467. profile: consoleNoop,
  46468. profileEnd: consoleNoop,
  46469. time: consoleNoop,
  46470. timeLog: consoleNoop,
  46471. timeEnd: consoleNoop,
  46472. timeStamp: consoleNoop,
  46473. context: consoleNoop,
  46474. memory: consoleNoop
  46475. };
  46476. }
  46477. // src/mock-doc/headers.ts
  46478. var MockHeaders = class {
  46479. constructor(init) {
  46480. this._values = [];
  46481. if (typeof init === "object") {
  46482. if (typeof init[Symbol.iterator] === "function") {
  46483. const kvs = [];
  46484. for (const kv of init) {
  46485. if (typeof kv[Symbol.iterator] === "function") {
  46486. kvs.push([...kv]);
  46487. }
  46488. }
  46489. for (const kv of kvs) {
  46490. this.append(kv[0], kv[1]);
  46491. }
  46492. } else {
  46493. for (const key in init) {
  46494. this.append(key, init[key]);
  46495. }
  46496. }
  46497. }
  46498. }
  46499. append(key, value) {
  46500. this._values.push([key, value + ""]);
  46501. }
  46502. delete(key) {
  46503. key = key.toLowerCase();
  46504. for (let i = this._values.length - 1; i >= 0; i--) {
  46505. if (this._values[i][0].toLowerCase() === key) {
  46506. this._values.splice(i, 1);
  46507. }
  46508. }
  46509. }
  46510. entries() {
  46511. const entries = [];
  46512. for (const kv of this.keys()) {
  46513. entries.push([kv, this.get(kv)]);
  46514. }
  46515. let index = -1;
  46516. return {
  46517. next() {
  46518. index++;
  46519. return {
  46520. value: entries[index],
  46521. done: !entries[index]
  46522. };
  46523. },
  46524. [Symbol.iterator]() {
  46525. return this;
  46526. }
  46527. };
  46528. }
  46529. forEach(cb) {
  46530. for (const kv of this.entries()) {
  46531. cb(kv[1], kv[0]);
  46532. }
  46533. }
  46534. get(key) {
  46535. const rtn = [];
  46536. key = key.toLowerCase();
  46537. for (const kv of this._values) {
  46538. if (kv[0].toLowerCase() === key) {
  46539. rtn.push(kv[1]);
  46540. }
  46541. }
  46542. return rtn.length > 0 ? rtn.join(", ") : null;
  46543. }
  46544. has(key) {
  46545. key = key.toLowerCase();
  46546. for (const kv of this._values) {
  46547. if (kv[0].toLowerCase() === key) {
  46548. return true;
  46549. }
  46550. }
  46551. return false;
  46552. }
  46553. keys() {
  46554. const keys = [];
  46555. for (const kv of this._values) {
  46556. const key = kv[0].toLowerCase();
  46557. if (!keys.includes(key)) {
  46558. keys.push(key);
  46559. }
  46560. }
  46561. let index = -1;
  46562. return {
  46563. next() {
  46564. index++;
  46565. return {
  46566. value: keys[index],
  46567. done: !keys[index]
  46568. };
  46569. },
  46570. [Symbol.iterator]() {
  46571. return this;
  46572. }
  46573. };
  46574. }
  46575. set(key, value) {
  46576. for (const kv of this._values) {
  46577. if (kv[0].toLowerCase() === key.toLowerCase()) {
  46578. kv[1] = value + "";
  46579. return;
  46580. }
  46581. }
  46582. this.append(key, value);
  46583. }
  46584. values() {
  46585. const values = this._values;
  46586. let index = -1;
  46587. return {
  46588. next() {
  46589. index++;
  46590. const done = !values[index];
  46591. return {
  46592. value: done ? void 0 : values[index][1],
  46593. done
  46594. };
  46595. },
  46596. [Symbol.iterator]() {
  46597. return this;
  46598. }
  46599. };
  46600. }
  46601. [Symbol.iterator]() {
  46602. return this.entries();
  46603. }
  46604. };
  46605. // src/mock-doc/parser.ts
  46606. var MockDOMParser = class {
  46607. parseFromString(htmlToParse, mimeType) {
  46608. if (mimeType !== "text/html") {
  46609. console.error("XML parsing not implemented yet, continuing as html");
  46610. }
  46611. return parseHtmlToDocument(htmlToParse);
  46612. }
  46613. };
  46614. // src/mock-doc/request-response.ts
  46615. var MockRequest = class _MockRequest {
  46616. constructor(input, init = {}) {
  46617. this._method = "GET";
  46618. this._url = "/";
  46619. this.bodyUsed = false;
  46620. this.cache = "default";
  46621. this.credentials = "same-origin";
  46622. this.integrity = "";
  46623. this.keepalive = false;
  46624. this.mode = "cors";
  46625. this.redirect = "follow";
  46626. this.referrer = "about:client";
  46627. this.referrerPolicy = "";
  46628. if (typeof input === "string") {
  46629. this.url = input;
  46630. } else if (input) {
  46631. Object.assign(this, input);
  46632. this.headers = new MockHeaders(input.headers);
  46633. }
  46634. Object.assign(this, init);
  46635. if (init.headers) {
  46636. this.headers = new MockHeaders(init.headers);
  46637. }
  46638. if (!this.headers) {
  46639. this.headers = new MockHeaders();
  46640. }
  46641. }
  46642. get url() {
  46643. if (typeof this._url === "string") {
  46644. return new URL(this._url, location.href).href;
  46645. }
  46646. return new URL("/", location.href).href;
  46647. }
  46648. set url(value) {
  46649. this._url = value;
  46650. }
  46651. get method() {
  46652. if (typeof this._method === "string") {
  46653. return this._method.toUpperCase();
  46654. }
  46655. return "GET";
  46656. }
  46657. set method(value) {
  46658. this._method = value;
  46659. }
  46660. clone() {
  46661. const clone = { ...this };
  46662. clone.headers = new MockHeaders(this.headers);
  46663. return new _MockRequest(clone);
  46664. }
  46665. };
  46666. var MockResponse = class _MockResponse {
  46667. constructor(body, init = {}) {
  46668. this.ok = true;
  46669. this.status = 200;
  46670. this.statusText = "";
  46671. this.type = "default";
  46672. this.url = "";
  46673. this._body = body;
  46674. if (init) {
  46675. Object.assign(this, init);
  46676. }
  46677. this.headers = new MockHeaders(init.headers);
  46678. }
  46679. async json() {
  46680. return JSON.parse(this._body);
  46681. }
  46682. async text() {
  46683. return this._body;
  46684. }
  46685. clone() {
  46686. const initClone = { ...this };
  46687. initClone.headers = new MockHeaders(this.headers);
  46688. return new _MockResponse(this._body, initClone);
  46689. }
  46690. };
  46691. // src/mock-doc/global.ts
  46692. function patchWindow(winToBePatched) {
  46693. const mockWin = new MockWindow(false);
  46694. WINDOW_FUNCTIONS.forEach((fnName) => {
  46695. if (typeof winToBePatched[fnName] !== "function") {
  46696. winToBePatched[fnName] = mockWin[fnName].bind(mockWin);
  46697. }
  46698. });
  46699. WINDOW_PROPS.forEach((propName) => {
  46700. if (winToBePatched === void 0) {
  46701. Object.defineProperty(winToBePatched, propName, {
  46702. get() {
  46703. return mockWin[propName];
  46704. },
  46705. set(val) {
  46706. mockWin[propName] = val;
  46707. },
  46708. configurable: true,
  46709. enumerable: true
  46710. });
  46711. }
  46712. });
  46713. }
  46714. function addGlobalsToWindowPrototype(mockWinPrototype) {
  46715. GLOBAL_CONSTRUCTORS.forEach(([cstrName, Cstr]) => {
  46716. Object.defineProperty(mockWinPrototype, cstrName, {
  46717. get() {
  46718. return this["__" + cstrName] || Cstr;
  46719. },
  46720. set(cstr) {
  46721. this["__" + cstrName] = cstr;
  46722. },
  46723. configurable: true,
  46724. enumerable: true
  46725. });
  46726. });
  46727. }
  46728. var WINDOW_FUNCTIONS = [
  46729. "addEventListener",
  46730. "alert",
  46731. "blur",
  46732. "cancelAnimationFrame",
  46733. "cancelIdleCallback",
  46734. "clearInterval",
  46735. "clearTimeout",
  46736. "close",
  46737. "confirm",
  46738. "dispatchEvent",
  46739. "focus",
  46740. "getComputedStyle",
  46741. "matchMedia",
  46742. "open",
  46743. "prompt",
  46744. "removeEventListener",
  46745. "requestAnimationFrame",
  46746. "requestIdleCallback",
  46747. "URL"
  46748. ];
  46749. var WINDOW_PROPS = [
  46750. "customElements",
  46751. "devicePixelRatio",
  46752. "document",
  46753. "history",
  46754. "innerHeight",
  46755. "innerWidth",
  46756. "localStorage",
  46757. "location",
  46758. "navigator",
  46759. "pageXOffset",
  46760. "pageYOffset",
  46761. "performance",
  46762. "screenLeft",
  46763. "screenTop",
  46764. "screenX",
  46765. "screenY",
  46766. "scrollX",
  46767. "scrollY",
  46768. "sessionStorage",
  46769. "CSS",
  46770. "CustomEvent",
  46771. "Event",
  46772. "Element",
  46773. "HTMLElement",
  46774. "Node",
  46775. "NodeList",
  46776. "FocusEvent",
  46777. "KeyboardEvent",
  46778. "MouseEvent"
  46779. ];
  46780. var GLOBAL_CONSTRUCTORS = [
  46781. ["CustomEvent", MockCustomEvent],
  46782. ["DocumentFragment", MockDocumentFragment],
  46783. ["DOMParser", MockDOMParser],
  46784. ["Event", MockEvent],
  46785. ["FocusEvent", MockFocusEvent],
  46786. ["Headers", MockHeaders],
  46787. ["KeyboardEvent", MockKeyboardEvent],
  46788. ["MouseEvent", MockMouseEvent],
  46789. ["Request", MockRequest],
  46790. ["Response", MockResponse],
  46791. ["ShadowRoot", MockDocumentFragment],
  46792. ["HTMLAnchorElement", MockAnchorElement],
  46793. ["HTMLBaseElement", MockBaseElement],
  46794. ["HTMLButtonElement", MockButtonElement],
  46795. ["HTMLCanvasElement", MockCanvasElement],
  46796. ["HTMLFormElement", MockFormElement],
  46797. ["HTMLImageElement", MockImageElement],
  46798. ["HTMLInputElement", MockInputElement],
  46799. ["HTMLLinkElement", MockLinkElement],
  46800. ["HTMLMetaElement", MockMetaElement],
  46801. ["HTMLScriptElement", MockScriptElement],
  46802. ["HTMLStyleElement", MockStyleElement],
  46803. ["HTMLTemplateElement", MockTemplateElement],
  46804. ["HTMLTitleElement", MockTitleElement],
  46805. ["HTMLUListElement", MockUListElement]
  46806. ];
  46807. // src/mock-doc/history.ts
  46808. var MockHistory = class {
  46809. constructor() {
  46810. this.items = [];
  46811. }
  46812. get length() {
  46813. return this.items.length;
  46814. }
  46815. back() {
  46816. this.go(-1);
  46817. }
  46818. forward() {
  46819. this.go(1);
  46820. }
  46821. go(_value) {
  46822. }
  46823. pushState(_state, _title, _url) {
  46824. }
  46825. replaceState(_state, _title, _url) {
  46826. }
  46827. };
  46828. // src/mock-doc/intersection-observer.ts
  46829. var MockIntersectionObserver = class {
  46830. constructor() {
  46831. }
  46832. disconnect() {
  46833. }
  46834. observe() {
  46835. }
  46836. takeRecords() {
  46837. return [];
  46838. }
  46839. unobserve() {
  46840. }
  46841. };
  46842. // src/mock-doc/location.ts
  46843. var MockLocation = class {
  46844. constructor() {
  46845. this.ancestorOrigins = null;
  46846. this.protocol = "";
  46847. this.host = "";
  46848. this.hostname = "";
  46849. this.port = "";
  46850. this.pathname = "";
  46851. this.search = "";
  46852. this.hash = "";
  46853. this.username = "";
  46854. this.password = "";
  46855. this.origin = "";
  46856. this._href = "";
  46857. }
  46858. get href() {
  46859. return this._href;
  46860. }
  46861. set href(value) {
  46862. const url = new URL(value, "http://mockdoc.stenciljs.com");
  46863. this._href = url.href;
  46864. this.protocol = url.protocol;
  46865. this.host = url.host;
  46866. this.hostname = url.hostname;
  46867. this.port = url.port;
  46868. this.pathname = url.pathname;
  46869. this.search = url.search;
  46870. this.hash = url.hash;
  46871. this.username = url.username;
  46872. this.password = url.password;
  46873. this.origin = url.origin;
  46874. }
  46875. assign(_url) {
  46876. }
  46877. reload(_forcedReload) {
  46878. }
  46879. replace(_url) {
  46880. }
  46881. toString() {
  46882. return this.href;
  46883. }
  46884. };
  46885. // src/mock-doc/navigator.ts
  46886. var MockNavigator = class {
  46887. constructor() {
  46888. this.appCodeName = "MockNavigator";
  46889. this.appName = "MockNavigator";
  46890. this.appVersion = "MockNavigator";
  46891. this.platform = "MockNavigator";
  46892. this.userAgent = "MockNavigator";
  46893. }
  46894. };
  46895. // src/mock-doc/performance.ts
  46896. var MockPerformance = class {
  46897. constructor() {
  46898. this.timeOrigin = Date.now();
  46899. this.eventCounts = /* @__PURE__ */ new Map();
  46900. }
  46901. addEventListener() {
  46902. }
  46903. clearMarks() {
  46904. }
  46905. clearMeasures() {
  46906. }
  46907. clearResourceTimings() {
  46908. }
  46909. dispatchEvent() {
  46910. return true;
  46911. }
  46912. getEntries() {
  46913. return [];
  46914. }
  46915. getEntriesByName() {
  46916. return [];
  46917. }
  46918. getEntriesByType() {
  46919. return [];
  46920. }
  46921. // Stencil's implementation of `mark` is non-compliant with the `Performance` interface. Because Stencil will
  46922. // instantiate an instance of this class and may attempt to assign it to a variable of type `Performance`, the return
  46923. // type must match the `Performance` interface (rather than typing this function as returning `void` and ignoring the
  46924. // associated errors returned by the type checker)
  46925. // @ts-ignore
  46926. mark() {
  46927. }
  46928. // Stencil's implementation of `measure` is non-compliant with the `Performance` interface. Because Stencil will
  46929. // instantiate an instance of this class and may attempt to assign it to a variable of type `Performance`, the return
  46930. // type must match the `Performance` interface (rather than typing this function as returning `void` and ignoring the
  46931. // associated errors returned by the type checker)
  46932. // @ts-ignore
  46933. measure() {
  46934. }
  46935. get navigation() {
  46936. return {};
  46937. }
  46938. now() {
  46939. return Date.now() - this.timeOrigin;
  46940. }
  46941. get onresourcetimingbufferfull() {
  46942. return null;
  46943. }
  46944. removeEventListener() {
  46945. }
  46946. setResourceTimingBufferSize() {
  46947. }
  46948. get timing() {
  46949. return {};
  46950. }
  46951. toJSON() {
  46952. }
  46953. };
  46954. function resetPerformance(perf) {
  46955. if (perf != null) {
  46956. try {
  46957. perf.timeOrigin = Date.now();
  46958. } catch (e) {
  46959. }
  46960. }
  46961. }
  46962. // src/mock-doc/storage.ts
  46963. var MockStorage = class {
  46964. constructor() {
  46965. this.items = /* @__PURE__ */ new Map();
  46966. }
  46967. key(_value) {
  46968. }
  46969. getItem(key) {
  46970. key = String(key);
  46971. if (this.items.has(key)) {
  46972. return this.items.get(key);
  46973. }
  46974. return null;
  46975. }
  46976. setItem(key, value) {
  46977. if (value == null) {
  46978. value = "null";
  46979. }
  46980. this.items.set(String(key), String(value));
  46981. }
  46982. removeItem(key) {
  46983. this.items.delete(String(key));
  46984. }
  46985. clear() {
  46986. this.items.clear();
  46987. }
  46988. };
  46989. // src/mock-doc/window.ts
  46990. var nativeClearInterval = clearInterval;
  46991. var nativeClearTimeout = clearTimeout;
  46992. var nativeSetInterval = setInterval;
  46993. var nativeSetTimeout = setTimeout;
  46994. var nativeURL = URL;
  46995. var nativeWindow = globalThis.window;
  46996. var MockWindow = class {
  46997. constructor(html = null) {
  46998. if (html !== false) {
  46999. this.document = new MockDocument(html, this);
  47000. } else {
  47001. this.document = null;
  47002. }
  47003. this.performance = new MockPerformance();
  47004. this.customElements = new MockCustomElementRegistry(this);
  47005. this.console = createConsole();
  47006. resetWindowDefaults(this);
  47007. resetWindowDimensions(this);
  47008. }
  47009. addEventListener(type, handler) {
  47010. addEventListener(this, type, handler);
  47011. }
  47012. alert(msg) {
  47013. if (this.console) {
  47014. this.console.debug(msg);
  47015. } else {
  47016. console.debug(msg);
  47017. }
  47018. }
  47019. blur() {
  47020. }
  47021. cancelAnimationFrame(id) {
  47022. this.__clearTimeout.call(nativeWindow || this, id);
  47023. }
  47024. cancelIdleCallback(id) {
  47025. this.__clearTimeout.call(nativeWindow || this, id);
  47026. }
  47027. get CharacterData() {
  47028. if (this.__charDataCstr == null) {
  47029. const ownerDocument = this.document;
  47030. this.__charDataCstr = class extends MockNode2 {
  47031. constructor() {
  47032. super(ownerDocument, 0, "test", "");
  47033. throw new Error("Illegal constructor: cannot construct CharacterData");
  47034. }
  47035. };
  47036. }
  47037. return this.__charDataCstr;
  47038. }
  47039. set CharacterData(charDataCstr) {
  47040. this.__charDataCstr = charDataCstr;
  47041. }
  47042. clearInterval(id) {
  47043. this.__clearInterval.call(nativeWindow || this, id);
  47044. }
  47045. clearTimeout(id) {
  47046. this.__clearTimeout.call(nativeWindow || this, id);
  47047. }
  47048. close() {
  47049. resetWindow(this);
  47050. }
  47051. confirm() {
  47052. return false;
  47053. }
  47054. get CSS() {
  47055. return {
  47056. supports: () => true
  47057. };
  47058. }
  47059. get Document() {
  47060. if (this.__docCstr == null) {
  47061. const win = this;
  47062. this.__docCstr = class extends MockDocument {
  47063. constructor() {
  47064. super(false, win);
  47065. throw new Error("Illegal constructor: cannot construct Document");
  47066. }
  47067. };
  47068. }
  47069. return this.__docCstr;
  47070. }
  47071. set Document(docCstr) {
  47072. this.__docCstr = docCstr;
  47073. }
  47074. get DocumentFragment() {
  47075. if (this.__docFragCstr == null) {
  47076. const ownerDocument = this.document;
  47077. this.__docFragCstr = class extends MockDocumentFragment {
  47078. constructor() {
  47079. super(ownerDocument);
  47080. throw new Error("Illegal constructor: cannot construct DocumentFragment");
  47081. }
  47082. };
  47083. }
  47084. return this.__docFragCstr;
  47085. }
  47086. set DocumentFragment(docFragCstr) {
  47087. this.__docFragCstr = docFragCstr;
  47088. }
  47089. get DocumentType() {
  47090. if (this.__docTypeCstr == null) {
  47091. const ownerDocument = this.document;
  47092. this.__docTypeCstr = class extends MockNode2 {
  47093. constructor() {
  47094. super(ownerDocument, 0, "test", "");
  47095. throw new Error("Illegal constructor: cannot construct DocumentType");
  47096. }
  47097. };
  47098. }
  47099. return this.__docTypeCstr;
  47100. }
  47101. set DocumentType(docTypeCstr) {
  47102. this.__docTypeCstr = docTypeCstr;
  47103. }
  47104. get DOMTokenList() {
  47105. if (this.__domTokenListCstr == null) {
  47106. this.__domTokenListCstr = class MockDOMTokenList {
  47107. };
  47108. }
  47109. return this.__domTokenListCstr;
  47110. }
  47111. set DOMTokenList(domTokenListCstr) {
  47112. this.__domTokenListCstr = domTokenListCstr;
  47113. }
  47114. dispatchEvent(ev) {
  47115. return dispatchEvent(this, ev);
  47116. }
  47117. get Element() {
  47118. if (this.__elementCstr == null) {
  47119. const ownerDocument = this.document;
  47120. this.__elementCstr = class extends MockElement {
  47121. constructor() {
  47122. super(ownerDocument, "");
  47123. throw new Error("Illegal constructor: cannot construct Element");
  47124. }
  47125. };
  47126. }
  47127. return this.__elementCstr;
  47128. }
  47129. fetch(input, init) {
  47130. if (typeof fetch === "function") {
  47131. return fetch(input, init);
  47132. }
  47133. throw new Error(`fetch() not implemented`);
  47134. }
  47135. focus() {
  47136. }
  47137. getComputedStyle(_) {
  47138. return {
  47139. cssText: "",
  47140. length: 0,
  47141. parentRule: null,
  47142. getPropertyPriority() {
  47143. return null;
  47144. },
  47145. getPropertyValue() {
  47146. return "";
  47147. },
  47148. item() {
  47149. return null;
  47150. },
  47151. removeProperty() {
  47152. return null;
  47153. },
  47154. setProperty() {
  47155. return null;
  47156. }
  47157. };
  47158. }
  47159. get globalThis() {
  47160. return this;
  47161. }
  47162. get history() {
  47163. if (this.__history == null) {
  47164. this.__history = new MockHistory();
  47165. }
  47166. return this.__history;
  47167. }
  47168. set history(hsty) {
  47169. this.__history = hsty;
  47170. }
  47171. get JSON() {
  47172. return JSON;
  47173. }
  47174. get HTMLElement() {
  47175. if (this.__htmlElementCstr == null) {
  47176. const ownerDocument = this.document;
  47177. this.__htmlElementCstr = class extends MockHTMLElement {
  47178. constructor() {
  47179. super(ownerDocument, "");
  47180. const observedAttributes = this.constructor.observedAttributes;
  47181. if (Array.isArray(observedAttributes) && typeof this.attributeChangedCallback === "function") {
  47182. observedAttributes.forEach((attrName) => {
  47183. const attrValue = this.getAttribute(attrName);
  47184. if (attrValue != null) {
  47185. this.attributeChangedCallback(attrName, null, attrValue);
  47186. }
  47187. });
  47188. }
  47189. }
  47190. };
  47191. }
  47192. return this.__htmlElementCstr;
  47193. }
  47194. set HTMLElement(htmlElementCstr) {
  47195. this.__htmlElementCstr = htmlElementCstr;
  47196. }
  47197. get IntersectionObserver() {
  47198. return MockIntersectionObserver;
  47199. }
  47200. get localStorage() {
  47201. if (this.__localStorage == null) {
  47202. this.__localStorage = new MockStorage();
  47203. }
  47204. return this.__localStorage;
  47205. }
  47206. set localStorage(locStorage) {
  47207. this.__localStorage = locStorage;
  47208. }
  47209. get location() {
  47210. if (this.__location == null) {
  47211. this.__location = new MockLocation();
  47212. }
  47213. return this.__location;
  47214. }
  47215. set location(val) {
  47216. if (typeof val === "string") {
  47217. if (this.__location == null) {
  47218. this.__location = new MockLocation();
  47219. }
  47220. this.__location.href = val;
  47221. } else {
  47222. this.__location = val;
  47223. }
  47224. }
  47225. matchMedia(media) {
  47226. return {
  47227. media,
  47228. matches: false,
  47229. addListener: (_handler) => {
  47230. },
  47231. removeListener: (_handler) => {
  47232. },
  47233. addEventListener: (_type, _handler) => {
  47234. },
  47235. removeEventListener: (_type, _handler) => {
  47236. },
  47237. dispatchEvent: (_ev) => {
  47238. },
  47239. onchange: null
  47240. };
  47241. }
  47242. get Node() {
  47243. if (this.__nodeCstr == null) {
  47244. const ownerDocument = this.document;
  47245. this.__nodeCstr = class extends MockNode2 {
  47246. constructor() {
  47247. super(ownerDocument, 0, "test", "");
  47248. throw new Error("Illegal constructor: cannot construct Node");
  47249. }
  47250. };
  47251. }
  47252. return this.__nodeCstr;
  47253. }
  47254. get NodeList() {
  47255. if (this.__nodeListCstr == null) {
  47256. const ownerDocument = this.document;
  47257. this.__nodeListCstr = class extends MockNodeList {
  47258. constructor() {
  47259. super(ownerDocument, [], 0);
  47260. throw new Error("Illegal constructor: cannot construct NodeList");
  47261. }
  47262. };
  47263. }
  47264. return this.__nodeListCstr;
  47265. }
  47266. get navigator() {
  47267. if (this.__navigator == null) {
  47268. this.__navigator = new MockNavigator();
  47269. }
  47270. return this.__navigator;
  47271. }
  47272. set navigator(nav) {
  47273. this.__navigator = nav;
  47274. }
  47275. get parent() {
  47276. return null;
  47277. }
  47278. prompt() {
  47279. return "";
  47280. }
  47281. open() {
  47282. return null;
  47283. }
  47284. get origin() {
  47285. return this.location.origin;
  47286. }
  47287. removeEventListener(type, handler) {
  47288. removeEventListener(this, type, handler);
  47289. }
  47290. requestAnimationFrame(callback) {
  47291. return this.setTimeout(() => {
  47292. callback(Date.now());
  47293. }, 0);
  47294. }
  47295. requestIdleCallback(callback) {
  47296. return this.setTimeout(() => {
  47297. callback({
  47298. didTimeout: false,
  47299. timeRemaining: () => 0
  47300. });
  47301. }, 0);
  47302. }
  47303. scroll(_x, _y) {
  47304. }
  47305. scrollBy(_x, _y) {
  47306. }
  47307. scrollTo(_x, _y) {
  47308. }
  47309. get self() {
  47310. return this;
  47311. }
  47312. get sessionStorage() {
  47313. if (this.__sessionStorage == null) {
  47314. this.__sessionStorage = new MockStorage();
  47315. }
  47316. return this.__sessionStorage;
  47317. }
  47318. set sessionStorage(locStorage) {
  47319. this.__sessionStorage = locStorage;
  47320. }
  47321. setInterval(callback, ms, ...args) {
  47322. if (this.__timeouts == null) {
  47323. this.__timeouts = /* @__PURE__ */ new Set();
  47324. }
  47325. ms = Math.min(ms, this.__maxTimeout);
  47326. if (this.__allowInterval) {
  47327. const intervalId = this.__setInterval(() => {
  47328. if (this.__timeouts) {
  47329. this.__timeouts.delete(intervalId);
  47330. try {
  47331. callback(...args);
  47332. } catch (e) {
  47333. if (this.console) {
  47334. this.console.error(e);
  47335. } else {
  47336. console.error(e);
  47337. }
  47338. }
  47339. }
  47340. }, ms);
  47341. if (this.__timeouts) {
  47342. this.__timeouts.add(intervalId);
  47343. }
  47344. return intervalId;
  47345. }
  47346. const timeoutId = this.__setTimeout.call(
  47347. nativeWindow || this,
  47348. () => {
  47349. if (this.__timeouts) {
  47350. this.__timeouts.delete(timeoutId);
  47351. try {
  47352. callback(...args);
  47353. } catch (e) {
  47354. if (this.console) {
  47355. this.console.error(e);
  47356. } else {
  47357. console.error(e);
  47358. }
  47359. }
  47360. }
  47361. },
  47362. ms
  47363. );
  47364. if (this.__timeouts) {
  47365. this.__timeouts.add(timeoutId);
  47366. }
  47367. return timeoutId;
  47368. }
  47369. setTimeout(callback, ms, ...args) {
  47370. if (this.__timeouts == null) {
  47371. this.__timeouts = /* @__PURE__ */ new Set();
  47372. }
  47373. ms = Math.min(ms, this.__maxTimeout);
  47374. const timeoutId = this.__setTimeout.call(
  47375. nativeWindow || this,
  47376. () => {
  47377. if (this.__timeouts) {
  47378. this.__timeouts.delete(timeoutId);
  47379. try {
  47380. callback(...args);
  47381. } catch (e) {
  47382. if (this.console) {
  47383. this.console.error(e);
  47384. } else {
  47385. console.error(e);
  47386. }
  47387. }
  47388. }
  47389. },
  47390. ms
  47391. );
  47392. if (this.__timeouts) {
  47393. this.__timeouts.add(timeoutId);
  47394. }
  47395. return timeoutId;
  47396. }
  47397. get top() {
  47398. return this;
  47399. }
  47400. get window() {
  47401. return this;
  47402. }
  47403. onanimationstart() {
  47404. }
  47405. onanimationend() {
  47406. }
  47407. onanimationiteration() {
  47408. }
  47409. onabort() {
  47410. }
  47411. onauxclick() {
  47412. }
  47413. onbeforecopy() {
  47414. }
  47415. onbeforecut() {
  47416. }
  47417. onbeforepaste() {
  47418. }
  47419. onblur() {
  47420. }
  47421. oncancel() {
  47422. }
  47423. oncanplay() {
  47424. }
  47425. oncanplaythrough() {
  47426. }
  47427. onchange() {
  47428. }
  47429. onclick() {
  47430. }
  47431. onclose() {
  47432. }
  47433. oncontextmenu() {
  47434. }
  47435. oncopy() {
  47436. }
  47437. oncuechange() {
  47438. }
  47439. oncut() {
  47440. }
  47441. ondblclick() {
  47442. }
  47443. ondrag() {
  47444. }
  47445. ondragend() {
  47446. }
  47447. ondragenter() {
  47448. }
  47449. ondragleave() {
  47450. }
  47451. ondragover() {
  47452. }
  47453. ondragstart() {
  47454. }
  47455. ondrop() {
  47456. }
  47457. ondurationchange() {
  47458. }
  47459. onemptied() {
  47460. }
  47461. onended() {
  47462. }
  47463. onerror() {
  47464. }
  47465. onfocus() {
  47466. }
  47467. onfocusin() {
  47468. }
  47469. onfocusout() {
  47470. }
  47471. onformdata() {
  47472. }
  47473. onfullscreenchange() {
  47474. }
  47475. onfullscreenerror() {
  47476. }
  47477. ongotpointercapture() {
  47478. }
  47479. oninput() {
  47480. }
  47481. oninvalid() {
  47482. }
  47483. onkeydown() {
  47484. }
  47485. onkeypress() {
  47486. }
  47487. onkeyup() {
  47488. }
  47489. onload() {
  47490. }
  47491. onloadeddata() {
  47492. }
  47493. onloadedmetadata() {
  47494. }
  47495. onloadstart() {
  47496. }
  47497. onlostpointercapture() {
  47498. }
  47499. onmousedown() {
  47500. }
  47501. onmouseenter() {
  47502. }
  47503. onmouseleave() {
  47504. }
  47505. onmousemove() {
  47506. }
  47507. onmouseout() {
  47508. }
  47509. onmouseover() {
  47510. }
  47511. onmouseup() {
  47512. }
  47513. onmousewheel() {
  47514. }
  47515. onpaste() {
  47516. }
  47517. onpause() {
  47518. }
  47519. onplay() {
  47520. }
  47521. onplaying() {
  47522. }
  47523. onpointercancel() {
  47524. }
  47525. onpointerdown() {
  47526. }
  47527. onpointerenter() {
  47528. }
  47529. onpointerleave() {
  47530. }
  47531. onpointermove() {
  47532. }
  47533. onpointerout() {
  47534. }
  47535. onpointerover() {
  47536. }
  47537. onpointerup() {
  47538. }
  47539. onprogress() {
  47540. }
  47541. onratechange() {
  47542. }
  47543. onreset() {
  47544. }
  47545. onresize() {
  47546. }
  47547. onscroll() {
  47548. }
  47549. onsearch() {
  47550. }
  47551. onseeked() {
  47552. }
  47553. onseeking() {
  47554. }
  47555. onselect() {
  47556. }
  47557. onselectstart() {
  47558. }
  47559. onstalled() {
  47560. }
  47561. onsubmit() {
  47562. }
  47563. onsuspend() {
  47564. }
  47565. ontimeupdate() {
  47566. }
  47567. ontoggle() {
  47568. }
  47569. onvolumechange() {
  47570. }
  47571. onwaiting() {
  47572. }
  47573. onwebkitfullscreenchange() {
  47574. }
  47575. onwebkitfullscreenerror() {
  47576. }
  47577. onwheel() {
  47578. }
  47579. };
  47580. addGlobalsToWindowPrototype(MockWindow.prototype);
  47581. function resetWindowDefaults(win) {
  47582. win.__clearInterval = nativeClearInterval;
  47583. win.__clearTimeout = nativeClearTimeout;
  47584. win.__setInterval = nativeSetInterval;
  47585. win.__setTimeout = nativeSetTimeout;
  47586. win.__maxTimeout = 3e4;
  47587. win.__allowInterval = true;
  47588. win.URL = nativeURL;
  47589. }
  47590. function cloneWindow(srcWin, opts = {}) {
  47591. if (srcWin == null) {
  47592. return null;
  47593. }
  47594. const clonedWin = new MockWindow(false);
  47595. if (!opts.customElementProxy) {
  47596. srcWin.customElements = null;
  47597. }
  47598. if (srcWin.document != null) {
  47599. const clonedDoc = new MockDocument(false, clonedWin);
  47600. clonedWin.document = clonedDoc;
  47601. clonedDoc.documentElement = srcWin.document.documentElement.cloneNode(true);
  47602. } else {
  47603. clonedWin.document = new MockDocument(null, clonedWin);
  47604. }
  47605. return clonedWin;
  47606. }
  47607. function constrainTimeouts(win) {
  47608. win.__allowInterval = false;
  47609. win.__maxTimeout = 0;
  47610. }
  47611. function resetWindow(win) {
  47612. if (win != null) {
  47613. if (win.__timeouts) {
  47614. win.__timeouts.forEach((timeoutId) => {
  47615. nativeClearInterval(timeoutId);
  47616. nativeClearTimeout(timeoutId);
  47617. });
  47618. win.__timeouts.clear();
  47619. }
  47620. if (win.customElements && win.customElements.clear) {
  47621. win.customElements.clear();
  47622. }
  47623. resetDocument(win.document);
  47624. resetPerformance(win.performance);
  47625. for (const key in win) {
  47626. if (win.hasOwnProperty(key) && key !== "document" && key !== "performance" && key !== "customElements") {
  47627. delete win[key];
  47628. }
  47629. }
  47630. resetWindowDefaults(win);
  47631. resetWindowDimensions(win);
  47632. resetEventListeners(win);
  47633. if (win.document != null) {
  47634. try {
  47635. win.document.defaultView = win;
  47636. } catch (e) {
  47637. }
  47638. }
  47639. win.fetch = null;
  47640. win.Headers = null;
  47641. win.Request = null;
  47642. win.Response = null;
  47643. win.FetchError = null;
  47644. }
  47645. }
  47646. function resetWindowDimensions(win) {
  47647. try {
  47648. win.devicePixelRatio = 1;
  47649. win.innerHeight = 768;
  47650. win.innerWidth = 1366;
  47651. win.pageXOffset = 0;
  47652. win.pageYOffset = 0;
  47653. win.screenLeft = 0;
  47654. win.screenTop = 0;
  47655. win.screenX = 0;
  47656. win.screenY = 0;
  47657. win.scrollX = 0;
  47658. win.scrollY = 0;
  47659. win.screen = {
  47660. availHeight: win.innerHeight,
  47661. availLeft: 0,
  47662. availTop: 0,
  47663. availWidth: win.innerWidth,
  47664. colorDepth: 24,
  47665. height: win.innerHeight,
  47666. keepAwake: false,
  47667. orientation: {
  47668. angle: 0,
  47669. type: "portrait-primary"
  47670. },
  47671. pixelDepth: 24,
  47672. width: win.innerWidth
  47673. };
  47674. } catch (e) {
  47675. }
  47676. }
  47677. // src/mock-doc/document.ts
  47678. var MockDocument = class _MockDocument extends MockHTMLElement {
  47679. constructor(html = null, win = null) {
  47680. super(null, null);
  47681. this.nodeName = "#document" /* DOCUMENT_NODE */;
  47682. this.nodeType = 9 /* DOCUMENT_NODE */;
  47683. this.defaultView = win;
  47684. this.cookie = "";
  47685. this.referrer = "";
  47686. this.appendChild(this.createDocumentTypeNode());
  47687. if (typeof html === "string") {
  47688. const parsedDoc = parseDocumentUtil(this, html);
  47689. const documentElement = parsedDoc.children.find((elm) => elm.nodeName === "HTML");
  47690. if (documentElement != null) {
  47691. this.appendChild(documentElement);
  47692. setOwnerDocument(documentElement, this);
  47693. }
  47694. } else if (html !== false) {
  47695. const documentElement = new MockHTMLElement(this, "html");
  47696. this.appendChild(documentElement);
  47697. documentElement.appendChild(new MockHTMLElement(this, "head"));
  47698. documentElement.appendChild(new MockHTMLElement(this, "body"));
  47699. }
  47700. }
  47701. get dir() {
  47702. return this.documentElement.dir;
  47703. }
  47704. set dir(value) {
  47705. this.documentElement.dir = value;
  47706. }
  47707. get localName() {
  47708. throw new Error("Unimplemented");
  47709. }
  47710. get location() {
  47711. if (this.defaultView != null) {
  47712. return this.defaultView.location;
  47713. }
  47714. return null;
  47715. }
  47716. set location(val) {
  47717. if (this.defaultView != null) {
  47718. this.defaultView.location = val;
  47719. }
  47720. }
  47721. get baseURI() {
  47722. const baseNode = this.head.childNodes.find((node) => node.nodeName === "BASE");
  47723. if (baseNode) {
  47724. return baseNode.href;
  47725. }
  47726. return this.URL;
  47727. }
  47728. get URL() {
  47729. return this.location.href;
  47730. }
  47731. get styleSheets() {
  47732. return this.querySelectorAll("style");
  47733. }
  47734. get scripts() {
  47735. return this.querySelectorAll("script");
  47736. }
  47737. get forms() {
  47738. return this.querySelectorAll("form");
  47739. }
  47740. get images() {
  47741. return this.querySelectorAll("img");
  47742. }
  47743. get scrollingElement() {
  47744. return this.documentElement;
  47745. }
  47746. get documentElement() {
  47747. for (let i = this.childNodes.length - 1; i >= 0; i--) {
  47748. if (this.childNodes[i].nodeName === "HTML") {
  47749. return this.childNodes[i];
  47750. }
  47751. }
  47752. const documentElement = new MockHTMLElement(this, "html");
  47753. this.appendChild(documentElement);
  47754. return documentElement;
  47755. }
  47756. set documentElement(documentElement) {
  47757. for (let i = this.childNodes.length - 1; i >= 0; i--) {
  47758. if (this.childNodes[i].nodeType !== 10 /* DOCUMENT_TYPE_NODE */) {
  47759. this.childNodes[i].remove();
  47760. }
  47761. }
  47762. if (documentElement != null) {
  47763. this.appendChild(documentElement);
  47764. setOwnerDocument(documentElement, this);
  47765. }
  47766. }
  47767. get head() {
  47768. const documentElement = this.documentElement;
  47769. for (let i = 0; i < documentElement.childNodes.length; i++) {
  47770. if (documentElement.childNodes[i].nodeName === "HEAD") {
  47771. return documentElement.childNodes[i];
  47772. }
  47773. }
  47774. const head = new MockHTMLElement(this, "head");
  47775. documentElement.insertBefore(head, documentElement.firstChild);
  47776. return head;
  47777. }
  47778. set head(head) {
  47779. const documentElement = this.documentElement;
  47780. for (let i = documentElement.childNodes.length - 1; i >= 0; i--) {
  47781. if (documentElement.childNodes[i].nodeName === "HEAD") {
  47782. documentElement.childNodes[i].remove();
  47783. }
  47784. }
  47785. if (head != null) {
  47786. documentElement.insertBefore(head, documentElement.firstChild);
  47787. setOwnerDocument(head, this);
  47788. }
  47789. }
  47790. get body() {
  47791. const documentElement = this.documentElement;
  47792. for (let i = documentElement.childNodes.length - 1; i >= 0; i--) {
  47793. if (documentElement.childNodes[i].nodeName === "BODY") {
  47794. return documentElement.childNodes[i];
  47795. }
  47796. }
  47797. const body = new MockHTMLElement(this, "body");
  47798. documentElement.appendChild(body);
  47799. return body;
  47800. }
  47801. set body(body) {
  47802. const documentElement = this.documentElement;
  47803. for (let i = documentElement.childNodes.length - 1; i >= 0; i--) {
  47804. if (documentElement.childNodes[i].nodeName === "BODY") {
  47805. documentElement.childNodes[i].remove();
  47806. }
  47807. }
  47808. if (body != null) {
  47809. documentElement.appendChild(body);
  47810. setOwnerDocument(body, this);
  47811. }
  47812. }
  47813. appendChild(newNode) {
  47814. newNode.remove();
  47815. newNode.parentNode = this;
  47816. this.childNodes.push(newNode);
  47817. return newNode;
  47818. }
  47819. createComment(data) {
  47820. return new MockComment(this, data);
  47821. }
  47822. createAttribute(attrName) {
  47823. return new MockAttr(attrName.toLowerCase(), "");
  47824. }
  47825. createAttributeNS(namespaceURI, attrName) {
  47826. return new MockAttr(attrName, "", namespaceURI);
  47827. }
  47828. createElement(tagName) {
  47829. if (tagName === "#document" /* DOCUMENT_NODE */) {
  47830. const doc = new _MockDocument(false);
  47831. doc.nodeName = tagName;
  47832. doc.parentNode = null;
  47833. return doc;
  47834. }
  47835. return createElement(this, tagName);
  47836. }
  47837. createElementNS(namespaceURI, tagName) {
  47838. const elmNs = createElementNS(this, namespaceURI, tagName);
  47839. return elmNs;
  47840. }
  47841. createTextNode(text) {
  47842. return new MockTextNode(this, text);
  47843. }
  47844. createDocumentFragment() {
  47845. return new MockDocumentFragment(this);
  47846. }
  47847. createDocumentTypeNode() {
  47848. return new MockDocumentTypeNode(this);
  47849. }
  47850. getElementById(id) {
  47851. return getElementById(this, id);
  47852. }
  47853. getElementsByName(elmName) {
  47854. return getElementsByName(this, elmName.toLowerCase());
  47855. }
  47856. get title() {
  47857. const title = this.head.childNodes.find((elm) => elm.nodeName === "TITLE");
  47858. if (title != null && typeof title.textContent === "string") {
  47859. return title.textContent.trim();
  47860. }
  47861. return "";
  47862. }
  47863. set title(value) {
  47864. const head = this.head;
  47865. let title = head.childNodes.find((elm) => elm.nodeName === "TITLE");
  47866. if (title == null) {
  47867. title = this.createElement("title");
  47868. head.appendChild(title);
  47869. }
  47870. title.textContent = value;
  47871. }
  47872. };
  47873. function resetDocument(doc) {
  47874. if (doc != null) {
  47875. resetEventListeners(doc);
  47876. const documentElement = doc.documentElement;
  47877. if (documentElement != null) {
  47878. resetElement(documentElement);
  47879. for (let i = 0, ii = documentElement.childNodes.length; i < ii; i++) {
  47880. const childNode = documentElement.childNodes[i];
  47881. resetElement(childNode);
  47882. childNode.childNodes.length = 0;
  47883. }
  47884. }
  47885. for (const key in doc) {
  47886. if (doc.hasOwnProperty(key) && !DOC_KEY_KEEPERS.has(key)) {
  47887. delete doc[key];
  47888. }
  47889. }
  47890. try {
  47891. doc.nodeName = "#document" /* DOCUMENT_NODE */;
  47892. } catch (e) {
  47893. }
  47894. try {
  47895. doc.nodeType = 9 /* DOCUMENT_NODE */;
  47896. } catch (e) {
  47897. }
  47898. try {
  47899. doc.cookie = "";
  47900. } catch (e) {
  47901. }
  47902. try {
  47903. doc.referrer = "";
  47904. } catch (e) {
  47905. }
  47906. }
  47907. }
  47908. var DOC_KEY_KEEPERS = /* @__PURE__ */ new Set([
  47909. "nodeName",
  47910. "nodeType",
  47911. "nodeValue",
  47912. "ownerDocument",
  47913. "parentNode",
  47914. "childNodes",
  47915. "_shadowRoot"
  47916. ]);
  47917. function getElementById(elm, id) {
  47918. const children = elm.children;
  47919. for (let i = 0, ii = children.length; i < ii; i++) {
  47920. const childElm = children[i];
  47921. if (childElm.id === id) {
  47922. return childElm;
  47923. }
  47924. const childElmFound = getElementById(childElm, id);
  47925. if (childElmFound != null) {
  47926. return childElmFound;
  47927. }
  47928. }
  47929. return null;
  47930. }
  47931. function getElementsByName(elm, elmName, foundElms = []) {
  47932. const children = elm.children;
  47933. for (let i = 0, ii = children.length; i < ii; i++) {
  47934. const childElm = children[i];
  47935. if (childElm.name && childElm.name.toLowerCase() === elmName) {
  47936. foundElms.push(childElm);
  47937. }
  47938. getElementsByName(childElm, elmName, foundElms);
  47939. }
  47940. return foundElms;
  47941. }
  47942. function setOwnerDocument(elm, ownerDocument) {
  47943. for (let i = 0, ii = elm.childNodes.length; i < ii; i++) {
  47944. elm.childNodes[i].ownerDocument = ownerDocument;
  47945. if (elm.childNodes[i].nodeType === 1 /* ELEMENT_NODE */) {
  47946. setOwnerDocument(elm.childNodes[i], ownerDocument);
  47947. }
  47948. }
  47949. }
  47950. // src/hydrate/runner/create-window.ts
  47951. var templateWindows = /* @__PURE__ */ new Map();
  47952. function createWindowFromHtml(templateHtml, uniqueId) {
  47953. let templateWindow = templateWindows.get(uniqueId);
  47954. if (templateWindow == null) {
  47955. templateWindow = new MockWindow(templateHtml);
  47956. templateWindows.set(uniqueId, templateWindow);
  47957. }
  47958. const win = cloneWindow(templateWindow);
  47959. return win;
  47960. }
  47961. // src/utils/helpers.ts
  47962. var isString = (v) => typeof v === "string";
  47963. // src/utils/message-utils.ts
  47964. var catchError = (diagnostics, err2, msg) => {
  47965. const diagnostic = {
  47966. level: "error",
  47967. type: "build",
  47968. header: "Build Error",
  47969. messageText: "build error",
  47970. lines: []
  47971. };
  47972. if (isString(msg)) {
  47973. diagnostic.messageText = msg.length ? msg : "UNKNOWN ERROR";
  47974. } else if (err2 != null) {
  47975. if (err2.stack != null) {
  47976. diagnostic.messageText = err2.stack.toString();
  47977. } else {
  47978. if (err2.message != null) {
  47979. diagnostic.messageText = err2.message.length ? err2.message : "UNKNOWN ERROR";
  47980. } else {
  47981. diagnostic.messageText = err2.toString();
  47982. }
  47983. }
  47984. }
  47985. if (diagnostics != null && !shouldIgnoreError(diagnostic.messageText)) {
  47986. diagnostics.push(diagnostic);
  47987. }
  47988. return diagnostic;
  47989. };
  47990. var hasError = (diagnostics) => {
  47991. if (diagnostics == null || diagnostics.length === 0) {
  47992. return false;
  47993. }
  47994. return diagnostics.some((d) => d.level === "error" && d.type !== "runtime");
  47995. };
  47996. var shouldIgnoreError = (msg) => {
  47997. return msg === TASK_CANCELED_MSG;
  47998. };
  47999. var TASK_CANCELED_MSG = `task canceled`;
  48000. // src/utils/result.ts
  48001. var result_exports = {};
  48002. __export(result_exports, {
  48003. err: () => err,
  48004. map: () => map,
  48005. ok: () => ok,
  48006. unwrap: () => unwrap,
  48007. unwrapErr: () => unwrapErr
  48008. });
  48009. var ok = (value) => ({
  48010. isOk: true,
  48011. isErr: false,
  48012. value
  48013. });
  48014. var err = (value) => ({
  48015. isOk: false,
  48016. isErr: true,
  48017. value
  48018. });
  48019. function map(result, fn) {
  48020. if (result.isOk) {
  48021. const val = fn(result.value);
  48022. if (val instanceof Promise) {
  48023. return val.then((newVal) => ok(newVal));
  48024. } else {
  48025. return ok(val);
  48026. }
  48027. }
  48028. if (result.isErr) {
  48029. const value = result.value;
  48030. return err(value);
  48031. }
  48032. throw "should never get here";
  48033. }
  48034. var unwrap = (result) => {
  48035. if (result.isOk) {
  48036. return result.value;
  48037. } else {
  48038. throw result.value;
  48039. }
  48040. };
  48041. var unwrapErr = (result) => {
  48042. if (result.isErr) {
  48043. return result.value;
  48044. } else {
  48045. throw result.value;
  48046. }
  48047. };
  48048. // src/compiler/html/canonical-link.ts
  48049. var updateCanonicalLink = (doc, href) => {
  48050. var _a2;
  48051. let canonicalLinkElm = doc.head.querySelector('link[rel="canonical"]');
  48052. if (typeof href === "string") {
  48053. if (canonicalLinkElm == null) {
  48054. canonicalLinkElm = doc.createElement("link");
  48055. canonicalLinkElm.setAttribute("rel", "canonical");
  48056. doc.head.appendChild(canonicalLinkElm);
  48057. }
  48058. canonicalLinkElm.setAttribute("href", href);
  48059. } else {
  48060. if (canonicalLinkElm != null) {
  48061. const existingHref = canonicalLinkElm.getAttribute("href");
  48062. if (!existingHref) {
  48063. (_a2 = canonicalLinkElm.parentNode) == null ? void 0 : _a2.removeChild(canonicalLinkElm);
  48064. }
  48065. }
  48066. }
  48067. };
  48068. // src/compiler/html/relocate-meta-charset.ts
  48069. var relocateMetaCharset = (doc) => {
  48070. const head = doc.head;
  48071. let charsetElm = head.querySelector("meta[charset]");
  48072. if (charsetElm == null) {
  48073. charsetElm = doc.createElement("meta");
  48074. charsetElm.setAttribute("charset", "utf-8");
  48075. } else {
  48076. charsetElm.remove();
  48077. }
  48078. head.insertBefore(charsetElm, head.firstChild);
  48079. };
  48080. // src/compiler/style/css-parser/parse-css.ts
  48081. var parseCss = (css, filePath) => {
  48082. let lineno = 1;
  48083. let column = 1;
  48084. const diagnostics = [];
  48085. const updatePosition = (str) => {
  48086. const lines = str.match(/\n/g);
  48087. if (lines) lineno += lines.length;
  48088. const i = str.lastIndexOf("\n");
  48089. column = ~i ? str.length - i : column + str.length;
  48090. };
  48091. const position = () => {
  48092. const start = { line: lineno, column };
  48093. return (node) => {
  48094. node.position = new ParsePosition(start);
  48095. whitespace();
  48096. return node;
  48097. };
  48098. };
  48099. const error = (msg) => {
  48100. const srcLines = css.split("\n");
  48101. const d = {
  48102. level: "error",
  48103. type: "css",
  48104. language: "css",
  48105. header: "CSS Parse",
  48106. messageText: msg,
  48107. absFilePath: filePath,
  48108. lines: [
  48109. {
  48110. lineIndex: lineno - 1,
  48111. lineNumber: lineno,
  48112. errorCharStart: column,
  48113. text: css[lineno - 1]
  48114. }
  48115. ]
  48116. };
  48117. if (lineno > 1) {
  48118. const previousLine = {
  48119. lineIndex: lineno - 1,
  48120. lineNumber: lineno - 1,
  48121. text: css[lineno - 2],
  48122. errorCharStart: -1,
  48123. errorLength: -1
  48124. };
  48125. d.lines.unshift(previousLine);
  48126. }
  48127. if (lineno + 2 < srcLines.length) {
  48128. const nextLine = {
  48129. lineIndex: lineno,
  48130. lineNumber: lineno + 1,
  48131. text: srcLines[lineno],
  48132. errorCharStart: -1,
  48133. errorLength: -1
  48134. };
  48135. d.lines.push(nextLine);
  48136. }
  48137. diagnostics.push(d);
  48138. return null;
  48139. };
  48140. const stylesheet = () => {
  48141. const rulesList = rules();
  48142. return {
  48143. type: 14 /* StyleSheet */,
  48144. stylesheet: {
  48145. source: filePath,
  48146. rules: rulesList
  48147. }
  48148. };
  48149. };
  48150. const open = () => match(/^{\s*/);
  48151. const close = () => match(/^}/);
  48152. const match = (re) => {
  48153. const m = re.exec(css);
  48154. if (!m) return;
  48155. const str = m[0];
  48156. updatePosition(str);
  48157. css = css.slice(str.length);
  48158. return m;
  48159. };
  48160. const rules = () => {
  48161. let node;
  48162. const rules2 = [];
  48163. whitespace();
  48164. comments(rules2);
  48165. while (css.length && css.charAt(0) !== "}" && (node = atrule() || rule())) {
  48166. rules2.push(node);
  48167. comments(rules2);
  48168. }
  48169. return rules2;
  48170. };
  48171. const whitespace = () => match(/^\s*/);
  48172. const comments = (rules2) => {
  48173. let c;
  48174. rules2 = rules2 || [];
  48175. while (c = comment()) {
  48176. rules2.push(c);
  48177. }
  48178. return rules2;
  48179. };
  48180. const comment = () => {
  48181. const pos = position();
  48182. if ("/" !== css.charAt(0) || "*" !== css.charAt(1)) return null;
  48183. let i = 2;
  48184. while ("" !== css.charAt(i) && ("*" !== css.charAt(i) || "/" !== css.charAt(i + 1))) ++i;
  48185. i += 2;
  48186. if ("" === css.charAt(i - 1)) {
  48187. return error("End of comment missing");
  48188. }
  48189. const comment2 = css.slice(2, i - 2);
  48190. column += 2;
  48191. updatePosition(comment2);
  48192. css = css.slice(i);
  48193. column += 2;
  48194. return pos({
  48195. type: 1 /* Comment */,
  48196. comment: comment2
  48197. });
  48198. };
  48199. const selector = () => {
  48200. const m = match(/^([^{]+)/);
  48201. if (!m) return null;
  48202. return trim(m[0]).replace(/\/\*([^*]|[\r\n]|(\*+([^*/]|[\r\n])))*\*\/+/g, "").replace(/"(?:\\"|[^"])*"|'(?:\\'|[^'])*'/g, function(m2) {
  48203. return m2.replace(/,/g, "\u200C");
  48204. }).split(/\s*(?![^(]*\)),\s*/).map(function(s) {
  48205. return s.replace(/\u200C/g, ",");
  48206. });
  48207. };
  48208. const declaration = () => {
  48209. const pos = position();
  48210. let prop = match(/^(\*?[-#\/\*\\\w]+(\[[0-9a-z_-]+\])?)\s*/);
  48211. if (!prop) return null;
  48212. prop = trim(prop[0]);
  48213. if (!match(/^:\s*/)) return error(`property missing ':'`);
  48214. const val = match(/^((?:'(?:\\'|.)*?'|"(?:\\"|.)*?"|\([^\)]*?\)|[^};])+)/);
  48215. const ret = pos({
  48216. type: 4 /* Declaration */,
  48217. property: prop.replace(commentre, ""),
  48218. value: val ? trim(val[0]).replace(commentre, "") : ""
  48219. });
  48220. match(/^[;\s]*/);
  48221. return ret;
  48222. };
  48223. const declarations = () => {
  48224. const decls = [];
  48225. if (!open()) return error(`missing '{'`);
  48226. comments(decls);
  48227. let decl;
  48228. while (decl = declaration()) {
  48229. decls.push(decl);
  48230. comments(decls);
  48231. }
  48232. if (!close()) return error(`missing '}'`);
  48233. return decls;
  48234. };
  48235. const keyframe = () => {
  48236. let m;
  48237. const values = [];
  48238. const pos = position();
  48239. while (m = match(/^((\d+\.\d+|\.\d+|\d+)%?|[a-z]+)\s*/)) {
  48240. values.push(m[1]);
  48241. match(/^,\s*/);
  48242. }
  48243. if (!values.length) return null;
  48244. return pos({
  48245. type: 9 /* KeyFrame */,
  48246. values,
  48247. declarations: declarations()
  48248. });
  48249. };
  48250. const atkeyframes = () => {
  48251. const pos = position();
  48252. let m = match(/^@([-\w]+)?keyframes\s*/);
  48253. if (!m) return null;
  48254. const vendor = m[1];
  48255. m = match(/^([-\w]+)\s*/);
  48256. if (!m) return error(`@keyframes missing name`);
  48257. const name = m[1];
  48258. if (!open()) return error(`@keyframes missing '{'`);
  48259. let frame;
  48260. let frames = comments();
  48261. while (frame = keyframe()) {
  48262. frames.push(frame);
  48263. frames = frames.concat(comments());
  48264. }
  48265. if (!close()) return error(`@keyframes missing '}'`);
  48266. return pos({
  48267. type: 8 /* KeyFrames */,
  48268. name,
  48269. vendor,
  48270. keyframes: frames
  48271. });
  48272. };
  48273. const atsupports = () => {
  48274. const pos = position();
  48275. const m = match(/^@supports *([^{]+)/);
  48276. if (!m) return null;
  48277. const supports = trim(m[1]);
  48278. if (!open()) return error(`@supports missing '{'`);
  48279. const style = comments().concat(rules());
  48280. if (!close()) return error(`@supports missing '}'`);
  48281. return pos({
  48282. type: 15 /* Supports */,
  48283. supports,
  48284. rules: style
  48285. });
  48286. };
  48287. const athost = () => {
  48288. const pos = position();
  48289. const m = match(/^@host\s*/);
  48290. if (!m) return null;
  48291. if (!open()) return error(`@host missing '{'`);
  48292. const style = comments().concat(rules());
  48293. if (!close()) return error(`@host missing '}'`);
  48294. return pos({
  48295. type: 6 /* Host */,
  48296. rules: style
  48297. });
  48298. };
  48299. const atmedia = () => {
  48300. const pos = position();
  48301. const m = match(/^@media *([^{]+)/);
  48302. if (!m) return null;
  48303. const media = trim(m[1]);
  48304. if (!open()) return error(`@media missing '{'`);
  48305. const style = comments().concat(rules());
  48306. if (!close()) return error(`@media missing '}'`);
  48307. return pos({
  48308. type: 10 /* Media */,
  48309. media,
  48310. rules: style
  48311. });
  48312. };
  48313. const atcustommedia = () => {
  48314. const pos = position();
  48315. const m = match(/^@custom-media\s+(--[^\s]+)\s*([^{;]+);/);
  48316. if (!m) return null;
  48317. return pos({
  48318. type: 2 /* CustomMedia */,
  48319. name: trim(m[1]),
  48320. media: trim(m[2])
  48321. });
  48322. };
  48323. const atpage = () => {
  48324. const pos = position();
  48325. const m = match(/^@page */);
  48326. if (!m) return null;
  48327. const sel = selector() || [];
  48328. if (!open()) return error(`@page missing '{'`);
  48329. let decls = comments();
  48330. let decl;
  48331. while (decl = declaration()) {
  48332. decls.push(decl);
  48333. decls = decls.concat(comments());
  48334. }
  48335. if (!close()) return error(`@page missing '}'`);
  48336. return pos({
  48337. type: 12 /* Page */,
  48338. selectors: sel,
  48339. declarations: decls
  48340. });
  48341. };
  48342. const atdocument = () => {
  48343. const pos = position();
  48344. const m = match(/^@([-\w]+)?document *([^{]+)/);
  48345. if (!m) return null;
  48346. const vendor = trim(m[1]);
  48347. const doc = trim(m[2]);
  48348. if (!open()) return error(`@document missing '{'`);
  48349. const style = comments().concat(rules());
  48350. if (!close()) return error(`@document missing '}'`);
  48351. return pos({
  48352. type: 3 /* Document */,
  48353. document: doc,
  48354. vendor,
  48355. rules: style
  48356. });
  48357. };
  48358. const atfontface = () => {
  48359. const pos = position();
  48360. const m = match(/^@font-face\s*/);
  48361. if (!m) return null;
  48362. if (!open()) return error(`@font-face missing '{'`);
  48363. let decls = comments();
  48364. let decl;
  48365. while (decl = declaration()) {
  48366. decls.push(decl);
  48367. decls = decls.concat(comments());
  48368. }
  48369. if (!close()) return error(`@font-face missing '}'`);
  48370. return pos({
  48371. type: 5 /* FontFace */,
  48372. declarations: decls
  48373. });
  48374. };
  48375. const compileAtrule = (nodeName, nodeType) => {
  48376. const re = new RegExp("^@" + nodeName + "\\s*([^;]+);");
  48377. return () => {
  48378. const pos = position();
  48379. const m = match(re);
  48380. if (!m) return null;
  48381. const node = {
  48382. type: nodeType
  48383. };
  48384. node[nodeName] = m[1].trim();
  48385. return pos(node);
  48386. };
  48387. };
  48388. const atimport = compileAtrule("import", 7 /* Import */);
  48389. const atcharset = compileAtrule("charset", 0 /* Charset */);
  48390. const atnamespace = compileAtrule("namespace", 11 /* Namespace */);
  48391. const atrule = () => {
  48392. if (css[0] !== "@") return null;
  48393. return atkeyframes() || atmedia() || atcustommedia() || atsupports() || atimport() || atcharset() || atnamespace() || atdocument() || atpage() || athost() || atfontface();
  48394. };
  48395. const rule = () => {
  48396. const pos = position();
  48397. const sel = selector();
  48398. if (!sel) return error("selector missing");
  48399. comments();
  48400. return pos({
  48401. type: 13 /* Rule */,
  48402. selectors: sel,
  48403. declarations: declarations()
  48404. });
  48405. };
  48406. class ParsePosition {
  48407. constructor(start) {
  48408. this.start = start;
  48409. this.end = { line: lineno, column };
  48410. this.source = filePath;
  48411. }
  48412. }
  48413. ParsePosition.prototype.content = css;
  48414. return {
  48415. diagnostics,
  48416. ...addParent(stylesheet())
  48417. };
  48418. };
  48419. var trim = (str) => str ? str.trim() : "";
  48420. var addParent = (obj, parent) => {
  48421. const isNode = obj && typeof obj.type === "string";
  48422. const childParent = isNode ? obj : parent;
  48423. for (const k in obj) {
  48424. const value = obj[k];
  48425. if (Array.isArray(value)) {
  48426. value.forEach(function(v) {
  48427. addParent(v, childParent);
  48428. });
  48429. } else if (value && typeof value === "object") {
  48430. addParent(value, childParent);
  48431. }
  48432. }
  48433. if (isNode) {
  48434. Object.defineProperty(obj, "parent", {
  48435. configurable: true,
  48436. writable: true,
  48437. enumerable: false,
  48438. value: parent || null
  48439. });
  48440. }
  48441. return obj;
  48442. };
  48443. var commentre = /\/\*[^*]*\*+([^/*][^*]*\*+)*\//g;
  48444. // src/compiler/style/css-parser/get-css-selectors.ts
  48445. var getCssSelectors = (sel) => {
  48446. SELECTORS.all.length = SELECTORS.tags.length = SELECTORS.classNames.length = SELECTORS.ids.length = SELECTORS.attrs.length = 0;
  48447. sel = sel.replace(/\./g, " .").replace(/\#/g, " #").replace(/\[/g, " [").replace(/\>/g, " > ").replace(/\+/g, " + ").replace(/\~/g, " ~ ").replace(/\*/g, " * ").replace(/\:not\((.*?)\)/g, " ");
  48448. const items = sel.split(" ");
  48449. for (let i = 0, l = items.length; i < l; i++) {
  48450. items[i] = items[i].split(":")[0];
  48451. if (items[i].length === 0) continue;
  48452. if (items[i].charAt(0) === ".") {
  48453. SELECTORS.classNames.push(items[i].slice(1));
  48454. } else if (items[i].charAt(0) === "#") {
  48455. SELECTORS.ids.push(items[i].slice(1));
  48456. } else if (items[i].charAt(0) === "[") {
  48457. items[i] = items[i].slice(1).split("=")[0].split("]")[0].trim();
  48458. SELECTORS.attrs.push(items[i].toLowerCase());
  48459. } else if (/[a-z]/g.test(items[i].charAt(0))) {
  48460. SELECTORS.tags.push(items[i].toLowerCase());
  48461. }
  48462. }
  48463. SELECTORS.classNames = SELECTORS.classNames.sort((a, b) => {
  48464. if (a.length < b.length) return -1;
  48465. if (a.length > b.length) return 1;
  48466. return 0;
  48467. });
  48468. return SELECTORS;
  48469. };
  48470. var SELECTORS = {
  48471. all: [],
  48472. tags: [],
  48473. classNames: [],
  48474. ids: [],
  48475. attrs: []
  48476. };
  48477. // src/compiler/style/css-parser/serialize-css.ts
  48478. var serializeCss = (stylesheet, serializeOpts) => {
  48479. const usedSelectors = serializeOpts.usedSelectors || null;
  48480. const opts = {
  48481. usedSelectors: usedSelectors || null,
  48482. hasUsedAttrs: !!usedSelectors && usedSelectors.attrs.size > 0,
  48483. hasUsedClassNames: !!usedSelectors && usedSelectors.classNames.size > 0,
  48484. hasUsedIds: !!usedSelectors && usedSelectors.ids.size > 0,
  48485. hasUsedTags: !!usedSelectors && usedSelectors.tags.size > 0
  48486. };
  48487. const rules = stylesheet.rules;
  48488. if (!rules) {
  48489. return "";
  48490. }
  48491. const rulesLen = rules.length;
  48492. const out = [];
  48493. for (let i = 0; i < rulesLen; i++) {
  48494. out.push(serializeCssVisitNode(opts, rules[i], i, rulesLen));
  48495. }
  48496. return out.join("");
  48497. };
  48498. var serializeCssVisitNode = (opts, node, index, len) => {
  48499. var _a2;
  48500. const nodeType = node.type;
  48501. if (nodeType === 4 /* Declaration */) {
  48502. return serializeCssDeclaration(node, index, len);
  48503. }
  48504. if (nodeType === 13 /* Rule */) {
  48505. return serializeCssRule(opts, node);
  48506. }
  48507. if (nodeType === 1 /* Comment */) {
  48508. if (((_a2 = node.comment) == null ? void 0 : _a2[0]) === "!") {
  48509. return `/*${node.comment}*/`;
  48510. } else {
  48511. return "";
  48512. }
  48513. }
  48514. if (nodeType === 10 /* Media */) {
  48515. return serializeCssMedia(opts, node);
  48516. }
  48517. if (nodeType === 8 /* KeyFrames */) {
  48518. return serializeCssKeyframes(opts, node);
  48519. }
  48520. if (nodeType === 9 /* KeyFrame */) {
  48521. return serializeCssKeyframe(opts, node);
  48522. }
  48523. if (nodeType === 5 /* FontFace */) {
  48524. return serializeCssFontFace(opts, node);
  48525. }
  48526. if (nodeType === 15 /* Supports */) {
  48527. return serializeCssSupports(opts, node);
  48528. }
  48529. if (nodeType === 7 /* Import */) {
  48530. return "@import " + node.import + ";";
  48531. }
  48532. if (nodeType === 0 /* Charset */) {
  48533. return "@charset " + node.charset + ";";
  48534. }
  48535. if (nodeType === 12 /* Page */) {
  48536. return serializeCssPage(opts, node);
  48537. }
  48538. if (nodeType === 6 /* Host */) {
  48539. return "@host{" + serializeCssMapVisit(opts, node.rules) + "}";
  48540. }
  48541. if (nodeType === 2 /* CustomMedia */) {
  48542. return "@custom-media " + node.name + " " + node.media + ";";
  48543. }
  48544. if (nodeType === 3 /* Document */) {
  48545. return serializeCssDocument(opts, node);
  48546. }
  48547. if (nodeType === 11 /* Namespace */) {
  48548. return "@namespace " + node.namespace + ";";
  48549. }
  48550. return "";
  48551. };
  48552. var serializeCssRule = (opts, node) => {
  48553. var _a2, _b;
  48554. const decls = node.declarations;
  48555. const usedSelectors = opts.usedSelectors;
  48556. const selectors = (_b = (_a2 = node.selectors) == null ? void 0 : _a2.slice()) != null ? _b : [];
  48557. if (decls == null || decls.length === 0) {
  48558. return "";
  48559. }
  48560. if (usedSelectors) {
  48561. let i;
  48562. let j;
  48563. let include = true;
  48564. for (i = selectors.length - 1; i >= 0; i--) {
  48565. const sel = getCssSelectors(selectors[i]);
  48566. include = true;
  48567. let jlen = sel.classNames.length;
  48568. if (jlen > 0 && opts.hasUsedClassNames) {
  48569. for (j = 0; j < jlen; j++) {
  48570. if (!usedSelectors.classNames.has(sel.classNames[j])) {
  48571. include = false;
  48572. break;
  48573. }
  48574. }
  48575. }
  48576. if (include && opts.hasUsedTags) {
  48577. jlen = sel.tags.length;
  48578. if (jlen > 0) {
  48579. for (j = 0; j < jlen; j++) {
  48580. if (!usedSelectors.tags.has(sel.tags[j])) {
  48581. include = false;
  48582. break;
  48583. }
  48584. }
  48585. }
  48586. }
  48587. if (include && opts.hasUsedAttrs) {
  48588. jlen = sel.attrs.length;
  48589. if (jlen > 0) {
  48590. for (j = 0; j < jlen; j++) {
  48591. if (!usedSelectors.attrs.has(sel.attrs[j])) {
  48592. include = false;
  48593. break;
  48594. }
  48595. }
  48596. }
  48597. }
  48598. if (include && opts.hasUsedIds) {
  48599. jlen = sel.ids.length;
  48600. if (jlen > 0) {
  48601. for (j = 0; j < jlen; j++) {
  48602. if (!usedSelectors.ids.has(sel.ids[j])) {
  48603. include = false;
  48604. break;
  48605. }
  48606. }
  48607. }
  48608. }
  48609. if (!include) {
  48610. selectors.splice(i, 1);
  48611. }
  48612. }
  48613. }
  48614. if (selectors.length === 0) {
  48615. return "";
  48616. }
  48617. const cleanedSelectors = [];
  48618. let cleanedSelector = "";
  48619. if (node.selectors) {
  48620. for (const selector of node.selectors) {
  48621. cleanedSelector = removeSelectorWhitespace(selector);
  48622. if (!cleanedSelectors.includes(cleanedSelector)) {
  48623. cleanedSelectors.push(cleanedSelector);
  48624. }
  48625. }
  48626. }
  48627. return `${cleanedSelectors}{${serializeCssMapVisit(opts, decls)}}`;
  48628. };
  48629. var serializeCssDeclaration = (node, index, len) => {
  48630. if (node.value === "") {
  48631. return "";
  48632. }
  48633. if (len - 1 === index) {
  48634. return node.property + ":" + node.value;
  48635. }
  48636. return node.property + ":" + node.value + ";";
  48637. };
  48638. var serializeCssMedia = (opts, node) => {
  48639. const mediaCss = serializeCssMapVisit(opts, node.rules);
  48640. if (mediaCss === "") {
  48641. return "";
  48642. }
  48643. return "@media " + removeMediaWhitespace(node.media) + "{" + mediaCss + "}";
  48644. };
  48645. var serializeCssKeyframes = (opts, node) => {
  48646. const keyframesCss = serializeCssMapVisit(opts, node.keyframes);
  48647. if (keyframesCss === "") {
  48648. return "";
  48649. }
  48650. return "@" + (node.vendor || "") + "keyframes " + node.name + "{" + keyframesCss + "}";
  48651. };
  48652. var serializeCssKeyframe = (opts, node) => {
  48653. var _a2, _b;
  48654. return ((_b = (_a2 = node.values) == null ? void 0 : _a2.join(",")) != null ? _b : "") + "{" + serializeCssMapVisit(opts, node.declarations) + "}";
  48655. };
  48656. var serializeCssFontFace = (opts, node) => {
  48657. const fontCss = serializeCssMapVisit(opts, node.declarations);
  48658. if (fontCss === "") {
  48659. return "";
  48660. }
  48661. return "@font-face{" + fontCss + "}";
  48662. };
  48663. var serializeCssSupports = (opts, node) => {
  48664. const supportsCss = serializeCssMapVisit(opts, node.rules);
  48665. if (supportsCss === "") {
  48666. return "";
  48667. }
  48668. return "@supports " + node.supports + "{" + supportsCss + "}";
  48669. };
  48670. var serializeCssPage = (opts, node) => {
  48671. var _a2, _b;
  48672. const sel = (_b = (_a2 = node.selectors) == null ? void 0 : _a2.join(", ")) != null ? _b : "";
  48673. return "@page " + sel + "{" + serializeCssMapVisit(opts, node.declarations) + "}";
  48674. };
  48675. var serializeCssDocument = (opts, node) => {
  48676. const documentCss = serializeCssMapVisit(opts, node.rules);
  48677. const doc = "@" + (node.vendor || "") + "document " + node.document;
  48678. if (documentCss === "") {
  48679. return "";
  48680. }
  48681. return doc + "{" + documentCss + "}";
  48682. };
  48683. var serializeCssMapVisit = (opts, nodes) => {
  48684. let rtn = "";
  48685. if (nodes) {
  48686. for (let i = 0, len = nodes.length; i < len; i++) {
  48687. rtn += serializeCssVisitNode(opts, nodes[i], i, len);
  48688. }
  48689. }
  48690. return rtn;
  48691. };
  48692. var removeSelectorWhitespace = (selector) => {
  48693. let rtn = "";
  48694. let char = "";
  48695. let inAttr = false;
  48696. selector = selector.trim();
  48697. for (let i = 0, l = selector.length; i < l; i++) {
  48698. char = selector[i];
  48699. if (char === "[" && rtn[rtn.length - 1] !== "\\") {
  48700. inAttr = true;
  48701. } else if (char === "]" && rtn[rtn.length - 1] !== "\\") {
  48702. inAttr = false;
  48703. }
  48704. if (!inAttr && CSS_WS_REG.test(char)) {
  48705. if (CSS_NEXT_CHAR_REG.test(selector[i + 1])) {
  48706. continue;
  48707. }
  48708. if (CSS_PREV_CHAR_REG.test(rtn[rtn.length - 1])) {
  48709. continue;
  48710. }
  48711. rtn += " ";
  48712. } else {
  48713. rtn += char;
  48714. }
  48715. }
  48716. return rtn;
  48717. };
  48718. var removeMediaWhitespace = (media) => {
  48719. var _a2;
  48720. let rtn = "";
  48721. let char = "";
  48722. media = (_a2 = media == null ? void 0 : media.trim()) != null ? _a2 : "";
  48723. for (let i = 0, l = media.length; i < l; i++) {
  48724. char = media[i];
  48725. if (CSS_WS_REG.test(char)) {
  48726. if (CSS_WS_REG.test(rtn[rtn.length - 1])) {
  48727. continue;
  48728. }
  48729. rtn += " ";
  48730. } else {
  48731. rtn += char;
  48732. }
  48733. }
  48734. return rtn;
  48735. };
  48736. var CSS_WS_REG = /\s/;
  48737. var CSS_NEXT_CHAR_REG = /[>\(\)\~\,\+\s]/;
  48738. var CSS_PREV_CHAR_REG = /[>\(\~\,\+]/;
  48739. // src/compiler/style/css-parser/used-selectors.ts
  48740. var getUsedSelectors = (elm) => {
  48741. const usedSelectors = {
  48742. attrs: /* @__PURE__ */ new Set(),
  48743. classNames: /* @__PURE__ */ new Set(),
  48744. ids: /* @__PURE__ */ new Set(),
  48745. tags: /* @__PURE__ */ new Set()
  48746. };
  48747. collectUsedSelectors(usedSelectors, elm);
  48748. return usedSelectors;
  48749. };
  48750. var collectUsedSelectors = (usedSelectors, elm) => {
  48751. if (elm != null && elm.nodeType === 1) {
  48752. const children = elm.children;
  48753. const tagName = elm.nodeName.toLowerCase();
  48754. usedSelectors.tags.add(tagName);
  48755. const attributes = elm.attributes;
  48756. for (let i = 0, l = attributes.length; i < l; i++) {
  48757. const attr = attributes.item(i);
  48758. const attrName = attr.name.toLowerCase();
  48759. usedSelectors.attrs.add(attrName);
  48760. if (attrName === "class") {
  48761. const classList = elm.classList;
  48762. for (let i2 = 0, l2 = classList.length; i2 < l2; i2++) {
  48763. usedSelectors.classNames.add(classList.item(i2));
  48764. }
  48765. } else if (attrName === "id") {
  48766. usedSelectors.ids.add(attr.value);
  48767. }
  48768. }
  48769. if (children) {
  48770. for (let i = 0, l = children.length; i < l; i++) {
  48771. collectUsedSelectors(usedSelectors, children[i]);
  48772. }
  48773. }
  48774. }
  48775. };
  48776. // src/compiler/html/remove-unused-styles.ts
  48777. var removeUnusedStyles = (doc, diagnostics) => {
  48778. try {
  48779. const styleElms = doc.head.querySelectorAll(`style[data-styles]`);
  48780. const styleLen = styleElms.length;
  48781. if (styleLen > 0) {
  48782. const usedSelectors = getUsedSelectors(doc.documentElement);
  48783. for (let i = 0; i < styleLen; i++) {
  48784. removeUnusedStyleText(usedSelectors, diagnostics, styleElms[i]);
  48785. }
  48786. }
  48787. } catch (e) {
  48788. catchError(diagnostics, e);
  48789. }
  48790. };
  48791. var removeUnusedStyleText = (usedSelectors, diagnostics, styleElm) => {
  48792. try {
  48793. const parseResults = parseCss(styleElm.innerHTML);
  48794. diagnostics.push(...parseResults.diagnostics);
  48795. if (hasError(diagnostics)) {
  48796. return;
  48797. }
  48798. try {
  48799. styleElm.innerHTML = serializeCss(parseResults.stylesheet, {
  48800. usedSelectors
  48801. });
  48802. } catch (e) {
  48803. diagnostics.push({
  48804. level: "warn",
  48805. type: "css",
  48806. header: "CSS Stringify",
  48807. messageText: e,
  48808. lines: []
  48809. });
  48810. }
  48811. } catch (e) {
  48812. diagnostics.push({
  48813. level: "warn",
  48814. type: "css",
  48815. header: "CSS Parse",
  48816. messageText: e,
  48817. lines: []
  48818. });
  48819. }
  48820. };
  48821. // src/hydrate/runner/inspect-element.ts
  48822. function inspectElement(results, elm, depth) {
  48823. const children = [...Array.from(elm.children), ...Array.from(elm.shadowRoot ? elm.shadowRoot.children : [])];
  48824. for (let i = 0, ii = children.length; i < ii; i++) {
  48825. const childElm = children[i];
  48826. const tagName = childElm.nodeName.toLowerCase();
  48827. if (tagName.includes("-")) {
  48828. const cmp = results.components.find((c) => c.tag === tagName);
  48829. if (cmp != null) {
  48830. cmp.count++;
  48831. if (depth > cmp.depth) {
  48832. cmp.depth = depth;
  48833. }
  48834. }
  48835. } else {
  48836. switch (tagName) {
  48837. case "a":
  48838. const anchor = collectAttributes(childElm);
  48839. anchor.href = childElm.href;
  48840. if (typeof anchor.href === "string") {
  48841. if (!results.anchors.some((a) => a.href === anchor.href)) {
  48842. results.anchors.push(anchor);
  48843. }
  48844. }
  48845. break;
  48846. case "img":
  48847. const img = collectAttributes(childElm);
  48848. img.src = childElm.src;
  48849. if (typeof img.src === "string") {
  48850. if (!results.imgs.some((a) => a.src === img.src)) {
  48851. results.imgs.push(img);
  48852. }
  48853. }
  48854. break;
  48855. case "link":
  48856. const link = collectAttributes(childElm);
  48857. link.href = childElm.href;
  48858. if (typeof link.rel === "string" && link.rel.toLowerCase() === "stylesheet") {
  48859. if (typeof link.href === "string") {
  48860. if (!results.styles.some((s) => s.link === link.href)) {
  48861. delete link.rel;
  48862. delete link.type;
  48863. results.styles.push(link);
  48864. }
  48865. }
  48866. }
  48867. break;
  48868. case "script":
  48869. const script = collectAttributes(childElm);
  48870. if (childElm.hasAttribute("src")) {
  48871. script.src = childElm.src;
  48872. if (typeof script.src === "string") {
  48873. if (!results.scripts.some((s) => s.src === script.src)) {
  48874. results.scripts.push(script);
  48875. }
  48876. }
  48877. } else {
  48878. const staticDataKey = childElm.getAttribute("data-stencil-static");
  48879. if (staticDataKey) {
  48880. results.staticData.push({
  48881. id: staticDataKey,
  48882. type: childElm.getAttribute("type"),
  48883. content: childElm.textContent
  48884. });
  48885. }
  48886. }
  48887. break;
  48888. }
  48889. }
  48890. depth++;
  48891. inspectElement(results, childElm, depth);
  48892. }
  48893. }
  48894. function collectAttributes(node) {
  48895. const parsedElm = {};
  48896. const attrs = node.attributes;
  48897. for (let i = 0, ii = attrs.length; i < ii; i++) {
  48898. const attr = attrs.item(i);
  48899. const attrName = attr.nodeName.toLowerCase();
  48900. if (SKIP_ATTRS.has(attrName)) {
  48901. continue;
  48902. }
  48903. const attrValue = attr.nodeValue;
  48904. if (attrName === "class" && attrValue === "") {
  48905. continue;
  48906. }
  48907. parsedElm[attrName] = attrValue;
  48908. }
  48909. return parsedElm;
  48910. }
  48911. var SKIP_ATTRS = /* @__PURE__ */ new Set(["s-id", "c-id"]);
  48912. // src/hydrate/runner/patch-dom-implementation.ts
  48913. function patchDomImplementation(doc, opts) {
  48914. let win;
  48915. if (doc.defaultView != null) {
  48916. opts.destroyWindow = true;
  48917. patchWindow(doc.defaultView);
  48918. win = doc.defaultView;
  48919. } else {
  48920. opts.destroyWindow = true;
  48921. opts.destroyDocument = false;
  48922. win = new MockWindow(false);
  48923. }
  48924. if (win.document !== doc) {
  48925. win.document = doc;
  48926. }
  48927. if (doc.defaultView !== win) {
  48928. doc.defaultView = win;
  48929. }
  48930. const HTMLElement = doc.documentElement.constructor.prototype;
  48931. if (typeof HTMLElement.getRootNode !== "function") {
  48932. const elm = doc.createElement("unknown-element");
  48933. const HTMLUnknownElement = elm.constructor.prototype;
  48934. HTMLUnknownElement.getRootNode = getRootNode;
  48935. }
  48936. if (typeof doc.createEvent === "function") {
  48937. const CustomEvent = doc.createEvent("CustomEvent").constructor;
  48938. if (win.CustomEvent !== CustomEvent) {
  48939. win.CustomEvent = CustomEvent;
  48940. }
  48941. }
  48942. try {
  48943. win.__stencil_baseURI = doc.baseURI;
  48944. } catch (e) {
  48945. Object.defineProperty(doc, "baseURI", {
  48946. get() {
  48947. const baseElm = doc.querySelector("base[href]");
  48948. if (baseElm) {
  48949. return new URL(baseElm.getAttribute("href"), win.location.href).href;
  48950. }
  48951. return win.location.href;
  48952. }
  48953. });
  48954. }
  48955. return win;
  48956. }
  48957. function getRootNode(opts) {
  48958. const isComposed = opts != null && opts.composed === true;
  48959. let node = this;
  48960. while (node.parentNode != null) {
  48961. node = node.parentNode;
  48962. if (isComposed === true && node.parentNode == null && node.host != null) {
  48963. node = node.host;
  48964. }
  48965. }
  48966. return node;
  48967. }
  48968. // src/hydrate/runner/render-utils.ts
  48969. function normalizeHydrateOptions(inputOpts) {
  48970. const outputOpts = Object.assign(
  48971. {
  48972. serializeToHtml: false,
  48973. destroyWindow: false,
  48974. destroyDocument: false
  48975. },
  48976. inputOpts || {}
  48977. );
  48978. if (typeof outputOpts.clientHydrateAnnotations !== "boolean") {
  48979. outputOpts.clientHydrateAnnotations = true;
  48980. }
  48981. if (typeof outputOpts.constrainTimeouts !== "boolean") {
  48982. outputOpts.constrainTimeouts = true;
  48983. }
  48984. if (typeof outputOpts.maxHydrateCount !== "number") {
  48985. outputOpts.maxHydrateCount = 300;
  48986. }
  48987. if (typeof outputOpts.runtimeLogging !== "boolean") {
  48988. outputOpts.runtimeLogging = false;
  48989. }
  48990. if (typeof outputOpts.timeout !== "number") {
  48991. outputOpts.timeout = 15e3;
  48992. }
  48993. if (Array.isArray(outputOpts.excludeComponents)) {
  48994. outputOpts.excludeComponents = outputOpts.excludeComponents.filter(filterValidTags).map(mapValidTags);
  48995. } else {
  48996. outputOpts.excludeComponents = [];
  48997. }
  48998. if (Array.isArray(outputOpts.staticComponents)) {
  48999. outputOpts.staticComponents = outputOpts.staticComponents.filter(filterValidTags).map(mapValidTags);
  49000. } else {
  49001. outputOpts.staticComponents = [];
  49002. }
  49003. return outputOpts;
  49004. }
  49005. function filterValidTags(tag) {
  49006. return typeof tag === "string" && tag.includes("-");
  49007. }
  49008. function mapValidTags(tag) {
  49009. return tag.trim().toLowerCase();
  49010. }
  49011. function generateHydrateResults(opts) {
  49012. if (typeof opts.url !== "string") {
  49013. opts.url = `https://hydrate.stenciljs.com/`;
  49014. }
  49015. if (typeof opts.buildId !== "string") {
  49016. opts.buildId = createHydrateBuildId();
  49017. }
  49018. const results = {
  49019. buildId: opts.buildId,
  49020. diagnostics: [],
  49021. url: opts.url,
  49022. host: null,
  49023. hostname: null,
  49024. href: null,
  49025. pathname: null,
  49026. port: null,
  49027. search: null,
  49028. hash: null,
  49029. html: null,
  49030. httpStatus: null,
  49031. hydratedCount: 0,
  49032. anchors: [],
  49033. components: [],
  49034. imgs: [],
  49035. scripts: [],
  49036. staticData: [],
  49037. styles: [],
  49038. title: null
  49039. };
  49040. try {
  49041. const url = new URL(opts.url, `https://hydrate.stenciljs.com/`);
  49042. results.url = url.href;
  49043. results.host = url.host;
  49044. results.hostname = url.hostname;
  49045. results.href = url.href;
  49046. results.port = url.port;
  49047. results.pathname = url.pathname;
  49048. results.search = url.search;
  49049. results.hash = url.hash;
  49050. } catch (e) {
  49051. renderCatchError(results, e);
  49052. }
  49053. return results;
  49054. }
  49055. var createHydrateBuildId = () => {
  49056. let chars = "abcdefghijklmnopqrstuvwxyz";
  49057. let buildId = "";
  49058. while (buildId.length < 8) {
  49059. const char = chars[Math.floor(Math.random() * chars.length)];
  49060. buildId += char;
  49061. if (buildId.length === 1) {
  49062. chars += "0123456789";
  49063. }
  49064. }
  49065. return buildId;
  49066. };
  49067. function renderBuildDiagnostic(results, level, header, msg) {
  49068. const diagnostic = {
  49069. level,
  49070. type: "build",
  49071. header,
  49072. messageText: msg,
  49073. relFilePath: void 0,
  49074. absFilePath: void 0,
  49075. lines: []
  49076. };
  49077. if (results.pathname) {
  49078. if (results.pathname !== "/") {
  49079. diagnostic.header += ": " + results.pathname;
  49080. }
  49081. } else if (results.url) {
  49082. diagnostic.header += ": " + results.url;
  49083. }
  49084. results.diagnostics.push(diagnostic);
  49085. return diagnostic;
  49086. }
  49087. function renderBuildError(results, msg) {
  49088. return renderBuildDiagnostic(results, "error", "Hydrate Error", msg || "");
  49089. }
  49090. function renderCatchError(results, err2) {
  49091. const diagnostic = renderBuildError(results);
  49092. if (err2 != null) {
  49093. if (err2.stack != null) {
  49094. diagnostic.messageText = err2.stack.toString();
  49095. } else {
  49096. if (err2.message != null) {
  49097. diagnostic.messageText = err2.message.toString();
  49098. } else {
  49099. diagnostic.messageText = err2.toString();
  49100. }
  49101. }
  49102. }
  49103. return diagnostic;
  49104. }
  49105. // src/hydrate/runner/runtime-log.ts
  49106. function runtimeLogging(win, opts, results) {
  49107. try {
  49108. const pathname = win.location.pathname;
  49109. win.console.error = (...msgs) => {
  49110. const errMsg = msgs.reduce((errMsg2, m) => {
  49111. if (m) {
  49112. if (m.stack != null) {
  49113. return errMsg2 + " " + String(m.stack);
  49114. } else {
  49115. if (m.message != null) {
  49116. return errMsg2 + " " + String(m.message);
  49117. }
  49118. }
  49119. }
  49120. return String(m);
  49121. }, "").trim();
  49122. if (errMsg !== "") {
  49123. renderCatchError(results, errMsg);
  49124. if (opts.runtimeLogging) {
  49125. runtimeLog(pathname, "error", [errMsg]);
  49126. }
  49127. }
  49128. };
  49129. win.console.debug = (...msgs) => {
  49130. renderBuildDiagnostic(results, "debug", "Hydrate Debug", [...msgs].join(", "));
  49131. if (opts.runtimeLogging) {
  49132. runtimeLog(pathname, "debug", msgs);
  49133. }
  49134. };
  49135. if (opts.runtimeLogging) {
  49136. ["log", "warn", "assert", "info", "trace"].forEach((type) => {
  49137. win.console[type] = (...msgs) => {
  49138. runtimeLog(pathname, type, msgs);
  49139. };
  49140. });
  49141. }
  49142. } catch (e) {
  49143. renderCatchError(results, e);
  49144. }
  49145. }
  49146. function runtimeLog(pathname, type, msgs) {
  49147. global.console[type].apply(global.console, [`[ ${pathname} ${type} ] `, ...msgs]);
  49148. }
  49149. // src/hydrate/runner/window-initialize.ts
  49150. function initializeWindow(win, doc, opts, results) {
  49151. if (typeof opts.url === "string") {
  49152. try {
  49153. win.location.href = opts.url;
  49154. } catch (e) {
  49155. }
  49156. }
  49157. if (typeof opts.userAgent === "string") {
  49158. try {
  49159. win.navigator.userAgent = opts.userAgent;
  49160. } catch (e) {
  49161. }
  49162. }
  49163. if (typeof opts.cookie === "string") {
  49164. try {
  49165. doc.cookie = opts.cookie;
  49166. } catch (e) {
  49167. }
  49168. }
  49169. if (typeof opts.referrer === "string") {
  49170. try {
  49171. doc.referrer = opts.referrer;
  49172. } catch (e) {
  49173. }
  49174. }
  49175. if (typeof opts.direction === "string") {
  49176. try {
  49177. doc.documentElement.setAttribute("dir", opts.direction);
  49178. } catch (e) {
  49179. }
  49180. }
  49181. if (typeof opts.language === "string") {
  49182. try {
  49183. doc.documentElement.setAttribute("lang", opts.language);
  49184. } catch (e) {
  49185. }
  49186. }
  49187. if (typeof opts.buildId === "string") {
  49188. try {
  49189. doc.documentElement.setAttribute("data-stencil-build", opts.buildId);
  49190. } catch (e) {
  49191. }
  49192. }
  49193. try {
  49194. win.customElements = null;
  49195. } catch (e) {
  49196. }
  49197. if (opts.constrainTimeouts) {
  49198. constrainTimeouts(win);
  49199. }
  49200. runtimeLogging(win, opts, results);
  49201. return win;
  49202. }
  49203. // src/hydrate/runner/render.ts
  49204. var NOOP = () => {
  49205. };
  49206. function streamToString(html, option) {
  49207. return renderToString(html, option, true);
  49208. }
  49209. function renderToString(html, options, asStream) {
  49210. const opts = normalizeHydrateOptions(options);
  49211. opts.serializeToHtml = true;
  49212. opts.fullDocument = typeof opts.fullDocument === "boolean" ? opts.fullDocument : true;
  49213. opts.serializeShadowRoot = typeof opts.serializeShadowRoot === "boolean" ? opts.serializeShadowRoot : true;
  49214. opts.constrainTimeouts = false;
  49215. return hydrateDocument(html, opts, asStream);
  49216. }
  49217. function hydrateDocument(doc, options, asStream) {
  49218. const opts = normalizeHydrateOptions(options);
  49219. let win = null;
  49220. const results = generateHydrateResults(opts);
  49221. if (hasError(results.diagnostics)) {
  49222. return Promise.resolve(results);
  49223. }
  49224. if (typeof doc === "string") {
  49225. try {
  49226. opts.destroyWindow = true;
  49227. opts.destroyDocument = true;
  49228. win = new MockWindow(doc);
  49229. if (!asStream) {
  49230. return render(win, opts, results).then(() => results);
  49231. }
  49232. return renderStream(win, opts, results);
  49233. } catch (e) {
  49234. if (win && win.close) {
  49235. win.close();
  49236. }
  49237. win = null;
  49238. renderCatchError(results, e);
  49239. return Promise.resolve(results);
  49240. }
  49241. }
  49242. if (isValidDocument(doc)) {
  49243. try {
  49244. opts.destroyDocument = false;
  49245. win = patchDomImplementation(doc, opts);
  49246. if (!asStream) {
  49247. return render(win, opts, results).then(() => results);
  49248. }
  49249. return renderStream(win, opts, results);
  49250. } catch (e) {
  49251. if (win && win.close) {
  49252. win.close();
  49253. }
  49254. win = null;
  49255. renderCatchError(results, e);
  49256. return Promise.resolve(results);
  49257. }
  49258. }
  49259. renderBuildError(results, `Invalid html or document. Must be either a valid "html" string, or DOM "document".`);
  49260. return Promise.resolve(results);
  49261. }
  49262. async function render(win, opts, results) {
  49263. if ("process" in globalThis && typeof process.on === "function" && !process.__stencilErrors) {
  49264. process.__stencilErrors = true;
  49265. process.on("unhandledRejection", (e) => {
  49266. console.log("unhandledRejection", e);
  49267. });
  49268. }
  49269. initializeWindow(win, win.document, opts, results);
  49270. const beforeHydrateFn = typeof opts.beforeHydrate === "function" ? opts.beforeHydrate : NOOP;
  49271. try {
  49272. await Promise.resolve(beforeHydrateFn(win.document));
  49273. return new Promise((resolve) => hydrateFactory(win, opts, results, afterHydrate, resolve));
  49274. } catch (e) {
  49275. renderCatchError(results, e);
  49276. return finalizeHydrate(win, win.document, opts, results);
  49277. }
  49278. }
  49279. function renderStream(win, opts, results) {
  49280. async function* processRender() {
  49281. const renderResult = await render(win, opts, results);
  49282. yield renderResult.html;
  49283. }
  49284. return Readable.from(processRender());
  49285. }
  49286. async function afterHydrate(win, opts, results, resolve) {
  49287. const afterHydrateFn = typeof opts.afterHydrate === "function" ? opts.afterHydrate : NOOP;
  49288. try {
  49289. await Promise.resolve(afterHydrateFn(win.document));
  49290. return resolve(finalizeHydrate(win, win.document, opts, results));
  49291. } catch (e) {
  49292. renderCatchError(results, e);
  49293. return resolve(finalizeHydrate(win, win.document, opts, results));
  49294. }
  49295. }
  49296. function finalizeHydrate(win, doc, opts, results) {
  49297. try {
  49298. inspectElement(results, doc.documentElement, 0);
  49299. if (opts.removeUnusedStyles !== false) {
  49300. try {
  49301. removeUnusedStyles(doc, results.diagnostics);
  49302. } catch (e) {
  49303. renderCatchError(results, e);
  49304. }
  49305. }
  49306. if (typeof opts.title === "string") {
  49307. try {
  49308. doc.title = opts.title;
  49309. } catch (e) {
  49310. renderCatchError(results, e);
  49311. }
  49312. }
  49313. results.title = doc.title;
  49314. if (opts.removeScripts) {
  49315. removeScripts(doc.documentElement);
  49316. }
  49317. try {
  49318. updateCanonicalLink(doc, opts.canonicalUrl);
  49319. } catch (e) {
  49320. renderCatchError(results, e);
  49321. }
  49322. try {
  49323. relocateMetaCharset(doc);
  49324. } catch (e) {
  49325. }
  49326. if (!hasError(results.diagnostics)) {
  49327. results.httpStatus = 200;
  49328. }
  49329. try {
  49330. const metaStatus = doc.head.querySelector('meta[http-equiv="status"]');
  49331. if (metaStatus != null) {
  49332. const metaStatusContent = metaStatus.getAttribute("content");
  49333. if (metaStatusContent && metaStatusContent.length > 0) {
  49334. results.httpStatus = parseInt(metaStatusContent, 10);
  49335. }
  49336. }
  49337. } catch (e) {
  49338. }
  49339. if (opts.clientHydrateAnnotations) {
  49340. doc.documentElement.classList.add("hydrated");
  49341. }
  49342. if (opts.serializeToHtml) {
  49343. results.html = serializeDocumentToString(doc, opts);
  49344. }
  49345. } catch (e) {
  49346. renderCatchError(results, e);
  49347. }
  49348. destroyWindow(win, doc, opts, results);
  49349. return results;
  49350. }
  49351. function destroyWindow(win, doc, opts, results) {
  49352. if (!opts.destroyWindow) {
  49353. return;
  49354. }
  49355. try {
  49356. if (!opts.destroyDocument) {
  49357. win.document = null;
  49358. doc.defaultView = null;
  49359. }
  49360. if (win.close) {
  49361. win.close();
  49362. }
  49363. } catch (e) {
  49364. renderCatchError(results, e);
  49365. }
  49366. }
  49367. function serializeDocumentToString(doc, opts) {
  49368. return serializeNodeToHtml(doc, {
  49369. approximateLineWidth: opts.approximateLineWidth,
  49370. outerHtml: false,
  49371. prettyHtml: opts.prettyHtml,
  49372. removeAttributeQuotes: opts.removeAttributeQuotes,
  49373. removeBooleanAttributeQuotes: opts.removeBooleanAttributeQuotes,
  49374. removeEmptyAttributes: opts.removeEmptyAttributes,
  49375. removeHtmlComments: opts.removeHtmlComments,
  49376. serializeShadowRoot: opts.serializeShadowRoot,
  49377. fullDocument: opts.fullDocument
  49378. });
  49379. }
  49380. function isValidDocument(doc) {
  49381. return doc != null && doc.nodeType === 9 && doc.documentElement != null && doc.documentElement.nodeType === 1 && doc.body != null && doc.body.nodeType === 1;
  49382. }
  49383. function removeScripts(elm) {
  49384. const children = elm.children;
  49385. for (let i = children.length - 1; i >= 0; i--) {
  49386. const child = children[i];
  49387. removeScripts(child);
  49388. if (child.nodeName === "SCRIPT" || child.nodeName === "LINK" && child.getAttribute("rel") === "modulepreload") {
  49389. child.remove();
  49390. }
  49391. }
  49392. }
  49393. export { createWindowFromHtml, hydrateDocument, renderToString, serializeDocumentToString, streamToString };