12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920392139223923392439253926392739283929393039313932393339343935393639373938393939403941394239433944394539463947394839493950395139523953395439553956395739583959396039613962396339643965396639673968396939703971397239733974397539763977397839793980398139823983398439853986398739883989399039913992399339943995399639973998399940004001400240034004400540064007400840094010401140124013401440154016401740184019402040214022402340244025402640274028402940304031403240334034403540364037403840394040404140424043404440454046404740484049405040514052405340544055405640574058405940604061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130413141324133413441354136413741384139414041414142414341444145414641474148414941504151415241534154415541564157415841594160416141624163416441654166416741684169417041714172417341744175417641774178417941804181418241834184418541864187418841894190419141924193419441954196419741984199420042014202420342044205420642074208420942104211421242134214421542164217421842194220422142224223422442254226422742284229423042314232423342344235423642374238423942404241424242434244424542464247424842494250425142524253425442554256425742584259426042614262426342644265426642674268426942704271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340434143424343434443454346434743484349435043514352435343544355435643574358435943604361436243634364436543664367436843694370437143724373437443754376437743784379438043814382438343844385438643874388438943904391439243934394439543964397439843994400440144024403440444054406440744084409441044114412441344144415441644174418441944204421442244234424442544264427442844294430443144324433443444354436443744384439444044414442444344444445444644474448444944504451445244534454445544564457445844594460446144624463446444654466446744684469447044714472447344744475447644774478447944804481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550455145524553455445554556455745584559456045614562456345644565456645674568456945704571457245734574457545764577457845794580458145824583458445854586458745884589459045914592459345944595459645974598459946004601460246034604460546064607460846094610461146124613461446154616461746184619462046214622462346244625462646274628462946304631463246334634463546364637463846394640464146424643464446454646464746484649465046514652465346544655465646574658465946604661466246634664466546664667466846694670467146724673467446754676467746784679468046814682468346844685468646874688468946904691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760476147624763476447654766476747684769477047714772477347744775477647774778477947804781478247834784478547864787478847894790479147924793479447954796479747984799480048014802480348044805480648074808480948104811481248134814481548164817481848194820482148224823482448254826482748284829483048314832483348344835483648374838483948404841484248434844484548464847484848494850485148524853485448554856485748584859486048614862486348644865486648674868486948704871487248734874487548764877487848794880488148824883488448854886488748884889489048914892489348944895489648974898489949004901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970497149724973497449754976497749784979498049814982498349844985498649874988498949904991499249934994499549964997499849995000500150025003500450055006500750085009501050115012501350145015501650175018501950205021502250235024502550265027502850295030503150325033503450355036503750385039504050415042504350445045504650475048504950505051505250535054505550565057505850595060506150625063506450655066506750685069507050715072507350745075507650775078507950805081508250835084508550865087508850895090509150925093509450955096509750985099510051015102510351045105510651075108510951105111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180518151825183518451855186518751885189519051915192519351945195519651975198519952005201520252035204520552065207520852095210521152125213521452155216521752185219522052215222522352245225522652275228522952305231523252335234523552365237523852395240524152425243524452455246524752485249525052515252525352545255525652575258525952605261526252635264526552665267526852695270527152725273527452755276527752785279528052815282528352845285528652875288528952905291529252935294529552965297529852995300530153025303530453055306530753085309531053115312531353145315531653175318531953205321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390539153925393539453955396539753985399540054015402540354045405540654075408540954105411541254135414541554165417541854195420542154225423542454255426542754285429543054315432543354345435543654375438543954405441544254435444544554465447544854495450545154525453545454555456545754585459546054615462546354645465546654675468546954705471547254735474547554765477547854795480548154825483548454855486548754885489549054915492549354945495549654975498549955005501550255035504550555065507550855095510551155125513551455155516551755185519552055215522552355245525552655275528552955305531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600560156025603560456055606560756085609561056115612561356145615561656175618561956205621562256235624562556265627562856295630563156325633563456355636563756385639564056415642564356445645564656475648564956505651565256535654565556565657565856595660566156625663566456655666566756685669567056715672567356745675567656775678567956805681568256835684568556865687568856895690569156925693569456955696569756985699570057015702570357045705570657075708570957105711571257135714571557165717571857195720572157225723572457255726572757285729573057315732573357345735573657375738573957405741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810581158125813581458155816581758185819582058215822582358245825582658275828582958305831583258335834583558365837583858395840584158425843584458455846584758485849585058515852585358545855585658575858585958605861586258635864586558665867586858695870587158725873587458755876587758785879588058815882588358845885588658875888588958905891589258935894589558965897589858995900590159025903590459055906590759085909591059115912591359145915591659175918591959205921592259235924592559265927592859295930593159325933593459355936593759385939594059415942594359445945594659475948594959505951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020602160226023602460256026602760286029603060316032603360346035603660376038603960406041604260436044604560466047604860496050605160526053605460556056605760586059606060616062606360646065606660676068606960706071607260736074607560766077607860796080608160826083608460856086608760886089609060916092609360946095609660976098609961006101610261036104610561066107610861096110611161126113611461156116611761186119612061216122612361246125612661276128612961306131613261336134613561366137613861396140614161426143614461456146614761486149615061516152615361546155615661576158615961606161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230623162326233623462356236623762386239624062416242624362446245624662476248624962506251625262536254625562566257625862596260626162626263626462656266626762686269627062716272627362746275627662776278627962806281628262836284628562866287628862896290629162926293629462956296629762986299630063016302630363046305630663076308630963106311631263136314631563166317631863196320632163226323632463256326632763286329633063316332633363346335633663376338633963406341634263436344634563466347634863496350635163526353635463556356635763586359636063616362636363646365636663676368636963706371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440644164426443644464456446644764486449645064516452645364546455645664576458645964606461646264636464646564666467646864696470647164726473647464756476647764786479648064816482648364846485648664876488648964906491649264936494649564966497649864996500650165026503650465056506650765086509651065116512651365146515651665176518651965206521652265236524652565266527652865296530653165326533653465356536653765386539654065416542654365446545654665476548654965506551655265536554655565566557655865596560656165626563656465656566656765686569657065716572657365746575657665776578657965806581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650665166526653665466556656665766586659666066616662666366646665666666676668666966706671667266736674667566766677667866796680668166826683668466856686668766886689669066916692669366946695669666976698669967006701670267036704670567066707670867096710671167126713671467156716671767186719672067216722672367246725672667276728672967306731673267336734673567366737673867396740674167426743674467456746674767486749675067516752675367546755675667576758675967606761676267636764676567666767676867696770677167726773677467756776677767786779678067816782678367846785678667876788678967906791679267936794679567966797679867996800680168026803680468056806680768086809681068116812681368146815681668176818681968206821682268236824682568266827682868296830683168326833683468356836683768386839684068416842684368446845684668476848684968506851685268536854685568566857685868596860686168626863686468656866686768686869687068716872687368746875687668776878687968806881688268836884688568866887688868896890689168926893689468956896689768986899690069016902690369046905690669076908690969106911691269136914691569166917691869196920692169226923692469256926692769286929693069316932693369346935693669376938693969406941694269436944694569466947694869496950695169526953695469556956695769586959696069616962696369646965696669676968696969706971697269736974697569766977697869796980698169826983698469856986698769886989699069916992699369946995699669976998699970007001700270037004700570067007700870097010701170127013701470157016701770187019702070217022702370247025702670277028702970307031703270337034703570367037703870397040704170427043704470457046704770487049705070517052705370547055705670577058705970607061706270637064706570667067706870697070707170727073707470757076707770787079708070817082708370847085708670877088708970907091709270937094709570967097709870997100710171027103710471057106710771087109711071117112711371147115711671177118711971207121712271237124712571267127712871297130713171327133713471357136713771387139714071417142714371447145714671477148714971507151715271537154715571567157715871597160716171627163716471657166716771687169717071717172717371747175717671777178717971807181718271837184718571867187718871897190719171927193719471957196719771987199720072017202720372047205720672077208720972107211721272137214721572167217721872197220722172227223722472257226722772287229723072317232723372347235723672377238723972407241724272437244724572467247724872497250725172527253725472557256725772587259726072617262726372647265726672677268726972707271727272737274727572767277727872797280728172827283728472857286728772887289729072917292729372947295729672977298729973007301730273037304730573067307730873097310731173127313731473157316731773187319732073217322732373247325732673277328732973307331733273337334733573367337733873397340734173427343734473457346734773487349735073517352735373547355735673577358735973607361736273637364736573667367736873697370737173727373737473757376737773787379738073817382738373847385738673877388738973907391739273937394739573967397739873997400740174027403740474057406740774087409741074117412741374147415741674177418741974207421742274237424742574267427742874297430743174327433743474357436743774387439744074417442744374447445744674477448744974507451745274537454745574567457745874597460746174627463746474657466746774687469747074717472747374747475747674777478747974807481748274837484748574867487748874897490749174927493749474957496749774987499750075017502750375047505750675077508750975107511751275137514751575167517751875197520752175227523752475257526752775287529753075317532753375347535753675377538753975407541754275437544754575467547754875497550755175527553755475557556755775587559756075617562756375647565756675677568756975707571757275737574757575767577757875797580758175827583758475857586758775887589759075917592759375947595759675977598759976007601760276037604760576067607760876097610761176127613761476157616761776187619762076217622762376247625762676277628762976307631763276337634763576367637763876397640764176427643764476457646764776487649765076517652765376547655765676577658765976607661766276637664766576667667766876697670767176727673767476757676767776787679768076817682768376847685768676877688768976907691769276937694769576967697769876997700770177027703770477057706770777087709771077117712771377147715771677177718771977207721772277237724772577267727772877297730773177327733773477357736773777387739774077417742774377447745774677477748774977507751775277537754775577567757775877597760776177627763776477657766776777687769777077717772777377747775777677777778777977807781778277837784778577867787778877897790779177927793779477957796779777987799780078017802780378047805780678077808780978107811781278137814781578167817781878197820782178227823782478257826782778287829783078317832783378347835783678377838783978407841784278437844784578467847784878497850785178527853785478557856785778587859786078617862786378647865786678677868786978707871787278737874787578767877787878797880788178827883788478857886788778887889789078917892789378947895789678977898789979007901790279037904790579067907790879097910791179127913791479157916791779187919792079217922792379247925792679277928792979307931793279337934793579367937793879397940794179427943794479457946794779487949795079517952795379547955795679577958795979607961796279637964796579667967796879697970797179727973797479757976797779787979798079817982798379847985798679877988798979907991799279937994799579967997799879998000800180028003800480058006800780088009801080118012801380148015801680178018801980208021802280238024802580268027802880298030803180328033803480358036803780388039804080418042804380448045804680478048804980508051805280538054805580568057805880598060806180628063806480658066806780688069807080718072807380748075807680778078807980808081808280838084808580868087808880898090809180928093809480958096809780988099810081018102810381048105810681078108810981108111811281138114811581168117811881198120812181228123812481258126812781288129813081318132813381348135813681378138813981408141814281438144814581468147814881498150815181528153815481558156815781588159816081618162816381648165816681678168816981708171817281738174817581768177817881798180818181828183818481858186818781888189819081918192819381948195819681978198819982008201820282038204820582068207820882098210821182128213821482158216821782188219822082218222822382248225822682278228822982308231823282338234823582368237823882398240824182428243824482458246824782488249825082518252825382548255825682578258825982608261826282638264826582668267826882698270827182728273827482758276827782788279828082818282828382848285828682878288828982908291829282938294829582968297829882998300830183028303830483058306830783088309831083118312831383148315831683178318831983208321832283238324832583268327832883298330833183328333833483358336833783388339834083418342834383448345834683478348834983508351835283538354835583568357835883598360836183628363836483658366836783688369837083718372837383748375837683778378837983808381838283838384838583868387838883898390839183928393839483958396839783988399840084018402840384048405840684078408840984108411841284138414841584168417841884198420842184228423842484258426842784288429843084318432843384348435843684378438843984408441844284438444844584468447844884498450845184528453845484558456845784588459846084618462846384648465846684678468846984708471847284738474847584768477847884798480848184828483848484858486848784888489849084918492849384948495849684978498849985008501850285038504850585068507850885098510851185128513851485158516851785188519852085218522852385248525852685278528852985308531853285338534853585368537853885398540854185428543854485458546854785488549855085518552855385548555855685578558855985608561856285638564856585668567856885698570857185728573857485758576857785788579858085818582858385848585858685878588858985908591859285938594859585968597859885998600860186028603860486058606860786088609861086118612861386148615861686178618861986208621862286238624862586268627862886298630863186328633863486358636863786388639864086418642864386448645864686478648864986508651865286538654865586568657865886598660866186628663866486658666866786688669867086718672867386748675867686778678867986808681868286838684868586868687868886898690869186928693869486958696869786988699870087018702870387048705870687078708870987108711871287138714871587168717871887198720872187228723872487258726872787288729873087318732873387348735873687378738873987408741874287438744874587468747874887498750875187528753875487558756875787588759876087618762876387648765876687678768876987708771877287738774877587768777877887798780878187828783878487858786878787888789879087918792879387948795879687978798879988008801880288038804880588068807880888098810881188128813881488158816881788188819882088218822882388248825882688278828882988308831883288338834883588368837883888398840884188428843884488458846884788488849885088518852885388548855885688578858885988608861886288638864886588668867886888698870887188728873887488758876887788788879888088818882888388848885888688878888888988908891889288938894889588968897889888998900890189028903890489058906890789088909891089118912891389148915891689178918891989208921892289238924892589268927892889298930893189328933893489358936893789388939894089418942894389448945894689478948894989508951895289538954895589568957895889598960896189628963896489658966896789688969897089718972897389748975897689778978897989808981898289838984898589868987898889898990899189928993899489958996899789988999900090019002900390049005900690079008900990109011901290139014901590169017901890199020902190229023902490259026902790289029903090319032903390349035903690379038903990409041904290439044904590469047904890499050905190529053905490559056905790589059906090619062906390649065906690679068906990709071907290739074907590769077907890799080908190829083908490859086908790889089909090919092909390949095909690979098909991009101910291039104910591069107910891099110911191129113911491159116911791189119912091219122912391249125912691279128912991309131913291339134913591369137913891399140914191429143914491459146914791489149915091519152915391549155915691579158915991609161916291639164916591669167916891699170917191729173917491759176917791789179918091819182918391849185918691879188918991909191919291939194919591969197919891999200920192029203920492059206920792089209921092119212921392149215921692179218921992209221922292239224922592269227922892299230923192329233923492359236923792389239924092419242924392449245924692479248924992509251925292539254925592569257925892599260926192629263926492659266926792689269927092719272927392749275927692779278927992809281928292839284928592869287928892899290929192929293929492959296929792989299930093019302930393049305930693079308930993109311931293139314931593169317931893199320932193229323932493259326932793289329933093319332933393349335933693379338933993409341934293439344934593469347934893499350935193529353935493559356935793589359936093619362936393649365936693679368936993709371937293739374937593769377937893799380938193829383938493859386938793889389939093919392939393949395939693979398939994009401940294039404940594069407940894099410941194129413941494159416941794189419942094219422942394249425942694279428942994309431943294339434943594369437943894399440944194429443944494459446944794489449945094519452945394549455945694579458945994609461946294639464946594669467946894699470947194729473947494759476947794789479948094819482948394849485948694879488948994909491949294939494949594969497949894999500950195029503950495059506950795089509951095119512951395149515951695179518951995209521952295239524952595269527952895299530953195329533953495359536953795389539954095419542954395449545954695479548954995509551955295539554955595569557955895599560956195629563956495659566956795689569957095719572957395749575957695779578957995809581958295839584958595869587958895899590959195929593959495959596959795989599960096019602960396049605960696079608960996109611961296139614961596169617961896199620962196229623962496259626962796289629963096319632963396349635963696379638963996409641964296439644964596469647964896499650965196529653965496559656965796589659966096619662966396649665966696679668966996709671967296739674967596769677967896799680968196829683968496859686968796889689969096919692969396949695969696979698969997009701970297039704970597069707970897099710971197129713971497159716971797189719972097219722972397249725972697279728972997309731973297339734973597369737973897399740974197429743974497459746974797489749975097519752975397549755975697579758975997609761976297639764976597669767976897699770977197729773977497759776977797789779978097819782978397849785978697879788978997909791979297939794979597969797979897999800980198029803980498059806980798089809981098119812981398149815981698179818981998209821982298239824982598269827982898299830983198329833983498359836983798389839984098419842984398449845984698479848984998509851985298539854985598569857985898599860986198629863986498659866986798689869987098719872987398749875987698779878987998809881988298839884988598869887988898899890989198929893989498959896989798989899990099019902990399049905990699079908990999109911991299139914991599169917991899199920992199229923992499259926992799289929993099319932993399349935993699379938993999409941994299439944994599469947994899499950995199529953995499559956995799589959996099619962996399649965996699679968996999709971997299739974997599769977997899799980998199829983998499859986998799889989999099919992999399949995999699979998999910000100011000210003100041000510006100071000810009100101001110012100131001410015100161001710018100191002010021100221002310024100251002610027100281002910030100311003210033100341003510036100371003810039100401004110042100431004410045100461004710048100491005010051100521005310054100551005610057100581005910060100611006210063100641006510066100671006810069100701007110072100731007410075100761007710078100791008010081100821008310084100851008610087100881008910090100911009210093100941009510096100971009810099101001010110102101031010410105101061010710108101091011010111101121011310114101151011610117101181011910120101211012210123101241012510126101271012810129101301013110132101331013410135101361013710138101391014010141101421014310144101451014610147101481014910150101511015210153101541015510156101571015810159101601016110162101631016410165101661016710168101691017010171101721017310174101751017610177101781017910180101811018210183101841018510186101871018810189101901019110192101931019410195101961019710198101991020010201102021020310204102051020610207102081020910210102111021210213102141021510216102171021810219102201022110222102231022410225102261022710228102291023010231102321023310234102351023610237102381023910240102411024210243102441024510246102471024810249102501025110252102531025410255102561025710258102591026010261102621026310264102651026610267102681026910270102711027210273102741027510276102771027810279102801028110282102831028410285102861028710288102891029010291102921029310294102951029610297102981029910300103011030210303103041030510306103071030810309103101031110312103131031410315103161031710318103191032010321103221032310324103251032610327103281032910330103311033210333103341033510336103371033810339103401034110342103431034410345103461034710348103491035010351103521035310354103551035610357103581035910360103611036210363103641036510366103671036810369103701037110372103731037410375103761037710378103791038010381103821038310384103851038610387103881038910390103911039210393103941039510396103971039810399104001040110402104031040410405104061040710408104091041010411104121041310414104151041610417104181041910420104211042210423104241042510426104271042810429104301043110432104331043410435104361043710438104391044010441104421044310444104451044610447104481044910450104511045210453104541045510456104571045810459104601046110462104631046410465104661046710468104691047010471104721047310474104751047610477104781047910480104811048210483104841048510486104871048810489104901049110492104931049410495104961049710498104991050010501105021050310504105051050610507105081050910510105111051210513105141051510516105171051810519105201052110522105231052410525105261052710528105291053010531105321053310534105351053610537105381053910540105411054210543105441054510546105471054810549105501055110552105531055410555105561055710558105591056010561105621056310564105651056610567105681056910570105711057210573105741057510576105771057810579105801058110582105831058410585105861058710588105891059010591105921059310594105951059610597105981059910600106011060210603106041060510606106071060810609106101061110612106131061410615106161061710618106191062010621106221062310624106251062610627106281062910630106311063210633106341063510636106371063810639106401064110642106431064410645106461064710648106491065010651106521065310654106551065610657106581065910660106611066210663106641066510666106671066810669106701067110672106731067410675106761067710678106791068010681106821068310684106851068610687106881068910690106911069210693106941069510696106971069810699107001070110702107031070410705107061070710708107091071010711107121071310714107151071610717107181071910720107211072210723107241072510726107271072810729107301073110732107331073410735107361073710738107391074010741107421074310744107451074610747107481074910750107511075210753107541075510756107571075810759107601076110762107631076410765107661076710768107691077010771107721077310774107751077610777107781077910780107811078210783107841078510786107871078810789107901079110792107931079410795107961079710798107991080010801108021080310804108051080610807108081080910810108111081210813108141081510816108171081810819108201082110822108231082410825108261082710828108291083010831108321083310834108351083610837108381083910840108411084210843108441084510846108471084810849108501085110852108531085410855108561085710858108591086010861108621086310864108651086610867108681086910870108711087210873108741087510876108771087810879108801088110882108831088410885108861088710888108891089010891108921089310894108951089610897108981089910900109011090210903109041090510906109071090810909109101091110912109131091410915109161091710918109191092010921109221092310924109251092610927109281092910930109311093210933109341093510936109371093810939109401094110942109431094410945109461094710948109491095010951109521095310954109551095610957109581095910960109611096210963109641096510966109671096810969109701097110972109731097410975109761097710978109791098010981109821098310984109851098610987109881098910990109911099210993109941099510996109971099810999110001100111002110031100411005110061100711008110091101011011110121101311014110151101611017110181101911020110211102211023110241102511026110271102811029110301103111032110331103411035110361103711038110391104011041110421104311044110451104611047110481104911050110511105211053110541105511056110571105811059110601106111062110631106411065110661106711068110691107011071110721107311074110751107611077110781107911080110811108211083110841108511086110871108811089110901109111092110931109411095110961109711098110991110011101111021110311104111051110611107111081110911110111111111211113111141111511116111171111811119111201112111122111231112411125111261112711128111291113011131111321113311134111351113611137111381113911140111411114211143111441114511146111471114811149111501115111152111531115411155111561115711158111591116011161111621116311164111651116611167111681116911170111711117211173111741117511176111771117811179111801118111182111831118411185111861118711188111891119011191111921119311194111951119611197111981119911200112011120211203112041120511206112071120811209112101121111212112131121411215112161121711218112191122011221112221122311224112251122611227112281122911230112311123211233112341123511236112371123811239112401124111242112431124411245112461124711248112491125011251112521125311254112551125611257112581125911260112611126211263112641126511266112671126811269112701127111272112731127411275112761127711278112791128011281112821128311284112851128611287112881128911290112911129211293112941129511296112971129811299113001130111302113031130411305113061130711308113091131011311113121131311314113151131611317113181131911320113211132211323113241132511326113271132811329113301133111332113331133411335113361133711338113391134011341113421134311344113451134611347113481134911350113511135211353113541135511356113571135811359113601136111362113631136411365113661136711368113691137011371113721137311374113751137611377113781137911380113811138211383113841138511386113871138811389113901139111392113931139411395113961139711398113991140011401114021140311404114051140611407114081140911410114111141211413114141141511416114171141811419114201142111422114231142411425114261142711428114291143011431114321143311434114351143611437114381143911440114411144211443114441144511446114471144811449114501145111452114531145411455114561145711458114591146011461114621146311464114651146611467114681146911470114711147211473114741147511476114771147811479114801148111482114831148411485114861148711488114891149011491114921149311494114951149611497114981149911500115011150211503115041150511506115071150811509115101151111512115131151411515115161151711518115191152011521115221152311524115251152611527115281152911530115311153211533115341153511536115371153811539115401154111542115431154411545115461154711548115491155011551115521155311554115551155611557115581155911560115611156211563115641156511566115671156811569115701157111572115731157411575115761157711578115791158011581115821158311584115851158611587115881158911590115911159211593115941159511596115971159811599116001160111602116031160411605116061160711608116091161011611116121161311614116151161611617116181161911620116211162211623116241162511626116271162811629116301163111632116331163411635116361163711638116391164011641116421164311644116451164611647116481164911650116511165211653116541165511656116571165811659116601166111662116631166411665116661166711668116691167011671116721167311674116751167611677116781167911680116811168211683116841168511686116871168811689116901169111692116931169411695116961169711698116991170011701117021170311704117051170611707117081170911710117111171211713117141171511716117171171811719117201172111722117231172411725117261172711728117291173011731117321173311734117351173611737117381173911740117411174211743117441174511746117471174811749117501175111752117531175411755117561175711758117591176011761117621176311764117651176611767117681176911770117711177211773117741177511776117771177811779117801178111782117831178411785117861178711788117891179011791117921179311794117951179611797117981179911800118011180211803118041180511806118071180811809118101181111812118131181411815118161181711818118191182011821118221182311824118251182611827118281182911830118311183211833118341183511836118371183811839118401184111842118431184411845118461184711848118491185011851118521185311854118551185611857118581185911860118611186211863118641186511866118671186811869118701187111872118731187411875118761187711878118791188011881118821188311884118851188611887118881188911890118911189211893118941189511896118971189811899119001190111902119031190411905119061190711908119091191011911119121191311914119151191611917119181191911920119211192211923119241192511926119271192811929119301193111932119331193411935119361193711938119391194011941119421194311944119451194611947119481194911950119511195211953119541195511956119571195811959119601196111962119631196411965119661196711968119691197011971119721197311974119751197611977119781197911980119811198211983119841198511986119871198811989119901199111992119931199411995119961199711998119991200012001120021200312004120051200612007120081200912010120111201212013120141201512016120171201812019120201202112022120231202412025120261202712028120291203012031120321203312034120351203612037120381203912040120411204212043120441204512046120471204812049120501205112052120531205412055120561205712058120591206012061120621206312064120651206612067120681206912070120711207212073120741207512076120771207812079120801208112082120831208412085120861208712088120891209012091120921209312094120951209612097120981209912100121011210212103121041210512106121071210812109121101211112112121131211412115121161211712118121191212012121121221212312124121251212612127121281212912130121311213212133121341213512136121371213812139121401214112142121431214412145121461214712148121491215012151121521215312154121551215612157121581215912160121611216212163121641216512166121671216812169121701217112172121731217412175121761217712178121791218012181121821218312184121851218612187121881218912190121911219212193121941219512196121971219812199122001220112202122031220412205122061220712208122091221012211122121221312214122151221612217122181221912220122211222212223122241222512226122271222812229122301223112232122331223412235122361223712238122391224012241122421224312244122451224612247122481224912250122511225212253122541225512256122571225812259122601226112262122631226412265122661226712268122691227012271122721227312274122751227612277122781227912280122811228212283122841228512286122871228812289122901229112292122931229412295122961229712298122991230012301123021230312304123051230612307123081230912310123111231212313123141231512316123171231812319123201232112322123231232412325123261232712328123291233012331123321233312334123351233612337123381233912340123411234212343123441234512346123471234812349123501235112352123531235412355123561235712358123591236012361123621236312364123651236612367123681236912370123711237212373123741237512376123771237812379123801238112382123831238412385123861238712388123891239012391123921239312394123951239612397123981239912400124011240212403124041240512406124071240812409124101241112412124131241412415124161241712418124191242012421124221242312424124251242612427124281242912430124311243212433124341243512436124371243812439124401244112442124431244412445124461244712448124491245012451124521245312454124551245612457124581245912460124611246212463124641246512466124671246812469124701247112472124731247412475124761247712478124791248012481124821248312484124851248612487124881248912490124911249212493124941249512496124971249812499125001250112502125031250412505125061250712508125091251012511125121251312514125151251612517125181251912520125211252212523125241252512526125271252812529125301253112532125331253412535125361253712538125391254012541125421254312544125451254612547125481254912550125511255212553125541255512556125571255812559125601256112562125631256412565125661256712568125691257012571125721257312574125751257612577125781257912580125811258212583125841258512586125871258812589125901259112592125931259412595125961259712598125991260012601126021260312604126051260612607126081260912610126111261212613126141261512616126171261812619126201262112622126231262412625126261262712628126291263012631126321263312634126351263612637126381263912640126411264212643126441264512646126471264812649126501265112652126531265412655126561265712658126591266012661126621266312664126651266612667126681266912670126711267212673126741267512676126771267812679126801268112682126831268412685126861268712688126891269012691126921269312694126951269612697126981269912700127011270212703127041270512706127071270812709127101271112712127131271412715127161271712718127191272012721127221272312724127251272612727127281272912730127311273212733127341273512736127371273812739127401274112742127431274412745127461274712748127491275012751127521275312754127551275612757127581275912760127611276212763127641276512766127671276812769127701277112772127731277412775127761277712778127791278012781127821278312784127851278612787127881278912790127911279212793127941279512796127971279812799128001280112802128031280412805128061280712808128091281012811128121281312814128151281612817128181281912820128211282212823128241282512826128271282812829128301283112832128331283412835128361283712838128391284012841128421284312844128451284612847128481284912850128511285212853128541285512856128571285812859128601286112862128631286412865128661286712868128691287012871128721287312874128751287612877128781287912880128811288212883128841288512886128871288812889128901289112892128931289412895128961289712898128991290012901129021290312904129051290612907129081290912910129111291212913129141291512916129171291812919129201292112922129231292412925129261292712928129291293012931129321293312934129351293612937129381293912940129411294212943129441294512946129471294812949129501295112952129531295412955129561295712958129591296012961129621296312964129651296612967129681296912970129711297212973129741297512976129771297812979129801298112982129831298412985129861298712988129891299012991129921299312994129951299612997129981299913000130011300213003130041300513006130071300813009130101301113012130131301413015130161301713018130191302013021130221302313024130251302613027130281302913030130311303213033130341303513036130371303813039130401304113042130431304413045130461304713048130491305013051130521305313054130551305613057130581305913060130611306213063130641306513066130671306813069130701307113072130731307413075130761307713078130791308013081130821308313084130851308613087130881308913090130911309213093130941309513096130971309813099131001310113102131031310413105131061310713108131091311013111131121311313114131151311613117131181311913120131211312213123131241312513126131271312813129131301313113132131331313413135131361313713138131391314013141131421314313144131451314613147131481314913150131511315213153131541315513156131571315813159131601316113162131631316413165131661316713168131691317013171131721317313174131751317613177131781317913180131811318213183131841318513186131871318813189131901319113192131931319413195131961319713198131991320013201132021320313204132051320613207132081320913210132111321213213132141321513216132171321813219132201322113222132231322413225132261322713228132291323013231132321323313234132351323613237132381323913240132411324213243132441324513246132471324813249132501325113252132531325413255132561325713258132591326013261132621326313264132651326613267132681326913270132711327213273132741327513276132771327813279132801328113282132831328413285132861328713288132891329013291132921329313294132951329613297132981329913300133011330213303133041330513306133071330813309133101331113312133131331413315133161331713318133191332013321133221332313324133251332613327133281332913330133311333213333133341333513336133371333813339133401334113342133431334413345133461334713348133491335013351133521335313354133551335613357133581335913360133611336213363133641336513366133671336813369133701337113372133731337413375133761337713378133791338013381133821338313384133851338613387133881338913390133911339213393133941339513396133971339813399134001340113402134031340413405134061340713408134091341013411134121341313414134151341613417134181341913420134211342213423134241342513426134271342813429134301343113432134331343413435134361343713438134391344013441134421344313444134451344613447134481344913450134511345213453134541345513456134571345813459134601346113462134631346413465134661346713468134691347013471134721347313474134751347613477134781347913480134811348213483134841348513486134871348813489134901349113492134931349413495134961349713498134991350013501135021350313504135051350613507135081350913510135111351213513135141351513516135171351813519135201352113522135231352413525135261352713528135291353013531135321353313534135351353613537135381353913540135411354213543135441354513546135471354813549135501355113552135531355413555135561355713558135591356013561135621356313564135651356613567135681356913570135711357213573135741357513576135771357813579135801358113582135831358413585135861358713588135891359013591135921359313594135951359613597135981359913600136011360213603136041360513606136071360813609136101361113612136131361413615136161361713618136191362013621136221362313624136251362613627136281362913630136311363213633136341363513636136371363813639136401364113642136431364413645136461364713648136491365013651136521365313654136551365613657136581365913660136611366213663136641366513666136671366813669136701367113672136731367413675136761367713678136791368013681136821368313684136851368613687136881368913690136911369213693136941369513696136971369813699137001370113702137031370413705137061370713708137091371013711137121371313714137151371613717137181371913720137211372213723137241372513726137271372813729137301373113732137331373413735137361373713738137391374013741137421374313744137451374613747137481374913750137511375213753137541375513756137571375813759137601376113762137631376413765137661376713768137691377013771137721377313774137751377613777137781377913780137811378213783137841378513786137871378813789137901379113792137931379413795137961379713798137991380013801138021380313804138051380613807138081380913810138111381213813138141381513816138171381813819138201382113822138231382413825138261382713828138291383013831138321383313834138351383613837138381383913840138411384213843138441384513846138471384813849138501385113852138531385413855138561385713858138591386013861138621386313864138651386613867138681386913870138711387213873138741387513876138771387813879138801388113882138831388413885138861388713888138891389013891138921389313894138951389613897138981389913900139011390213903139041390513906139071390813909139101391113912139131391413915139161391713918139191392013921139221392313924139251392613927139281392913930139311393213933139341393513936139371393813939139401394113942139431394413945139461394713948139491395013951139521395313954139551395613957139581395913960139611396213963139641396513966139671396813969139701397113972139731397413975139761397713978139791398013981139821398313984139851398613987139881398913990139911399213993139941399513996139971399813999140001400114002140031400414005140061400714008140091401014011140121401314014140151401614017140181401914020140211402214023140241402514026140271402814029140301403114032140331403414035140361403714038140391404014041140421404314044140451404614047140481404914050140511405214053140541405514056140571405814059140601406114062140631406414065140661406714068140691407014071140721407314074140751407614077140781407914080140811408214083140841408514086140871408814089140901409114092140931409414095140961409714098140991410014101141021410314104141051410614107141081410914110141111411214113141141411514116141171411814119141201412114122141231412414125141261412714128141291413014131141321413314134141351413614137141381413914140141411414214143141441414514146141471414814149141501415114152141531415414155141561415714158141591416014161141621416314164141651416614167141681416914170141711417214173141741417514176141771417814179141801418114182141831418414185141861418714188141891419014191141921419314194141951419614197141981419914200142011420214203142041420514206142071420814209142101421114212142131421414215142161421714218142191422014221142221422314224142251422614227142281422914230142311423214233142341423514236142371423814239142401424114242142431424414245142461424714248142491425014251142521425314254142551425614257142581425914260142611426214263142641426514266142671426814269142701427114272142731427414275142761427714278142791428014281142821428314284142851428614287142881428914290142911429214293142941429514296142971429814299143001430114302143031430414305143061430714308143091431014311143121431314314143151431614317143181431914320143211432214323143241432514326143271432814329143301433114332143331433414335143361433714338143391434014341143421434314344143451434614347143481434914350143511435214353143541435514356143571435814359143601436114362143631436414365143661436714368143691437014371143721437314374143751437614377143781437914380143811438214383143841438514386143871438814389143901439114392143931439414395143961439714398143991440014401144021440314404144051440614407144081440914410144111441214413144141441514416144171441814419144201442114422144231442414425144261442714428144291443014431144321443314434144351443614437144381443914440144411444214443144441444514446144471444814449144501445114452144531445414455144561445714458144591446014461144621446314464144651446614467144681446914470144711447214473144741447514476144771447814479144801448114482144831448414485144861448714488144891449014491144921449314494144951449614497144981449914500145011450214503145041450514506145071450814509145101451114512145131451414515145161451714518145191452014521145221452314524145251452614527145281452914530145311453214533145341453514536145371453814539145401454114542145431454414545145461454714548145491455014551145521455314554145551455614557145581455914560145611456214563145641456514566145671456814569145701457114572145731457414575145761457714578145791458014581145821458314584145851458614587145881458914590145911459214593145941459514596145971459814599146001460114602146031460414605146061460714608146091461014611146121461314614146151461614617146181461914620146211462214623146241462514626146271462814629146301463114632146331463414635146361463714638146391464014641146421464314644146451464614647146481464914650146511465214653146541465514656146571465814659146601466114662146631466414665146661466714668146691467014671146721467314674146751467614677146781467914680146811468214683146841468514686146871468814689146901469114692146931469414695146961469714698146991470014701147021470314704147051470614707147081470914710147111471214713147141471514716147171471814719147201472114722147231472414725147261472714728147291473014731147321473314734147351473614737147381473914740147411474214743147441474514746147471474814749147501475114752147531475414755147561475714758147591476014761147621476314764147651476614767147681476914770147711477214773147741477514776147771477814779147801478114782147831478414785147861478714788147891479014791147921479314794147951479614797147981479914800148011480214803148041480514806148071480814809148101481114812148131481414815148161481714818148191482014821148221482314824148251482614827148281482914830148311483214833148341483514836148371483814839148401484114842148431484414845148461484714848148491485014851148521485314854148551485614857148581485914860148611486214863148641486514866148671486814869148701487114872148731487414875148761487714878148791488014881148821488314884148851488614887148881488914890148911489214893148941489514896148971489814899149001490114902149031490414905149061490714908149091491014911149121491314914149151491614917149181491914920149211492214923149241492514926149271492814929149301493114932149331493414935149361493714938149391494014941149421494314944149451494614947149481494914950149511495214953149541495514956149571495814959149601496114962149631496414965149661496714968149691497014971149721497314974149751497614977149781497914980149811498214983149841498514986149871498814989149901499114992149931499414995149961499714998149991500015001150021500315004150051500615007150081500915010150111501215013150141501515016150171501815019150201502115022150231502415025150261502715028150291503015031150321503315034150351503615037150381503915040150411504215043150441504515046150471504815049150501505115052150531505415055150561505715058150591506015061150621506315064150651506615067150681506915070150711507215073150741507515076150771507815079150801508115082150831508415085150861508715088150891509015091150921509315094150951509615097150981509915100151011510215103151041510515106151071510815109151101511115112151131511415115151161511715118151191512015121151221512315124151251512615127151281512915130151311513215133151341513515136151371513815139151401514115142151431514415145151461514715148151491515015151151521515315154151551515615157151581515915160151611516215163151641516515166151671516815169151701517115172151731517415175151761517715178151791518015181151821518315184151851518615187151881518915190151911519215193151941519515196151971519815199152001520115202152031520415205152061520715208152091521015211152121521315214152151521615217152181521915220152211522215223152241522515226152271522815229152301523115232152331523415235152361523715238152391524015241152421524315244152451524615247152481524915250152511525215253152541525515256152571525815259152601526115262152631526415265152661526715268152691527015271152721527315274152751527615277152781527915280152811528215283152841528515286152871528815289152901529115292152931529415295152961529715298152991530015301153021530315304153051530615307153081530915310153111531215313153141531515316153171531815319153201532115322153231532415325153261532715328153291533015331153321533315334153351533615337153381533915340153411534215343153441534515346153471534815349153501535115352153531535415355153561535715358153591536015361153621536315364153651536615367153681536915370153711537215373153741537515376153771537815379153801538115382153831538415385153861538715388153891539015391153921539315394153951539615397153981539915400154011540215403154041540515406154071540815409154101541115412154131541415415154161541715418154191542015421154221542315424154251542615427154281542915430154311543215433154341543515436154371543815439154401544115442154431544415445154461544715448154491545015451154521545315454154551545615457154581545915460154611546215463154641546515466154671546815469154701547115472154731547415475154761547715478154791548015481154821548315484154851548615487154881548915490154911549215493154941549515496154971549815499155001550115502155031550415505155061550715508155091551015511155121551315514155151551615517155181551915520155211552215523155241552515526155271552815529155301553115532155331553415535155361553715538155391554015541155421554315544155451554615547155481554915550155511555215553155541555515556155571555815559155601556115562155631556415565155661556715568155691557015571155721557315574155751557615577155781557915580155811558215583155841558515586155871558815589155901559115592155931559415595155961559715598155991560015601156021560315604156051560615607156081560915610156111561215613156141561515616156171561815619156201562115622156231562415625156261562715628156291563015631156321563315634156351563615637156381563915640156411564215643156441564515646156471564815649156501565115652156531565415655156561565715658156591566015661156621566315664156651566615667156681566915670156711567215673156741567515676156771567815679156801568115682156831568415685156861568715688156891569015691156921569315694156951569615697156981569915700157011570215703157041570515706157071570815709157101571115712157131571415715157161571715718157191572015721157221572315724157251572615727157281572915730157311573215733157341573515736157371573815739157401574115742157431574415745157461574715748157491575015751157521575315754157551575615757157581575915760157611576215763157641576515766157671576815769157701577115772157731577415775157761577715778157791578015781157821578315784157851578615787157881578915790157911579215793157941579515796157971579815799158001580115802158031580415805158061580715808158091581015811158121581315814158151581615817158181581915820158211582215823158241582515826158271582815829158301583115832158331583415835158361583715838158391584015841158421584315844158451584615847158481584915850158511585215853158541585515856158571585815859158601586115862158631586415865158661586715868158691587015871158721587315874158751587615877158781587915880158811588215883158841588515886158871588815889158901589115892158931589415895158961589715898158991590015901159021590315904159051590615907159081590915910159111591215913159141591515916159171591815919159201592115922159231592415925159261592715928159291593015931159321593315934159351593615937159381593915940159411594215943159441594515946159471594815949159501595115952159531595415955159561595715958159591596015961159621596315964159651596615967159681596915970159711597215973159741597515976159771597815979159801598115982159831598415985159861598715988159891599015991159921599315994159951599615997159981599916000160011600216003160041600516006160071600816009160101601116012160131601416015160161601716018160191602016021160221602316024160251602616027160281602916030160311603216033160341603516036160371603816039160401604116042160431604416045160461604716048160491605016051160521605316054160551605616057160581605916060160611606216063160641606516066160671606816069160701607116072160731607416075160761607716078160791608016081160821608316084160851608616087160881608916090160911609216093160941609516096160971609816099161001610116102161031610416105161061610716108161091611016111161121611316114161151611616117161181611916120161211612216123161241612516126161271612816129161301613116132161331613416135161361613716138161391614016141161421614316144161451614616147161481614916150161511615216153161541615516156161571615816159161601616116162161631616416165161661616716168161691617016171161721617316174161751617616177161781617916180161811618216183161841618516186161871618816189161901619116192161931619416195161961619716198161991620016201162021620316204162051620616207162081620916210162111621216213162141621516216162171621816219162201622116222162231622416225162261622716228162291623016231162321623316234162351623616237162381623916240162411624216243162441624516246162471624816249162501625116252162531625416255162561625716258162591626016261162621626316264162651626616267162681626916270162711627216273162741627516276162771627816279162801628116282162831628416285162861628716288162891629016291162921629316294162951629616297162981629916300163011630216303163041630516306163071630816309163101631116312163131631416315163161631716318163191632016321163221632316324163251632616327163281632916330163311633216333163341633516336163371633816339163401634116342163431634416345163461634716348163491635016351163521635316354163551635616357163581635916360163611636216363163641636516366163671636816369163701637116372163731637416375163761637716378163791638016381163821638316384163851638616387163881638916390163911639216393163941639516396163971639816399164001640116402164031640416405164061640716408164091641016411164121641316414164151641616417164181641916420164211642216423164241642516426164271642816429164301643116432164331643416435164361643716438164391644016441164421644316444164451644616447164481644916450164511645216453164541645516456164571645816459164601646116462164631646416465164661646716468164691647016471164721647316474164751647616477164781647916480164811648216483164841648516486164871648816489164901649116492164931649416495164961649716498164991650016501165021650316504165051650616507165081650916510165111651216513165141651516516165171651816519165201652116522165231652416525165261652716528165291653016531165321653316534165351653616537165381653916540165411654216543165441654516546165471654816549165501655116552165531655416555165561655716558165591656016561165621656316564165651656616567165681656916570165711657216573165741657516576165771657816579165801658116582165831658416585165861658716588165891659016591165921659316594165951659616597165981659916600166011660216603166041660516606166071660816609166101661116612166131661416615166161661716618166191662016621166221662316624166251662616627166281662916630166311663216633166341663516636166371663816639166401664116642166431664416645166461664716648166491665016651166521665316654166551665616657166581665916660166611666216663166641666516666166671666816669166701667116672166731667416675166761667716678166791668016681166821668316684166851668616687166881668916690166911669216693166941669516696166971669816699167001670116702167031670416705167061670716708167091671016711167121671316714167151671616717167181671916720167211672216723167241672516726167271672816729167301673116732167331673416735167361673716738167391674016741167421674316744167451674616747167481674916750167511675216753167541675516756167571675816759167601676116762167631676416765167661676716768167691677016771167721677316774167751677616777167781677916780167811678216783167841678516786167871678816789167901679116792167931679416795167961679716798167991680016801168021680316804168051680616807168081680916810168111681216813168141681516816168171681816819168201682116822168231682416825168261682716828168291683016831168321683316834168351683616837168381683916840168411684216843168441684516846168471684816849168501685116852168531685416855168561685716858168591686016861168621686316864168651686616867168681686916870168711687216873168741687516876168771687816879168801688116882168831688416885168861688716888168891689016891168921689316894168951689616897168981689916900169011690216903169041690516906169071690816909169101691116912169131691416915169161691716918169191692016921169221692316924169251692616927169281692916930169311693216933169341693516936169371693816939169401694116942169431694416945169461694716948169491695016951169521695316954169551695616957169581695916960169611696216963169641696516966169671696816969169701697116972169731697416975169761697716978169791698016981169821698316984169851698616987169881698916990169911699216993169941699516996169971699816999170001700117002170031700417005170061700717008170091701017011170121701317014170151701617017170181701917020170211702217023170241702517026170271702817029170301703117032170331703417035170361703717038170391704017041170421704317044170451704617047170481704917050170511705217053170541705517056170571705817059170601706117062170631706417065170661706717068170691707017071170721707317074170751707617077170781707917080170811708217083170841708517086170871708817089170901709117092170931709417095170961709717098170991710017101171021710317104171051710617107171081710917110171111711217113171141711517116171171711817119171201712117122171231712417125171261712717128171291713017131171321713317134171351713617137171381713917140171411714217143171441714517146171471714817149171501715117152171531715417155171561715717158171591716017161171621716317164171651716617167171681716917170171711717217173171741717517176171771717817179171801718117182171831718417185171861718717188171891719017191171921719317194171951719617197171981719917200172011720217203172041720517206172071720817209172101721117212172131721417215172161721717218172191722017221172221722317224172251722617227172281722917230172311723217233172341723517236172371723817239172401724117242172431724417245172461724717248172491725017251172521725317254172551725617257172581725917260172611726217263172641726517266172671726817269172701727117272172731727417275172761727717278172791728017281172821728317284172851728617287172881728917290172911729217293172941729517296172971729817299173001730117302173031730417305173061730717308173091731017311173121731317314173151731617317173181731917320173211732217323173241732517326173271732817329173301733117332173331733417335173361733717338173391734017341173421734317344173451734617347173481734917350173511735217353173541735517356173571735817359173601736117362173631736417365173661736717368173691737017371173721737317374173751737617377173781737917380173811738217383173841738517386173871738817389173901739117392173931739417395173961739717398173991740017401174021740317404174051740617407174081740917410174111741217413174141741517416174171741817419174201742117422174231742417425174261742717428174291743017431174321743317434174351743617437174381743917440174411744217443174441744517446174471744817449174501745117452174531745417455174561745717458174591746017461174621746317464174651746617467174681746917470174711747217473174741747517476174771747817479174801748117482174831748417485174861748717488174891749017491174921749317494174951749617497174981749917500175011750217503175041750517506175071750817509175101751117512175131751417515175161751717518175191752017521175221752317524175251752617527175281752917530175311753217533175341753517536175371753817539175401754117542175431754417545175461754717548175491755017551175521755317554175551755617557175581755917560175611756217563175641756517566175671756817569175701757117572175731757417575175761757717578175791758017581175821758317584175851758617587175881758917590175911759217593175941759517596175971759817599176001760117602176031760417605176061760717608176091761017611176121761317614176151761617617176181761917620176211762217623176241762517626176271762817629176301763117632176331763417635176361763717638176391764017641176421764317644176451764617647176481764917650176511765217653176541765517656176571765817659176601766117662176631766417665176661766717668176691767017671176721767317674176751767617677176781767917680176811768217683176841768517686176871768817689176901769117692176931769417695176961769717698176991770017701177021770317704177051770617707177081770917710177111771217713177141771517716177171771817719177201772117722177231772417725177261772717728177291773017731177321773317734177351773617737177381773917740177411774217743177441774517746177471774817749177501775117752177531775417755177561775717758177591776017761177621776317764177651776617767177681776917770177711777217773177741777517776177771777817779177801778117782177831778417785177861778717788177891779017791177921779317794177951779617797177981779917800178011780217803178041780517806178071780817809178101781117812178131781417815178161781717818178191782017821178221782317824178251782617827178281782917830178311783217833178341783517836178371783817839178401784117842178431784417845178461784717848178491785017851178521785317854178551785617857178581785917860178611786217863178641786517866178671786817869178701787117872178731787417875178761787717878178791788017881178821788317884178851788617887178881788917890178911789217893178941789517896178971789817899179001790117902179031790417905179061790717908179091791017911179121791317914179151791617917179181791917920179211792217923179241792517926179271792817929179301793117932179331793417935179361793717938179391794017941179421794317944179451794617947179481794917950179511795217953179541795517956179571795817959179601796117962179631796417965179661796717968179691797017971179721797317974179751797617977179781797917980179811798217983179841798517986179871798817989179901799117992179931799417995179961799717998179991800018001180021800318004180051800618007180081800918010180111801218013180141801518016180171801818019180201802118022180231802418025180261802718028180291803018031180321803318034180351803618037180381803918040180411804218043180441804518046180471804818049180501805118052180531805418055180561805718058180591806018061180621806318064180651806618067180681806918070180711807218073180741807518076180771807818079180801808118082180831808418085180861808718088180891809018091180921809318094180951809618097180981809918100181011810218103181041810518106181071810818109181101811118112181131811418115181161811718118181191812018121181221812318124181251812618127181281812918130181311813218133181341813518136181371813818139181401814118142181431814418145181461814718148181491815018151181521815318154181551815618157181581815918160181611816218163181641816518166181671816818169181701817118172181731817418175181761817718178181791818018181181821818318184181851818618187181881818918190181911819218193181941819518196181971819818199182001820118202182031820418205182061820718208182091821018211182121821318214182151821618217182181821918220182211822218223182241822518226182271822818229182301823118232182331823418235182361823718238182391824018241182421824318244182451824618247182481824918250182511825218253182541825518256182571825818259182601826118262182631826418265182661826718268182691827018271182721827318274182751827618277182781827918280182811828218283182841828518286182871828818289182901829118292182931829418295182961829718298182991830018301183021830318304183051830618307183081830918310183111831218313183141831518316183171831818319183201832118322183231832418325183261832718328183291833018331183321833318334183351833618337183381833918340183411834218343183441834518346183471834818349183501835118352183531835418355183561835718358183591836018361183621836318364183651836618367183681836918370183711837218373183741837518376183771837818379183801838118382183831838418385183861838718388183891839018391183921839318394183951839618397183981839918400184011840218403184041840518406184071840818409184101841118412184131841418415184161841718418184191842018421184221842318424184251842618427184281842918430184311843218433184341843518436184371843818439184401844118442184431844418445184461844718448184491845018451184521845318454184551845618457184581845918460184611846218463184641846518466184671846818469184701847118472184731847418475184761847718478184791848018481184821848318484184851848618487184881848918490184911849218493184941849518496184971849818499185001850118502185031850418505185061850718508185091851018511185121851318514185151851618517185181851918520185211852218523185241852518526185271852818529185301853118532185331853418535185361853718538185391854018541185421854318544185451854618547185481854918550185511855218553185541855518556185571855818559185601856118562185631856418565185661856718568185691857018571185721857318574185751857618577185781857918580185811858218583185841858518586185871858818589185901859118592185931859418595185961859718598185991860018601186021860318604186051860618607186081860918610186111861218613186141861518616186171861818619186201862118622186231862418625186261862718628186291863018631186321863318634186351863618637186381863918640186411864218643186441864518646186471864818649186501865118652186531865418655186561865718658186591866018661186621866318664186651866618667186681866918670186711867218673186741867518676186771867818679186801868118682186831868418685186861868718688186891869018691186921869318694186951869618697186981869918700187011870218703187041870518706187071870818709187101871118712187131871418715187161871718718187191872018721187221872318724187251872618727187281872918730187311873218733187341873518736187371873818739187401874118742187431874418745187461874718748187491875018751187521875318754187551875618757187581875918760187611876218763187641876518766187671876818769187701877118772187731877418775187761877718778187791878018781187821878318784187851878618787187881878918790187911879218793187941879518796187971879818799188001880118802188031880418805188061880718808188091881018811188121881318814188151881618817188181881918820188211882218823188241882518826188271882818829188301883118832188331883418835188361883718838188391884018841188421884318844188451884618847188481884918850188511885218853188541885518856188571885818859188601886118862188631886418865188661886718868188691887018871188721887318874188751887618877188781887918880188811888218883188841888518886188871888818889188901889118892188931889418895188961889718898188991890018901189021890318904189051890618907189081890918910189111891218913189141891518916189171891818919189201892118922189231892418925189261892718928189291893018931189321893318934189351893618937189381893918940189411894218943189441894518946189471894818949189501895118952189531895418955189561895718958189591896018961189621896318964189651896618967189681896918970189711897218973189741897518976189771897818979189801898118982189831898418985189861898718988189891899018991189921899318994189951899618997189981899919000190011900219003190041900519006190071900819009190101901119012190131901419015190161901719018190191902019021190221902319024190251902619027190281902919030190311903219033190341903519036190371903819039190401904119042190431904419045190461904719048190491905019051190521905319054190551905619057190581905919060190611906219063190641906519066190671906819069190701907119072190731907419075190761907719078190791908019081190821908319084190851908619087190881908919090190911909219093190941909519096190971909819099191001910119102191031910419105191061910719108191091911019111191121911319114191151911619117191181911919120191211912219123191241912519126191271912819129191301913119132191331913419135191361913719138191391914019141191421914319144191451914619147191481914919150191511915219153191541915519156191571915819159191601916119162191631916419165191661916719168191691917019171191721917319174191751917619177191781917919180191811918219183191841918519186191871918819189191901919119192191931919419195191961919719198191991920019201192021920319204192051920619207192081920919210192111921219213192141921519216192171921819219192201922119222192231922419225192261922719228192291923019231192321923319234192351923619237192381923919240192411924219243192441924519246192471924819249192501925119252192531925419255192561925719258192591926019261192621926319264192651926619267192681926919270192711927219273192741927519276192771927819279192801928119282192831928419285192861928719288192891929019291192921929319294192951929619297192981929919300193011930219303193041930519306193071930819309193101931119312193131931419315193161931719318193191932019321193221932319324193251932619327193281932919330193311933219333193341933519336193371933819339193401934119342193431934419345193461934719348193491935019351193521935319354193551935619357193581935919360193611936219363193641936519366193671936819369193701937119372193731937419375193761937719378193791938019381193821938319384193851938619387193881938919390193911939219393193941939519396193971939819399194001940119402194031940419405194061940719408194091941019411194121941319414194151941619417194181941919420194211942219423194241942519426194271942819429194301943119432194331943419435194361943719438194391944019441194421944319444194451944619447194481944919450194511945219453194541945519456194571945819459194601946119462194631946419465194661946719468194691947019471194721947319474194751947619477194781947919480194811948219483194841948519486194871948819489194901949119492194931949419495194961949719498194991950019501195021950319504195051950619507195081950919510195111951219513195141951519516195171951819519195201952119522195231952419525195261952719528195291953019531195321953319534195351953619537195381953919540195411954219543195441954519546195471954819549195501955119552195531955419555195561955719558195591956019561195621956319564195651956619567195681956919570195711957219573195741957519576195771957819579195801958119582195831958419585195861958719588195891959019591195921959319594195951959619597195981959919600196011960219603196041960519606196071960819609196101961119612196131961419615196161961719618196191962019621196221962319624196251962619627196281962919630196311963219633196341963519636196371963819639196401964119642196431964419645196461964719648196491965019651196521965319654196551965619657196581965919660196611966219663196641966519666196671966819669196701967119672196731967419675196761967719678196791968019681196821968319684196851968619687196881968919690196911969219693196941969519696196971969819699197001970119702197031970419705197061970719708197091971019711197121971319714197151971619717197181971919720197211972219723197241972519726197271972819729197301973119732197331973419735197361973719738197391974019741197421974319744197451974619747197481974919750197511975219753197541975519756197571975819759197601976119762197631976419765197661976719768197691977019771197721977319774197751977619777197781977919780197811978219783197841978519786197871978819789197901979119792197931979419795197961979719798197991980019801198021980319804198051980619807198081980919810198111981219813198141981519816198171981819819198201982119822198231982419825198261982719828198291983019831198321983319834198351983619837198381983919840198411984219843198441984519846198471984819849198501985119852198531985419855198561985719858198591986019861198621986319864198651986619867198681986919870198711987219873198741987519876198771987819879198801988119882198831988419885198861988719888198891989019891198921989319894198951989619897198981989919900199011990219903199041990519906199071990819909199101991119912199131991419915199161991719918199191992019921199221992319924199251992619927199281992919930199311993219933199341993519936199371993819939199401994119942199431994419945199461994719948199491995019951199521995319954199551995619957199581995919960199611996219963199641996519966199671996819969199701997119972199731997419975199761997719978199791998019981199821998319984199851998619987199881998919990199911999219993199941999519996199971999819999200002000120002200032000420005200062000720008200092001020011200122001320014200152001620017200182001920020200212002220023200242002520026200272002820029200302003120032200332003420035200362003720038200392004020041200422004320044200452004620047200482004920050200512005220053200542005520056200572005820059200602006120062200632006420065200662006720068200692007020071200722007320074200752007620077200782007920080200812008220083200842008520086200872008820089200902009120092200932009420095200962009720098200992010020101201022010320104201052010620107201082010920110201112011220113201142011520116201172011820119201202012120122201232012420125201262012720128201292013020131201322013320134201352013620137201382013920140201412014220143201442014520146201472014820149201502015120152201532015420155201562015720158201592016020161201622016320164201652016620167201682016920170201712017220173201742017520176201772017820179201802018120182201832018420185201862018720188201892019020191201922019320194201952019620197201982019920200202012020220203202042020520206202072020820209202102021120212202132021420215202162021720218202192022020221202222022320224202252022620227202282022920230202312023220233202342023520236202372023820239202402024120242202432024420245202462024720248202492025020251202522025320254202552025620257202582025920260202612026220263202642026520266202672026820269202702027120272202732027420275202762027720278202792028020281202822028320284202852028620287202882028920290202912029220293202942029520296202972029820299203002030120302203032030420305203062030720308203092031020311203122031320314203152031620317203182031920320203212032220323203242032520326203272032820329203302033120332203332033420335203362033720338203392034020341203422034320344203452034620347203482034920350203512035220353203542035520356203572035820359203602036120362203632036420365203662036720368203692037020371203722037320374203752037620377203782037920380203812038220383203842038520386203872038820389203902039120392203932039420395203962039720398203992040020401204022040320404204052040620407204082040920410204112041220413204142041520416204172041820419204202042120422204232042420425204262042720428204292043020431204322043320434204352043620437204382043920440204412044220443204442044520446204472044820449204502045120452204532045420455204562045720458204592046020461204622046320464204652046620467204682046920470204712047220473204742047520476204772047820479204802048120482204832048420485204862048720488204892049020491204922049320494204952049620497204982049920500205012050220503205042050520506205072050820509205102051120512205132051420515205162051720518205192052020521205222052320524205252052620527205282052920530205312053220533205342053520536205372053820539205402054120542205432054420545205462054720548205492055020551205522055320554205552055620557205582055920560205612056220563205642056520566205672056820569205702057120572205732057420575205762057720578205792058020581205822058320584205852058620587205882058920590205912059220593205942059520596205972059820599206002060120602206032060420605206062060720608206092061020611206122061320614206152061620617206182061920620206212062220623206242062520626206272062820629206302063120632206332063420635206362063720638206392064020641206422064320644206452064620647206482064920650206512065220653206542065520656206572065820659206602066120662206632066420665206662066720668206692067020671206722067320674206752067620677206782067920680206812068220683206842068520686206872068820689206902069120692206932069420695206962069720698206992070020701207022070320704207052070620707207082070920710207112071220713207142071520716207172071820719207202072120722207232072420725207262072720728207292073020731207322073320734207352073620737207382073920740207412074220743207442074520746207472074820749207502075120752207532075420755207562075720758207592076020761207622076320764207652076620767207682076920770207712077220773207742077520776207772077820779207802078120782207832078420785207862078720788207892079020791207922079320794207952079620797207982079920800208012080220803208042080520806208072080820809208102081120812208132081420815208162081720818208192082020821208222082320824208252082620827208282082920830208312083220833208342083520836208372083820839208402084120842208432084420845208462084720848208492085020851208522085320854208552085620857208582085920860208612086220863208642086520866208672086820869208702087120872208732087420875208762087720878208792088020881208822088320884208852088620887208882088920890208912089220893208942089520896208972089820899209002090120902209032090420905209062090720908209092091020911209122091320914209152091620917209182091920920209212092220923209242092520926209272092820929209302093120932209332093420935209362093720938209392094020941209422094320944209452094620947209482094920950209512095220953209542095520956209572095820959209602096120962209632096420965209662096720968209692097020971209722097320974209752097620977209782097920980209812098220983209842098520986209872098820989209902099120992209932099420995209962099720998209992100021001210022100321004210052100621007210082100921010210112101221013210142101521016210172101821019210202102121022210232102421025210262102721028210292103021031210322103321034210352103621037210382103921040210412104221043210442104521046210472104821049210502105121052210532105421055210562105721058210592106021061210622106321064210652106621067210682106921070210712107221073210742107521076210772107821079210802108121082210832108421085210862108721088210892109021091210922109321094210952109621097210982109921100211012110221103211042110521106211072110821109211102111121112211132111421115211162111721118211192112021121211222112321124211252112621127211282112921130211312113221133211342113521136211372113821139211402114121142211432114421145211462114721148211492115021151211522115321154211552115621157211582115921160211612116221163211642116521166211672116821169211702117121172211732117421175211762117721178211792118021181211822118321184211852118621187211882118921190211912119221193211942119521196211972119821199212002120121202212032120421205212062120721208212092121021211212122121321214212152121621217212182121921220212212122221223212242122521226212272122821229212302123121232212332123421235212362123721238212392124021241212422124321244212452124621247212482124921250212512125221253212542125521256212572125821259212602126121262212632126421265212662126721268212692127021271212722127321274212752127621277212782127921280212812128221283212842128521286212872128821289212902129121292212932129421295212962129721298212992130021301213022130321304213052130621307213082130921310213112131221313213142131521316213172131821319213202132121322213232132421325213262132721328213292133021331213322133321334213352133621337213382133921340213412134221343213442134521346213472134821349213502135121352213532135421355213562135721358213592136021361213622136321364213652136621367213682136921370213712137221373213742137521376213772137821379213802138121382213832138421385213862138721388213892139021391213922139321394213952139621397213982139921400214012140221403214042140521406214072140821409214102141121412214132141421415214162141721418214192142021421214222142321424214252142621427214282142921430214312143221433214342143521436214372143821439214402144121442214432144421445214462144721448214492145021451214522145321454214552145621457214582145921460214612146221463214642146521466214672146821469214702147121472214732147421475214762147721478214792148021481214822148321484214852148621487214882148921490214912149221493214942149521496214972149821499215002150121502215032150421505215062150721508215092151021511215122151321514215152151621517215182151921520215212152221523215242152521526215272152821529215302153121532215332153421535215362153721538215392154021541215422154321544215452154621547215482154921550215512155221553215542155521556215572155821559215602156121562215632156421565215662156721568215692157021571215722157321574215752157621577215782157921580215812158221583215842158521586215872158821589215902159121592215932159421595215962159721598215992160021601216022160321604216052160621607216082160921610216112161221613216142161521616216172161821619216202162121622216232162421625216262162721628216292163021631216322163321634216352163621637216382163921640216412164221643216442164521646216472164821649216502165121652216532165421655216562165721658216592166021661216622166321664216652166621667216682166921670216712167221673216742167521676216772167821679216802168121682216832168421685216862168721688216892169021691216922169321694216952169621697216982169921700217012170221703217042170521706217072170821709217102171121712217132171421715217162171721718217192172021721217222172321724217252172621727217282172921730217312173221733217342173521736217372173821739217402174121742217432174421745217462174721748217492175021751217522175321754217552175621757217582175921760217612176221763217642176521766217672176821769217702177121772217732177421775217762177721778217792178021781217822178321784217852178621787217882178921790217912179221793217942179521796217972179821799218002180121802218032180421805218062180721808218092181021811218122181321814218152181621817218182181921820218212182221823218242182521826218272182821829218302183121832218332183421835218362183721838218392184021841218422184321844218452184621847218482184921850218512185221853218542185521856218572185821859218602186121862218632186421865218662186721868218692187021871218722187321874218752187621877218782187921880218812188221883218842188521886218872188821889218902189121892218932189421895218962189721898218992190021901219022190321904219052190621907219082190921910219112191221913219142191521916219172191821919219202192121922219232192421925219262192721928219292193021931219322193321934219352193621937219382193921940219412194221943219442194521946219472194821949219502195121952219532195421955219562195721958219592196021961219622196321964219652196621967219682196921970219712197221973219742197521976219772197821979219802198121982219832198421985219862198721988219892199021991219922199321994219952199621997219982199922000220012200222003220042200522006220072200822009220102201122012220132201422015220162201722018220192202022021220222202322024220252202622027220282202922030220312203222033220342203522036220372203822039220402204122042220432204422045220462204722048220492205022051220522205322054220552205622057220582205922060220612206222063220642206522066220672206822069220702207122072220732207422075220762207722078220792208022081220822208322084220852208622087220882208922090220912209222093220942209522096220972209822099221002210122102221032210422105221062210722108221092211022111221122211322114221152211622117221182211922120221212212222123221242212522126221272212822129221302213122132221332213422135221362213722138221392214022141221422214322144221452214622147221482214922150221512215222153221542215522156221572215822159221602216122162221632216422165221662216722168221692217022171221722217322174221752217622177221782217922180221812218222183221842218522186221872218822189221902219122192221932219422195221962219722198221992220022201222022220322204222052220622207222082220922210222112221222213222142221522216222172221822219222202222122222222232222422225222262222722228222292223022231222322223322234222352223622237222382223922240222412224222243222442224522246222472224822249222502225122252222532225422255222562225722258222592226022261222622226322264222652226622267222682226922270222712227222273222742227522276222772227822279222802228122282222832228422285222862228722288222892229022291222922229322294222952229622297222982229922300223012230222303223042230522306223072230822309223102231122312223132231422315223162231722318223192232022321223222232322324223252232622327223282232922330223312233222333223342233522336223372233822339223402234122342223432234422345223462234722348223492235022351223522235322354223552235622357223582235922360223612236222363223642236522366223672236822369223702237122372223732237422375223762237722378223792238022381223822238322384223852238622387223882238922390223912239222393223942239522396223972239822399224002240122402224032240422405224062240722408224092241022411224122241322414224152241622417224182241922420224212242222423224242242522426224272242822429224302243122432224332243422435224362243722438224392244022441224422244322444224452244622447224482244922450224512245222453224542245522456224572245822459224602246122462224632246422465224662246722468224692247022471224722247322474224752247622477224782247922480224812248222483224842248522486224872248822489224902249122492224932249422495224962249722498224992250022501225022250322504225052250622507225082250922510225112251222513225142251522516225172251822519225202252122522225232252422525225262252722528225292253022531225322253322534225352253622537225382253922540225412254222543225442254522546225472254822549225502255122552225532255422555225562255722558225592256022561225622256322564225652256622567225682256922570225712257222573225742257522576225772257822579225802258122582225832258422585225862258722588225892259022591225922259322594225952259622597225982259922600226012260222603226042260522606226072260822609226102261122612226132261422615226162261722618226192262022621226222262322624226252262622627226282262922630226312263222633226342263522636226372263822639226402264122642226432264422645226462264722648226492265022651226522265322654226552265622657226582265922660226612266222663226642266522666226672266822669226702267122672226732267422675226762267722678226792268022681226822268322684226852268622687226882268922690226912269222693226942269522696226972269822699227002270122702227032270422705227062270722708227092271022711227122271322714227152271622717227182271922720227212272222723227242272522726227272272822729227302273122732227332273422735227362273722738227392274022741227422274322744227452274622747227482274922750227512275222753227542275522756227572275822759227602276122762227632276422765227662276722768227692277022771227722277322774227752277622777227782277922780227812278222783227842278522786227872278822789227902279122792227932279422795227962279722798227992280022801228022280322804228052280622807228082280922810228112281222813228142281522816228172281822819228202282122822228232282422825228262282722828228292283022831228322283322834228352283622837228382283922840228412284222843228442284522846228472284822849228502285122852228532285422855228562285722858228592286022861228622286322864228652286622867228682286922870228712287222873228742287522876228772287822879228802288122882228832288422885228862288722888228892289022891228922289322894228952289622897228982289922900229012290222903229042290522906229072290822909229102291122912229132291422915229162291722918229192292022921229222292322924229252292622927229282292922930229312293222933229342293522936229372293822939229402294122942229432294422945229462294722948229492295022951229522295322954229552295622957229582295922960229612296222963229642296522966229672296822969229702297122972229732297422975229762297722978229792298022981229822298322984229852298622987229882298922990229912299222993229942299522996229972299822999230002300123002230032300423005230062300723008230092301023011230122301323014230152301623017230182301923020230212302223023230242302523026230272302823029230302303123032230332303423035230362303723038230392304023041230422304323044230452304623047230482304923050230512305223053230542305523056230572305823059230602306123062230632306423065230662306723068230692307023071230722307323074230752307623077230782307923080230812308223083230842308523086230872308823089230902309123092230932309423095230962309723098230992310023101231022310323104231052310623107231082310923110231112311223113231142311523116231172311823119231202312123122231232312423125231262312723128231292313023131231322313323134231352313623137231382313923140231412314223143231442314523146231472314823149231502315123152231532315423155231562315723158231592316023161231622316323164231652316623167231682316923170231712317223173231742317523176231772317823179231802318123182231832318423185231862318723188231892319023191231922319323194231952319623197231982319923200232012320223203232042320523206232072320823209232102321123212232132321423215232162321723218232192322023221232222322323224232252322623227232282322923230232312323223233232342323523236232372323823239232402324123242232432324423245232462324723248232492325023251232522325323254232552325623257232582325923260232612326223263232642326523266232672326823269232702327123272232732327423275232762327723278232792328023281232822328323284232852328623287232882328923290232912329223293232942329523296232972329823299233002330123302233032330423305233062330723308233092331023311233122331323314233152331623317233182331923320233212332223323233242332523326233272332823329233302333123332233332333423335233362333723338233392334023341233422334323344233452334623347233482334923350233512335223353233542335523356233572335823359233602336123362233632336423365233662336723368233692337023371233722337323374233752337623377233782337923380233812338223383233842338523386233872338823389233902339123392233932339423395233962339723398233992340023401234022340323404234052340623407234082340923410234112341223413234142341523416234172341823419234202342123422234232342423425234262342723428234292343023431234322343323434234352343623437234382343923440234412344223443234442344523446234472344823449234502345123452234532345423455234562345723458234592346023461234622346323464234652346623467234682346923470234712347223473234742347523476234772347823479234802348123482234832348423485234862348723488234892349023491234922349323494234952349623497234982349923500235012350223503235042350523506235072350823509235102351123512235132351423515235162351723518235192352023521235222352323524235252352623527235282352923530235312353223533235342353523536235372353823539235402354123542235432354423545235462354723548235492355023551235522355323554235552355623557235582355923560235612356223563235642356523566235672356823569235702357123572235732357423575235762357723578235792358023581235822358323584235852358623587235882358923590235912359223593235942359523596235972359823599236002360123602236032360423605236062360723608236092361023611236122361323614236152361623617236182361923620236212362223623236242362523626236272362823629236302363123632236332363423635236362363723638236392364023641236422364323644236452364623647236482364923650236512365223653236542365523656236572365823659236602366123662236632366423665236662366723668236692367023671236722367323674236752367623677236782367923680236812368223683236842368523686236872368823689236902369123692236932369423695236962369723698236992370023701237022370323704237052370623707237082370923710237112371223713237142371523716237172371823719237202372123722237232372423725237262372723728237292373023731237322373323734237352373623737237382373923740237412374223743237442374523746237472374823749237502375123752237532375423755237562375723758237592376023761237622376323764237652376623767237682376923770237712377223773237742377523776237772377823779237802378123782237832378423785237862378723788237892379023791237922379323794237952379623797237982379923800238012380223803238042380523806238072380823809238102381123812238132381423815238162381723818238192382023821238222382323824238252382623827238282382923830238312383223833238342383523836238372383823839238402384123842238432384423845238462384723848238492385023851238522385323854238552385623857238582385923860238612386223863238642386523866238672386823869238702387123872238732387423875238762387723878238792388023881238822388323884238852388623887238882388923890238912389223893238942389523896238972389823899239002390123902239032390423905239062390723908239092391023911239122391323914239152391623917239182391923920239212392223923239242392523926239272392823929239302393123932239332393423935239362393723938239392394023941239422394323944239452394623947239482394923950239512395223953239542395523956239572395823959239602396123962239632396423965239662396723968239692397023971239722397323974239752397623977239782397923980239812398223983239842398523986239872398823989239902399123992239932399423995239962399723998239992400024001240022400324004240052400624007240082400924010240112401224013240142401524016240172401824019240202402124022240232402424025240262402724028240292403024031240322403324034240352403624037240382403924040240412404224043240442404524046240472404824049240502405124052240532405424055240562405724058240592406024061240622406324064240652406624067240682406924070240712407224073240742407524076240772407824079240802408124082240832408424085240862408724088240892409024091240922409324094240952409624097240982409924100241012410224103241042410524106241072410824109241102411124112241132411424115241162411724118241192412024121241222412324124241252412624127241282412924130241312413224133241342413524136241372413824139241402414124142241432414424145241462414724148241492415024151241522415324154241552415624157241582415924160241612416224163241642416524166241672416824169241702417124172 |
- (function (global, factory) {
- typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
- typeof define === 'function' && define.amd ? define(['exports'], factory) :
- (factory((global.svelte = {})));
- }(this, (function (exports) { 'use strict';
- function assign(tar, src) {
- for (var k in src) tar[k] = src[k];
- return tar;
- }
- // https://html.spec.whatwg.org/multipage/syntax.html#attributes-2
- const now = (typeof process !== 'undefined' && process.hrtime)
- ? () => {
- const t = process.hrtime();
- return t[0] * 1e3 + t[1] / 1e6;
- }
- : () => self.performance.now();
- function collapseTimings(timings) {
- const result = {};
- timings.forEach(timing => {
- result[timing.label] = Object.assign({
- total: timing.end - timing.start
- }, timing.children && collapseTimings(timing.children));
- });
- return result;
- }
- class Stats {
- constructor({ onwarn }) {
- this.startTime = now();
- this.stack = [];
- this.currentChildren = this.timings = [];
- this.onwarn = onwarn;
- this.warnings = [];
- }
- start(label) {
- const timing = {
- label,
- start: now(),
- end: null,
- children: []
- };
- this.currentChildren.push(timing);
- this.stack.push(timing);
- this.currentTiming = timing;
- this.currentChildren = timing.children;
- }
- stop(label) {
- if (label !== this.currentTiming.label) {
- throw new Error(`Mismatched timing labels (expected ${this.currentTiming.label}, got ${label})`);
- }
- this.currentTiming.end = now();
- this.stack.pop();
- this.currentTiming = this.stack[this.stack.length - 1];
- this.currentChildren = this.currentTiming ? this.currentTiming.children : this.timings;
- }
- render(component) {
- const timings = Object.assign({
- total: now() - this.startTime
- }, collapseTimings(this.timings));
- // TODO would be good to have this info even
- // if options.generate is false
- const imports = component && component.imports.map(node => {
- return {
- source: node.source.value,
- specifiers: node.specifiers.map(specifier => {
- return {
- name: (specifier.type === 'ImportDefaultSpecifier' ? 'default' :
- specifier.type === 'ImportNamespaceSpecifier' ? '*' :
- specifier.imported.name),
- as: specifier.local.name
- };
- })
- };
- });
- const hooks = component && {
- oncreate: !!component.templateProperties.oncreate,
- ondestroy: !!component.templateProperties.ondestroy,
- onstate: !!component.templateProperties.onstate,
- onupdate: !!component.templateProperties.onupdate
- };
- const computed = new Set(component.computations.map(c => c.key));
- return {
- props: Array.from(component.expectedProperties).filter(key => !computed.has(key)),
- timings,
- warnings: this.warnings,
- imports,
- hooks
- };
- }
- warn(warning) {
- this.warnings.push(warning);
- this.onwarn(warning);
- }
- }
- // Reserved word lists for various dialects of the language
- var reservedWords = {
- 3: "abstract boolean byte char class double enum export extends final float goto implements import int interface long native package private protected public short static super synchronized throws transient volatile",
- 5: "class enum extends super const export import",
- 6: "enum",
- strict: "implements interface let package private protected public static yield",
- strictBind: "eval arguments"
- };
- // And the keywords
- var ecma5AndLessKeywords = "break case catch continue debugger default do else finally for function if return switch throw try var while with null true false instanceof typeof void delete new in this";
- var keywords = {
- 5: ecma5AndLessKeywords,
- 6: ecma5AndLessKeywords + " const class extends export import super"
- };
- var keywordRelationalOperator = /^in(stanceof)?$/;
- // ## Character categories
- // Big ugly regular expressions that match characters in the
- // whitespace, identifier, and identifier-start categories. These
- // are only applied when a character is found to actually have a
- // code point above 128.
- // Generated by `bin/generate-identifier-regex.js`.
- var nonASCIIidentifierStartChars = "\xaa\xb5\xba\xc0-\xd6\xd8-\xf6\xf8-\u02c1\u02c6-\u02d1\u02e0-\u02e4\u02ec\u02ee\u0370-\u0374\u0376\u0377\u037a-\u037d\u037f\u0386\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03f5\u03f7-\u0481\u048a-\u052f\u0531-\u0556\u0559\u0560-\u0588\u05d0-\u05ea\u05ef-\u05f2\u0620-\u064a\u066e\u066f\u0671-\u06d3\u06d5\u06e5\u06e6\u06ee\u06ef\u06fa-\u06fc\u06ff\u0710\u0712-\u072f\u074d-\u07a5\u07b1\u07ca-\u07ea\u07f4\u07f5\u07fa\u0800-\u0815\u081a\u0824\u0828\u0840-\u0858\u0860-\u086a\u08a0-\u08b4\u08b6-\u08bd\u0904-\u0939\u093d\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098c\u098f\u0990\u0993-\u09a8\u09aa-\u09b0\u09b2\u09b6-\u09b9\u09bd\u09ce\u09dc\u09dd\u09df-\u09e1\u09f0\u09f1\u09fc\u0a05-\u0a0a\u0a0f\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32\u0a33\u0a35\u0a36\u0a38\u0a39\u0a59-\u0a5c\u0a5e\u0a72-\u0a74\u0a85-\u0a8d\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab2\u0ab3\u0ab5-\u0ab9\u0abd\u0ad0\u0ae0\u0ae1\u0af9\u0b05-\u0b0c\u0b0f\u0b10\u0b13-\u0b28\u0b2a-\u0b30\u0b32\u0b33\u0b35-\u0b39\u0b3d\u0b5c\u0b5d\u0b5f-\u0b61\u0b71\u0b83\u0b85-\u0b8a\u0b8e-\u0b90\u0b92-\u0b95\u0b99\u0b9a\u0b9c\u0b9e\u0b9f\u0ba3\u0ba4\u0ba8-\u0baa\u0bae-\u0bb9\u0bd0\u0c05-\u0c0c\u0c0e-\u0c10\u0c12-\u0c28\u0c2a-\u0c39\u0c3d\u0c58-\u0c5a\u0c60\u0c61\u0c80\u0c85-\u0c8c\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cbd\u0cde\u0ce0\u0ce1\u0cf1\u0cf2\u0d05-\u0d0c\u0d0e-\u0d10\u0d12-\u0d3a\u0d3d\u0d4e\u0d54-\u0d56\u0d5f-\u0d61\u0d7a-\u0d7f\u0d85-\u0d96\u0d9a-\u0db1\u0db3-\u0dbb\u0dbd\u0dc0-\u0dc6\u0e01-\u0e30\u0e32\u0e33\u0e40-\u0e46\u0e81\u0e82\u0e84\u0e87\u0e88\u0e8a\u0e8d\u0e94-\u0e97\u0e99-\u0e9f\u0ea1-\u0ea3\u0ea5\u0ea7\u0eaa\u0eab\u0ead-\u0eb0\u0eb2\u0eb3\u0ebd\u0ec0-\u0ec4\u0ec6\u0edc-\u0edf\u0f00\u0f40-\u0f47\u0f49-\u0f6c\u0f88-\u0f8c\u1000-\u102a\u103f\u1050-\u1055\u105a-\u105d\u1061\u1065\u1066\u106e-\u1070\u1075-\u1081\u108e\u10a0-\u10c5\u10c7\u10cd\u10d0-\u10fa\u10fc-\u1248\u124a-\u124d\u1250-\u1256\u1258\u125a-\u125d\u1260-\u1288\u128a-\u128d\u1290-\u12b0\u12b2-\u12b5\u12b8-\u12be\u12c0\u12c2-\u12c5\u12c8-\u12d6\u12d8-\u1310\u1312-\u1315\u1318-\u135a\u1380-\u138f\u13a0-\u13f5\u13f8-\u13fd\u1401-\u166c\u166f-\u167f\u1681-\u169a\u16a0-\u16ea\u16ee-\u16f8\u1700-\u170c\u170e-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176c\u176e-\u1770\u1780-\u17b3\u17d7\u17dc\u1820-\u1878\u1880-\u18a8\u18aa\u18b0-\u18f5\u1900-\u191e\u1950-\u196d\u1970-\u1974\u1980-\u19ab\u19b0-\u19c9\u1a00-\u1a16\u1a20-\u1a54\u1aa7\u1b05-\u1b33\u1b45-\u1b4b\u1b83-\u1ba0\u1bae\u1baf\u1bba-\u1be5\u1c00-\u1c23\u1c4d-\u1c4f\u1c5a-\u1c7d\u1c80-\u1c88\u1c90-\u1cba\u1cbd-\u1cbf\u1ce9-\u1cec\u1cee-\u1cf1\u1cf5\u1cf6\u1d00-\u1dbf\u1e00-\u1f15\u1f18-\u1f1d\u1f20-\u1f45\u1f48-\u1f4d\u1f50-\u1f57\u1f59\u1f5b\u1f5d\u1f5f-\u1f7d\u1f80-\u1fb4\u1fb6-\u1fbc\u1fbe\u1fc2-\u1fc4\u1fc6-\u1fcc\u1fd0-\u1fd3\u1fd6-\u1fdb\u1fe0-\u1fec\u1ff2-\u1ff4\u1ff6-\u1ffc\u2071\u207f\u2090-\u209c\u2102\u2107\u210a-\u2113\u2115\u2118-\u211d\u2124\u2126\u2128\u212a-\u2139\u213c-\u213f\u2145-\u2149\u214e\u2160-\u2188\u2c00-\u2c2e\u2c30-\u2c5e\u2c60-\u2ce4\u2ceb-\u2cee\u2cf2\u2cf3\u2d00-\u2d25\u2d27\u2d2d\u2d30-\u2d67\u2d6f\u2d80-\u2d96\u2da0-\u2da6\u2da8-\u2dae\u2db0-\u2db6\u2db8-\u2dbe\u2dc0-\u2dc6\u2dc8-\u2dce\u2dd0-\u2dd6\u2dd8-\u2dde\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303c\u3041-\u3096\u309b-\u309f\u30a1-\u30fa\u30fc-\u30ff\u3105-\u312f\u3131-\u318e\u31a0-\u31ba\u31f0-\u31ff\u3400-\u4db5\u4e00-\u9fef\ua000-\ua48c\ua4d0-\ua4fd\ua500-\ua60c\ua610-\ua61f\ua62a\ua62b\ua640-\ua66e\ua67f-\ua69d\ua6a0-\ua6ef\ua717-\ua71f\ua722-\ua788\ua78b-\ua7b9\ua7f7-\ua801\ua803-\ua805\ua807-\ua80a\ua80c-\ua822\ua840-\ua873\ua882-\ua8b3\ua8f2-\ua8f7\ua8fb\ua8fd\ua8fe\ua90a-\ua925\ua930-\ua946\ua960-\ua97c\ua984-\ua9b2\ua9cf\ua9e0-\ua9e4\ua9e6-\ua9ef\ua9fa-\ua9fe\uaa00-\uaa28\uaa40-\uaa42\uaa44-\uaa4b\uaa60-\uaa76\uaa7a\uaa7e-\uaaaf\uaab1\uaab5\uaab6\uaab9-\uaabd\uaac0\uaac2\uaadb-\uaadd\uaae0-\uaaea\uaaf2-\uaaf4\uab01-\uab06\uab09-\uab0e\uab11-\uab16\uab20-\uab26\uab28-\uab2e\uab30-\uab5a\uab5c-\uab65\uab70-\uabe2\uac00-\ud7a3\ud7b0-\ud7c6\ud7cb-\ud7fb\uf900-\ufa6d\ufa70-\ufad9\ufb00-\ufb06\ufb13-\ufb17\ufb1d\ufb1f-\ufb28\ufb2a-\ufb36\ufb38-\ufb3c\ufb3e\ufb40\ufb41\ufb43\ufb44\ufb46-\ufbb1\ufbd3-\ufd3d\ufd50-\ufd8f\ufd92-\ufdc7\ufdf0-\ufdfb\ufe70-\ufe74\ufe76-\ufefc\uff21-\uff3a\uff41-\uff5a\uff66-\uffbe\uffc2-\uffc7\uffca-\uffcf\uffd2-\uffd7\uffda-\uffdc";
- var nonASCIIidentifierChars = "\u200c\u200d\xb7\u0300-\u036f\u0387\u0483-\u0487\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u064b-\u0669\u0670\u06d6-\u06dc\u06df-\u06e4\u06e7\u06e8\u06ea-\u06ed\u06f0-\u06f9\u0711\u0730-\u074a\u07a6-\u07b0\u07c0-\u07c9\u07eb-\u07f3\u07fd\u0816-\u0819\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0859-\u085b\u08d3-\u08e1\u08e3-\u0903\u093a-\u093c\u093e-\u094f\u0951-\u0957\u0962\u0963\u0966-\u096f\u0981-\u0983\u09bc\u09be-\u09c4\u09c7\u09c8\u09cb-\u09cd\u09d7\u09e2\u09e3\u09e6-\u09ef\u09fe\u0a01-\u0a03\u0a3c\u0a3e-\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a66-\u0a71\u0a75\u0a81-\u0a83\u0abc\u0abe-\u0ac5\u0ac7-\u0ac9\u0acb-\u0acd\u0ae2\u0ae3\u0ae6-\u0aef\u0afa-\u0aff\u0b01-\u0b03\u0b3c\u0b3e-\u0b44\u0b47\u0b48\u0b4b-\u0b4d\u0b56\u0b57\u0b62\u0b63\u0b66-\u0b6f\u0b82\u0bbe-\u0bc2\u0bc6-\u0bc8\u0bca-\u0bcd\u0bd7\u0be6-\u0bef\u0c00-\u0c04\u0c3e-\u0c44\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c62\u0c63\u0c66-\u0c6f\u0c81-\u0c83\u0cbc\u0cbe-\u0cc4\u0cc6-\u0cc8\u0cca-\u0ccd\u0cd5\u0cd6\u0ce2\u0ce3\u0ce6-\u0cef\u0d00-\u0d03\u0d3b\u0d3c\u0d3e-\u0d44\u0d46-\u0d48\u0d4a-\u0d4d\u0d57\u0d62\u0d63\u0d66-\u0d6f\u0d82\u0d83\u0dca\u0dcf-\u0dd4\u0dd6\u0dd8-\u0ddf\u0de6-\u0def\u0df2\u0df3\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0e50-\u0e59\u0eb1\u0eb4-\u0eb9\u0ebb\u0ebc\u0ec8-\u0ecd\u0ed0-\u0ed9\u0f18\u0f19\u0f20-\u0f29\u0f35\u0f37\u0f39\u0f3e\u0f3f\u0f71-\u0f84\u0f86\u0f87\u0f8d-\u0f97\u0f99-\u0fbc\u0fc6\u102b-\u103e\u1040-\u1049\u1056-\u1059\u105e-\u1060\u1062-\u1064\u1067-\u106d\u1071-\u1074\u1082-\u108d\u108f-\u109d\u135d-\u135f\u1369-\u1371\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17b4-\u17d3\u17dd\u17e0-\u17e9\u180b-\u180d\u1810-\u1819\u18a9\u1920-\u192b\u1930-\u193b\u1946-\u194f\u19d0-\u19da\u1a17-\u1a1b\u1a55-\u1a5e\u1a60-\u1a7c\u1a7f-\u1a89\u1a90-\u1a99\u1ab0-\u1abd\u1b00-\u1b04\u1b34-\u1b44\u1b50-\u1b59\u1b6b-\u1b73\u1b80-\u1b82\u1ba1-\u1bad\u1bb0-\u1bb9\u1be6-\u1bf3\u1c24-\u1c37\u1c40-\u1c49\u1c50-\u1c59\u1cd0-\u1cd2\u1cd4-\u1ce8\u1ced\u1cf2-\u1cf4\u1cf7-\u1cf9\u1dc0-\u1df9\u1dfb-\u1dff\u203f\u2040\u2054\u20d0-\u20dc\u20e1\u20e5-\u20f0\u2cef-\u2cf1\u2d7f\u2de0-\u2dff\u302a-\u302f\u3099\u309a\ua620-\ua629\ua66f\ua674-\ua67d\ua69e\ua69f\ua6f0\ua6f1\ua802\ua806\ua80b\ua823-\ua827\ua880\ua881\ua8b4-\ua8c5\ua8d0-\ua8d9\ua8e0-\ua8f1\ua8ff-\ua909\ua926-\ua92d\ua947-\ua953\ua980-\ua983\ua9b3-\ua9c0\ua9d0-\ua9d9\ua9e5\ua9f0-\ua9f9\uaa29-\uaa36\uaa43\uaa4c\uaa4d\uaa50-\uaa59\uaa7b-\uaa7d\uaab0\uaab2-\uaab4\uaab7\uaab8\uaabe\uaabf\uaac1\uaaeb-\uaaef\uaaf5\uaaf6\uabe3-\uabea\uabec\uabed\uabf0-\uabf9\ufb1e\ufe00-\ufe0f\ufe20-\ufe2f\ufe33\ufe34\ufe4d-\ufe4f\uff10-\uff19\uff3f";
- var nonASCIIidentifierStart = new RegExp("[" + nonASCIIidentifierStartChars + "]");
- var nonASCIIidentifier = new RegExp("[" + nonASCIIidentifierStartChars + nonASCIIidentifierChars + "]");
- nonASCIIidentifierStartChars = nonASCIIidentifierChars = null;
- // These are a run-length and offset encoded representation of the
- // >0xffff code points that are a valid part of identifiers. The
- // offset starts at 0x10000, and each pair of numbers represents an
- // offset to the next range, and then a size of the range. They were
- // generated by bin/generate-identifier-regex.js
- // eslint-disable-next-line comma-spacing
- var astralIdentifierStartCodes = [0,11,2,25,2,18,2,1,2,14,3,13,35,122,70,52,268,28,4,48,48,31,14,29,6,37,11,29,3,35,5,7,2,4,43,157,19,35,5,35,5,39,9,51,157,310,10,21,11,7,153,5,3,0,2,43,2,1,4,0,3,22,11,22,10,30,66,18,2,1,11,21,11,25,71,55,7,1,65,0,16,3,2,2,2,28,43,28,4,28,36,7,2,27,28,53,11,21,11,18,14,17,111,72,56,50,14,50,14,35,477,28,11,0,9,21,190,52,76,44,33,24,27,35,30,0,12,34,4,0,13,47,15,3,22,0,2,0,36,17,2,24,85,6,2,0,2,3,2,14,2,9,8,46,39,7,3,1,3,21,2,6,2,1,2,4,4,0,19,0,13,4,159,52,19,3,54,47,21,1,2,0,185,46,42,3,37,47,21,0,60,42,86,26,230,43,117,63,32,0,257,0,11,39,8,0,22,0,12,39,3,3,20,0,35,56,264,8,2,36,18,0,50,29,113,6,2,1,2,37,22,0,26,5,2,1,2,31,15,0,328,18,270,921,103,110,18,195,2749,1070,4050,582,8634,568,8,30,114,29,19,47,17,3,32,20,6,18,689,63,129,68,12,0,67,12,65,1,31,6129,15,754,9486,286,82,395,2309,106,6,12,4,8,8,9,5991,84,2,70,2,1,3,0,3,1,3,3,2,11,2,0,2,6,2,64,2,3,3,7,2,6,2,27,2,3,2,4,2,0,4,6,2,339,3,24,2,24,2,30,2,24,2,30,2,24,2,30,2,24,2,30,2,24,2,7,4149,196,60,67,1213,3,2,26,2,1,2,0,3,0,2,9,2,3,2,0,2,0,7,0,5,0,2,0,2,0,2,2,2,1,2,0,3,0,2,0,2,0,2,0,2,0,2,1,2,0,3,3,2,6,2,3,2,3,2,0,2,9,2,16,6,2,2,4,2,16,4421,42710,42,4148,12,221,3,5761,15,7472,3104,541];
- // eslint-disable-next-line comma-spacing
- var astralIdentifierCodes = [509,0,227,0,150,4,294,9,1368,2,2,1,6,3,41,2,5,0,166,1,574,3,9,9,525,10,176,2,54,14,32,9,16,3,46,10,54,9,7,2,37,13,2,9,6,1,45,0,13,2,49,13,9,3,4,9,83,11,7,0,161,11,6,9,7,3,56,1,2,6,3,1,3,2,10,0,11,1,3,6,4,4,193,17,10,9,5,0,82,19,13,9,214,6,3,8,28,1,83,16,16,9,82,12,9,9,84,14,5,9,243,14,166,9,280,9,41,6,2,3,9,0,10,10,47,15,406,7,2,7,17,9,57,21,2,13,123,5,4,0,2,1,2,6,2,0,9,9,49,4,2,1,2,4,9,9,330,3,19306,9,135,4,60,6,26,9,1016,45,17,3,19723,1,5319,4,4,5,9,7,3,6,31,3,149,2,1418,49,513,54,5,49,9,0,15,0,23,4,2,14,1361,6,2,16,3,6,2,1,2,4,2214,6,110,6,6,9,792487,239];
- // This has a complexity linear to the value of the code. The
- // assumption is that looking up astral identifier characters is
- // rare.
- function isInAstralSet(code, set) {
- var pos = 0x10000;
- for (var i = 0; i < set.length; i += 2) {
- pos += set[i];
- if (pos > code) { return false }
- pos += set[i + 1];
- if (pos >= code) { return true }
- }
- }
- // Test whether a given character code starts an identifier.
- function isIdentifierStart(code, astral) {
- if (code < 65) { return code === 36 }
- if (code < 91) { return true }
- if (code < 97) { return code === 95 }
- if (code < 123) { return true }
- if (code <= 0xffff) { return code >= 0xaa && nonASCIIidentifierStart.test(String.fromCharCode(code)) }
- if (astral === false) { return false }
- return isInAstralSet(code, astralIdentifierStartCodes)
- }
- // Test whether a given character is part of an identifier.
- function isIdentifierChar(code, astral) {
- if (code < 48) { return code === 36 }
- if (code < 58) { return true }
- if (code < 65) { return false }
- if (code < 91) { return true }
- if (code < 97) { return code === 95 }
- if (code < 123) { return true }
- if (code <= 0xffff) { return code >= 0xaa && nonASCIIidentifier.test(String.fromCharCode(code)) }
- if (astral === false) { return false }
- return isInAstralSet(code, astralIdentifierStartCodes) || isInAstralSet(code, astralIdentifierCodes)
- }
- // ## Token types
- // The assignment of fine-grained, information-carrying type objects
- // allows the tokenizer to store the information it has about a
- // token in a way that is very cheap for the parser to look up.
- // All token type variables start with an underscore, to make them
- // easy to recognize.
- // The `beforeExpr` property is used to disambiguate between regular
- // expressions and divisions. It is set on all token types that can
- // be followed by an expression (thus, a slash after them would be a
- // regular expression).
- //
- // The `startsExpr` property is used to check if the token ends a
- // `yield` expression. It is set on all token types that either can
- // directly start an expression (like a quotation mark) or can
- // continue an expression (like the body of a string).
- //
- // `isLoop` marks a keyword as starting a loop, which is important
- // to know when parsing a label, in order to allow or disallow
- // continue jumps to that label.
- var TokenType = function TokenType(label, conf) {
- if ( conf === void 0 ) conf = {};
- this.label = label;
- this.keyword = conf.keyword;
- this.beforeExpr = !!conf.beforeExpr;
- this.startsExpr = !!conf.startsExpr;
- this.isLoop = !!conf.isLoop;
- this.isAssign = !!conf.isAssign;
- this.prefix = !!conf.prefix;
- this.postfix = !!conf.postfix;
- this.binop = conf.binop || null;
- this.updateContext = null;
- };
- function binop(name, prec) {
- return new TokenType(name, {beforeExpr: true, binop: prec})
- }
- var beforeExpr = {beforeExpr: true};
- var startsExpr = {startsExpr: true};
- // Map keyword names to token types.
- var keywords$1 = {};
- // Succinct definitions of keyword token types
- function kw(name, options) {
- if ( options === void 0 ) options = {};
- options.keyword = name;
- return keywords$1[name] = new TokenType(name, options)
- }
- var types = {
- num: new TokenType("num", startsExpr),
- regexp: new TokenType("regexp", startsExpr),
- string: new TokenType("string", startsExpr),
- name: new TokenType("name", startsExpr),
- eof: new TokenType("eof"),
- // Punctuation token types.
- bracketL: new TokenType("[", {beforeExpr: true, startsExpr: true}),
- bracketR: new TokenType("]"),
- braceL: new TokenType("{", {beforeExpr: true, startsExpr: true}),
- braceR: new TokenType("}"),
- parenL: new TokenType("(", {beforeExpr: true, startsExpr: true}),
- parenR: new TokenType(")"),
- comma: new TokenType(",", beforeExpr),
- semi: new TokenType(";", beforeExpr),
- colon: new TokenType(":", beforeExpr),
- dot: new TokenType("."),
- question: new TokenType("?", beforeExpr),
- arrow: new TokenType("=>", beforeExpr),
- template: new TokenType("template"),
- invalidTemplate: new TokenType("invalidTemplate"),
- ellipsis: new TokenType("...", beforeExpr),
- backQuote: new TokenType("`", startsExpr),
- dollarBraceL: new TokenType("${", {beforeExpr: true, startsExpr: true}),
- // Operators. These carry several kinds of properties to help the
- // parser use them properly (the presence of these properties is
- // what categorizes them as operators).
- //
- // `binop`, when present, specifies that this operator is a binary
- // operator, and will refer to its precedence.
- //
- // `prefix` and `postfix` mark the operator as a prefix or postfix
- // unary operator.
- //
- // `isAssign` marks all of `=`, `+=`, `-=` etcetera, which act as
- // binary operators with a very low precedence, that should result
- // in AssignmentExpression nodes.
- eq: new TokenType("=", {beforeExpr: true, isAssign: true}),
- assign: new TokenType("_=", {beforeExpr: true, isAssign: true}),
- incDec: new TokenType("++/--", {prefix: true, postfix: true, startsExpr: true}),
- prefix: new TokenType("!/~", {beforeExpr: true, prefix: true, startsExpr: true}),
- logicalOR: binop("||", 1),
- logicalAND: binop("&&", 2),
- bitwiseOR: binop("|", 3),
- bitwiseXOR: binop("^", 4),
- bitwiseAND: binop("&", 5),
- equality: binop("==/!=/===/!==", 6),
- relational: binop("</>/<=/>=", 7),
- bitShift: binop("<</>>/>>>", 8),
- plusMin: new TokenType("+/-", {beforeExpr: true, binop: 9, prefix: true, startsExpr: true}),
- modulo: binop("%", 10),
- star: binop("*", 10),
- slash: binop("/", 10),
- starstar: new TokenType("**", {beforeExpr: true}),
- // Keyword token types.
- _break: kw("break"),
- _case: kw("case", beforeExpr),
- _catch: kw("catch"),
- _continue: kw("continue"),
- _debugger: kw("debugger"),
- _default: kw("default", beforeExpr),
- _do: kw("do", {isLoop: true, beforeExpr: true}),
- _else: kw("else", beforeExpr),
- _finally: kw("finally"),
- _for: kw("for", {isLoop: true}),
- _function: kw("function", startsExpr),
- _if: kw("if"),
- _return: kw("return", beforeExpr),
- _switch: kw("switch"),
- _throw: kw("throw", beforeExpr),
- _try: kw("try"),
- _var: kw("var"),
- _const: kw("const"),
- _while: kw("while", {isLoop: true}),
- _with: kw("with"),
- _new: kw("new", {beforeExpr: true, startsExpr: true}),
- _this: kw("this", startsExpr),
- _super: kw("super", startsExpr),
- _class: kw("class", startsExpr),
- _extends: kw("extends", beforeExpr),
- _export: kw("export"),
- _import: kw("import"),
- _null: kw("null", startsExpr),
- _true: kw("true", startsExpr),
- _false: kw("false", startsExpr),
- _in: kw("in", {beforeExpr: true, binop: 7}),
- _instanceof: kw("instanceof", {beforeExpr: true, binop: 7}),
- _typeof: kw("typeof", {beforeExpr: true, prefix: true, startsExpr: true}),
- _void: kw("void", {beforeExpr: true, prefix: true, startsExpr: true}),
- _delete: kw("delete", {beforeExpr: true, prefix: true, startsExpr: true})
- };
- // Matches a whole line break (where CRLF is considered a single
- // line break). Used to count lines.
- var lineBreak = /\r\n?|\n|\u2028|\u2029/;
- var lineBreakG = new RegExp(lineBreak.source, "g");
- function isNewLine(code, ecma2019String) {
- return code === 10 || code === 13 || (!ecma2019String && (code === 0x2028 || code === 0x2029))
- }
- var nonASCIIwhitespace = /[\u1680\u180e\u2000-\u200a\u202f\u205f\u3000\ufeff]/;
- var skipWhiteSpace = /(?:\s|\/\/.*|\/\*[^]*?\*\/)*/g;
- var ref = Object.prototype;
- var hasOwnProperty = ref.hasOwnProperty;
- var toString = ref.toString;
- // Checks if an object has a property.
- function has(obj, propName) {
- return hasOwnProperty.call(obj, propName)
- }
- var isArray = Array.isArray || (function (obj) { return (
- toString.call(obj) === "[object Array]"
- ); });
- // These are used when `options.locations` is on, for the
- // `startLoc` and `endLoc` properties.
- var Position = function Position(line, col) {
- this.line = line;
- this.column = col;
- };
- Position.prototype.offset = function offset (n) {
- return new Position(this.line, this.column + n)
- };
- var SourceLocation = function SourceLocation(p, start, end) {
- this.start = start;
- this.end = end;
- if (p.sourceFile !== null) { this.source = p.sourceFile; }
- };
- // The `getLineInfo` function is mostly useful when the
- // `locations` option is off (for performance reasons) and you
- // want to find the line/column position for a given character
- // offset. `input` should be the code string that the offset refers
- // into.
- function getLineInfo(input, offset) {
- for (var line = 1, cur = 0;;) {
- lineBreakG.lastIndex = cur;
- var match = lineBreakG.exec(input);
- if (match && match.index < offset) {
- ++line;
- cur = match.index + match[0].length;
- } else {
- return new Position(line, offset - cur)
- }
- }
- }
- // A second optional argument can be given to further configure
- // the parser process. These options are recognized:
- var defaultOptions = {
- // `ecmaVersion` indicates the ECMAScript version to parse. Must
- // be either 3, 5, 6 (2015), 7 (2016), or 8 (2017). This influences support
- // for strict mode, the set of reserved words, and support for
- // new syntax features. The default is 7.
- ecmaVersion: 7,
- // `sourceType` indicates the mode the code should be parsed in.
- // Can be either `"script"` or `"module"`. This influences global
- // strict mode and parsing of `import` and `export` declarations.
- sourceType: "script",
- // `onInsertedSemicolon` can be a callback that will be called
- // when a semicolon is automatically inserted. It will be passed
- // th position of the comma as an offset, and if `locations` is
- // enabled, it is given the location as a `{line, column}` object
- // as second argument.
- onInsertedSemicolon: null,
- // `onTrailingComma` is similar to `onInsertedSemicolon`, but for
- // trailing commas.
- onTrailingComma: null,
- // By default, reserved words are only enforced if ecmaVersion >= 5.
- // Set `allowReserved` to a boolean value to explicitly turn this on
- // an off. When this option has the value "never", reserved words
- // and keywords can also not be used as property names.
- allowReserved: null,
- // When enabled, a return at the top level is not considered an
- // error.
- allowReturnOutsideFunction: false,
- // When enabled, import/export statements are not constrained to
- // appearing at the top of the program.
- allowImportExportEverywhere: false,
- // When enabled, await identifiers are allowed to appear at the top-level scope,
- // but they are still not allowed in non-async functions.
- allowAwaitOutsideFunction: false,
- // When enabled, hashbang directive in the beginning of file
- // is allowed and treated as a line comment.
- allowHashBang: false,
- // When `locations` is on, `loc` properties holding objects with
- // `start` and `end` properties in `{line, column}` form (with
- // line being 1-based and column 0-based) will be attached to the
- // nodes.
- locations: false,
- // A function can be passed as `onToken` option, which will
- // cause Acorn to call that function with object in the same
- // format as tokens returned from `tokenizer().getToken()`. Note
- // that you are not allowed to call the parser from the
- // callback—that will corrupt its internal state.
- onToken: null,
- // A function can be passed as `onComment` option, which will
- // cause Acorn to call that function with `(block, text, start,
- // end)` parameters whenever a comment is skipped. `block` is a
- // boolean indicating whether this is a block (`/* */`) comment,
- // `text` is the content of the comment, and `start` and `end` are
- // character offsets that denote the start and end of the comment.
- // When the `locations` option is on, two more parameters are
- // passed, the full `{line, column}` locations of the start and
- // end of the comments. Note that you are not allowed to call the
- // parser from the callback—that will corrupt its internal state.
- onComment: null,
- // Nodes have their start and end characters offsets recorded in
- // `start` and `end` properties (directly on the node, rather than
- // the `loc` object, which holds line/column data. To also add a
- // [semi-standardized][range] `range` property holding a `[start,
- // end]` array with the same numbers, set the `ranges` option to
- // `true`.
- //
- // [range]: https://bugzilla.mozilla.org/show_bug.cgi?id=745678
- ranges: false,
- // It is possible to parse multiple files into a single AST by
- // passing the tree produced by parsing the first file as
- // `program` option in subsequent parses. This will add the
- // toplevel forms of the parsed file to the `Program` (top) node
- // of an existing parse tree.
- program: null,
- // When `locations` is on, you can pass this to record the source
- // file in every node's `loc` object.
- sourceFile: null,
- // This value, if given, is stored in every node, whether
- // `locations` is on or off.
- directSourceFile: null,
- // When enabled, parenthesized expressions are represented by
- // (non-standard) ParenthesizedExpression nodes
- preserveParens: false,
- plugins: {}
- };
- // Interpret and default an options object
- function getOptions(opts) {
- var options = {};
- for (var opt in defaultOptions)
- { options[opt] = opts && has(opts, opt) ? opts[opt] : defaultOptions[opt]; }
- if (options.ecmaVersion >= 2015)
- { options.ecmaVersion -= 2009; }
- if (options.allowReserved == null)
- { options.allowReserved = options.ecmaVersion < 5; }
- if (isArray(options.onToken)) {
- var tokens = options.onToken;
- options.onToken = function (token) { return tokens.push(token); };
- }
- if (isArray(options.onComment))
- { options.onComment = pushComment(options, options.onComment); }
- return options
- }
- function pushComment(options, array) {
- return function(block, text, start, end, startLoc, endLoc) {
- var comment = {
- type: block ? "Block" : "Line",
- value: text,
- start: start,
- end: end
- };
- if (options.locations)
- { comment.loc = new SourceLocation(this, startLoc, endLoc); }
- if (options.ranges)
- { comment.range = [start, end]; }
- array.push(comment);
- }
- }
- // Registered plugins
- var plugins = {};
- function keywordRegexp(words) {
- return new RegExp("^(?:" + words.replace(/ /g, "|") + ")$")
- }
- var Parser = function Parser(options, input, startPos) {
- this.options = options = getOptions(options);
- this.sourceFile = options.sourceFile;
- this.keywords = keywordRegexp(keywords[options.ecmaVersion >= 6 ? 6 : 5]);
- var reserved = "";
- if (!options.allowReserved) {
- for (var v = options.ecmaVersion;; v--)
- { if (reserved = reservedWords[v]) { break } }
- if (options.sourceType === "module") { reserved += " await"; }
- }
- this.reservedWords = keywordRegexp(reserved);
- var reservedStrict = (reserved ? reserved + " " : "") + reservedWords.strict;
- this.reservedWordsStrict = keywordRegexp(reservedStrict);
- this.reservedWordsStrictBind = keywordRegexp(reservedStrict + " " + reservedWords.strictBind);
- this.input = String(input);
- // Used to signal to callers of `readWord1` whether the word
- // contained any escape sequences. This is needed because words with
- // escape sequences must not be interpreted as keywords.
- this.containsEsc = false;
- // Load plugins
- this.loadPlugins(options.plugins);
- // Set up token state
- // The current position of the tokenizer in the input.
- if (startPos) {
- this.pos = startPos;
- this.lineStart = this.input.lastIndexOf("\n", startPos - 1) + 1;
- this.curLine = this.input.slice(0, this.lineStart).split(lineBreak).length;
- } else {
- this.pos = this.lineStart = 0;
- this.curLine = 1;
- }
- // Properties of the current token:
- // Its type
- this.type = types.eof;
- // For tokens that include more information than their type, the value
- this.value = null;
- // Its start and end offset
- this.start = this.end = this.pos;
- // And, if locations are used, the {line, column} object
- // corresponding to those offsets
- this.startLoc = this.endLoc = this.curPosition();
- // Position information for the previous token
- this.lastTokEndLoc = this.lastTokStartLoc = null;
- this.lastTokStart = this.lastTokEnd = this.pos;
- // The context stack is used to superficially track syntactic
- // context to predict whether a regular expression is allowed in a
- // given position.
- this.context = this.initialContext();
- this.exprAllowed = true;
- // Figure out if it's a module code.
- this.inModule = options.sourceType === "module";
- this.strict = this.inModule || this.strictDirective(this.pos);
- // Used to signify the start of a potential arrow function
- this.potentialArrowAt = -1;
- // Flags to track whether we are in a function, a generator, an async function.
- this.inFunction = this.inGenerator = this.inAsync = false;
- // Positions to delayed-check that yield/await does not exist in default parameters.
- this.yieldPos = this.awaitPos = 0;
- // Labels in scope.
- this.labels = [];
- // If enabled, skip leading hashbang line.
- if (this.pos === 0 && options.allowHashBang && this.input.slice(0, 2) === "#!")
- { this.skipLineComment(2); }
- // Scope tracking for duplicate variable names (see scope.js)
- this.scopeStack = [];
- this.enterFunctionScope();
- // For RegExp validation
- this.regexpState = null;
- };
- // DEPRECATED Kept for backwards compatibility until 3.0 in case a plugin uses them
- Parser.prototype.isKeyword = function isKeyword (word) { return this.keywords.test(word) };
- Parser.prototype.isReservedWord = function isReservedWord (word) { return this.reservedWords.test(word) };
- Parser.prototype.extend = function extend (name, f) {
- this[name] = f(this[name]);
- };
- Parser.prototype.loadPlugins = function loadPlugins (pluginConfigs) {
- var this$1 = this;
- for (var name in pluginConfigs) {
- var plugin = plugins[name];
- if (!plugin) { throw new Error("Plugin '" + name + "' not found") }
- plugin(this$1, pluginConfigs[name]);
- }
- };
- Parser.prototype.parse = function parse () {
- var node = this.options.program || this.startNode();
- this.nextToken();
- return this.parseTopLevel(node)
- };
- var pp = Parser.prototype;
- // ## Parser utilities
- var literal = /^(?:'((?:\\.|[^'])*?)'|"((?:\\.|[^"])*?)"|;)/;
- pp.strictDirective = function(start) {
- var this$1 = this;
- for (;;) {
- skipWhiteSpace.lastIndex = start;
- start += skipWhiteSpace.exec(this$1.input)[0].length;
- var match = literal.exec(this$1.input.slice(start));
- if (!match) { return false }
- if ((match[1] || match[2]) === "use strict") { return true }
- start += match[0].length;
- }
- };
- // Predicate that tests whether the next token is of the given
- // type, and if yes, consumes it as a side effect.
- pp.eat = function(type) {
- if (this.type === type) {
- this.next();
- return true
- } else {
- return false
- }
- };
- // Tests whether parsed token is a contextual keyword.
- pp.isContextual = function(name) {
- return this.type === types.name && this.value === name && !this.containsEsc
- };
- // Consumes contextual keyword if possible.
- pp.eatContextual = function(name) {
- if (!this.isContextual(name)) { return false }
- this.next();
- return true
- };
- // Asserts that following token is given contextual keyword.
- pp.expectContextual = function(name) {
- if (!this.eatContextual(name)) { this.unexpected(); }
- };
- // Test whether a semicolon can be inserted at the current position.
- pp.canInsertSemicolon = function() {
- return this.type === types.eof ||
- this.type === types.braceR ||
- lineBreak.test(this.input.slice(this.lastTokEnd, this.start))
- };
- pp.insertSemicolon = function() {
- if (this.canInsertSemicolon()) {
- if (this.options.onInsertedSemicolon)
- { this.options.onInsertedSemicolon(this.lastTokEnd, this.lastTokEndLoc); }
- return true
- }
- };
- // Consume a semicolon, or, failing that, see if we are allowed to
- // pretend that there is a semicolon at this position.
- pp.semicolon = function() {
- if (!this.eat(types.semi) && !this.insertSemicolon()) { this.unexpected(); }
- };
- pp.afterTrailingComma = function(tokType, notNext) {
- if (this.type === tokType) {
- if (this.options.onTrailingComma)
- { this.options.onTrailingComma(this.lastTokStart, this.lastTokStartLoc); }
- if (!notNext)
- { this.next(); }
- return true
- }
- };
- // Expect a token of a given type. If found, consume it, otherwise,
- // raise an unexpected token error.
- pp.expect = function(type) {
- this.eat(type) || this.unexpected();
- };
- // Raise an unexpected token error.
- pp.unexpected = function(pos) {
- this.raise(pos != null ? pos : this.start, "Unexpected token");
- };
- function DestructuringErrors() {
- this.shorthandAssign =
- this.trailingComma =
- this.parenthesizedAssign =
- this.parenthesizedBind =
- this.doubleProto =
- -1;
- }
- pp.checkPatternErrors = function(refDestructuringErrors, isAssign) {
- if (!refDestructuringErrors) { return }
- if (refDestructuringErrors.trailingComma > -1)
- { this.raiseRecoverable(refDestructuringErrors.trailingComma, "Comma is not permitted after the rest element"); }
- var parens = isAssign ? refDestructuringErrors.parenthesizedAssign : refDestructuringErrors.parenthesizedBind;
- if (parens > -1) { this.raiseRecoverable(parens, "Parenthesized pattern"); }
- };
- pp.checkExpressionErrors = function(refDestructuringErrors, andThrow) {
- if (!refDestructuringErrors) { return false }
- var shorthandAssign = refDestructuringErrors.shorthandAssign;
- var doubleProto = refDestructuringErrors.doubleProto;
- if (!andThrow) { return shorthandAssign >= 0 || doubleProto >= 0 }
- if (shorthandAssign >= 0)
- { this.raise(shorthandAssign, "Shorthand property assignments are valid only in destructuring patterns"); }
- if (doubleProto >= 0)
- { this.raiseRecoverable(doubleProto, "Redefinition of __proto__ property"); }
- };
- pp.checkYieldAwaitInDefaultParams = function() {
- if (this.yieldPos && (!this.awaitPos || this.yieldPos < this.awaitPos))
- { this.raise(this.yieldPos, "Yield expression cannot be a default value"); }
- if (this.awaitPos)
- { this.raise(this.awaitPos, "Await expression cannot be a default value"); }
- };
- pp.isSimpleAssignTarget = function(expr) {
- if (expr.type === "ParenthesizedExpression")
- { return this.isSimpleAssignTarget(expr.expression) }
- return expr.type === "Identifier" || expr.type === "MemberExpression"
- };
- var pp$1 = Parser.prototype;
- // ### Statement parsing
- // Parse a program. Initializes the parser, reads any number of
- // statements, and wraps them in a Program node. Optionally takes a
- // `program` argument. If present, the statements will be appended
- // to its body instead of creating a new node.
- pp$1.parseTopLevel = function(node) {
- var this$1 = this;
- var exports = {};
- if (!node.body) { node.body = []; }
- while (this.type !== types.eof) {
- var stmt = this$1.parseStatement(true, true, exports);
- node.body.push(stmt);
- }
- this.adaptDirectivePrologue(node.body);
- this.next();
- if (this.options.ecmaVersion >= 6) {
- node.sourceType = this.options.sourceType;
- }
- return this.finishNode(node, "Program")
- };
- var loopLabel = {kind: "loop"};
- var switchLabel = {kind: "switch"};
- pp$1.isLet = function() {
- if (this.options.ecmaVersion < 6 || !this.isContextual("let")) { return false }
- skipWhiteSpace.lastIndex = this.pos;
- var skip = skipWhiteSpace.exec(this.input);
- var next = this.pos + skip[0].length, nextCh = this.input.charCodeAt(next);
- if (nextCh === 91 || nextCh === 123) { return true } // '{' and '['
- if (isIdentifierStart(nextCh, true)) {
- var pos = next + 1;
- while (isIdentifierChar(this.input.charCodeAt(pos), true)) { ++pos; }
- var ident = this.input.slice(next, pos);
- if (!keywordRelationalOperator.test(ident)) { return true }
- }
- return false
- };
- // check 'async [no LineTerminator here] function'
- // - 'async /*foo*/ function' is OK.
- // - 'async /*\n*/ function' is invalid.
- pp$1.isAsyncFunction = function() {
- if (this.options.ecmaVersion < 8 || !this.isContextual("async"))
- { return false }
- skipWhiteSpace.lastIndex = this.pos;
- var skip = skipWhiteSpace.exec(this.input);
- var next = this.pos + skip[0].length;
- return !lineBreak.test(this.input.slice(this.pos, next)) &&
- this.input.slice(next, next + 8) === "function" &&
- (next + 8 === this.input.length || !isIdentifierChar(this.input.charAt(next + 8)))
- };
- // Parse a single statement.
- //
- // If expecting a statement and finding a slash operator, parse a
- // regular expression literal. This is to handle cases like
- // `if (foo) /blah/.exec(foo)`, where looking at the previous token
- // does not help.
- pp$1.parseStatement = function(declaration, topLevel, exports) {
- var starttype = this.type, node = this.startNode(), kind;
- if (this.isLet()) {
- starttype = types._var;
- kind = "let";
- }
- // Most types of statements are recognized by the keyword they
- // start with. Many are trivial to parse, some require a bit of
- // complexity.
- switch (starttype) {
- case types._break: case types._continue: return this.parseBreakContinueStatement(node, starttype.keyword)
- case types._debugger: return this.parseDebuggerStatement(node)
- case types._do: return this.parseDoStatement(node)
- case types._for: return this.parseForStatement(node)
- case types._function:
- if (!declaration && this.options.ecmaVersion >= 6) { this.unexpected(); }
- return this.parseFunctionStatement(node, false)
- case types._class:
- if (!declaration) { this.unexpected(); }
- return this.parseClass(node, true)
- case types._if: return this.parseIfStatement(node)
- case types._return: return this.parseReturnStatement(node)
- case types._switch: return this.parseSwitchStatement(node)
- case types._throw: return this.parseThrowStatement(node)
- case types._try: return this.parseTryStatement(node)
- case types._const: case types._var:
- kind = kind || this.value;
- if (!declaration && kind !== "var") { this.unexpected(); }
- return this.parseVarStatement(node, kind)
- case types._while: return this.parseWhileStatement(node)
- case types._with: return this.parseWithStatement(node)
- case types.braceL: return this.parseBlock()
- case types.semi: return this.parseEmptyStatement(node)
- case types._export:
- case types._import:
- if (!this.options.allowImportExportEverywhere) {
- if (!topLevel)
- { this.raise(this.start, "'import' and 'export' may only appear at the top level"); }
- if (!this.inModule)
- { this.raise(this.start, "'import' and 'export' may appear only with 'sourceType: module'"); }
- }
- return starttype === types._import ? this.parseImport(node) : this.parseExport(node, exports)
- // If the statement does not start with a statement keyword or a
- // brace, it's an ExpressionStatement or LabeledStatement. We
- // simply start parsing an expression, and afterwards, if the
- // next token is a colon and the expression was a simple
- // Identifier node, we switch to interpreting it as a label.
- default:
- if (this.isAsyncFunction()) {
- if (!declaration) { this.unexpected(); }
- this.next();
- return this.parseFunctionStatement(node, true)
- }
- var maybeName = this.value, expr = this.parseExpression();
- if (starttype === types.name && expr.type === "Identifier" && this.eat(types.colon))
- { return this.parseLabeledStatement(node, maybeName, expr) }
- else { return this.parseExpressionStatement(node, expr) }
- }
- };
- pp$1.parseBreakContinueStatement = function(node, keyword) {
- var this$1 = this;
- var isBreak = keyword === "break";
- this.next();
- if (this.eat(types.semi) || this.insertSemicolon()) { node.label = null; }
- else if (this.type !== types.name) { this.unexpected(); }
- else {
- node.label = this.parseIdent();
- this.semicolon();
- }
- // Verify that there is an actual destination to break or
- // continue to.
- var i = 0;
- for (; i < this.labels.length; ++i) {
- var lab = this$1.labels[i];
- if (node.label == null || lab.name === node.label.name) {
- if (lab.kind != null && (isBreak || lab.kind === "loop")) { break }
- if (node.label && isBreak) { break }
- }
- }
- if (i === this.labels.length) { this.raise(node.start, "Unsyntactic " + keyword); }
- return this.finishNode(node, isBreak ? "BreakStatement" : "ContinueStatement")
- };
- pp$1.parseDebuggerStatement = function(node) {
- this.next();
- this.semicolon();
- return this.finishNode(node, "DebuggerStatement")
- };
- pp$1.parseDoStatement = function(node) {
- this.next();
- this.labels.push(loopLabel);
- node.body = this.parseStatement(false);
- this.labels.pop();
- this.expect(types._while);
- node.test = this.parseParenExpression();
- if (this.options.ecmaVersion >= 6)
- { this.eat(types.semi); }
- else
- { this.semicolon(); }
- return this.finishNode(node, "DoWhileStatement")
- };
- // Disambiguating between a `for` and a `for`/`in` or `for`/`of`
- // loop is non-trivial. Basically, we have to parse the init `var`
- // statement or expression, disallowing the `in` operator (see
- // the second parameter to `parseExpression`), and then check
- // whether the next token is `in` or `of`. When there is no init
- // part (semicolon immediately after the opening parenthesis), it
- // is a regular `for` loop.
- pp$1.parseForStatement = function(node) {
- this.next();
- var awaitAt = (this.options.ecmaVersion >= 9 && (this.inAsync || (!this.inFunction && this.options.allowAwaitOutsideFunction)) && this.eatContextual("await")) ? this.lastTokStart : -1;
- this.labels.push(loopLabel);
- this.enterLexicalScope();
- this.expect(types.parenL);
- if (this.type === types.semi) {
- if (awaitAt > -1) { this.unexpected(awaitAt); }
- return this.parseFor(node, null)
- }
- var isLet = this.isLet();
- if (this.type === types._var || this.type === types._const || isLet) {
- var init$1 = this.startNode(), kind = isLet ? "let" : this.value;
- this.next();
- this.parseVar(init$1, true, kind);
- this.finishNode(init$1, "VariableDeclaration");
- if ((this.type === types._in || (this.options.ecmaVersion >= 6 && this.isContextual("of"))) && init$1.declarations.length === 1 &&
- !(kind !== "var" && init$1.declarations[0].init)) {
- if (this.options.ecmaVersion >= 9) {
- if (this.type === types._in) {
- if (awaitAt > -1) { this.unexpected(awaitAt); }
- } else { node.await = awaitAt > -1; }
- }
- return this.parseForIn(node, init$1)
- }
- if (awaitAt > -1) { this.unexpected(awaitAt); }
- return this.parseFor(node, init$1)
- }
- var refDestructuringErrors = new DestructuringErrors;
- var init = this.parseExpression(true, refDestructuringErrors);
- if (this.type === types._in || (this.options.ecmaVersion >= 6 && this.isContextual("of"))) {
- if (this.options.ecmaVersion >= 9) {
- if (this.type === types._in) {
- if (awaitAt > -1) { this.unexpected(awaitAt); }
- } else { node.await = awaitAt > -1; }
- }
- this.toAssignable(init, false, refDestructuringErrors);
- this.checkLVal(init);
- return this.parseForIn(node, init)
- } else {
- this.checkExpressionErrors(refDestructuringErrors, true);
- }
- if (awaitAt > -1) { this.unexpected(awaitAt); }
- return this.parseFor(node, init)
- };
- pp$1.parseFunctionStatement = function(node, isAsync) {
- this.next();
- return this.parseFunction(node, true, false, isAsync)
- };
- pp$1.parseIfStatement = function(node) {
- this.next();
- node.test = this.parseParenExpression();
- // allow function declarations in branches, but only in non-strict mode
- node.consequent = this.parseStatement(!this.strict && this.type === types._function);
- node.alternate = this.eat(types._else) ? this.parseStatement(!this.strict && this.type === types._function) : null;
- return this.finishNode(node, "IfStatement")
- };
- pp$1.parseReturnStatement = function(node) {
- if (!this.inFunction && !this.options.allowReturnOutsideFunction)
- { this.raise(this.start, "'return' outside of function"); }
- this.next();
- // In `return` (and `break`/`continue`), the keywords with
- // optional arguments, we eagerly look for a semicolon or the
- // possibility to insert one.
- if (this.eat(types.semi) || this.insertSemicolon()) { node.argument = null; }
- else { node.argument = this.parseExpression(); this.semicolon(); }
- return this.finishNode(node, "ReturnStatement")
- };
- pp$1.parseSwitchStatement = function(node) {
- var this$1 = this;
- this.next();
- node.discriminant = this.parseParenExpression();
- node.cases = [];
- this.expect(types.braceL);
- this.labels.push(switchLabel);
- this.enterLexicalScope();
- // Statements under must be grouped (by label) in SwitchCase
- // nodes. `cur` is used to keep the node that we are currently
- // adding statements to.
- var cur;
- for (var sawDefault = false; this.type !== types.braceR;) {
- if (this$1.type === types._case || this$1.type === types._default) {
- var isCase = this$1.type === types._case;
- if (cur) { this$1.finishNode(cur, "SwitchCase"); }
- node.cases.push(cur = this$1.startNode());
- cur.consequent = [];
- this$1.next();
- if (isCase) {
- cur.test = this$1.parseExpression();
- } else {
- if (sawDefault) { this$1.raiseRecoverable(this$1.lastTokStart, "Multiple default clauses"); }
- sawDefault = true;
- cur.test = null;
- }
- this$1.expect(types.colon);
- } else {
- if (!cur) { this$1.unexpected(); }
- cur.consequent.push(this$1.parseStatement(true));
- }
- }
- this.exitLexicalScope();
- if (cur) { this.finishNode(cur, "SwitchCase"); }
- this.next(); // Closing brace
- this.labels.pop();
- return this.finishNode(node, "SwitchStatement")
- };
- pp$1.parseThrowStatement = function(node) {
- this.next();
- if (lineBreak.test(this.input.slice(this.lastTokEnd, this.start)))
- { this.raise(this.lastTokEnd, "Illegal newline after throw"); }
- node.argument = this.parseExpression();
- this.semicolon();
- return this.finishNode(node, "ThrowStatement")
- };
- // Reused empty array added for node fields that are always empty.
- var empty = [];
- pp$1.parseTryStatement = function(node) {
- this.next();
- node.block = this.parseBlock();
- node.handler = null;
- if (this.type === types._catch) {
- var clause = this.startNode();
- this.next();
- if (this.eat(types.parenL)) {
- clause.param = this.parseBindingAtom();
- this.enterLexicalScope();
- this.checkLVal(clause.param, "let");
- this.expect(types.parenR);
- } else {
- if (this.options.ecmaVersion < 10) { this.unexpected(); }
- clause.param = null;
- this.enterLexicalScope();
- }
- clause.body = this.parseBlock(false);
- this.exitLexicalScope();
- node.handler = this.finishNode(clause, "CatchClause");
- }
- node.finalizer = this.eat(types._finally) ? this.parseBlock() : null;
- if (!node.handler && !node.finalizer)
- { this.raise(node.start, "Missing catch or finally clause"); }
- return this.finishNode(node, "TryStatement")
- };
- pp$1.parseVarStatement = function(node, kind) {
- this.next();
- this.parseVar(node, false, kind);
- this.semicolon();
- return this.finishNode(node, "VariableDeclaration")
- };
- pp$1.parseWhileStatement = function(node) {
- this.next();
- node.test = this.parseParenExpression();
- this.labels.push(loopLabel);
- node.body = this.parseStatement(false);
- this.labels.pop();
- return this.finishNode(node, "WhileStatement")
- };
- pp$1.parseWithStatement = function(node) {
- if (this.strict) { this.raise(this.start, "'with' in strict mode"); }
- this.next();
- node.object = this.parseParenExpression();
- node.body = this.parseStatement(false);
- return this.finishNode(node, "WithStatement")
- };
- pp$1.parseEmptyStatement = function(node) {
- this.next();
- return this.finishNode(node, "EmptyStatement")
- };
- pp$1.parseLabeledStatement = function(node, maybeName, expr) {
- var this$1 = this;
- for (var i$1 = 0, list = this$1.labels; i$1 < list.length; i$1 += 1)
- {
- var label = list[i$1];
- if (label.name === maybeName)
- { this$1.raise(expr.start, "Label '" + maybeName + "' is already declared");
- } }
- var kind = this.type.isLoop ? "loop" : this.type === types._switch ? "switch" : null;
- for (var i = this.labels.length - 1; i >= 0; i--) {
- var label$1 = this$1.labels[i];
- if (label$1.statementStart === node.start) {
- // Update information about previous labels on this node
- label$1.statementStart = this$1.start;
- label$1.kind = kind;
- } else { break }
- }
- this.labels.push({name: maybeName, kind: kind, statementStart: this.start});
- node.body = this.parseStatement(true);
- if (node.body.type === "ClassDeclaration" ||
- node.body.type === "VariableDeclaration" && node.body.kind !== "var" ||
- node.body.type === "FunctionDeclaration" && (this.strict || node.body.generator || node.body.async))
- { this.raiseRecoverable(node.body.start, "Invalid labeled declaration"); }
- this.labels.pop();
- node.label = expr;
- return this.finishNode(node, "LabeledStatement")
- };
- pp$1.parseExpressionStatement = function(node, expr) {
- node.expression = expr;
- this.semicolon();
- return this.finishNode(node, "ExpressionStatement")
- };
- // Parse a semicolon-enclosed block of statements, handling `"use
- // strict"` declarations when `allowStrict` is true (used for
- // function bodies).
- pp$1.parseBlock = function(createNewLexicalScope) {
- var this$1 = this;
- if ( createNewLexicalScope === void 0 ) createNewLexicalScope = true;
- var node = this.startNode();
- node.body = [];
- this.expect(types.braceL);
- if (createNewLexicalScope) {
- this.enterLexicalScope();
- }
- while (!this.eat(types.braceR)) {
- var stmt = this$1.parseStatement(true);
- node.body.push(stmt);
- }
- if (createNewLexicalScope) {
- this.exitLexicalScope();
- }
- return this.finishNode(node, "BlockStatement")
- };
- // Parse a regular `for` loop. The disambiguation code in
- // `parseStatement` will already have parsed the init statement or
- // expression.
- pp$1.parseFor = function(node, init) {
- node.init = init;
- this.expect(types.semi);
- node.test = this.type === types.semi ? null : this.parseExpression();
- this.expect(types.semi);
- node.update = this.type === types.parenR ? null : this.parseExpression();
- this.expect(types.parenR);
- this.exitLexicalScope();
- node.body = this.parseStatement(false);
- this.labels.pop();
- return this.finishNode(node, "ForStatement")
- };
- // Parse a `for`/`in` and `for`/`of` loop, which are almost
- // same from parser's perspective.
- pp$1.parseForIn = function(node, init) {
- var type = this.type === types._in ? "ForInStatement" : "ForOfStatement";
- this.next();
- if (type === "ForInStatement") {
- if (init.type === "AssignmentPattern" ||
- (init.type === "VariableDeclaration" && init.declarations[0].init != null &&
- (this.strict || init.declarations[0].id.type !== "Identifier")))
- { this.raise(init.start, "Invalid assignment in for-in loop head"); }
- }
- node.left = init;
- node.right = type === "ForInStatement" ? this.parseExpression() : this.parseMaybeAssign();
- this.expect(types.parenR);
- this.exitLexicalScope();
- node.body = this.parseStatement(false);
- this.labels.pop();
- return this.finishNode(node, type)
- };
- // Parse a list of variable declarations.
- pp$1.parseVar = function(node, isFor, kind) {
- var this$1 = this;
- node.declarations = [];
- node.kind = kind;
- for (;;) {
- var decl = this$1.startNode();
- this$1.parseVarId(decl, kind);
- if (this$1.eat(types.eq)) {
- decl.init = this$1.parseMaybeAssign(isFor);
- } else if (kind === "const" && !(this$1.type === types._in || (this$1.options.ecmaVersion >= 6 && this$1.isContextual("of")))) {
- this$1.unexpected();
- } else if (decl.id.type !== "Identifier" && !(isFor && (this$1.type === types._in || this$1.isContextual("of")))) {
- this$1.raise(this$1.lastTokEnd, "Complex binding patterns require an initialization value");
- } else {
- decl.init = null;
- }
- node.declarations.push(this$1.finishNode(decl, "VariableDeclarator"));
- if (!this$1.eat(types.comma)) { break }
- }
- return node
- };
- pp$1.parseVarId = function(decl, kind) {
- decl.id = this.parseBindingAtom(kind);
- this.checkLVal(decl.id, kind, false);
- };
- // Parse a function declaration or literal (depending on the
- // `isStatement` parameter).
- pp$1.parseFunction = function(node, isStatement, allowExpressionBody, isAsync) {
- this.initFunction(node);
- if (this.options.ecmaVersion >= 9 || this.options.ecmaVersion >= 6 && !isAsync)
- { node.generator = this.eat(types.star); }
- if (this.options.ecmaVersion >= 8)
- { node.async = !!isAsync; }
- if (isStatement) {
- node.id = isStatement === "nullableID" && this.type !== types.name ? null : this.parseIdent();
- if (node.id) {
- this.checkLVal(node.id, this.inModule && !this.inFunction ? "let" : "var");
- }
- }
- var oldInGen = this.inGenerator, oldInAsync = this.inAsync,
- oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldInFunc = this.inFunction;
- this.inGenerator = node.generator;
- this.inAsync = node.async;
- this.yieldPos = 0;
- this.awaitPos = 0;
- this.inFunction = true;
- this.enterFunctionScope();
- if (!isStatement)
- { node.id = this.type === types.name ? this.parseIdent() : null; }
- this.parseFunctionParams(node);
- this.parseFunctionBody(node, allowExpressionBody);
- this.inGenerator = oldInGen;
- this.inAsync = oldInAsync;
- this.yieldPos = oldYieldPos;
- this.awaitPos = oldAwaitPos;
- this.inFunction = oldInFunc;
- return this.finishNode(node, isStatement ? "FunctionDeclaration" : "FunctionExpression")
- };
- pp$1.parseFunctionParams = function(node) {
- this.expect(types.parenL);
- node.params = this.parseBindingList(types.parenR, false, this.options.ecmaVersion >= 8);
- this.checkYieldAwaitInDefaultParams();
- };
- // Parse a class declaration or literal (depending on the
- // `isStatement` parameter).
- pp$1.parseClass = function(node, isStatement) {
- var this$1 = this;
- this.next();
- this.parseClassId(node, isStatement);
- this.parseClassSuper(node);
- var classBody = this.startNode();
- var hadConstructor = false;
- classBody.body = [];
- this.expect(types.braceL);
- while (!this.eat(types.braceR)) {
- var member = this$1.parseClassMember(classBody);
- if (member && member.type === "MethodDefinition" && member.kind === "constructor") {
- if (hadConstructor) { this$1.raise(member.start, "Duplicate constructor in the same class"); }
- hadConstructor = true;
- }
- }
- node.body = this.finishNode(classBody, "ClassBody");
- return this.finishNode(node, isStatement ? "ClassDeclaration" : "ClassExpression")
- };
- pp$1.parseClassMember = function(classBody) {
- var this$1 = this;
- if (this.eat(types.semi)) { return null }
- var method = this.startNode();
- var tryContextual = function (k, noLineBreak) {
- if ( noLineBreak === void 0 ) noLineBreak = false;
- var start = this$1.start, startLoc = this$1.startLoc;
- if (!this$1.eatContextual(k)) { return false }
- if (this$1.type !== types.parenL && (!noLineBreak || !this$1.canInsertSemicolon())) { return true }
- if (method.key) { this$1.unexpected(); }
- method.computed = false;
- method.key = this$1.startNodeAt(start, startLoc);
- method.key.name = k;
- this$1.finishNode(method.key, "Identifier");
- return false
- };
- method.kind = "method";
- method.static = tryContextual("static");
- var isGenerator = this.eat(types.star);
- var isAsync = false;
- if (!isGenerator) {
- if (this.options.ecmaVersion >= 8 && tryContextual("async", true)) {
- isAsync = true;
- isGenerator = this.options.ecmaVersion >= 9 && this.eat(types.star);
- } else if (tryContextual("get")) {
- method.kind = "get";
- } else if (tryContextual("set")) {
- method.kind = "set";
- }
- }
- if (!method.key) { this.parsePropertyName(method); }
- var key = method.key;
- if (!method.computed && !method.static && (key.type === "Identifier" && key.name === "constructor" ||
- key.type === "Literal" && key.value === "constructor")) {
- if (method.kind !== "method") { this.raise(key.start, "Constructor can't have get/set modifier"); }
- if (isGenerator) { this.raise(key.start, "Constructor can't be a generator"); }
- if (isAsync) { this.raise(key.start, "Constructor can't be an async method"); }
- method.kind = "constructor";
- } else if (method.static && key.type === "Identifier" && key.name === "prototype") {
- this.raise(key.start, "Classes may not have a static property named prototype");
- }
- this.parseClassMethod(classBody, method, isGenerator, isAsync);
- if (method.kind === "get" && method.value.params.length !== 0)
- { this.raiseRecoverable(method.value.start, "getter should have no params"); }
- if (method.kind === "set" && method.value.params.length !== 1)
- { this.raiseRecoverable(method.value.start, "setter should have exactly one param"); }
- if (method.kind === "set" && method.value.params[0].type === "RestElement")
- { this.raiseRecoverable(method.value.params[0].start, "Setter cannot use rest params"); }
- return method
- };
- pp$1.parseClassMethod = function(classBody, method, isGenerator, isAsync) {
- method.value = this.parseMethod(isGenerator, isAsync);
- classBody.body.push(this.finishNode(method, "MethodDefinition"));
- };
- pp$1.parseClassId = function(node, isStatement) {
- node.id = this.type === types.name ? this.parseIdent() : isStatement === true ? this.unexpected() : null;
- };
- pp$1.parseClassSuper = function(node) {
- node.superClass = this.eat(types._extends) ? this.parseExprSubscripts() : null;
- };
- // Parses module export declaration.
- pp$1.parseExport = function(node, exports) {
- var this$1 = this;
- this.next();
- // export * from '...'
- if (this.eat(types.star)) {
- this.expectContextual("from");
- if (this.type !== types.string) { this.unexpected(); }
- node.source = this.parseExprAtom();
- this.semicolon();
- return this.finishNode(node, "ExportAllDeclaration")
- }
- if (this.eat(types._default)) { // export default ...
- this.checkExport(exports, "default", this.lastTokStart);
- var isAsync;
- if (this.type === types._function || (isAsync = this.isAsyncFunction())) {
- var fNode = this.startNode();
- this.next();
- if (isAsync) { this.next(); }
- node.declaration = this.parseFunction(fNode, "nullableID", false, isAsync);
- } else if (this.type === types._class) {
- var cNode = this.startNode();
- node.declaration = this.parseClass(cNode, "nullableID");
- } else {
- node.declaration = this.parseMaybeAssign();
- this.semicolon();
- }
- return this.finishNode(node, "ExportDefaultDeclaration")
- }
- // export var|const|let|function|class ...
- if (this.shouldParseExportStatement()) {
- node.declaration = this.parseStatement(true);
- if (node.declaration.type === "VariableDeclaration")
- { this.checkVariableExport(exports, node.declaration.declarations); }
- else
- { this.checkExport(exports, node.declaration.id.name, node.declaration.id.start); }
- node.specifiers = [];
- node.source = null;
- } else { // export { x, y as z } [from '...']
- node.declaration = null;
- node.specifiers = this.parseExportSpecifiers(exports);
- if (this.eatContextual("from")) {
- if (this.type !== types.string) { this.unexpected(); }
- node.source = this.parseExprAtom();
- } else {
- // check for keywords used as local names
- for (var i = 0, list = node.specifiers; i < list.length; i += 1) {
- var spec = list[i];
- this$1.checkUnreserved(spec.local);
- }
- node.source = null;
- }
- this.semicolon();
- }
- return this.finishNode(node, "ExportNamedDeclaration")
- };
- pp$1.checkExport = function(exports, name, pos) {
- if (!exports) { return }
- if (has(exports, name))
- { this.raiseRecoverable(pos, "Duplicate export '" + name + "'"); }
- exports[name] = true;
- };
- pp$1.checkPatternExport = function(exports, pat) {
- var this$1 = this;
- var type = pat.type;
- if (type === "Identifier")
- { this.checkExport(exports, pat.name, pat.start); }
- else if (type === "ObjectPattern")
- { for (var i = 0, list = pat.properties; i < list.length; i += 1)
- {
- var prop = list[i];
- this$1.checkPatternExport(exports, prop);
- } }
- else if (type === "ArrayPattern")
- { for (var i$1 = 0, list$1 = pat.elements; i$1 < list$1.length; i$1 += 1) {
- var elt = list$1[i$1];
- if (elt) { this$1.checkPatternExport(exports, elt); }
- } }
- else if (type === "Property")
- { this.checkPatternExport(exports, pat.value); }
- else if (type === "AssignmentPattern")
- { this.checkPatternExport(exports, pat.left); }
- else if (type === "RestElement")
- { this.checkPatternExport(exports, pat.argument); }
- else if (type === "ParenthesizedExpression")
- { this.checkPatternExport(exports, pat.expression); }
- };
- pp$1.checkVariableExport = function(exports, decls) {
- var this$1 = this;
- if (!exports) { return }
- for (var i = 0, list = decls; i < list.length; i += 1)
- {
- var decl = list[i];
- this$1.checkPatternExport(exports, decl.id);
- }
- };
- pp$1.shouldParseExportStatement = function() {
- return this.type.keyword === "var" ||
- this.type.keyword === "const" ||
- this.type.keyword === "class" ||
- this.type.keyword === "function" ||
- this.isLet() ||
- this.isAsyncFunction()
- };
- // Parses a comma-separated list of module exports.
- pp$1.parseExportSpecifiers = function(exports) {
- var this$1 = this;
- var nodes = [], first = true;
- // export { x, y as z } [from '...']
- this.expect(types.braceL);
- while (!this.eat(types.braceR)) {
- if (!first) {
- this$1.expect(types.comma);
- if (this$1.afterTrailingComma(types.braceR)) { break }
- } else { first = false; }
- var node = this$1.startNode();
- node.local = this$1.parseIdent(true);
- node.exported = this$1.eatContextual("as") ? this$1.parseIdent(true) : node.local;
- this$1.checkExport(exports, node.exported.name, node.exported.start);
- nodes.push(this$1.finishNode(node, "ExportSpecifier"));
- }
- return nodes
- };
- // Parses import declaration.
- pp$1.parseImport = function(node) {
- this.next();
- // import '...'
- if (this.type === types.string) {
- node.specifiers = empty;
- node.source = this.parseExprAtom();
- } else {
- node.specifiers = this.parseImportSpecifiers();
- this.expectContextual("from");
- node.source = this.type === types.string ? this.parseExprAtom() : this.unexpected();
- }
- this.semicolon();
- return this.finishNode(node, "ImportDeclaration")
- };
- // Parses a comma-separated list of module imports.
- pp$1.parseImportSpecifiers = function() {
- var this$1 = this;
- var nodes = [], first = true;
- if (this.type === types.name) {
- // import defaultObj, { x, y as z } from '...'
- var node = this.startNode();
- node.local = this.parseIdent();
- this.checkLVal(node.local, "let");
- nodes.push(this.finishNode(node, "ImportDefaultSpecifier"));
- if (!this.eat(types.comma)) { return nodes }
- }
- if (this.type === types.star) {
- var node$1 = this.startNode();
- this.next();
- this.expectContextual("as");
- node$1.local = this.parseIdent();
- this.checkLVal(node$1.local, "let");
- nodes.push(this.finishNode(node$1, "ImportNamespaceSpecifier"));
- return nodes
- }
- this.expect(types.braceL);
- while (!this.eat(types.braceR)) {
- if (!first) {
- this$1.expect(types.comma);
- if (this$1.afterTrailingComma(types.braceR)) { break }
- } else { first = false; }
- var node$2 = this$1.startNode();
- node$2.imported = this$1.parseIdent(true);
- if (this$1.eatContextual("as")) {
- node$2.local = this$1.parseIdent();
- } else {
- this$1.checkUnreserved(node$2.imported);
- node$2.local = node$2.imported;
- }
- this$1.checkLVal(node$2.local, "let");
- nodes.push(this$1.finishNode(node$2, "ImportSpecifier"));
- }
- return nodes
- };
- // Set `ExpressionStatement#directive` property for directive prologues.
- pp$1.adaptDirectivePrologue = function(statements) {
- for (var i = 0; i < statements.length && this.isDirectiveCandidate(statements[i]); ++i) {
- statements[i].directive = statements[i].expression.raw.slice(1, -1);
- }
- };
- pp$1.isDirectiveCandidate = function(statement) {
- return (
- statement.type === "ExpressionStatement" &&
- statement.expression.type === "Literal" &&
- typeof statement.expression.value === "string" &&
- // Reject parenthesized strings.
- (this.input[statement.start] === "\"" || this.input[statement.start] === "'")
- )
- };
- var pp$2 = Parser.prototype;
- // Convert existing expression atom to assignable pattern
- // if possible.
- pp$2.toAssignable = function(node, isBinding, refDestructuringErrors) {
- var this$1 = this;
- if (this.options.ecmaVersion >= 6 && node) {
- switch (node.type) {
- case "Identifier":
- if (this.inAsync && node.name === "await")
- { this.raise(node.start, "Can not use 'await' as identifier inside an async function"); }
- break
- case "ObjectPattern":
- case "ArrayPattern":
- case "RestElement":
- break
- case "ObjectExpression":
- node.type = "ObjectPattern";
- if (refDestructuringErrors) { this.checkPatternErrors(refDestructuringErrors, true); }
- for (var i = 0, list = node.properties; i < list.length; i += 1) {
- var prop = list[i];
- this$1.toAssignable(prop, isBinding);
- // Early error:
- // AssignmentRestProperty[Yield, Await] :
- // `...` DestructuringAssignmentTarget[Yield, Await]
- //
- // It is a Syntax Error if |DestructuringAssignmentTarget| is an |ArrayLiteral| or an |ObjectLiteral|.
- if (
- prop.type === "RestElement" &&
- (prop.argument.type === "ArrayPattern" || prop.argument.type === "ObjectPattern")
- ) {
- this$1.raise(prop.argument.start, "Unexpected token");
- }
- }
- break
- case "Property":
- // AssignmentProperty has type === "Property"
- if (node.kind !== "init") { this.raise(node.key.start, "Object pattern can't contain getter or setter"); }
- this.toAssignable(node.value, isBinding);
- break
- case "ArrayExpression":
- node.type = "ArrayPattern";
- if (refDestructuringErrors) { this.checkPatternErrors(refDestructuringErrors, true); }
- this.toAssignableList(node.elements, isBinding);
- break
- case "SpreadElement":
- node.type = "RestElement";
- this.toAssignable(node.argument, isBinding);
- if (node.argument.type === "AssignmentPattern")
- { this.raise(node.argument.start, "Rest elements cannot have a default value"); }
- break
- case "AssignmentExpression":
- if (node.operator !== "=") { this.raise(node.left.end, "Only '=' operator can be used for specifying default value."); }
- node.type = "AssignmentPattern";
- delete node.operator;
- this.toAssignable(node.left, isBinding);
- // falls through to AssignmentPattern
- case "AssignmentPattern":
- break
- case "ParenthesizedExpression":
- this.toAssignable(node.expression, isBinding);
- break
- case "MemberExpression":
- if (!isBinding) { break }
- default:
- this.raise(node.start, "Assigning to rvalue");
- }
- } else if (refDestructuringErrors) { this.checkPatternErrors(refDestructuringErrors, true); }
- return node
- };
- // Convert list of expression atoms to binding list.
- pp$2.toAssignableList = function(exprList, isBinding) {
- var this$1 = this;
- var end = exprList.length;
- for (var i = 0; i < end; i++) {
- var elt = exprList[i];
- if (elt) { this$1.toAssignable(elt, isBinding); }
- }
- if (end) {
- var last = exprList[end - 1];
- if (this.options.ecmaVersion === 6 && isBinding && last && last.type === "RestElement" && last.argument.type !== "Identifier")
- { this.unexpected(last.argument.start); }
- }
- return exprList
- };
- // Parses spread element.
- pp$2.parseSpread = function(refDestructuringErrors) {
- var node = this.startNode();
- this.next();
- node.argument = this.parseMaybeAssign(false, refDestructuringErrors);
- return this.finishNode(node, "SpreadElement")
- };
- pp$2.parseRestBinding = function() {
- var node = this.startNode();
- this.next();
- // RestElement inside of a function parameter must be an identifier
- if (this.options.ecmaVersion === 6 && this.type !== types.name)
- { this.unexpected(); }
- node.argument = this.parseBindingAtom();
- return this.finishNode(node, "RestElement")
- };
- // Parses lvalue (assignable) atom.
- pp$2.parseBindingAtom = function() {
- if (this.options.ecmaVersion >= 6) {
- switch (this.type) {
- case types.bracketL:
- var node = this.startNode();
- this.next();
- node.elements = this.parseBindingList(types.bracketR, true, true);
- return this.finishNode(node, "ArrayPattern")
- case types.braceL:
- return this.parseObj(true)
- }
- }
- return this.parseIdent()
- };
- pp$2.parseBindingList = function(close, allowEmpty, allowTrailingComma) {
- var this$1 = this;
- var elts = [], first = true;
- while (!this.eat(close)) {
- if (first) { first = false; }
- else { this$1.expect(types.comma); }
- if (allowEmpty && this$1.type === types.comma) {
- elts.push(null);
- } else if (allowTrailingComma && this$1.afterTrailingComma(close)) {
- break
- } else if (this$1.type === types.ellipsis) {
- var rest = this$1.parseRestBinding();
- this$1.parseBindingListItem(rest);
- elts.push(rest);
- if (this$1.type === types.comma) { this$1.raise(this$1.start, "Comma is not permitted after the rest element"); }
- this$1.expect(close);
- break
- } else {
- var elem = this$1.parseMaybeDefault(this$1.start, this$1.startLoc);
- this$1.parseBindingListItem(elem);
- elts.push(elem);
- }
- }
- return elts
- };
- pp$2.parseBindingListItem = function(param) {
- return param
- };
- // Parses assignment pattern around given atom if possible.
- pp$2.parseMaybeDefault = function(startPos, startLoc, left) {
- left = left || this.parseBindingAtom();
- if (this.options.ecmaVersion < 6 || !this.eat(types.eq)) { return left }
- var node = this.startNodeAt(startPos, startLoc);
- node.left = left;
- node.right = this.parseMaybeAssign();
- return this.finishNode(node, "AssignmentPattern")
- };
- // Verify that a node is an lval — something that can be assigned
- // to.
- // bindingType can be either:
- // 'var' indicating that the lval creates a 'var' binding
- // 'let' indicating that the lval creates a lexical ('let' or 'const') binding
- // 'none' indicating that the binding should be checked for illegal identifiers, but not for duplicate references
- pp$2.checkLVal = function(expr, bindingType, checkClashes) {
- var this$1 = this;
- switch (expr.type) {
- case "Identifier":
- if (this.strict && this.reservedWordsStrictBind.test(expr.name))
- { this.raiseRecoverable(expr.start, (bindingType ? "Binding " : "Assigning to ") + expr.name + " in strict mode"); }
- if (checkClashes) {
- if (has(checkClashes, expr.name))
- { this.raiseRecoverable(expr.start, "Argument name clash"); }
- checkClashes[expr.name] = true;
- }
- if (bindingType && bindingType !== "none") {
- if (
- bindingType === "var" && !this.canDeclareVarName(expr.name) ||
- bindingType !== "var" && !this.canDeclareLexicalName(expr.name)
- ) {
- this.raiseRecoverable(expr.start, ("Identifier '" + (expr.name) + "' has already been declared"));
- }
- if (bindingType === "var") {
- this.declareVarName(expr.name);
- } else {
- this.declareLexicalName(expr.name);
- }
- }
- break
- case "MemberExpression":
- if (bindingType) { this.raiseRecoverable(expr.start, "Binding member expression"); }
- break
- case "ObjectPattern":
- for (var i = 0, list = expr.properties; i < list.length; i += 1)
- {
- var prop = list[i];
- this$1.checkLVal(prop, bindingType, checkClashes);
- }
- break
- case "Property":
- // AssignmentProperty has type === "Property"
- this.checkLVal(expr.value, bindingType, checkClashes);
- break
- case "ArrayPattern":
- for (var i$1 = 0, list$1 = expr.elements; i$1 < list$1.length; i$1 += 1) {
- var elem = list$1[i$1];
- if (elem) { this$1.checkLVal(elem, bindingType, checkClashes); }
- }
- break
- case "AssignmentPattern":
- this.checkLVal(expr.left, bindingType, checkClashes);
- break
- case "RestElement":
- this.checkLVal(expr.argument, bindingType, checkClashes);
- break
- case "ParenthesizedExpression":
- this.checkLVal(expr.expression, bindingType, checkClashes);
- break
- default:
- this.raise(expr.start, (bindingType ? "Binding" : "Assigning to") + " rvalue");
- }
- };
- // A recursive descent parser operates by defining functions for all
- // syntactic elements, and recursively calling those, each function
- // advancing the input stream and returning an AST node. Precedence
- // of constructs (for example, the fact that `!x[1]` means `!(x[1])`
- // instead of `(!x)[1]` is handled by the fact that the parser
- // function that parses unary prefix operators is called first, and
- // in turn calls the function that parses `[]` subscripts — that
- // way, it'll receive the node for `x[1]` already parsed, and wraps
- // *that* in the unary operator node.
- //
- // Acorn uses an [operator precedence parser][opp] to handle binary
- // operator precedence, because it is much more compact than using
- // the technique outlined above, which uses different, nesting
- // functions to specify precedence, for all of the ten binary
- // precedence levels that JavaScript defines.
- //
- // [opp]: http://en.wikipedia.org/wiki/Operator-precedence_parser
- var pp$3 = Parser.prototype;
- // Check if property name clashes with already added.
- // Object/class getters and setters are not allowed to clash —
- // either with each other or with an init property — and in
- // strict mode, init properties are also not allowed to be repeated.
- pp$3.checkPropClash = function(prop, propHash, refDestructuringErrors) {
- if (this.options.ecmaVersion >= 9 && prop.type === "SpreadElement")
- { return }
- if (this.options.ecmaVersion >= 6 && (prop.computed || prop.method || prop.shorthand))
- { return }
- var key = prop.key;
- var name;
- switch (key.type) {
- case "Identifier": name = key.name; break
- case "Literal": name = String(key.value); break
- default: return
- }
- var kind = prop.kind;
- if (this.options.ecmaVersion >= 6) {
- if (name === "__proto__" && kind === "init") {
- if (propHash.proto) {
- if (refDestructuringErrors && refDestructuringErrors.doubleProto < 0) { refDestructuringErrors.doubleProto = key.start; }
- // Backwards-compat kludge. Can be removed in version 6.0
- else { this.raiseRecoverable(key.start, "Redefinition of __proto__ property"); }
- }
- propHash.proto = true;
- }
- return
- }
- name = "$" + name;
- var other = propHash[name];
- if (other) {
- var redefinition;
- if (kind === "init") {
- redefinition = this.strict && other.init || other.get || other.set;
- } else {
- redefinition = other.init || other[kind];
- }
- if (redefinition)
- { this.raiseRecoverable(key.start, "Redefinition of property"); }
- } else {
- other = propHash[name] = {
- init: false,
- get: false,
- set: false
- };
- }
- other[kind] = true;
- };
- // ### Expression parsing
- // These nest, from the most general expression type at the top to
- // 'atomic', nondivisible expression types at the bottom. Most of
- // the functions will simply let the function(s) below them parse,
- // and, *if* the syntactic construct they handle is present, wrap
- // the AST node that the inner parser gave them in another node.
- // Parse a full expression. The optional arguments are used to
- // forbid the `in` operator (in for loops initalization expressions)
- // and provide reference for storing '=' operator inside shorthand
- // property assignment in contexts where both object expression
- // and object pattern might appear (so it's possible to raise
- // delayed syntax error at correct position).
- pp$3.parseExpression = function(noIn, refDestructuringErrors) {
- var this$1 = this;
- var startPos = this.start, startLoc = this.startLoc;
- var expr = this.parseMaybeAssign(noIn, refDestructuringErrors);
- if (this.type === types.comma) {
- var node = this.startNodeAt(startPos, startLoc);
- node.expressions = [expr];
- while (this.eat(types.comma)) { node.expressions.push(this$1.parseMaybeAssign(noIn, refDestructuringErrors)); }
- return this.finishNode(node, "SequenceExpression")
- }
- return expr
- };
- // Parse an assignment expression. This includes applications of
- // operators like `+=`.
- pp$3.parseMaybeAssign = function(noIn, refDestructuringErrors, afterLeftParse) {
- if (this.inGenerator && this.isContextual("yield")) { return this.parseYield() }
- var ownDestructuringErrors = false, oldParenAssign = -1, oldTrailingComma = -1;
- if (refDestructuringErrors) {
- oldParenAssign = refDestructuringErrors.parenthesizedAssign;
- oldTrailingComma = refDestructuringErrors.trailingComma;
- refDestructuringErrors.parenthesizedAssign = refDestructuringErrors.trailingComma = -1;
- } else {
- refDestructuringErrors = new DestructuringErrors;
- ownDestructuringErrors = true;
- }
- var startPos = this.start, startLoc = this.startLoc;
- if (this.type === types.parenL || this.type === types.name)
- { this.potentialArrowAt = this.start; }
- var left = this.parseMaybeConditional(noIn, refDestructuringErrors);
- if (afterLeftParse) { left = afterLeftParse.call(this, left, startPos, startLoc); }
- if (this.type.isAssign) {
- var node = this.startNodeAt(startPos, startLoc);
- node.operator = this.value;
- node.left = this.type === types.eq ? this.toAssignable(left, false, refDestructuringErrors) : left;
- if (!ownDestructuringErrors) { DestructuringErrors.call(refDestructuringErrors); }
- refDestructuringErrors.shorthandAssign = -1; // reset because shorthand default was used correctly
- this.checkLVal(left);
- this.next();
- node.right = this.parseMaybeAssign(noIn);
- return this.finishNode(node, "AssignmentExpression")
- } else {
- if (ownDestructuringErrors) { this.checkExpressionErrors(refDestructuringErrors, true); }
- }
- if (oldParenAssign > -1) { refDestructuringErrors.parenthesizedAssign = oldParenAssign; }
- if (oldTrailingComma > -1) { refDestructuringErrors.trailingComma = oldTrailingComma; }
- return left
- };
- // Parse a ternary conditional (`?:`) operator.
- pp$3.parseMaybeConditional = function(noIn, refDestructuringErrors) {
- var startPos = this.start, startLoc = this.startLoc;
- var expr = this.parseExprOps(noIn, refDestructuringErrors);
- if (this.checkExpressionErrors(refDestructuringErrors)) { return expr }
- if (this.eat(types.question)) {
- var node = this.startNodeAt(startPos, startLoc);
- node.test = expr;
- node.consequent = this.parseMaybeAssign();
- this.expect(types.colon);
- node.alternate = this.parseMaybeAssign(noIn);
- return this.finishNode(node, "ConditionalExpression")
- }
- return expr
- };
- // Start the precedence parser.
- pp$3.parseExprOps = function(noIn, refDestructuringErrors) {
- var startPos = this.start, startLoc = this.startLoc;
- var expr = this.parseMaybeUnary(refDestructuringErrors, false);
- if (this.checkExpressionErrors(refDestructuringErrors)) { return expr }
- return expr.start === startPos && expr.type === "ArrowFunctionExpression" ? expr : this.parseExprOp(expr, startPos, startLoc, -1, noIn)
- };
- // Parse binary operators with the operator precedence parsing
- // algorithm. `left` is the left-hand side of the operator.
- // `minPrec` provides context that allows the function to stop and
- // defer further parser to one of its callers when it encounters an
- // operator that has a lower precedence than the set it is parsing.
- pp$3.parseExprOp = function(left, leftStartPos, leftStartLoc, minPrec, noIn) {
- var prec = this.type.binop;
- if (prec != null && (!noIn || this.type !== types._in)) {
- if (prec > minPrec) {
- var logical = this.type === types.logicalOR || this.type === types.logicalAND;
- var op = this.value;
- this.next();
- var startPos = this.start, startLoc = this.startLoc;
- var right = this.parseExprOp(this.parseMaybeUnary(null, false), startPos, startLoc, prec, noIn);
- var node = this.buildBinary(leftStartPos, leftStartLoc, left, right, op, logical);
- return this.parseExprOp(node, leftStartPos, leftStartLoc, minPrec, noIn)
- }
- }
- return left
- };
- pp$3.buildBinary = function(startPos, startLoc, left, right, op, logical) {
- var node = this.startNodeAt(startPos, startLoc);
- node.left = left;
- node.operator = op;
- node.right = right;
- return this.finishNode(node, logical ? "LogicalExpression" : "BinaryExpression")
- };
- // Parse unary operators, both prefix and postfix.
- pp$3.parseMaybeUnary = function(refDestructuringErrors, sawUnary) {
- var this$1 = this;
- var startPos = this.start, startLoc = this.startLoc, expr;
- if (this.isContextual("await") && (this.inAsync || (!this.inFunction && this.options.allowAwaitOutsideFunction))) {
- expr = this.parseAwait();
- sawUnary = true;
- } else if (this.type.prefix) {
- var node = this.startNode(), update = this.type === types.incDec;
- node.operator = this.value;
- node.prefix = true;
- this.next();
- node.argument = this.parseMaybeUnary(null, true);
- this.checkExpressionErrors(refDestructuringErrors, true);
- if (update) { this.checkLVal(node.argument); }
- else if (this.strict && node.operator === "delete" &&
- node.argument.type === "Identifier")
- { this.raiseRecoverable(node.start, "Deleting local variable in strict mode"); }
- else { sawUnary = true; }
- expr = this.finishNode(node, update ? "UpdateExpression" : "UnaryExpression");
- } else {
- expr = this.parseExprSubscripts(refDestructuringErrors);
- if (this.checkExpressionErrors(refDestructuringErrors)) { return expr }
- while (this.type.postfix && !this.canInsertSemicolon()) {
- var node$1 = this$1.startNodeAt(startPos, startLoc);
- node$1.operator = this$1.value;
- node$1.prefix = false;
- node$1.argument = expr;
- this$1.checkLVal(expr);
- this$1.next();
- expr = this$1.finishNode(node$1, "UpdateExpression");
- }
- }
- if (!sawUnary && this.eat(types.starstar))
- { return this.buildBinary(startPos, startLoc, expr, this.parseMaybeUnary(null, false), "**", false) }
- else
- { return expr }
- };
- // Parse call, dot, and `[]`-subscript expressions.
- pp$3.parseExprSubscripts = function(refDestructuringErrors) {
- var startPos = this.start, startLoc = this.startLoc;
- var expr = this.parseExprAtom(refDestructuringErrors);
- var skipArrowSubscripts = expr.type === "ArrowFunctionExpression" && this.input.slice(this.lastTokStart, this.lastTokEnd) !== ")";
- if (this.checkExpressionErrors(refDestructuringErrors) || skipArrowSubscripts) { return expr }
- var result = this.parseSubscripts(expr, startPos, startLoc);
- if (refDestructuringErrors && result.type === "MemberExpression") {
- if (refDestructuringErrors.parenthesizedAssign >= result.start) { refDestructuringErrors.parenthesizedAssign = -1; }
- if (refDestructuringErrors.parenthesizedBind >= result.start) { refDestructuringErrors.parenthesizedBind = -1; }
- }
- return result
- };
- pp$3.parseSubscripts = function(base, startPos, startLoc, noCalls) {
- var this$1 = this;
- var maybeAsyncArrow = this.options.ecmaVersion >= 8 && base.type === "Identifier" && base.name === "async" &&
- this.lastTokEnd === base.end && !this.canInsertSemicolon() && this.input.slice(base.start, base.end) === "async";
- for (var computed = (void 0);;) {
- if ((computed = this$1.eat(types.bracketL)) || this$1.eat(types.dot)) {
- var node = this$1.startNodeAt(startPos, startLoc);
- node.object = base;
- node.property = computed ? this$1.parseExpression() : this$1.parseIdent(true);
- node.computed = !!computed;
- if (computed) { this$1.expect(types.bracketR); }
- base = this$1.finishNode(node, "MemberExpression");
- } else if (!noCalls && this$1.eat(types.parenL)) {
- var refDestructuringErrors = new DestructuringErrors, oldYieldPos = this$1.yieldPos, oldAwaitPos = this$1.awaitPos;
- this$1.yieldPos = 0;
- this$1.awaitPos = 0;
- var exprList = this$1.parseExprList(types.parenR, this$1.options.ecmaVersion >= 8, false, refDestructuringErrors);
- if (maybeAsyncArrow && !this$1.canInsertSemicolon() && this$1.eat(types.arrow)) {
- this$1.checkPatternErrors(refDestructuringErrors, false);
- this$1.checkYieldAwaitInDefaultParams();
- this$1.yieldPos = oldYieldPos;
- this$1.awaitPos = oldAwaitPos;
- return this$1.parseArrowExpression(this$1.startNodeAt(startPos, startLoc), exprList, true)
- }
- this$1.checkExpressionErrors(refDestructuringErrors, true);
- this$1.yieldPos = oldYieldPos || this$1.yieldPos;
- this$1.awaitPos = oldAwaitPos || this$1.awaitPos;
- var node$1 = this$1.startNodeAt(startPos, startLoc);
- node$1.callee = base;
- node$1.arguments = exprList;
- base = this$1.finishNode(node$1, "CallExpression");
- } else if (this$1.type === types.backQuote) {
- var node$2 = this$1.startNodeAt(startPos, startLoc);
- node$2.tag = base;
- node$2.quasi = this$1.parseTemplate({isTagged: true});
- base = this$1.finishNode(node$2, "TaggedTemplateExpression");
- } else {
- return base
- }
- }
- };
- // Parse an atomic expression — either a single token that is an
- // expression, an expression started by a keyword like `function` or
- // `new`, or an expression wrapped in punctuation like `()`, `[]`,
- // or `{}`.
- pp$3.parseExprAtom = function(refDestructuringErrors) {
- var node, canBeArrow = this.potentialArrowAt === this.start;
- switch (this.type) {
- case types._super:
- if (!this.inFunction)
- { this.raise(this.start, "'super' outside of function or class"); }
- node = this.startNode();
- this.next();
- // The `super` keyword can appear at below:
- // SuperProperty:
- // super [ Expression ]
- // super . IdentifierName
- // SuperCall:
- // super Arguments
- if (this.type !== types.dot && this.type !== types.bracketL && this.type !== types.parenL)
- { this.unexpected(); }
- return this.finishNode(node, "Super")
- case types._this:
- node = this.startNode();
- this.next();
- return this.finishNode(node, "ThisExpression")
- case types.name:
- var startPos = this.start, startLoc = this.startLoc, containsEsc = this.containsEsc;
- var id = this.parseIdent(this.type !== types.name);
- if (this.options.ecmaVersion >= 8 && !containsEsc && id.name === "async" && !this.canInsertSemicolon() && this.eat(types._function))
- { return this.parseFunction(this.startNodeAt(startPos, startLoc), false, false, true) }
- if (canBeArrow && !this.canInsertSemicolon()) {
- if (this.eat(types.arrow))
- { return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), [id], false) }
- if (this.options.ecmaVersion >= 8 && id.name === "async" && this.type === types.name && !containsEsc) {
- id = this.parseIdent();
- if (this.canInsertSemicolon() || !this.eat(types.arrow))
- { this.unexpected(); }
- return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), [id], true)
- }
- }
- return id
- case types.regexp:
- var value = this.value;
- node = this.parseLiteral(value.value);
- node.regex = {pattern: value.pattern, flags: value.flags};
- return node
- case types.num: case types.string:
- return this.parseLiteral(this.value)
- case types._null: case types._true: case types._false:
- node = this.startNode();
- node.value = this.type === types._null ? null : this.type === types._true;
- node.raw = this.type.keyword;
- this.next();
- return this.finishNode(node, "Literal")
- case types.parenL:
- var start = this.start, expr = this.parseParenAndDistinguishExpression(canBeArrow);
- if (refDestructuringErrors) {
- if (refDestructuringErrors.parenthesizedAssign < 0 && !this.isSimpleAssignTarget(expr))
- { refDestructuringErrors.parenthesizedAssign = start; }
- if (refDestructuringErrors.parenthesizedBind < 0)
- { refDestructuringErrors.parenthesizedBind = start; }
- }
- return expr
- case types.bracketL:
- node = this.startNode();
- this.next();
- node.elements = this.parseExprList(types.bracketR, true, true, refDestructuringErrors);
- return this.finishNode(node, "ArrayExpression")
- case types.braceL:
- return this.parseObj(false, refDestructuringErrors)
- case types._function:
- node = this.startNode();
- this.next();
- return this.parseFunction(node, false)
- case types._class:
- return this.parseClass(this.startNode(), false)
- case types._new:
- return this.parseNew()
- case types.backQuote:
- return this.parseTemplate()
- default:
- this.unexpected();
- }
- };
- pp$3.parseLiteral = function(value) {
- var node = this.startNode();
- node.value = value;
- node.raw = this.input.slice(this.start, this.end);
- this.next();
- return this.finishNode(node, "Literal")
- };
- pp$3.parseParenExpression = function() {
- this.expect(types.parenL);
- var val = this.parseExpression();
- this.expect(types.parenR);
- return val
- };
- pp$3.parseParenAndDistinguishExpression = function(canBeArrow) {
- var this$1 = this;
- var startPos = this.start, startLoc = this.startLoc, val, allowTrailingComma = this.options.ecmaVersion >= 8;
- if (this.options.ecmaVersion >= 6) {
- this.next();
- var innerStartPos = this.start, innerStartLoc = this.startLoc;
- var exprList = [], first = true, lastIsComma = false;
- var refDestructuringErrors = new DestructuringErrors, oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, spreadStart;
- this.yieldPos = 0;
- this.awaitPos = 0;
- while (this.type !== types.parenR) {
- first ? first = false : this$1.expect(types.comma);
- if (allowTrailingComma && this$1.afterTrailingComma(types.parenR, true)) {
- lastIsComma = true;
- break
- } else if (this$1.type === types.ellipsis) {
- spreadStart = this$1.start;
- exprList.push(this$1.parseParenItem(this$1.parseRestBinding()));
- if (this$1.type === types.comma) { this$1.raise(this$1.start, "Comma is not permitted after the rest element"); }
- break
- } else {
- exprList.push(this$1.parseMaybeAssign(false, refDestructuringErrors, this$1.parseParenItem));
- }
- }
- var innerEndPos = this.start, innerEndLoc = this.startLoc;
- this.expect(types.parenR);
- if (canBeArrow && !this.canInsertSemicolon() && this.eat(types.arrow)) {
- this.checkPatternErrors(refDestructuringErrors, false);
- this.checkYieldAwaitInDefaultParams();
- this.yieldPos = oldYieldPos;
- this.awaitPos = oldAwaitPos;
- return this.parseParenArrowList(startPos, startLoc, exprList)
- }
- if (!exprList.length || lastIsComma) { this.unexpected(this.lastTokStart); }
- if (spreadStart) { this.unexpected(spreadStart); }
- this.checkExpressionErrors(refDestructuringErrors, true);
- this.yieldPos = oldYieldPos || this.yieldPos;
- this.awaitPos = oldAwaitPos || this.awaitPos;
- if (exprList.length > 1) {
- val = this.startNodeAt(innerStartPos, innerStartLoc);
- val.expressions = exprList;
- this.finishNodeAt(val, "SequenceExpression", innerEndPos, innerEndLoc);
- } else {
- val = exprList[0];
- }
- } else {
- val = this.parseParenExpression();
- }
- if (this.options.preserveParens) {
- var par = this.startNodeAt(startPos, startLoc);
- par.expression = val;
- return this.finishNode(par, "ParenthesizedExpression")
- } else {
- return val
- }
- };
- pp$3.parseParenItem = function(item) {
- return item
- };
- pp$3.parseParenArrowList = function(startPos, startLoc, exprList) {
- return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), exprList)
- };
- // New's precedence is slightly tricky. It must allow its argument to
- // be a `[]` or dot subscript expression, but not a call — at least,
- // not without wrapping it in parentheses. Thus, it uses the noCalls
- // argument to parseSubscripts to prevent it from consuming the
- // argument list.
- var empty$1 = [];
- pp$3.parseNew = function() {
- var node = this.startNode();
- var meta = this.parseIdent(true);
- if (this.options.ecmaVersion >= 6 && this.eat(types.dot)) {
- node.meta = meta;
- var containsEsc = this.containsEsc;
- node.property = this.parseIdent(true);
- if (node.property.name !== "target" || containsEsc)
- { this.raiseRecoverable(node.property.start, "The only valid meta property for new is new.target"); }
- if (!this.inFunction)
- { this.raiseRecoverable(node.start, "new.target can only be used in functions"); }
- return this.finishNode(node, "MetaProperty")
- }
- var startPos = this.start, startLoc = this.startLoc;
- node.callee = this.parseSubscripts(this.parseExprAtom(), startPos, startLoc, true);
- if (this.eat(types.parenL)) { node.arguments = this.parseExprList(types.parenR, this.options.ecmaVersion >= 8, false); }
- else { node.arguments = empty$1; }
- return this.finishNode(node, "NewExpression")
- };
- // Parse template expression.
- pp$3.parseTemplateElement = function(ref) {
- var isTagged = ref.isTagged;
- var elem = this.startNode();
- if (this.type === types.invalidTemplate) {
- if (!isTagged) {
- this.raiseRecoverable(this.start, "Bad escape sequence in untagged template literal");
- }
- elem.value = {
- raw: this.value,
- cooked: null
- };
- } else {
- elem.value = {
- raw: this.input.slice(this.start, this.end).replace(/\r\n?/g, "\n"),
- cooked: this.value
- };
- }
- this.next();
- elem.tail = this.type === types.backQuote;
- return this.finishNode(elem, "TemplateElement")
- };
- pp$3.parseTemplate = function(ref) {
- var this$1 = this;
- if ( ref === void 0 ) ref = {};
- var isTagged = ref.isTagged; if ( isTagged === void 0 ) isTagged = false;
- var node = this.startNode();
- this.next();
- node.expressions = [];
- var curElt = this.parseTemplateElement({isTagged: isTagged});
- node.quasis = [curElt];
- while (!curElt.tail) {
- if (this$1.type === types.eof) { this$1.raise(this$1.pos, "Unterminated template literal"); }
- this$1.expect(types.dollarBraceL);
- node.expressions.push(this$1.parseExpression());
- this$1.expect(types.braceR);
- node.quasis.push(curElt = this$1.parseTemplateElement({isTagged: isTagged}));
- }
- this.next();
- return this.finishNode(node, "TemplateLiteral")
- };
- pp$3.isAsyncProp = function(prop) {
- return !prop.computed && prop.key.type === "Identifier" && prop.key.name === "async" &&
- (this.type === types.name || this.type === types.num || this.type === types.string || this.type === types.bracketL || this.type.keyword || (this.options.ecmaVersion >= 9 && this.type === types.star)) &&
- !lineBreak.test(this.input.slice(this.lastTokEnd, this.start))
- };
- // Parse an object literal or binding pattern.
- pp$3.parseObj = function(isPattern, refDestructuringErrors) {
- var this$1 = this;
- var node = this.startNode(), first = true, propHash = {};
- node.properties = [];
- this.next();
- while (!this.eat(types.braceR)) {
- if (!first) {
- this$1.expect(types.comma);
- if (this$1.afterTrailingComma(types.braceR)) { break }
- } else { first = false; }
- var prop = this$1.parseProperty(isPattern, refDestructuringErrors);
- if (!isPattern) { this$1.checkPropClash(prop, propHash, refDestructuringErrors); }
- node.properties.push(prop);
- }
- return this.finishNode(node, isPattern ? "ObjectPattern" : "ObjectExpression")
- };
- pp$3.parseProperty = function(isPattern, refDestructuringErrors) {
- var prop = this.startNode(), isGenerator, isAsync, startPos, startLoc;
- if (this.options.ecmaVersion >= 9 && this.eat(types.ellipsis)) {
- if (isPattern) {
- prop.argument = this.parseIdent(false);
- if (this.type === types.comma) {
- this.raise(this.start, "Comma is not permitted after the rest element");
- }
- return this.finishNode(prop, "RestElement")
- }
- // To disallow parenthesized identifier via `this.toAssignable()`.
- if (this.type === types.parenL && refDestructuringErrors) {
- if (refDestructuringErrors.parenthesizedAssign < 0) {
- refDestructuringErrors.parenthesizedAssign = this.start;
- }
- if (refDestructuringErrors.parenthesizedBind < 0) {
- refDestructuringErrors.parenthesizedBind = this.start;
- }
- }
- // Parse argument.
- prop.argument = this.parseMaybeAssign(false, refDestructuringErrors);
- // To disallow trailing comma via `this.toAssignable()`.
- if (this.type === types.comma && refDestructuringErrors && refDestructuringErrors.trailingComma < 0) {
- refDestructuringErrors.trailingComma = this.start;
- }
- // Finish
- return this.finishNode(prop, "SpreadElement")
- }
- if (this.options.ecmaVersion >= 6) {
- prop.method = false;
- prop.shorthand = false;
- if (isPattern || refDestructuringErrors) {
- startPos = this.start;
- startLoc = this.startLoc;
- }
- if (!isPattern)
- { isGenerator = this.eat(types.star); }
- }
- var containsEsc = this.containsEsc;
- this.parsePropertyName(prop);
- if (!isPattern && !containsEsc && this.options.ecmaVersion >= 8 && !isGenerator && this.isAsyncProp(prop)) {
- isAsync = true;
- isGenerator = this.options.ecmaVersion >= 9 && this.eat(types.star);
- this.parsePropertyName(prop, refDestructuringErrors);
- } else {
- isAsync = false;
- }
- this.parsePropertyValue(prop, isPattern, isGenerator, isAsync, startPos, startLoc, refDestructuringErrors, containsEsc);
- return this.finishNode(prop, "Property")
- };
- pp$3.parsePropertyValue = function(prop, isPattern, isGenerator, isAsync, startPos, startLoc, refDestructuringErrors, containsEsc) {
- if ((isGenerator || isAsync) && this.type === types.colon)
- { this.unexpected(); }
- if (this.eat(types.colon)) {
- prop.value = isPattern ? this.parseMaybeDefault(this.start, this.startLoc) : this.parseMaybeAssign(false, refDestructuringErrors);
- prop.kind = "init";
- } else if (this.options.ecmaVersion >= 6 && this.type === types.parenL) {
- if (isPattern) { this.unexpected(); }
- prop.kind = "init";
- prop.method = true;
- prop.value = this.parseMethod(isGenerator, isAsync);
- } else if (!isPattern && !containsEsc &&
- this.options.ecmaVersion >= 5 && !prop.computed && prop.key.type === "Identifier" &&
- (prop.key.name === "get" || prop.key.name === "set") &&
- (this.type !== types.comma && this.type !== types.braceR)) {
- if (isGenerator || isAsync) { this.unexpected(); }
- prop.kind = prop.key.name;
- this.parsePropertyName(prop);
- prop.value = this.parseMethod(false);
- var paramCount = prop.kind === "get" ? 0 : 1;
- if (prop.value.params.length !== paramCount) {
- var start = prop.value.start;
- if (prop.kind === "get")
- { this.raiseRecoverable(start, "getter should have no params"); }
- else
- { this.raiseRecoverable(start, "setter should have exactly one param"); }
- } else {
- if (prop.kind === "set" && prop.value.params[0].type === "RestElement")
- { this.raiseRecoverable(prop.value.params[0].start, "Setter cannot use rest params"); }
- }
- } else if (this.options.ecmaVersion >= 6 && !prop.computed && prop.key.type === "Identifier") {
- this.checkUnreserved(prop.key);
- prop.kind = "init";
- if (isPattern) {
- prop.value = this.parseMaybeDefault(startPos, startLoc, prop.key);
- } else if (this.type === types.eq && refDestructuringErrors) {
- if (refDestructuringErrors.shorthandAssign < 0)
- { refDestructuringErrors.shorthandAssign = this.start; }
- prop.value = this.parseMaybeDefault(startPos, startLoc, prop.key);
- } else {
- prop.value = prop.key;
- }
- prop.shorthand = true;
- } else { this.unexpected(); }
- };
- pp$3.parsePropertyName = function(prop) {
- if (this.options.ecmaVersion >= 6) {
- if (this.eat(types.bracketL)) {
- prop.computed = true;
- prop.key = this.parseMaybeAssign();
- this.expect(types.bracketR);
- return prop.key
- } else {
- prop.computed = false;
- }
- }
- return prop.key = this.type === types.num || this.type === types.string ? this.parseExprAtom() : this.parseIdent(true)
- };
- // Initialize empty function node.
- pp$3.initFunction = function(node) {
- node.id = null;
- if (this.options.ecmaVersion >= 6) {
- node.generator = false;
- node.expression = false;
- }
- if (this.options.ecmaVersion >= 8)
- { node.async = false; }
- };
- // Parse object or class method.
- pp$3.parseMethod = function(isGenerator, isAsync) {
- var node = this.startNode(), oldInGen = this.inGenerator, oldInAsync = this.inAsync,
- oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldInFunc = this.inFunction;
- this.initFunction(node);
- if (this.options.ecmaVersion >= 6)
- { node.generator = isGenerator; }
- if (this.options.ecmaVersion >= 8)
- { node.async = !!isAsync; }
- this.inGenerator = node.generator;
- this.inAsync = node.async;
- this.yieldPos = 0;
- this.awaitPos = 0;
- this.inFunction = true;
- this.enterFunctionScope();
- this.expect(types.parenL);
- node.params = this.parseBindingList(types.parenR, false, this.options.ecmaVersion >= 8);
- this.checkYieldAwaitInDefaultParams();
- this.parseFunctionBody(node, false);
- this.inGenerator = oldInGen;
- this.inAsync = oldInAsync;
- this.yieldPos = oldYieldPos;
- this.awaitPos = oldAwaitPos;
- this.inFunction = oldInFunc;
- return this.finishNode(node, "FunctionExpression")
- };
- // Parse arrow function expression with given parameters.
- pp$3.parseArrowExpression = function(node, params, isAsync) {
- var oldInGen = this.inGenerator, oldInAsync = this.inAsync,
- oldYieldPos = this.yieldPos, oldAwaitPos = this.awaitPos, oldInFunc = this.inFunction;
- this.enterFunctionScope();
- this.initFunction(node);
- if (this.options.ecmaVersion >= 8)
- { node.async = !!isAsync; }
- this.inGenerator = false;
- this.inAsync = node.async;
- this.yieldPos = 0;
- this.awaitPos = 0;
- this.inFunction = true;
- node.params = this.toAssignableList(params, true);
- this.parseFunctionBody(node, true);
- this.inGenerator = oldInGen;
- this.inAsync = oldInAsync;
- this.yieldPos = oldYieldPos;
- this.awaitPos = oldAwaitPos;
- this.inFunction = oldInFunc;
- return this.finishNode(node, "ArrowFunctionExpression")
- };
- // Parse function body and check parameters.
- pp$3.parseFunctionBody = function(node, isArrowFunction) {
- var isExpression = isArrowFunction && this.type !== types.braceL;
- var oldStrict = this.strict, useStrict = false;
- if (isExpression) {
- node.body = this.parseMaybeAssign();
- node.expression = true;
- this.checkParams(node, false);
- } else {
- var nonSimple = this.options.ecmaVersion >= 7 && !this.isSimpleParamList(node.params);
- if (!oldStrict || nonSimple) {
- useStrict = this.strictDirective(this.end);
- // If this is a strict mode function, verify that argument names
- // are not repeated, and it does not try to bind the words `eval`
- // or `arguments`.
- if (useStrict && nonSimple)
- { this.raiseRecoverable(node.start, "Illegal 'use strict' directive in function with non-simple parameter list"); }
- }
- // Start a new scope with regard to labels and the `inFunction`
- // flag (restore them to their old value afterwards).
- var oldLabels = this.labels;
- this.labels = [];
- if (useStrict) { this.strict = true; }
- // Add the params to varDeclaredNames to ensure that an error is thrown
- // if a let/const declaration in the function clashes with one of the params.
- this.checkParams(node, !oldStrict && !useStrict && !isArrowFunction && this.isSimpleParamList(node.params));
- node.body = this.parseBlock(false);
- node.expression = false;
- this.adaptDirectivePrologue(node.body.body);
- this.labels = oldLabels;
- }
- this.exitFunctionScope();
- if (this.strict && node.id) {
- // Ensure the function name isn't a forbidden identifier in strict mode, e.g. 'eval'
- this.checkLVal(node.id, "none");
- }
- this.strict = oldStrict;
- };
- pp$3.isSimpleParamList = function(params) {
- for (var i = 0, list = params; i < list.length; i += 1)
- {
- var param = list[i];
- if (param.type !== "Identifier") { return false
- } }
- return true
- };
- // Checks function params for various disallowed patterns such as using "eval"
- // or "arguments" and duplicate parameters.
- pp$3.checkParams = function(node, allowDuplicates) {
- var this$1 = this;
- var nameHash = {};
- for (var i = 0, list = node.params; i < list.length; i += 1)
- {
- var param = list[i];
- this$1.checkLVal(param, "var", allowDuplicates ? null : nameHash);
- }
- };
- // Parses a comma-separated list of expressions, and returns them as
- // an array. `close` is the token type that ends the list, and
- // `allowEmpty` can be turned on to allow subsequent commas with
- // nothing in between them to be parsed as `null` (which is needed
- // for array literals).
- pp$3.parseExprList = function(close, allowTrailingComma, allowEmpty, refDestructuringErrors) {
- var this$1 = this;
- var elts = [], first = true;
- while (!this.eat(close)) {
- if (!first) {
- this$1.expect(types.comma);
- if (allowTrailingComma && this$1.afterTrailingComma(close)) { break }
- } else { first = false; }
- var elt = (void 0);
- if (allowEmpty && this$1.type === types.comma)
- { elt = null; }
- else if (this$1.type === types.ellipsis) {
- elt = this$1.parseSpread(refDestructuringErrors);
- if (refDestructuringErrors && this$1.type === types.comma && refDestructuringErrors.trailingComma < 0)
- { refDestructuringErrors.trailingComma = this$1.start; }
- } else {
- elt = this$1.parseMaybeAssign(false, refDestructuringErrors);
- }
- elts.push(elt);
- }
- return elts
- };
- pp$3.checkUnreserved = function(ref) {
- var start = ref.start;
- var end = ref.end;
- var name = ref.name;
- if (this.inGenerator && name === "yield")
- { this.raiseRecoverable(start, "Can not use 'yield' as identifier inside a generator"); }
- if (this.inAsync && name === "await")
- { this.raiseRecoverable(start, "Can not use 'await' as identifier inside an async function"); }
- if (this.isKeyword(name))
- { this.raise(start, ("Unexpected keyword '" + name + "'")); }
- if (this.options.ecmaVersion < 6 &&
- this.input.slice(start, end).indexOf("\\") !== -1) { return }
- var re = this.strict ? this.reservedWordsStrict : this.reservedWords;
- if (re.test(name)) {
- if (!this.inAsync && name === "await")
- { this.raiseRecoverable(start, "Can not use keyword 'await' outside an async function"); }
- this.raiseRecoverable(start, ("The keyword '" + name + "' is reserved"));
- }
- };
- // Parse the next token as an identifier. If `liberal` is true (used
- // when parsing properties), it will also convert keywords into
- // identifiers.
- pp$3.parseIdent = function(liberal, isBinding) {
- var node = this.startNode();
- if (liberal && this.options.allowReserved === "never") { liberal = false; }
- if (this.type === types.name) {
- node.name = this.value;
- } else if (this.type.keyword) {
- node.name = this.type.keyword;
- // To fix https://github.com/acornjs/acorn/issues/575
- // `class` and `function` keywords push new context into this.context.
- // But there is no chance to pop the context if the keyword is consumed as an identifier such as a property name.
- // If the previous token is a dot, this does not apply because the context-managing code already ignored the keyword
- if ((node.name === "class" || node.name === "function") &&
- (this.lastTokEnd !== this.lastTokStart + 1 || this.input.charCodeAt(this.lastTokStart) !== 46)) {
- this.context.pop();
- }
- } else {
- this.unexpected();
- }
- this.next();
- this.finishNode(node, "Identifier");
- if (!liberal) { this.checkUnreserved(node); }
- return node
- };
- // Parses yield expression inside generator.
- pp$3.parseYield = function() {
- if (!this.yieldPos) { this.yieldPos = this.start; }
- var node = this.startNode();
- this.next();
- if (this.type === types.semi || this.canInsertSemicolon() || (this.type !== types.star && !this.type.startsExpr)) {
- node.delegate = false;
- node.argument = null;
- } else {
- node.delegate = this.eat(types.star);
- node.argument = this.parseMaybeAssign();
- }
- return this.finishNode(node, "YieldExpression")
- };
- pp$3.parseAwait = function() {
- if (!this.awaitPos) { this.awaitPos = this.start; }
- var node = this.startNode();
- this.next();
- node.argument = this.parseMaybeUnary(null, true);
- return this.finishNode(node, "AwaitExpression")
- };
- var pp$4 = Parser.prototype;
- // This function is used to raise exceptions on parse errors. It
- // takes an offset integer (into the current `input`) to indicate
- // the location of the error, attaches the position to the end
- // of the error message, and then raises a `SyntaxError` with that
- // message.
- pp$4.raise = function(pos, message) {
- var loc = getLineInfo(this.input, pos);
- message += " (" + loc.line + ":" + loc.column + ")";
- var err = new SyntaxError(message);
- err.pos = pos; err.loc = loc; err.raisedAt = this.pos;
- throw err
- };
- pp$4.raiseRecoverable = pp$4.raise;
- pp$4.curPosition = function() {
- if (this.options.locations) {
- return new Position(this.curLine, this.pos - this.lineStart)
- }
- };
- var pp$5 = Parser.prototype;
- // Object.assign polyfill
- var assign$1 = Object.assign || function(target) {
- var sources = [], len = arguments.length - 1;
- while ( len-- > 0 ) sources[ len ] = arguments[ len + 1 ];
- for (var i = 0, list = sources; i < list.length; i += 1) {
- var source = list[i];
- for (var key in source) {
- if (has(source, key)) {
- target[key] = source[key];
- }
- }
- }
- return target
- };
- // The functions in this module keep track of declared variables in the current scope in order to detect duplicate variable names.
- pp$5.enterFunctionScope = function() {
- // var: a hash of var-declared names in the current lexical scope
- // lexical: a hash of lexically-declared names in the current lexical scope
- // childVar: a hash of var-declared names in all child lexical scopes of the current lexical scope (within the current function scope)
- // parentLexical: a hash of lexically-declared names in all parent lexical scopes of the current lexical scope (within the current function scope)
- this.scopeStack.push({var: {}, lexical: {}, childVar: {}, parentLexical: {}});
- };
- pp$5.exitFunctionScope = function() {
- this.scopeStack.pop();
- };
- pp$5.enterLexicalScope = function() {
- var parentScope = this.scopeStack[this.scopeStack.length - 1];
- var childScope = {var: {}, lexical: {}, childVar: {}, parentLexical: {}};
- this.scopeStack.push(childScope);
- assign$1(childScope.parentLexical, parentScope.lexical, parentScope.parentLexical);
- };
- pp$5.exitLexicalScope = function() {
- var childScope = this.scopeStack.pop();
- var parentScope = this.scopeStack[this.scopeStack.length - 1];
- assign$1(parentScope.childVar, childScope.var, childScope.childVar);
- };
- /**
- * A name can be declared with `var` if there are no variables with the same name declared with `let`/`const`
- * in the current lexical scope or any of the parent lexical scopes in this function.
- */
- pp$5.canDeclareVarName = function(name) {
- var currentScope = this.scopeStack[this.scopeStack.length - 1];
- return !has(currentScope.lexical, name) && !has(currentScope.parentLexical, name)
- };
- /**
- * A name can be declared with `let`/`const` if there are no variables with the same name declared with `let`/`const`
- * in the current scope, and there are no variables with the same name declared with `var` in the current scope or in
- * any child lexical scopes in this function.
- */
- pp$5.canDeclareLexicalName = function(name) {
- var currentScope = this.scopeStack[this.scopeStack.length - 1];
- return !has(currentScope.lexical, name) && !has(currentScope.var, name) && !has(currentScope.childVar, name)
- };
- pp$5.declareVarName = function(name) {
- this.scopeStack[this.scopeStack.length - 1].var[name] = true;
- };
- pp$5.declareLexicalName = function(name) {
- this.scopeStack[this.scopeStack.length - 1].lexical[name] = true;
- };
- var Node = function Node(parser, pos, loc) {
- this.type = "";
- this.start = pos;
- this.end = 0;
- if (parser.options.locations)
- { this.loc = new SourceLocation(parser, loc); }
- if (parser.options.directSourceFile)
- { this.sourceFile = parser.options.directSourceFile; }
- if (parser.options.ranges)
- { this.range = [pos, 0]; }
- };
- // Start an AST node, attaching a start offset.
- var pp$6 = Parser.prototype;
- pp$6.startNode = function() {
- return new Node(this, this.start, this.startLoc)
- };
- pp$6.startNodeAt = function(pos, loc) {
- return new Node(this, pos, loc)
- };
- // Finish an AST node, adding `type` and `end` properties.
- function finishNodeAt(node, type, pos, loc) {
- node.type = type;
- node.end = pos;
- if (this.options.locations)
- { node.loc.end = loc; }
- if (this.options.ranges)
- { node.range[1] = pos; }
- return node
- }
- pp$6.finishNode = function(node, type) {
- return finishNodeAt.call(this, node, type, this.lastTokEnd, this.lastTokEndLoc)
- };
- // Finish node at given position
- pp$6.finishNodeAt = function(node, type, pos, loc) {
- return finishNodeAt.call(this, node, type, pos, loc)
- };
- // The algorithm used to determine whether a regexp can appear at a
- // given point in the program is loosely based on sweet.js' approach.
- // See https://github.com/mozilla/sweet.js/wiki/design
- var TokContext = function TokContext(token, isExpr, preserveSpace, override, generator) {
- this.token = token;
- this.isExpr = !!isExpr;
- this.preserveSpace = !!preserveSpace;
- this.override = override;
- this.generator = !!generator;
- };
- var types$1 = {
- b_stat: new TokContext("{", false),
- b_expr: new TokContext("{", true),
- b_tmpl: new TokContext("${", false),
- p_stat: new TokContext("(", false),
- p_expr: new TokContext("(", true),
- q_tmpl: new TokContext("`", true, true, function (p) { return p.tryReadTemplateToken(); }),
- f_stat: new TokContext("function", false),
- f_expr: new TokContext("function", true),
- f_expr_gen: new TokContext("function", true, false, null, true),
- f_gen: new TokContext("function", false, false, null, true)
- };
- var pp$7 = Parser.prototype;
- pp$7.initialContext = function() {
- return [types$1.b_stat]
- };
- pp$7.braceIsBlock = function(prevType) {
- var parent = this.curContext();
- if (parent === types$1.f_expr || parent === types$1.f_stat)
- { return true }
- if (prevType === types.colon && (parent === types$1.b_stat || parent === types$1.b_expr))
- { return !parent.isExpr }
- // The check for `tt.name && exprAllowed` detects whether we are
- // after a `yield` or `of` construct. See the `updateContext` for
- // `tt.name`.
- if (prevType === types._return || prevType === types.name && this.exprAllowed)
- { return lineBreak.test(this.input.slice(this.lastTokEnd, this.start)) }
- if (prevType === types._else || prevType === types.semi || prevType === types.eof || prevType === types.parenR || prevType === types.arrow)
- { return true }
- if (prevType === types.braceL)
- { return parent === types$1.b_stat }
- if (prevType === types._var || prevType === types.name)
- { return false }
- return !this.exprAllowed
- };
- pp$7.inGeneratorContext = function() {
- var this$1 = this;
- for (var i = this.context.length - 1; i >= 1; i--) {
- var context = this$1.context[i];
- if (context.token === "function")
- { return context.generator }
- }
- return false
- };
- pp$7.updateContext = function(prevType) {
- var update, type = this.type;
- if (type.keyword && prevType === types.dot)
- { this.exprAllowed = false; }
- else if (update = type.updateContext)
- { update.call(this, prevType); }
- else
- { this.exprAllowed = type.beforeExpr; }
- };
- // Token-specific context update code
- types.parenR.updateContext = types.braceR.updateContext = function() {
- if (this.context.length === 1) {
- this.exprAllowed = true;
- return
- }
- var out = this.context.pop();
- if (out === types$1.b_stat && this.curContext().token === "function") {
- out = this.context.pop();
- }
- this.exprAllowed = !out.isExpr;
- };
- types.braceL.updateContext = function(prevType) {
- this.context.push(this.braceIsBlock(prevType) ? types$1.b_stat : types$1.b_expr);
- this.exprAllowed = true;
- };
- types.dollarBraceL.updateContext = function() {
- this.context.push(types$1.b_tmpl);
- this.exprAllowed = true;
- };
- types.parenL.updateContext = function(prevType) {
- var statementParens = prevType === types._if || prevType === types._for || prevType === types._with || prevType === types._while;
- this.context.push(statementParens ? types$1.p_stat : types$1.p_expr);
- this.exprAllowed = true;
- };
- types.incDec.updateContext = function() {
- // tokExprAllowed stays unchanged
- };
- types._function.updateContext = types._class.updateContext = function(prevType) {
- if (prevType.beforeExpr && prevType !== types.semi && prevType !== types._else &&
- !((prevType === types.colon || prevType === types.braceL) && this.curContext() === types$1.b_stat))
- { this.context.push(types$1.f_expr); }
- else
- { this.context.push(types$1.f_stat); }
- this.exprAllowed = false;
- };
- types.backQuote.updateContext = function() {
- if (this.curContext() === types$1.q_tmpl)
- { this.context.pop(); }
- else
- { this.context.push(types$1.q_tmpl); }
- this.exprAllowed = false;
- };
- types.star.updateContext = function(prevType) {
- if (prevType === types._function) {
- var index = this.context.length - 1;
- if (this.context[index] === types$1.f_expr)
- { this.context[index] = types$1.f_expr_gen; }
- else
- { this.context[index] = types$1.f_gen; }
- }
- this.exprAllowed = true;
- };
- types.name.updateContext = function(prevType) {
- var allowed = false;
- if (this.options.ecmaVersion >= 6 && prevType !== types.dot) {
- if (this.value === "of" && !this.exprAllowed ||
- this.value === "yield" && this.inGeneratorContext())
- { allowed = true; }
- }
- this.exprAllowed = allowed;
- };
- var data = {
- "$LONE": [
- "ASCII",
- "ASCII_Hex_Digit",
- "AHex",
- "Alphabetic",
- "Alpha",
- "Any",
- "Assigned",
- "Bidi_Control",
- "Bidi_C",
- "Bidi_Mirrored",
- "Bidi_M",
- "Case_Ignorable",
- "CI",
- "Cased",
- "Changes_When_Casefolded",
- "CWCF",
- "Changes_When_Casemapped",
- "CWCM",
- "Changes_When_Lowercased",
- "CWL",
- "Changes_When_NFKC_Casefolded",
- "CWKCF",
- "Changes_When_Titlecased",
- "CWT",
- "Changes_When_Uppercased",
- "CWU",
- "Dash",
- "Default_Ignorable_Code_Point",
- "DI",
- "Deprecated",
- "Dep",
- "Diacritic",
- "Dia",
- "Emoji",
- "Emoji_Component",
- "Emoji_Modifier",
- "Emoji_Modifier_Base",
- "Emoji_Presentation",
- "Extender",
- "Ext",
- "Grapheme_Base",
- "Gr_Base",
- "Grapheme_Extend",
- "Gr_Ext",
- "Hex_Digit",
- "Hex",
- "IDS_Binary_Operator",
- "IDSB",
- "IDS_Trinary_Operator",
- "IDST",
- "ID_Continue",
- "IDC",
- "ID_Start",
- "IDS",
- "Ideographic",
- "Ideo",
- "Join_Control",
- "Join_C",
- "Logical_Order_Exception",
- "LOE",
- "Lowercase",
- "Lower",
- "Math",
- "Noncharacter_Code_Point",
- "NChar",
- "Pattern_Syntax",
- "Pat_Syn",
- "Pattern_White_Space",
- "Pat_WS",
- "Quotation_Mark",
- "QMark",
- "Radical",
- "Regional_Indicator",
- "RI",
- "Sentence_Terminal",
- "STerm",
- "Soft_Dotted",
- "SD",
- "Terminal_Punctuation",
- "Term",
- "Unified_Ideograph",
- "UIdeo",
- "Uppercase",
- "Upper",
- "Variation_Selector",
- "VS",
- "White_Space",
- "space",
- "XID_Continue",
- "XIDC",
- "XID_Start",
- "XIDS"
- ],
- "General_Category": [
- "Cased_Letter",
- "LC",
- "Close_Punctuation",
- "Pe",
- "Connector_Punctuation",
- "Pc",
- "Control",
- "Cc",
- "cntrl",
- "Currency_Symbol",
- "Sc",
- "Dash_Punctuation",
- "Pd",
- "Decimal_Number",
- "Nd",
- "digit",
- "Enclosing_Mark",
- "Me",
- "Final_Punctuation",
- "Pf",
- "Format",
- "Cf",
- "Initial_Punctuation",
- "Pi",
- "Letter",
- "L",
- "Letter_Number",
- "Nl",
- "Line_Separator",
- "Zl",
- "Lowercase_Letter",
- "Ll",
- "Mark",
- "M",
- "Combining_Mark",
- "Math_Symbol",
- "Sm",
- "Modifier_Letter",
- "Lm",
- "Modifier_Symbol",
- "Sk",
- "Nonspacing_Mark",
- "Mn",
- "Number",
- "N",
- "Open_Punctuation",
- "Ps",
- "Other",
- "C",
- "Other_Letter",
- "Lo",
- "Other_Number",
- "No",
- "Other_Punctuation",
- "Po",
- "Other_Symbol",
- "So",
- "Paragraph_Separator",
- "Zp",
- "Private_Use",
- "Co",
- "Punctuation",
- "P",
- "punct",
- "Separator",
- "Z",
- "Space_Separator",
- "Zs",
- "Spacing_Mark",
- "Mc",
- "Surrogate",
- "Cs",
- "Symbol",
- "S",
- "Titlecase_Letter",
- "Lt",
- "Unassigned",
- "Cn",
- "Uppercase_Letter",
- "Lu"
- ],
- "Script": [
- "Adlam",
- "Adlm",
- "Ahom",
- "Anatolian_Hieroglyphs",
- "Hluw",
- "Arabic",
- "Arab",
- "Armenian",
- "Armn",
- "Avestan",
- "Avst",
- "Balinese",
- "Bali",
- "Bamum",
- "Bamu",
- "Bassa_Vah",
- "Bass",
- "Batak",
- "Batk",
- "Bengali",
- "Beng",
- "Bhaiksuki",
- "Bhks",
- "Bopomofo",
- "Bopo",
- "Brahmi",
- "Brah",
- "Braille",
- "Brai",
- "Buginese",
- "Bugi",
- "Buhid",
- "Buhd",
- "Canadian_Aboriginal",
- "Cans",
- "Carian",
- "Cari",
- "Caucasian_Albanian",
- "Aghb",
- "Chakma",
- "Cakm",
- "Cham",
- "Cherokee",
- "Cher",
- "Common",
- "Zyyy",
- "Coptic",
- "Copt",
- "Qaac",
- "Cuneiform",
- "Xsux",
- "Cypriot",
- "Cprt",
- "Cyrillic",
- "Cyrl",
- "Deseret",
- "Dsrt",
- "Devanagari",
- "Deva",
- "Duployan",
- "Dupl",
- "Egyptian_Hieroglyphs",
- "Egyp",
- "Elbasan",
- "Elba",
- "Ethiopic",
- "Ethi",
- "Georgian",
- "Geor",
- "Glagolitic",
- "Glag",
- "Gothic",
- "Goth",
- "Grantha",
- "Gran",
- "Greek",
- "Grek",
- "Gujarati",
- "Gujr",
- "Gurmukhi",
- "Guru",
- "Han",
- "Hani",
- "Hangul",
- "Hang",
- "Hanunoo",
- "Hano",
- "Hatran",
- "Hatr",
- "Hebrew",
- "Hebr",
- "Hiragana",
- "Hira",
- "Imperial_Aramaic",
- "Armi",
- "Inherited",
- "Zinh",
- "Qaai",
- "Inscriptional_Pahlavi",
- "Phli",
- "Inscriptional_Parthian",
- "Prti",
- "Javanese",
- "Java",
- "Kaithi",
- "Kthi",
- "Kannada",
- "Knda",
- "Katakana",
- "Kana",
- "Kayah_Li",
- "Kali",
- "Kharoshthi",
- "Khar",
- "Khmer",
- "Khmr",
- "Khojki",
- "Khoj",
- "Khudawadi",
- "Sind",
- "Lao",
- "Laoo",
- "Latin",
- "Latn",
- "Lepcha",
- "Lepc",
- "Limbu",
- "Limb",
- "Linear_A",
- "Lina",
- "Linear_B",
- "Linb",
- "Lisu",
- "Lycian",
- "Lyci",
- "Lydian",
- "Lydi",
- "Mahajani",
- "Mahj",
- "Malayalam",
- "Mlym",
- "Mandaic",
- "Mand",
- "Manichaean",
- "Mani",
- "Marchen",
- "Marc",
- "Masaram_Gondi",
- "Gonm",
- "Meetei_Mayek",
- "Mtei",
- "Mende_Kikakui",
- "Mend",
- "Meroitic_Cursive",
- "Merc",
- "Meroitic_Hieroglyphs",
- "Mero",
- "Miao",
- "Plrd",
- "Modi",
- "Mongolian",
- "Mong",
- "Mro",
- "Mroo",
- "Multani",
- "Mult",
- "Myanmar",
- "Mymr",
- "Nabataean",
- "Nbat",
- "New_Tai_Lue",
- "Talu",
- "Newa",
- "Nko",
- "Nkoo",
- "Nushu",
- "Nshu",
- "Ogham",
- "Ogam",
- "Ol_Chiki",
- "Olck",
- "Old_Hungarian",
- "Hung",
- "Old_Italic",
- "Ital",
- "Old_North_Arabian",
- "Narb",
- "Old_Permic",
- "Perm",
- "Old_Persian",
- "Xpeo",
- "Old_South_Arabian",
- "Sarb",
- "Old_Turkic",
- "Orkh",
- "Oriya",
- "Orya",
- "Osage",
- "Osge",
- "Osmanya",
- "Osma",
- "Pahawh_Hmong",
- "Hmng",
- "Palmyrene",
- "Palm",
- "Pau_Cin_Hau",
- "Pauc",
- "Phags_Pa",
- "Phag",
- "Phoenician",
- "Phnx",
- "Psalter_Pahlavi",
- "Phlp",
- "Rejang",
- "Rjng",
- "Runic",
- "Runr",
- "Samaritan",
- "Samr",
- "Saurashtra",
- "Saur",
- "Sharada",
- "Shrd",
- "Shavian",
- "Shaw",
- "Siddham",
- "Sidd",
- "SignWriting",
- "Sgnw",
- "Sinhala",
- "Sinh",
- "Sora_Sompeng",
- "Sora",
- "Soyombo",
- "Soyo",
- "Sundanese",
- "Sund",
- "Syloti_Nagri",
- "Sylo",
- "Syriac",
- "Syrc",
- "Tagalog",
- "Tglg",
- "Tagbanwa",
- "Tagb",
- "Tai_Le",
- "Tale",
- "Tai_Tham",
- "Lana",
- "Tai_Viet",
- "Tavt",
- "Takri",
- "Takr",
- "Tamil",
- "Taml",
- "Tangut",
- "Tang",
- "Telugu",
- "Telu",
- "Thaana",
- "Thaa",
- "Thai",
- "Tibetan",
- "Tibt",
- "Tifinagh",
- "Tfng",
- "Tirhuta",
- "Tirh",
- "Ugaritic",
- "Ugar",
- "Vai",
- "Vaii",
- "Warang_Citi",
- "Wara",
- "Yi",
- "Yiii",
- "Zanabazar_Square",
- "Zanb"
- ]
- };
- Array.prototype.push.apply(data.$LONE, data.General_Category);
- data.gc = data.General_Category;
- data.sc = data.Script_Extensions = data.scx = data.Script;
- var pp$9 = Parser.prototype;
- var RegExpValidationState = function RegExpValidationState(parser) {
- this.parser = parser;
- this.validFlags = "gim" + (parser.options.ecmaVersion >= 6 ? "uy" : "") + (parser.options.ecmaVersion >= 9 ? "s" : "");
- this.source = "";
- this.flags = "";
- this.start = 0;
- this.switchU = false;
- this.switchN = false;
- this.pos = 0;
- this.lastIntValue = 0;
- this.lastStringValue = "";
- this.lastAssertionIsQuantifiable = false;
- this.numCapturingParens = 0;
- this.maxBackReference = 0;
- this.groupNames = [];
- this.backReferenceNames = [];
- };
- RegExpValidationState.prototype.reset = function reset (start, pattern, flags) {
- var unicode = flags.indexOf("u") !== -1;
- this.start = start | 0;
- this.source = pattern + "";
- this.flags = flags;
- this.switchU = unicode && this.parser.options.ecmaVersion >= 6;
- this.switchN = unicode && this.parser.options.ecmaVersion >= 9;
- };
- RegExpValidationState.prototype.raise = function raise (message) {
- this.parser.raiseRecoverable(this.start, ("Invalid regular expression: /" + (this.source) + "/: " + message));
- };
- // If u flag is given, this returns the code point at the index (it combines a surrogate pair).
- // Otherwise, this returns the code unit of the index (can be a part of a surrogate pair).
- RegExpValidationState.prototype.at = function at (i) {
- var s = this.source;
- var l = s.length;
- if (i >= l) {
- return -1
- }
- var c = s.charCodeAt(i);
- if (!this.switchU || c <= 0xD7FF || c >= 0xE000 || i + 1 >= l) {
- return c
- }
- return (c << 10) + s.charCodeAt(i + 1) - 0x35FDC00
- };
- RegExpValidationState.prototype.nextIndex = function nextIndex (i) {
- var s = this.source;
- var l = s.length;
- if (i >= l) {
- return l
- }
- var c = s.charCodeAt(i);
- if (!this.switchU || c <= 0xD7FF || c >= 0xE000 || i + 1 >= l) {
- return i + 1
- }
- return i + 2
- };
- RegExpValidationState.prototype.current = function current () {
- return this.at(this.pos)
- };
- RegExpValidationState.prototype.lookahead = function lookahead () {
- return this.at(this.nextIndex(this.pos))
- };
- RegExpValidationState.prototype.advance = function advance () {
- this.pos = this.nextIndex(this.pos);
- };
- RegExpValidationState.prototype.eat = function eat (ch) {
- if (this.current() === ch) {
- this.advance();
- return true
- }
- return false
- };
- function codePointToString$1(ch) {
- if (ch <= 0xFFFF) { return String.fromCharCode(ch) }
- ch -= 0x10000;
- return String.fromCharCode((ch >> 10) + 0xD800, (ch & 0x03FF) + 0xDC00)
- }
- /**
- * Validate the flags part of a given RegExpLiteral.
- *
- * @param {RegExpValidationState} state The state to validate RegExp.
- * @returns {void}
- */
- pp$9.validateRegExpFlags = function(state) {
- var this$1 = this;
- var validFlags = state.validFlags;
- var flags = state.flags;
- for (var i = 0; i < flags.length; i++) {
- var flag = flags.charAt(i);
- if (validFlags.indexOf(flag) === -1) {
- this$1.raise(state.start, "Invalid regular expression flag");
- }
- if (flags.indexOf(flag, i + 1) > -1) {
- this$1.raise(state.start, "Duplicate regular expression flag");
- }
- }
- };
- /**
- * Validate the pattern part of a given RegExpLiteral.
- *
- * @param {RegExpValidationState} state The state to validate RegExp.
- * @returns {void}
- */
- pp$9.validateRegExpPattern = function(state) {
- this.regexp_pattern(state);
- // The goal symbol for the parse is |Pattern[~U, ~N]|. If the result of
- // parsing contains a |GroupName|, reparse with the goal symbol
- // |Pattern[~U, +N]| and use this result instead. Throw a *SyntaxError*
- // exception if _P_ did not conform to the grammar, if any elements of _P_
- // were not matched by the parse, or if any Early Error conditions exist.
- if (!state.switchN && this.options.ecmaVersion >= 9 && state.groupNames.length > 0) {
- state.switchN = true;
- this.regexp_pattern(state);
- }
- };
- // https://www.ecma-international.org/ecma-262/8.0/#prod-Pattern
- pp$9.regexp_pattern = function(state) {
- state.pos = 0;
- state.lastIntValue = 0;
- state.lastStringValue = "";
- state.lastAssertionIsQuantifiable = false;
- state.numCapturingParens = 0;
- state.maxBackReference = 0;
- state.groupNames.length = 0;
- state.backReferenceNames.length = 0;
- this.regexp_disjunction(state);
- if (state.pos !== state.source.length) {
- // Make the same messages as V8.
- if (state.eat(0x29 /* ) */)) {
- state.raise("Unmatched ')'");
- }
- if (state.eat(0x5D /* [ */) || state.eat(0x7D /* } */)) {
- state.raise("Lone quantifier brackets");
- }
- }
- if (state.maxBackReference > state.numCapturingParens) {
- state.raise("Invalid escape");
- }
- for (var i = 0, list = state.backReferenceNames; i < list.length; i += 1) {
- var name = list[i];
- if (state.groupNames.indexOf(name) === -1) {
- state.raise("Invalid named capture referenced");
- }
- }
- };
- // https://www.ecma-international.org/ecma-262/8.0/#prod-Disjunction
- pp$9.regexp_disjunction = function(state) {
- var this$1 = this;
- this.regexp_alternative(state);
- while (state.eat(0x7C /* | */)) {
- this$1.regexp_alternative(state);
- }
- // Make the same message as V8.
- if (this.regexp_eatQuantifier(state, true)) {
- state.raise("Nothing to repeat");
- }
- if (state.eat(0x7B /* { */)) {
- state.raise("Lone quantifier brackets");
- }
- };
- // https://www.ecma-international.org/ecma-262/8.0/#prod-Alternative
- pp$9.regexp_alternative = function(state) {
- while (state.pos < state.source.length && this.regexp_eatTerm(state))
- { }
- };
- // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-Term
- pp$9.regexp_eatTerm = function(state) {
- if (this.regexp_eatAssertion(state)) {
- // Handle `QuantifiableAssertion Quantifier` alternative.
- // `state.lastAssertionIsQuantifiable` is true if the last eaten Assertion
- // is a QuantifiableAssertion.
- if (state.lastAssertionIsQuantifiable && this.regexp_eatQuantifier(state)) {
- // Make the same message as V8.
- if (state.switchU) {
- state.raise("Invalid quantifier");
- }
- }
- return true
- }
- if (state.switchU ? this.regexp_eatAtom(state) : this.regexp_eatExtendedAtom(state)) {
- this.regexp_eatQuantifier(state);
- return true
- }
- return false
- };
- // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-Assertion
- pp$9.regexp_eatAssertion = function(state) {
- var start = state.pos;
- state.lastAssertionIsQuantifiable = false;
- // ^, $
- if (state.eat(0x5E /* ^ */) || state.eat(0x24 /* $ */)) {
- return true
- }
- // \b \B
- if (state.eat(0x5C /* \ */)) {
- if (state.eat(0x42 /* B */) || state.eat(0x62 /* b */)) {
- return true
- }
- state.pos = start;
- }
- // Lookahead / Lookbehind
- if (state.eat(0x28 /* ( */) && state.eat(0x3F /* ? */)) {
- var lookbehind = false;
- if (this.options.ecmaVersion >= 9) {
- lookbehind = state.eat(0x3C /* < */);
- }
- if (state.eat(0x3D /* = */) || state.eat(0x21 /* ! */)) {
- this.regexp_disjunction(state);
- if (!state.eat(0x29 /* ) */)) {
- state.raise("Unterminated group");
- }
- state.lastAssertionIsQuantifiable = !lookbehind;
- return true
- }
- }
- state.pos = start;
- return false
- };
- // https://www.ecma-international.org/ecma-262/8.0/#prod-Quantifier
- pp$9.regexp_eatQuantifier = function(state, noError) {
- if ( noError === void 0 ) noError = false;
- if (this.regexp_eatQuantifierPrefix(state, noError)) {
- state.eat(0x3F /* ? */);
- return true
- }
- return false
- };
- // https://www.ecma-international.org/ecma-262/8.0/#prod-QuantifierPrefix
- pp$9.regexp_eatQuantifierPrefix = function(state, noError) {
- return (
- state.eat(0x2A /* * */) ||
- state.eat(0x2B /* + */) ||
- state.eat(0x3F /* ? */) ||
- this.regexp_eatBracedQuantifier(state, noError)
- )
- };
- pp$9.regexp_eatBracedQuantifier = function(state, noError) {
- var start = state.pos;
- if (state.eat(0x7B /* { */)) {
- var min = 0, max = -1;
- if (this.regexp_eatDecimalDigits(state)) {
- min = state.lastIntValue;
- if (state.eat(0x2C /* , */) && this.regexp_eatDecimalDigits(state)) {
- max = state.lastIntValue;
- }
- if (state.eat(0x7D /* } */)) {
- // SyntaxError in https://www.ecma-international.org/ecma-262/8.0/#sec-term
- if (max !== -1 && max < min && !noError) {
- state.raise("numbers out of order in {} quantifier");
- }
- return true
- }
- }
- if (state.switchU && !noError) {
- state.raise("Incomplete quantifier");
- }
- state.pos = start;
- }
- return false
- };
- // https://www.ecma-international.org/ecma-262/8.0/#prod-Atom
- pp$9.regexp_eatAtom = function(state) {
- return (
- this.regexp_eatPatternCharacters(state) ||
- state.eat(0x2E /* . */) ||
- this.regexp_eatReverseSolidusAtomEscape(state) ||
- this.regexp_eatCharacterClass(state) ||
- this.regexp_eatUncapturingGroup(state) ||
- this.regexp_eatCapturingGroup(state)
- )
- };
- pp$9.regexp_eatReverseSolidusAtomEscape = function(state) {
- var start = state.pos;
- if (state.eat(0x5C /* \ */)) {
- if (this.regexp_eatAtomEscape(state)) {
- return true
- }
- state.pos = start;
- }
- return false
- };
- pp$9.regexp_eatUncapturingGroup = function(state) {
- var start = state.pos;
- if (state.eat(0x28 /* ( */)) {
- if (state.eat(0x3F /* ? */) && state.eat(0x3A /* : */)) {
- this.regexp_disjunction(state);
- if (state.eat(0x29 /* ) */)) {
- return true
- }
- state.raise("Unterminated group");
- }
- state.pos = start;
- }
- return false
- };
- pp$9.regexp_eatCapturingGroup = function(state) {
- if (state.eat(0x28 /* ( */)) {
- if (this.options.ecmaVersion >= 9) {
- this.regexp_groupSpecifier(state);
- } else if (state.current() === 0x3F /* ? */) {
- state.raise("Invalid group");
- }
- this.regexp_disjunction(state);
- if (state.eat(0x29 /* ) */)) {
- state.numCapturingParens += 1;
- return true
- }
- state.raise("Unterminated group");
- }
- return false
- };
- // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-ExtendedAtom
- pp$9.regexp_eatExtendedAtom = function(state) {
- return (
- state.eat(0x2E /* . */) ||
- this.regexp_eatReverseSolidusAtomEscape(state) ||
- this.regexp_eatCharacterClass(state) ||
- this.regexp_eatUncapturingGroup(state) ||
- this.regexp_eatCapturingGroup(state) ||
- this.regexp_eatInvalidBracedQuantifier(state) ||
- this.regexp_eatExtendedPatternCharacter(state)
- )
- };
- // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-InvalidBracedQuantifier
- pp$9.regexp_eatInvalidBracedQuantifier = function(state) {
- if (this.regexp_eatBracedQuantifier(state, true)) {
- state.raise("Nothing to repeat");
- }
- return false
- };
- // https://www.ecma-international.org/ecma-262/8.0/#prod-SyntaxCharacter
- pp$9.regexp_eatSyntaxCharacter = function(state) {
- var ch = state.current();
- if (isSyntaxCharacter(ch)) {
- state.lastIntValue = ch;
- state.advance();
- return true
- }
- return false
- };
- function isSyntaxCharacter(ch) {
- return (
- ch === 0x24 /* $ */ ||
- ch >= 0x28 /* ( */ && ch <= 0x2B /* + */ ||
- ch === 0x2E /* . */ ||
- ch === 0x3F /* ? */ ||
- ch >= 0x5B /* [ */ && ch <= 0x5E /* ^ */ ||
- ch >= 0x7B /* { */ && ch <= 0x7D /* } */
- )
- }
- // https://www.ecma-international.org/ecma-262/8.0/#prod-PatternCharacter
- // But eat eager.
- pp$9.regexp_eatPatternCharacters = function(state) {
- var start = state.pos;
- var ch = 0;
- while ((ch = state.current()) !== -1 && !isSyntaxCharacter(ch)) {
- state.advance();
- }
- return state.pos !== start
- };
- // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-ExtendedPatternCharacter
- pp$9.regexp_eatExtendedPatternCharacter = function(state) {
- var ch = state.current();
- if (
- ch !== -1 &&
- ch !== 0x24 /* $ */ &&
- !(ch >= 0x28 /* ( */ && ch <= 0x2B /* + */) &&
- ch !== 0x2E /* . */ &&
- ch !== 0x3F /* ? */ &&
- ch !== 0x5B /* [ */ &&
- ch !== 0x5E /* ^ */ &&
- ch !== 0x7C /* | */
- ) {
- state.advance();
- return true
- }
- return false
- };
- // GroupSpecifier[U] ::
- // [empty]
- // `?` GroupName[?U]
- pp$9.regexp_groupSpecifier = function(state) {
- if (state.eat(0x3F /* ? */)) {
- if (this.regexp_eatGroupName(state)) {
- if (state.groupNames.indexOf(state.lastStringValue) !== -1) {
- state.raise("Duplicate capture group name");
- }
- state.groupNames.push(state.lastStringValue);
- return
- }
- state.raise("Invalid group");
- }
- };
- // GroupName[U] ::
- // `<` RegExpIdentifierName[?U] `>`
- // Note: this updates `state.lastStringValue` property with the eaten name.
- pp$9.regexp_eatGroupName = function(state) {
- state.lastStringValue = "";
- if (state.eat(0x3C /* < */)) {
- if (this.regexp_eatRegExpIdentifierName(state) && state.eat(0x3E /* > */)) {
- return true
- }
- state.raise("Invalid capture group name");
- }
- return false
- };
- // RegExpIdentifierName[U] ::
- // RegExpIdentifierStart[?U]
- // RegExpIdentifierName[?U] RegExpIdentifierPart[?U]
- // Note: this updates `state.lastStringValue` property with the eaten name.
- pp$9.regexp_eatRegExpIdentifierName = function(state) {
- state.lastStringValue = "";
- if (this.regexp_eatRegExpIdentifierStart(state)) {
- state.lastStringValue += codePointToString$1(state.lastIntValue);
- while (this.regexp_eatRegExpIdentifierPart(state)) {
- state.lastStringValue += codePointToString$1(state.lastIntValue);
- }
- return true
- }
- return false
- };
- // RegExpIdentifierStart[U] ::
- // UnicodeIDStart
- // `$`
- // `_`
- // `\` RegExpUnicodeEscapeSequence[?U]
- pp$9.regexp_eatRegExpIdentifierStart = function(state) {
- var start = state.pos;
- var ch = state.current();
- state.advance();
- if (ch === 0x5C /* \ */ && this.regexp_eatRegExpUnicodeEscapeSequence(state)) {
- ch = state.lastIntValue;
- }
- if (isRegExpIdentifierStart(ch)) {
- state.lastIntValue = ch;
- return true
- }
- state.pos = start;
- return false
- };
- function isRegExpIdentifierStart(ch) {
- return isIdentifierStart(ch, true) || ch === 0x24 /* $ */ || ch === 0x5F /* _ */
- }
- // RegExpIdentifierPart[U] ::
- // UnicodeIDContinue
- // `$`
- // `_`
- // `\` RegExpUnicodeEscapeSequence[?U]
- // <ZWNJ>
- // <ZWJ>
- pp$9.regexp_eatRegExpIdentifierPart = function(state) {
- var start = state.pos;
- var ch = state.current();
- state.advance();
- if (ch === 0x5C /* \ */ && this.regexp_eatRegExpUnicodeEscapeSequence(state)) {
- ch = state.lastIntValue;
- }
- if (isRegExpIdentifierPart(ch)) {
- state.lastIntValue = ch;
- return true
- }
- state.pos = start;
- return false
- };
- function isRegExpIdentifierPart(ch) {
- return isIdentifierChar(ch, true) || ch === 0x24 /* $ */ || ch === 0x5F /* _ */ || ch === 0x200C /* <ZWNJ> */ || ch === 0x200D /* <ZWJ> */
- }
- // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-AtomEscape
- pp$9.regexp_eatAtomEscape = function(state) {
- if (
- this.regexp_eatBackReference(state) ||
- this.regexp_eatCharacterClassEscape(state) ||
- this.regexp_eatCharacterEscape(state) ||
- (state.switchN && this.regexp_eatKGroupName(state))
- ) {
- return true
- }
- if (state.switchU) {
- // Make the same message as V8.
- if (state.current() === 0x63 /* c */) {
- state.raise("Invalid unicode escape");
- }
- state.raise("Invalid escape");
- }
- return false
- };
- pp$9.regexp_eatBackReference = function(state) {
- var start = state.pos;
- if (this.regexp_eatDecimalEscape(state)) {
- var n = state.lastIntValue;
- if (state.switchU) {
- // For SyntaxError in https://www.ecma-international.org/ecma-262/8.0/#sec-atomescape
- if (n > state.maxBackReference) {
- state.maxBackReference = n;
- }
- return true
- }
- if (n <= state.numCapturingParens) {
- return true
- }
- state.pos = start;
- }
- return false
- };
- pp$9.regexp_eatKGroupName = function(state) {
- if (state.eat(0x6B /* k */)) {
- if (this.regexp_eatGroupName(state)) {
- state.backReferenceNames.push(state.lastStringValue);
- return true
- }
- state.raise("Invalid named reference");
- }
- return false
- };
- // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-CharacterEscape
- pp$9.regexp_eatCharacterEscape = function(state) {
- return (
- this.regexp_eatControlEscape(state) ||
- this.regexp_eatCControlLetter(state) ||
- this.regexp_eatZero(state) ||
- this.regexp_eatHexEscapeSequence(state) ||
- this.regexp_eatRegExpUnicodeEscapeSequence(state) ||
- (!state.switchU && this.regexp_eatLegacyOctalEscapeSequence(state)) ||
- this.regexp_eatIdentityEscape(state)
- )
- };
- pp$9.regexp_eatCControlLetter = function(state) {
- var start = state.pos;
- if (state.eat(0x63 /* c */)) {
- if (this.regexp_eatControlLetter(state)) {
- return true
- }
- state.pos = start;
- }
- return false
- };
- pp$9.regexp_eatZero = function(state) {
- if (state.current() === 0x30 /* 0 */ && !isDecimalDigit(state.lookahead())) {
- state.lastIntValue = 0;
- state.advance();
- return true
- }
- return false
- };
- // https://www.ecma-international.org/ecma-262/8.0/#prod-ControlEscape
- pp$9.regexp_eatControlEscape = function(state) {
- var ch = state.current();
- if (ch === 0x74 /* t */) {
- state.lastIntValue = 0x09; /* \t */
- state.advance();
- return true
- }
- if (ch === 0x6E /* n */) {
- state.lastIntValue = 0x0A; /* \n */
- state.advance();
- return true
- }
- if (ch === 0x76 /* v */) {
- state.lastIntValue = 0x0B; /* \v */
- state.advance();
- return true
- }
- if (ch === 0x66 /* f */) {
- state.lastIntValue = 0x0C; /* \f */
- state.advance();
- return true
- }
- if (ch === 0x72 /* r */) {
- state.lastIntValue = 0x0D; /* \r */
- state.advance();
- return true
- }
- return false
- };
- // https://www.ecma-international.org/ecma-262/8.0/#prod-ControlLetter
- pp$9.regexp_eatControlLetter = function(state) {
- var ch = state.current();
- if (isControlLetter(ch)) {
- state.lastIntValue = ch % 0x20;
- state.advance();
- return true
- }
- return false
- };
- function isControlLetter(ch) {
- return (
- (ch >= 0x41 /* A */ && ch <= 0x5A /* Z */) ||
- (ch >= 0x61 /* a */ && ch <= 0x7A /* z */)
- )
- }
- // https://www.ecma-international.org/ecma-262/8.0/#prod-RegExpUnicodeEscapeSequence
- pp$9.regexp_eatRegExpUnicodeEscapeSequence = function(state) {
- var start = state.pos;
- if (state.eat(0x75 /* u */)) {
- if (this.regexp_eatFixedHexDigits(state, 4)) {
- var lead = state.lastIntValue;
- if (state.switchU && lead >= 0xD800 && lead <= 0xDBFF) {
- var leadSurrogateEnd = state.pos;
- if (state.eat(0x5C /* \ */) && state.eat(0x75 /* u */) && this.regexp_eatFixedHexDigits(state, 4)) {
- var trail = state.lastIntValue;
- if (trail >= 0xDC00 && trail <= 0xDFFF) {
- state.lastIntValue = (lead - 0xD800) * 0x400 + (trail - 0xDC00) + 0x10000;
- return true
- }
- }
- state.pos = leadSurrogateEnd;
- state.lastIntValue = lead;
- }
- return true
- }
- if (
- state.switchU &&
- state.eat(0x7B /* { */) &&
- this.regexp_eatHexDigits(state) &&
- state.eat(0x7D /* } */) &&
- isValidUnicode(state.lastIntValue)
- ) {
- return true
- }
- if (state.switchU) {
- state.raise("Invalid unicode escape");
- }
- state.pos = start;
- }
- return false
- };
- function isValidUnicode(ch) {
- return ch >= 0 && ch <= 0x10FFFF
- }
- // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-IdentityEscape
- pp$9.regexp_eatIdentityEscape = function(state) {
- if (state.switchU) {
- if (this.regexp_eatSyntaxCharacter(state)) {
- return true
- }
- if (state.eat(0x2F /* / */)) {
- state.lastIntValue = 0x2F; /* / */
- return true
- }
- return false
- }
- var ch = state.current();
- if (ch !== 0x63 /* c */ && (!state.switchN || ch !== 0x6B /* k */)) {
- state.lastIntValue = ch;
- state.advance();
- return true
- }
- return false
- };
- // https://www.ecma-international.org/ecma-262/8.0/#prod-DecimalEscape
- pp$9.regexp_eatDecimalEscape = function(state) {
- state.lastIntValue = 0;
- var ch = state.current();
- if (ch >= 0x31 /* 1 */ && ch <= 0x39 /* 9 */) {
- do {
- state.lastIntValue = 10 * state.lastIntValue + (ch - 0x30 /* 0 */);
- state.advance();
- } while ((ch = state.current()) >= 0x30 /* 0 */ && ch <= 0x39 /* 9 */)
- return true
- }
- return false
- };
- // https://www.ecma-international.org/ecma-262/8.0/#prod-CharacterClassEscape
- pp$9.regexp_eatCharacterClassEscape = function(state) {
- var ch = state.current();
- if (isCharacterClassEscape(ch)) {
- state.lastIntValue = -1;
- state.advance();
- return true
- }
- if (
- state.switchU &&
- this.options.ecmaVersion >= 9 &&
- (ch === 0x50 /* P */ || ch === 0x70 /* p */)
- ) {
- state.lastIntValue = -1;
- state.advance();
- if (
- state.eat(0x7B /* { */) &&
- this.regexp_eatUnicodePropertyValueExpression(state) &&
- state.eat(0x7D /* } */)
- ) {
- return true
- }
- state.raise("Invalid property name");
- }
- return false
- };
- function isCharacterClassEscape(ch) {
- return (
- ch === 0x64 /* d */ ||
- ch === 0x44 /* D */ ||
- ch === 0x73 /* s */ ||
- ch === 0x53 /* S */ ||
- ch === 0x77 /* w */ ||
- ch === 0x57 /* W */
- )
- }
- // UnicodePropertyValueExpression ::
- // UnicodePropertyName `=` UnicodePropertyValue
- // LoneUnicodePropertyNameOrValue
- pp$9.regexp_eatUnicodePropertyValueExpression = function(state) {
- var start = state.pos;
- // UnicodePropertyName `=` UnicodePropertyValue
- if (this.regexp_eatUnicodePropertyName(state) && state.eat(0x3D /* = */)) {
- var name = state.lastStringValue;
- if (this.regexp_eatUnicodePropertyValue(state)) {
- var value = state.lastStringValue;
- this.regexp_validateUnicodePropertyNameAndValue(state, name, value);
- return true
- }
- }
- state.pos = start;
- // LoneUnicodePropertyNameOrValue
- if (this.regexp_eatLoneUnicodePropertyNameOrValue(state)) {
- var nameOrValue = state.lastStringValue;
- this.regexp_validateUnicodePropertyNameOrValue(state, nameOrValue);
- return true
- }
- return false
- };
- pp$9.regexp_validateUnicodePropertyNameAndValue = function(state, name, value) {
- if (!data.hasOwnProperty(name) || data[name].indexOf(value) === -1) {
- state.raise("Invalid property name");
- }
- };
- pp$9.regexp_validateUnicodePropertyNameOrValue = function(state, nameOrValue) {
- if (data.$LONE.indexOf(nameOrValue) === -1) {
- state.raise("Invalid property name");
- }
- };
- // UnicodePropertyName ::
- // UnicodePropertyNameCharacters
- pp$9.regexp_eatUnicodePropertyName = function(state) {
- var ch = 0;
- state.lastStringValue = "";
- while (isUnicodePropertyNameCharacter(ch = state.current())) {
- state.lastStringValue += codePointToString$1(ch);
- state.advance();
- }
- return state.lastStringValue !== ""
- };
- function isUnicodePropertyNameCharacter(ch) {
- return isControlLetter(ch) || ch === 0x5F /* _ */
- }
- // UnicodePropertyValue ::
- // UnicodePropertyValueCharacters
- pp$9.regexp_eatUnicodePropertyValue = function(state) {
- var ch = 0;
- state.lastStringValue = "";
- while (isUnicodePropertyValueCharacter(ch = state.current())) {
- state.lastStringValue += codePointToString$1(ch);
- state.advance();
- }
- return state.lastStringValue !== ""
- };
- function isUnicodePropertyValueCharacter(ch) {
- return isUnicodePropertyNameCharacter(ch) || isDecimalDigit(ch)
- }
- // LoneUnicodePropertyNameOrValue ::
- // UnicodePropertyValueCharacters
- pp$9.regexp_eatLoneUnicodePropertyNameOrValue = function(state) {
- return this.regexp_eatUnicodePropertyValue(state)
- };
- // https://www.ecma-international.org/ecma-262/8.0/#prod-CharacterClass
- pp$9.regexp_eatCharacterClass = function(state) {
- if (state.eat(0x5B /* [ */)) {
- state.eat(0x5E /* ^ */);
- this.regexp_classRanges(state);
- if (state.eat(0x5D /* [ */)) {
- return true
- }
- // Unreachable since it threw "unterminated regular expression" error before.
- state.raise("Unterminated character class");
- }
- return false
- };
- // https://www.ecma-international.org/ecma-262/8.0/#prod-ClassRanges
- // https://www.ecma-international.org/ecma-262/8.0/#prod-NonemptyClassRanges
- // https://www.ecma-international.org/ecma-262/8.0/#prod-NonemptyClassRangesNoDash
- pp$9.regexp_classRanges = function(state) {
- var this$1 = this;
- while (this.regexp_eatClassAtom(state)) {
- var left = state.lastIntValue;
- if (state.eat(0x2D /* - */) && this$1.regexp_eatClassAtom(state)) {
- var right = state.lastIntValue;
- if (state.switchU && (left === -1 || right === -1)) {
- state.raise("Invalid character class");
- }
- if (left !== -1 && right !== -1 && left > right) {
- state.raise("Range out of order in character class");
- }
- }
- }
- };
- // https://www.ecma-international.org/ecma-262/8.0/#prod-ClassAtom
- // https://www.ecma-international.org/ecma-262/8.0/#prod-ClassAtomNoDash
- pp$9.regexp_eatClassAtom = function(state) {
- var start = state.pos;
- if (state.eat(0x5C /* \ */)) {
- if (this.regexp_eatClassEscape(state)) {
- return true
- }
- if (state.switchU) {
- // Make the same message as V8.
- var ch$1 = state.current();
- if (ch$1 === 0x63 /* c */ || isOctalDigit(ch$1)) {
- state.raise("Invalid class escape");
- }
- state.raise("Invalid escape");
- }
- state.pos = start;
- }
- var ch = state.current();
- if (ch !== 0x5D /* [ */) {
- state.lastIntValue = ch;
- state.advance();
- return true
- }
- return false
- };
- // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-ClassEscape
- pp$9.regexp_eatClassEscape = function(state) {
- var start = state.pos;
- if (state.eat(0x62 /* b */)) {
- state.lastIntValue = 0x08; /* <BS> */
- return true
- }
- if (state.switchU && state.eat(0x2D /* - */)) {
- state.lastIntValue = 0x2D; /* - */
- return true
- }
- if (!state.switchU && state.eat(0x63 /* c */)) {
- if (this.regexp_eatClassControlLetter(state)) {
- return true
- }
- state.pos = start;
- }
- return (
- this.regexp_eatCharacterClassEscape(state) ||
- this.regexp_eatCharacterEscape(state)
- )
- };
- // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-ClassControlLetter
- pp$9.regexp_eatClassControlLetter = function(state) {
- var ch = state.current();
- if (isDecimalDigit(ch) || ch === 0x5F /* _ */) {
- state.lastIntValue = ch % 0x20;
- state.advance();
- return true
- }
- return false
- };
- // https://www.ecma-international.org/ecma-262/8.0/#prod-HexEscapeSequence
- pp$9.regexp_eatHexEscapeSequence = function(state) {
- var start = state.pos;
- if (state.eat(0x78 /* x */)) {
- if (this.regexp_eatFixedHexDigits(state, 2)) {
- return true
- }
- if (state.switchU) {
- state.raise("Invalid escape");
- }
- state.pos = start;
- }
- return false
- };
- // https://www.ecma-international.org/ecma-262/8.0/#prod-DecimalDigits
- pp$9.regexp_eatDecimalDigits = function(state) {
- var start = state.pos;
- var ch = 0;
- state.lastIntValue = 0;
- while (isDecimalDigit(ch = state.current())) {
- state.lastIntValue = 10 * state.lastIntValue + (ch - 0x30 /* 0 */);
- state.advance();
- }
- return state.pos !== start
- };
- function isDecimalDigit(ch) {
- return ch >= 0x30 /* 0 */ && ch <= 0x39 /* 9 */
- }
- // https://www.ecma-international.org/ecma-262/8.0/#prod-HexDigits
- pp$9.regexp_eatHexDigits = function(state) {
- var start = state.pos;
- var ch = 0;
- state.lastIntValue = 0;
- while (isHexDigit(ch = state.current())) {
- state.lastIntValue = 16 * state.lastIntValue + hexToInt(ch);
- state.advance();
- }
- return state.pos !== start
- };
- function isHexDigit(ch) {
- return (
- (ch >= 0x30 /* 0 */ && ch <= 0x39 /* 9 */) ||
- (ch >= 0x41 /* A */ && ch <= 0x46 /* F */) ||
- (ch >= 0x61 /* a */ && ch <= 0x66 /* f */)
- )
- }
- function hexToInt(ch) {
- if (ch >= 0x41 /* A */ && ch <= 0x46 /* F */) {
- return 10 + (ch - 0x41 /* A */)
- }
- if (ch >= 0x61 /* a */ && ch <= 0x66 /* f */) {
- return 10 + (ch - 0x61 /* a */)
- }
- return ch - 0x30 /* 0 */
- }
- // https://www.ecma-international.org/ecma-262/8.0/#prod-annexB-LegacyOctalEscapeSequence
- // Allows only 0-377(octal) i.e. 0-255(decimal).
- pp$9.regexp_eatLegacyOctalEscapeSequence = function(state) {
- if (this.regexp_eatOctalDigit(state)) {
- var n1 = state.lastIntValue;
- if (this.regexp_eatOctalDigit(state)) {
- var n2 = state.lastIntValue;
- if (n1 <= 3 && this.regexp_eatOctalDigit(state)) {
- state.lastIntValue = n1 * 64 + n2 * 8 + state.lastIntValue;
- } else {
- state.lastIntValue = n1 * 8 + n2;
- }
- } else {
- state.lastIntValue = n1;
- }
- return true
- }
- return false
- };
- // https://www.ecma-international.org/ecma-262/8.0/#prod-OctalDigit
- pp$9.regexp_eatOctalDigit = function(state) {
- var ch = state.current();
- if (isOctalDigit(ch)) {
- state.lastIntValue = ch - 0x30; /* 0 */
- state.advance();
- return true
- }
- state.lastIntValue = 0;
- return false
- };
- function isOctalDigit(ch) {
- return ch >= 0x30 /* 0 */ && ch <= 0x37 /* 7 */
- }
- // https://www.ecma-international.org/ecma-262/8.0/#prod-Hex4Digits
- // https://www.ecma-international.org/ecma-262/8.0/#prod-HexDigit
- // And HexDigit HexDigit in https://www.ecma-international.org/ecma-262/8.0/#prod-HexEscapeSequence
- pp$9.regexp_eatFixedHexDigits = function(state, length) {
- var start = state.pos;
- state.lastIntValue = 0;
- for (var i = 0; i < length; ++i) {
- var ch = state.current();
- if (!isHexDigit(ch)) {
- state.pos = start;
- return false
- }
- state.lastIntValue = 16 * state.lastIntValue + hexToInt(ch);
- state.advance();
- }
- return true
- };
- // Object type used to represent tokens. Note that normally, tokens
- // simply exist as properties on the parser object. This is only
- // used for the onToken callback and the external tokenizer.
- var Token = function Token(p) {
- this.type = p.type;
- this.value = p.value;
- this.start = p.start;
- this.end = p.end;
- if (p.options.locations)
- { this.loc = new SourceLocation(p, p.startLoc, p.endLoc); }
- if (p.options.ranges)
- { this.range = [p.start, p.end]; }
- };
- // ## Tokenizer
- var pp$8 = Parser.prototype;
- // Move to the next token
- pp$8.next = function() {
- if (this.options.onToken)
- { this.options.onToken(new Token(this)); }
- this.lastTokEnd = this.end;
- this.lastTokStart = this.start;
- this.lastTokEndLoc = this.endLoc;
- this.lastTokStartLoc = this.startLoc;
- this.nextToken();
- };
- pp$8.getToken = function() {
- this.next();
- return new Token(this)
- };
- // If we're in an ES6 environment, make parsers iterable
- if (typeof Symbol !== "undefined")
- { pp$8[Symbol.iterator] = function() {
- var this$1 = this;
- return {
- next: function () {
- var token = this$1.getToken();
- return {
- done: token.type === types.eof,
- value: token
- }
- }
- }
- }; }
- // Toggle strict mode. Re-reads the next number or string to please
- // pedantic tests (`"use strict"; 010;` should fail).
- pp$8.curContext = function() {
- return this.context[this.context.length - 1]
- };
- // Read a single token, updating the parser object's token-related
- // properties.
- pp$8.nextToken = function() {
- var curContext = this.curContext();
- if (!curContext || !curContext.preserveSpace) { this.skipSpace(); }
- this.start = this.pos;
- if (this.options.locations) { this.startLoc = this.curPosition(); }
- if (this.pos >= this.input.length) { return this.finishToken(types.eof) }
- if (curContext.override) { return curContext.override(this) }
- else { this.readToken(this.fullCharCodeAtPos()); }
- };
- pp$8.readToken = function(code) {
- // Identifier or keyword. '\uXXXX' sequences are allowed in
- // identifiers, so '\' also dispatches to that.
- if (isIdentifierStart(code, this.options.ecmaVersion >= 6) || code === 92 /* '\' */)
- { return this.readWord() }
- return this.getTokenFromCode(code)
- };
- pp$8.fullCharCodeAtPos = function() {
- var code = this.input.charCodeAt(this.pos);
- if (code <= 0xd7ff || code >= 0xe000) { return code }
- var next = this.input.charCodeAt(this.pos + 1);
- return (code << 10) + next - 0x35fdc00
- };
- pp$8.skipBlockComment = function() {
- var this$1 = this;
- var startLoc = this.options.onComment && this.curPosition();
- var start = this.pos, end = this.input.indexOf("*/", this.pos += 2);
- if (end === -1) { this.raise(this.pos - 2, "Unterminated comment"); }
- this.pos = end + 2;
- if (this.options.locations) {
- lineBreakG.lastIndex = start;
- var match;
- while ((match = lineBreakG.exec(this.input)) && match.index < this.pos) {
- ++this$1.curLine;
- this$1.lineStart = match.index + match[0].length;
- }
- }
- if (this.options.onComment)
- { this.options.onComment(true, this.input.slice(start + 2, end), start, this.pos,
- startLoc, this.curPosition()); }
- };
- pp$8.skipLineComment = function(startSkip) {
- var this$1 = this;
- var start = this.pos;
- var startLoc = this.options.onComment && this.curPosition();
- var ch = this.input.charCodeAt(this.pos += startSkip);
- while (this.pos < this.input.length && !isNewLine(ch)) {
- ch = this$1.input.charCodeAt(++this$1.pos);
- }
- if (this.options.onComment)
- { this.options.onComment(false, this.input.slice(start + startSkip, this.pos), start, this.pos,
- startLoc, this.curPosition()); }
- };
- // Called at the start of the parse and after every token. Skips
- // whitespace and comments, and.
- pp$8.skipSpace = function() {
- var this$1 = this;
- loop: while (this.pos < this.input.length) {
- var ch = this$1.input.charCodeAt(this$1.pos);
- switch (ch) {
- case 32: case 160: // ' '
- ++this$1.pos;
- break
- case 13:
- if (this$1.input.charCodeAt(this$1.pos + 1) === 10) {
- ++this$1.pos;
- }
- case 10: case 8232: case 8233:
- ++this$1.pos;
- if (this$1.options.locations) {
- ++this$1.curLine;
- this$1.lineStart = this$1.pos;
- }
- break
- case 47: // '/'
- switch (this$1.input.charCodeAt(this$1.pos + 1)) {
- case 42: // '*'
- this$1.skipBlockComment();
- break
- case 47:
- this$1.skipLineComment(2);
- break
- default:
- break loop
- }
- break
- default:
- if (ch > 8 && ch < 14 || ch >= 5760 && nonASCIIwhitespace.test(String.fromCharCode(ch))) {
- ++this$1.pos;
- } else {
- break loop
- }
- }
- }
- };
- // Called at the end of every token. Sets `end`, `val`, and
- // maintains `context` and `exprAllowed`, and skips the space after
- // the token, so that the next one's `start` will point at the
- // right position.
- pp$8.finishToken = function(type, val) {
- this.end = this.pos;
- if (this.options.locations) { this.endLoc = this.curPosition(); }
- var prevType = this.type;
- this.type = type;
- this.value = val;
- this.updateContext(prevType);
- };
- // ### Token reading
- // This is the function that is called to fetch the next token. It
- // is somewhat obscure, because it works in character codes rather
- // than characters, and because operator parsing has been inlined
- // into it.
- //
- // All in the name of speed.
- //
- pp$8.readToken_dot = function() {
- var next = this.input.charCodeAt(this.pos + 1);
- if (next >= 48 && next <= 57) { return this.readNumber(true) }
- var next2 = this.input.charCodeAt(this.pos + 2);
- if (this.options.ecmaVersion >= 6 && next === 46 && next2 === 46) { // 46 = dot '.'
- this.pos += 3;
- return this.finishToken(types.ellipsis)
- } else {
- ++this.pos;
- return this.finishToken(types.dot)
- }
- };
- pp$8.readToken_slash = function() { // '/'
- var next = this.input.charCodeAt(this.pos + 1);
- if (this.exprAllowed) { ++this.pos; return this.readRegexp() }
- if (next === 61) { return this.finishOp(types.assign, 2) }
- return this.finishOp(types.slash, 1)
- };
- pp$8.readToken_mult_modulo_exp = function(code) { // '%*'
- var next = this.input.charCodeAt(this.pos + 1);
- var size = 1;
- var tokentype = code === 42 ? types.star : types.modulo;
- // exponentiation operator ** and **=
- if (this.options.ecmaVersion >= 7 && code === 42 && next === 42) {
- ++size;
- tokentype = types.starstar;
- next = this.input.charCodeAt(this.pos + 2);
- }
- if (next === 61) { return this.finishOp(types.assign, size + 1) }
- return this.finishOp(tokentype, size)
- };
- pp$8.readToken_pipe_amp = function(code) { // '|&'
- var next = this.input.charCodeAt(this.pos + 1);
- if (next === code) { return this.finishOp(code === 124 ? types.logicalOR : types.logicalAND, 2) }
- if (next === 61) { return this.finishOp(types.assign, 2) }
- return this.finishOp(code === 124 ? types.bitwiseOR : types.bitwiseAND, 1)
- };
- pp$8.readToken_caret = function() { // '^'
- var next = this.input.charCodeAt(this.pos + 1);
- if (next === 61) { return this.finishOp(types.assign, 2) }
- return this.finishOp(types.bitwiseXOR, 1)
- };
- pp$8.readToken_plus_min = function(code) { // '+-'
- var next = this.input.charCodeAt(this.pos + 1);
- if (next === code) {
- if (next === 45 && !this.inModule && this.input.charCodeAt(this.pos + 2) === 62 &&
- (this.lastTokEnd === 0 || lineBreak.test(this.input.slice(this.lastTokEnd, this.pos)))) {
- // A `-->` line comment
- this.skipLineComment(3);
- this.skipSpace();
- return this.nextToken()
- }
- return this.finishOp(types.incDec, 2)
- }
- if (next === 61) { return this.finishOp(types.assign, 2) }
- return this.finishOp(types.plusMin, 1)
- };
- pp$8.readToken_lt_gt = function(code) { // '<>'
- var next = this.input.charCodeAt(this.pos + 1);
- var size = 1;
- if (next === code) {
- size = code === 62 && this.input.charCodeAt(this.pos + 2) === 62 ? 3 : 2;
- if (this.input.charCodeAt(this.pos + size) === 61) { return this.finishOp(types.assign, size + 1) }
- return this.finishOp(types.bitShift, size)
- }
- if (next === 33 && code === 60 && !this.inModule && this.input.charCodeAt(this.pos + 2) === 45 &&
- this.input.charCodeAt(this.pos + 3) === 45) {
- // `<!--`, an XML-style comment that should be interpreted as a line comment
- this.skipLineComment(4);
- this.skipSpace();
- return this.nextToken()
- }
- if (next === 61) { size = 2; }
- return this.finishOp(types.relational, size)
- };
- pp$8.readToken_eq_excl = function(code) { // '=!'
- var next = this.input.charCodeAt(this.pos + 1);
- if (next === 61) { return this.finishOp(types.equality, this.input.charCodeAt(this.pos + 2) === 61 ? 3 : 2) }
- if (code === 61 && next === 62 && this.options.ecmaVersion >= 6) { // '=>'
- this.pos += 2;
- return this.finishToken(types.arrow)
- }
- return this.finishOp(code === 61 ? types.eq : types.prefix, 1)
- };
- pp$8.getTokenFromCode = function(code) {
- switch (code) {
- // The interpretation of a dot depends on whether it is followed
- // by a digit or another two dots.
- case 46: // '.'
- return this.readToken_dot()
- // Punctuation tokens.
- case 40: ++this.pos; return this.finishToken(types.parenL)
- case 41: ++this.pos; return this.finishToken(types.parenR)
- case 59: ++this.pos; return this.finishToken(types.semi)
- case 44: ++this.pos; return this.finishToken(types.comma)
- case 91: ++this.pos; return this.finishToken(types.bracketL)
- case 93: ++this.pos; return this.finishToken(types.bracketR)
- case 123: ++this.pos; return this.finishToken(types.braceL)
- case 125: ++this.pos; return this.finishToken(types.braceR)
- case 58: ++this.pos; return this.finishToken(types.colon)
- case 63: ++this.pos; return this.finishToken(types.question)
- case 96: // '`'
- if (this.options.ecmaVersion < 6) { break }
- ++this.pos;
- return this.finishToken(types.backQuote)
- case 48: // '0'
- var next = this.input.charCodeAt(this.pos + 1);
- if (next === 120 || next === 88) { return this.readRadixNumber(16) } // '0x', '0X' - hex number
- if (this.options.ecmaVersion >= 6) {
- if (next === 111 || next === 79) { return this.readRadixNumber(8) } // '0o', '0O' - octal number
- if (next === 98 || next === 66) { return this.readRadixNumber(2) } // '0b', '0B' - binary number
- }
- // Anything else beginning with a digit is an integer, octal
- // number, or float.
- case 49: case 50: case 51: case 52: case 53: case 54: case 55: case 56: case 57: // 1-9
- return this.readNumber(false)
- // Quotes produce strings.
- case 34: case 39: // '"', "'"
- return this.readString(code)
- // Operators are parsed inline in tiny state machines. '=' (61) is
- // often referred to. `finishOp` simply skips the amount of
- // characters it is given as second argument, and returns a token
- // of the type given by its first argument.
- case 47: // '/'
- return this.readToken_slash()
- case 37: case 42: // '%*'
- return this.readToken_mult_modulo_exp(code)
- case 124: case 38: // '|&'
- return this.readToken_pipe_amp(code)
- case 94: // '^'
- return this.readToken_caret()
- case 43: case 45: // '+-'
- return this.readToken_plus_min(code)
- case 60: case 62: // '<>'
- return this.readToken_lt_gt(code)
- case 61: case 33: // '=!'
- return this.readToken_eq_excl(code)
- case 126: // '~'
- return this.finishOp(types.prefix, 1)
- }
- this.raise(this.pos, "Unexpected character '" + codePointToString(code) + "'");
- };
- pp$8.finishOp = function(type, size) {
- var str = this.input.slice(this.pos, this.pos + size);
- this.pos += size;
- return this.finishToken(type, str)
- };
- pp$8.readRegexp = function() {
- var this$1 = this;
- var escaped, inClass, start = this.pos;
- for (;;) {
- if (this$1.pos >= this$1.input.length) { this$1.raise(start, "Unterminated regular expression"); }
- var ch = this$1.input.charAt(this$1.pos);
- if (lineBreak.test(ch)) { this$1.raise(start, "Unterminated regular expression"); }
- if (!escaped) {
- if (ch === "[") { inClass = true; }
- else if (ch === "]" && inClass) { inClass = false; }
- else if (ch === "/" && !inClass) { break }
- escaped = ch === "\\";
- } else { escaped = false; }
- ++this$1.pos;
- }
- var pattern = this.input.slice(start, this.pos);
- ++this.pos;
- var flagsStart = this.pos;
- var flags = this.readWord1();
- if (this.containsEsc) { this.unexpected(flagsStart); }
- // Validate pattern
- var state = this.regexpState || (this.regexpState = new RegExpValidationState(this));
- state.reset(start, pattern, flags);
- this.validateRegExpFlags(state);
- this.validateRegExpPattern(state);
- // Create Literal#value property value.
- var value = null;
- try {
- value = new RegExp(pattern, flags);
- } catch (e) {
- // ESTree requires null if it failed to instantiate RegExp object.
- // https://github.com/estree/estree/blob/a27003adf4fd7bfad44de9cef372a2eacd527b1c/es5.md#regexpliteral
- }
- return this.finishToken(types.regexp, {pattern: pattern, flags: flags, value: value})
- };
- // Read an integer in the given radix. Return null if zero digits
- // were read, the integer value otherwise. When `len` is given, this
- // will return `null` unless the integer has exactly `len` digits.
- pp$8.readInt = function(radix, len) {
- var this$1 = this;
- var start = this.pos, total = 0;
- for (var i = 0, e = len == null ? Infinity : len; i < e; ++i) {
- var code = this$1.input.charCodeAt(this$1.pos), val = (void 0);
- if (code >= 97) { val = code - 97 + 10; } // a
- else if (code >= 65) { val = code - 65 + 10; } // A
- else if (code >= 48 && code <= 57) { val = code - 48; } // 0-9
- else { val = Infinity; }
- if (val >= radix) { break }
- ++this$1.pos;
- total = total * radix + val;
- }
- if (this.pos === start || len != null && this.pos - start !== len) { return null }
- return total
- };
- pp$8.readRadixNumber = function(radix) {
- this.pos += 2; // 0x
- var val = this.readInt(radix);
- if (val == null) { this.raise(this.start + 2, "Expected number in radix " + radix); }
- if (isIdentifierStart(this.fullCharCodeAtPos())) { this.raise(this.pos, "Identifier directly after number"); }
- return this.finishToken(types.num, val)
- };
- // Read an integer, octal integer, or floating-point number.
- pp$8.readNumber = function(startsWithDot) {
- var start = this.pos;
- if (!startsWithDot && this.readInt(10) === null) { this.raise(start, "Invalid number"); }
- var octal = this.pos - start >= 2 && this.input.charCodeAt(start) === 48;
- if (octal && this.strict) { this.raise(start, "Invalid number"); }
- if (octal && /[89]/.test(this.input.slice(start, this.pos))) { octal = false; }
- var next = this.input.charCodeAt(this.pos);
- if (next === 46 && !octal) { // '.'
- ++this.pos;
- this.readInt(10);
- next = this.input.charCodeAt(this.pos);
- }
- if ((next === 69 || next === 101) && !octal) { // 'eE'
- next = this.input.charCodeAt(++this.pos);
- if (next === 43 || next === 45) { ++this.pos; } // '+-'
- if (this.readInt(10) === null) { this.raise(start, "Invalid number"); }
- }
- if (isIdentifierStart(this.fullCharCodeAtPos())) { this.raise(this.pos, "Identifier directly after number"); }
- var str = this.input.slice(start, this.pos);
- var val = octal ? parseInt(str, 8) : parseFloat(str);
- return this.finishToken(types.num, val)
- };
- // Read a string value, interpreting backslash-escapes.
- pp$8.readCodePoint = function() {
- var ch = this.input.charCodeAt(this.pos), code;
- if (ch === 123) { // '{'
- if (this.options.ecmaVersion < 6) { this.unexpected(); }
- var codePos = ++this.pos;
- code = this.readHexChar(this.input.indexOf("}", this.pos) - this.pos);
- ++this.pos;
- if (code > 0x10FFFF) { this.invalidStringToken(codePos, "Code point out of bounds"); }
- } else {
- code = this.readHexChar(4);
- }
- return code
- };
- function codePointToString(code) {
- // UTF-16 Decoding
- if (code <= 0xFFFF) { return String.fromCharCode(code) }
- code -= 0x10000;
- return String.fromCharCode((code >> 10) + 0xD800, (code & 1023) + 0xDC00)
- }
- pp$8.readString = function(quote) {
- var this$1 = this;
- var out = "", chunkStart = ++this.pos;
- for (;;) {
- if (this$1.pos >= this$1.input.length) { this$1.raise(this$1.start, "Unterminated string constant"); }
- var ch = this$1.input.charCodeAt(this$1.pos);
- if (ch === quote) { break }
- if (ch === 92) { // '\'
- out += this$1.input.slice(chunkStart, this$1.pos);
- out += this$1.readEscapedChar(false);
- chunkStart = this$1.pos;
- } else {
- if (isNewLine(ch, this$1.options.ecmaVersion >= 10)) { this$1.raise(this$1.start, "Unterminated string constant"); }
- ++this$1.pos;
- }
- }
- out += this.input.slice(chunkStart, this.pos++);
- return this.finishToken(types.string, out)
- };
- // Reads template string tokens.
- var INVALID_TEMPLATE_ESCAPE_ERROR = {};
- pp$8.tryReadTemplateToken = function() {
- this.inTemplateElement = true;
- try {
- this.readTmplToken();
- } catch (err) {
- if (err === INVALID_TEMPLATE_ESCAPE_ERROR) {
- this.readInvalidTemplateToken();
- } else {
- throw err
- }
- }
- this.inTemplateElement = false;
- };
- pp$8.invalidStringToken = function(position, message) {
- if (this.inTemplateElement && this.options.ecmaVersion >= 9) {
- throw INVALID_TEMPLATE_ESCAPE_ERROR
- } else {
- this.raise(position, message);
- }
- };
- pp$8.readTmplToken = function() {
- var this$1 = this;
- var out = "", chunkStart = this.pos;
- for (;;) {
- if (this$1.pos >= this$1.input.length) { this$1.raise(this$1.start, "Unterminated template"); }
- var ch = this$1.input.charCodeAt(this$1.pos);
- if (ch === 96 || ch === 36 && this$1.input.charCodeAt(this$1.pos + 1) === 123) { // '`', '${'
- if (this$1.pos === this$1.start && (this$1.type === types.template || this$1.type === types.invalidTemplate)) {
- if (ch === 36) {
- this$1.pos += 2;
- return this$1.finishToken(types.dollarBraceL)
- } else {
- ++this$1.pos;
- return this$1.finishToken(types.backQuote)
- }
- }
- out += this$1.input.slice(chunkStart, this$1.pos);
- return this$1.finishToken(types.template, out)
- }
- if (ch === 92) { // '\'
- out += this$1.input.slice(chunkStart, this$1.pos);
- out += this$1.readEscapedChar(true);
- chunkStart = this$1.pos;
- } else if (isNewLine(ch)) {
- out += this$1.input.slice(chunkStart, this$1.pos);
- ++this$1.pos;
- switch (ch) {
- case 13:
- if (this$1.input.charCodeAt(this$1.pos) === 10) { ++this$1.pos; }
- case 10:
- out += "\n";
- break
- default:
- out += String.fromCharCode(ch);
- break
- }
- if (this$1.options.locations) {
- ++this$1.curLine;
- this$1.lineStart = this$1.pos;
- }
- chunkStart = this$1.pos;
- } else {
- ++this$1.pos;
- }
- }
- };
- // Reads a template token to search for the end, without validating any escape sequences
- pp$8.readInvalidTemplateToken = function() {
- var this$1 = this;
- for (; this.pos < this.input.length; this.pos++) {
- switch (this$1.input[this$1.pos]) {
- case "\\":
- ++this$1.pos;
- break
- case "$":
- if (this$1.input[this$1.pos + 1] !== "{") {
- break
- }
- // falls through
- case "`":
- return this$1.finishToken(types.invalidTemplate, this$1.input.slice(this$1.start, this$1.pos))
- // no default
- }
- }
- this.raise(this.start, "Unterminated template");
- };
- // Used to read escaped characters
- pp$8.readEscapedChar = function(inTemplate) {
- var ch = this.input.charCodeAt(++this.pos);
- ++this.pos;
- switch (ch) {
- case 110: return "\n" // 'n' -> '\n'
- case 114: return "\r" // 'r' -> '\r'
- case 120: return String.fromCharCode(this.readHexChar(2)) // 'x'
- case 117: return codePointToString(this.readCodePoint()) // 'u'
- case 116: return "\t" // 't' -> '\t'
- case 98: return "\b" // 'b' -> '\b'
- case 118: return "\u000b" // 'v' -> '\u000b'
- case 102: return "\f" // 'f' -> '\f'
- case 13: if (this.input.charCodeAt(this.pos) === 10) { ++this.pos; } // '\r\n'
- case 10: // ' \n'
- if (this.options.locations) { this.lineStart = this.pos; ++this.curLine; }
- return ""
- default:
- if (ch >= 48 && ch <= 55) {
- var octalStr = this.input.substr(this.pos - 1, 3).match(/^[0-7]+/)[0];
- var octal = parseInt(octalStr, 8);
- if (octal > 255) {
- octalStr = octalStr.slice(0, -1);
- octal = parseInt(octalStr, 8);
- }
- this.pos += octalStr.length - 1;
- ch = this.input.charCodeAt(this.pos);
- if ((octalStr !== "0" || ch === 56 || ch === 57) && (this.strict || inTemplate)) {
- this.invalidStringToken(
- this.pos - 1 - octalStr.length,
- inTemplate
- ? "Octal literal in template string"
- : "Octal literal in strict mode"
- );
- }
- return String.fromCharCode(octal)
- }
- return String.fromCharCode(ch)
- }
- };
- // Used to read character escape sequences ('\x', '\u', '\U').
- pp$8.readHexChar = function(len) {
- var codePos = this.pos;
- var n = this.readInt(16, len);
- if (n === null) { this.invalidStringToken(codePos, "Bad character escape sequence"); }
- return n
- };
- // Read an identifier, and return it as a string. Sets `this.containsEsc`
- // to whether the word contained a '\u' escape.
- //
- // Incrementally adds only escaped chars, adding other chunks as-is
- // as a micro-optimization.
- pp$8.readWord1 = function() {
- var this$1 = this;
- this.containsEsc = false;
- var word = "", first = true, chunkStart = this.pos;
- var astral = this.options.ecmaVersion >= 6;
- while (this.pos < this.input.length) {
- var ch = this$1.fullCharCodeAtPos();
- if (isIdentifierChar(ch, astral)) {
- this$1.pos += ch <= 0xffff ? 1 : 2;
- } else if (ch === 92) { // "\"
- this$1.containsEsc = true;
- word += this$1.input.slice(chunkStart, this$1.pos);
- var escStart = this$1.pos;
- if (this$1.input.charCodeAt(++this$1.pos) !== 117) // "u"
- { this$1.invalidStringToken(this$1.pos, "Expecting Unicode escape sequence \\uXXXX"); }
- ++this$1.pos;
- var esc = this$1.readCodePoint();
- if (!(first ? isIdentifierStart : isIdentifierChar)(esc, astral))
- { this$1.invalidStringToken(escStart, "Invalid Unicode escape"); }
- word += codePointToString(esc);
- chunkStart = this$1.pos;
- } else {
- break
- }
- first = false;
- }
- return word + this.input.slice(chunkStart, this.pos)
- };
- // Read an identifier or keyword token. Will check for reserved
- // words when necessary.
- pp$8.readWord = function() {
- var word = this.readWord1();
- var type = types.name;
- if (this.keywords.test(word)) {
- if (this.containsEsc) { this.raiseRecoverable(this.start, "Escape sequence in keyword " + word); }
- type = keywords$1[word];
- }
- return this.finishToken(type, word)
- };
- // Acorn is a tiny, fast JavaScript parser written in JavaScript.
- //
- // Acorn was written by Marijn Haverbeke, Ingvar Stepanyan, and
- // various contributors and released under an MIT license.
- //
- // Git repositories for Acorn are available at
- //
- // http://marijnhaverbeke.nl/git/acorn
- // https://github.com/acornjs/acorn.git
- //
- // Please use the [github bug tracker][ghbt] to report issues.
- //
- // [ghbt]: https://github.com/acornjs/acorn/issues
- //
- // This file defines the main parser interface. The library also comes
- // with a [error-tolerant parser][dammit] and an
- // [abstract syntax tree walker][walk], defined in other files.
- //
- // [dammit]: acorn_loose.js
- // [walk]: util/walk.js
- var version = "5.7.3";
- // The main exported interface (under `self.acorn` when in the
- // browser) is a `parse` function that takes a code string and
- // returns an abstract syntax tree as specified by [Mozilla parser
- // API][api].
- //
- // [api]: https://developer.mozilla.org/en-US/docs/SpiderMonkey/Parser_API
- function parse(input, options) {
- return new Parser(options, input).parse()
- }
- // This function tries to parse a single expression at a given
- // offset in a string. Useful for parsing mixed-language formats
- // that embed JavaScript expressions.
- function parseExpressionAt(input, pos, options) {
- var p = new Parser(options, input, pos);
- p.nextToken();
- return p.parseExpression()
- }
- // Acorn is organized as a tokenizer and a recursive-descent parser.
- // The `tokenizer` export provides an interface to the tokenizer.
- function tokenizer(input, options) {
- return new Parser(options, input)
- }
- // This is a terrible kludge to support the existing, pre-ES6
- // interface where the loose parser module retroactively adds exports
- // to this module.
- var parse_dammit;
- var LooseParser;
- var pluginsLoose; // eslint-disable-line camelcase
- function addLooseExports(parse, Parser$$1, plugins$$1) {
- parse_dammit = parse; // eslint-disable-line camelcase
- LooseParser = Parser$$1;
- pluginsLoose = plugins$$1;
- }
- var acorn = /*#__PURE__*/Object.freeze({
- version: version,
- parse: parse,
- parseExpressionAt: parseExpressionAt,
- tokenizer: tokenizer,
- get parse_dammit () { return parse_dammit; },
- get LooseParser () { return LooseParser; },
- get pluginsLoose () { return pluginsLoose; },
- addLooseExports: addLooseExports,
- Parser: Parser,
- plugins: plugins,
- defaultOptions: defaultOptions,
- Position: Position,
- SourceLocation: SourceLocation,
- getLineInfo: getLineInfo,
- Node: Node,
- TokenType: TokenType,
- tokTypes: types,
- keywordTypes: keywords$1,
- TokContext: TokContext,
- tokContexts: types$1,
- isIdentifierChar: isIdentifierChar,
- isIdentifierStart: isIdentifierStart,
- Token: Token,
- isNewLine: isNewLine,
- lineBreak: lineBreak,
- lineBreakG: lineBreakG,
- nonASCIIwhitespace: nonASCIIwhitespace
- });
- const literals = new Map([['true', true], ['false', false], ['null', null]]);
- function readExpression(parser) {
- const start = parser.index;
- const name = parser.readUntil(/\s*}/);
- if (name && /^[a-z]+$/.test(name)) {
- const end = start + name.length;
- if (literals.has(name)) {
- return {
- type: 'Literal',
- start,
- end,
- value: literals.get(name),
- raw: name,
- };
- }
- return {
- type: 'Identifier',
- start,
- end: start + name.length,
- name,
- };
- }
- parser.index = start;
- try {
- const node = parseExpressionAt(parser.template, parser.index, {
- ecmaVersion: 9,
- preserveParens: true,
- plugins: {
- dynamicImport: true
- }
- });
- parser.index = node.end;
- return node;
- }
- catch (err) {
- parser.acornError(err);
- }
- }
- /* eslint-disable no-underscore-dangle */
- const DynamicImportKey = 'Import';
- function injectDynamicImport(acorn) {
- const tt = acorn.tokTypes;
- // NOTE: This allows `yield import()` to parse correctly.
- tt._import.startsExpr = true;
- function parseDynamicImport() {
- const node = this.startNode();
- this.next();
- if (this.type !== tt.parenL) {
- this.unexpected();
- }
- return this.finishNode(node, DynamicImportKey);
- }
- function peekNext() {
- return this.input[this.pos];
- }
- // eslint-disable-next-line no-param-reassign
- acorn.plugins.dynamicImport = function dynamicImportPlugin(instance) {
- instance.extend('parseStatement', nextMethod => (
- function parseStatement(...args) {
- const node = this.startNode();
- if (this.type === tt._import) {
- const nextToken = peekNext.call(this);
- if (nextToken === tt.parenL.label) {
- const expr = this.parseExpression();
- return this.parseExpressionStatement(node, expr);
- }
- }
- return nextMethod.apply(this, args);
- }
- ));
- instance.extend('parseExprAtom', nextMethod => (
- function parseExprAtom(refDestructuringErrors) {
- if (this.type === tt._import) {
- return parseDynamicImport.call(this);
- }
- return nextMethod.call(this, refDestructuringErrors);
- }
- ));
- };
- return acorn;
- }
- function repeat(str, i) {
- let result = '';
- while (i--)
- result += str;
- return result;
- }
- const scriptClosingTag = '</script>';
- injectDynamicImport(acorn);
- function readScript(parser, start, attributes) {
- const scriptStart = parser.index;
- const scriptEnd = parser.template.indexOf(scriptClosingTag, scriptStart);
- if (scriptEnd === -1)
- parser.error({
- code: `unclosed-script`,
- message: `<script> must have a closing tag`
- });
- const source = repeat(' ', scriptStart) + parser.template.slice(scriptStart, scriptEnd);
- parser.index = scriptEnd + scriptClosingTag.length;
- let ast;
- try {
- ast = parse(source, {
- ecmaVersion: 9,
- sourceType: 'module',
- plugins: {
- dynamicImport: true
- }
- });
- }
- catch (err) {
- parser.acornError(err);
- }
- if (!ast.body.length)
- return null;
- ast.start = scriptStart;
- return {
- start,
- end: parser.index,
- attributes,
- content: ast,
- };
- }
- var MAX_LINE_LENGTH = 100;
- var OFFSET_CORRECTION = 60;
- var TAB_REPLACEMENT = ' ';
- function sourceFragment(error, extraLines) {
- function processLines(start, end) {
- return lines.slice(start, end).map(function(line, idx) {
- var num = String(start + idx + 1);
- while (num.length < maxNumLength) {
- num = ' ' + num;
- }
- return num + ' |' + line;
- }).join('\n');
- }
- var lines = error.source.split(/\n|\r\n?|\f/);
- var line = error.line;
- var column = error.column;
- var startLine = Math.max(1, line - extraLines) - 1;
- var endLine = Math.min(line + extraLines, lines.length + 1);
- var maxNumLength = Math.max(4, String(endLine).length) + 1;
- var cutLeft = 0;
- // correct column according to replaced tab before column
- column += (TAB_REPLACEMENT.length - 1) * (lines[line - 1].substr(0, column - 1).match(/\t/g) || []).length;
- if (column > MAX_LINE_LENGTH) {
- cutLeft = column - OFFSET_CORRECTION + 3;
- column = OFFSET_CORRECTION - 2;
- }
- for (var i = startLine; i <= endLine; i++) {
- if (i >= 0 && i < lines.length) {
- lines[i] = lines[i].replace(/\t/g, TAB_REPLACEMENT);
- lines[i] =
- (cutLeft > 0 && lines[i].length > cutLeft ? '\u2026' : '') +
- lines[i].substr(cutLeft, MAX_LINE_LENGTH - 2) +
- (lines[i].length > cutLeft + MAX_LINE_LENGTH - 1 ? '\u2026' : '');
- }
- }
- return [
- processLines(startLine, line),
- new Array(column + maxNumLength + 2).join('-') + '^',
- processLines(line, endLine)
- ].join('\n');
- }
- var CssSyntaxError = function(message, source, offset, line, column) {
- // some VMs prevent setting line/column otherwise (iOS Safari 10 even throw an exception)
- var error = Object.create(SyntaxError.prototype);
- error.name = 'CssSyntaxError';
- error.message = message;
- error.stack = (new Error().stack || '').replace(/^.+\n/, error.name + ': ' + error.message + '\n');
- error.source = source;
- error.offset = offset;
- error.line = line;
- error.column = column;
- error.sourceFragment = function(extraLines) {
- return sourceFragment(error, isNaN(extraLines) ? 0 : extraLines);
- };
- Object.defineProperty(error, 'formattedMessage', {
- get: function() {
- return (
- 'Parse error: ' + error.message + '\n' +
- sourceFragment(error, 2)
- );
- }
- });
- // for backward capability
- error.parseError = {
- offset: offset,
- line: line,
- column: column
- };
- return error;
- };
- var error = CssSyntaxError;
- // token types (note: value shouldn't intersect with used char codes)
- var WHITESPACE = 1;
- var IDENTIFIER = 2;
- var NUMBER = 3;
- var STRING = 4;
- var COMMENT = 5;
- var PUNCTUATOR = 6;
- var CDO = 7;
- var CDC = 8;
- var ATRULE = 14;
- var FUNCTION = 15;
- var URL = 16;
- var RAW = 17;
- var TAB = 9;
- var N = 10;
- var F = 12;
- var R = 13;
- var SPACE = 32;
- var TYPE = {
- WhiteSpace: WHITESPACE,
- Identifier: IDENTIFIER,
- Number: NUMBER,
- String: STRING,
- Comment: COMMENT,
- Punctuator: PUNCTUATOR,
- CDO: CDO,
- CDC: CDC,
- Atrule: ATRULE,
- Function: FUNCTION,
- Url: URL,
- Raw: RAW,
- ExclamationMark: 33, // !
- QuotationMark: 34, // "
- NumberSign: 35, // #
- DollarSign: 36, // $
- PercentSign: 37, // %
- Ampersand: 38, // &
- Apostrophe: 39, // '
- LeftParenthesis: 40, // (
- RightParenthesis: 41, // )
- Asterisk: 42, // *
- PlusSign: 43, // +
- Comma: 44, // ,
- HyphenMinus: 45, // -
- FullStop: 46, // .
- Solidus: 47, // /
- Colon: 58, // :
- Semicolon: 59, // ;
- LessThanSign: 60, // <
- EqualsSign: 61, // =
- GreaterThanSign: 62, // >
- QuestionMark: 63, // ?
- CommercialAt: 64, // @
- LeftSquareBracket: 91, // [
- Backslash: 92, // \
- RightSquareBracket: 93, // ]
- CircumflexAccent: 94, // ^
- LowLine: 95, // _
- GraveAccent: 96, // `
- LeftCurlyBracket: 123, // {
- VerticalLine: 124, // |
- RightCurlyBracket: 125, // }
- Tilde: 126 // ~
- };
- var NAME = Object.keys(TYPE).reduce(function(result, key) {
- result[TYPE[key]] = key;
- return result;
- }, {});
- // https://drafts.csswg.org/css-syntax/#tokenizer-definitions
- // > non-ASCII code point
- // > A code point with a value equal to or greater than U+0080 <control>
- // > name-start code point
- // > A letter, a non-ASCII code point, or U+005F LOW LINE (_).
- // > name code point
- // > A name-start code point, a digit, or U+002D HYPHEN-MINUS (-)
- // That means only ASCII code points has a special meaning and we a maps for 0..127 codes only
- var SafeUint32Array = typeof Uint32Array !== 'undefined' ? Uint32Array : Array; // fallback on Array when TypedArray is not supported
- var SYMBOL_TYPE = new SafeUint32Array(0x80);
- var PUNCTUATION = new SafeUint32Array(0x80);
- var STOP_URL_RAW = new SafeUint32Array(0x80);
- for (var i = 0; i < SYMBOL_TYPE.length; i++) {
- SYMBOL_TYPE[i] = IDENTIFIER;
- }
- // fill categories
- [
- TYPE.ExclamationMark, // !
- TYPE.QuotationMark, // "
- TYPE.NumberSign, // #
- TYPE.DollarSign, // $
- TYPE.PercentSign, // %
- TYPE.Ampersand, // &
- TYPE.Apostrophe, // '
- TYPE.LeftParenthesis, // (
- TYPE.RightParenthesis, // )
- TYPE.Asterisk, // *
- TYPE.PlusSign, // +
- TYPE.Comma, // ,
- TYPE.HyphenMinus, // -
- TYPE.FullStop, // .
- TYPE.Solidus, // /
- TYPE.Colon, // :
- TYPE.Semicolon, // ;
- TYPE.LessThanSign, // <
- TYPE.EqualsSign, // =
- TYPE.GreaterThanSign, // >
- TYPE.QuestionMark, // ?
- TYPE.CommercialAt, // @
- TYPE.LeftSquareBracket, // [
- // TYPE.Backslash, // \
- TYPE.RightSquareBracket, // ]
- TYPE.CircumflexAccent, // ^
- // TYPE.LowLine, // _
- TYPE.GraveAccent, // `
- TYPE.LeftCurlyBracket, // {
- TYPE.VerticalLine, // |
- TYPE.RightCurlyBracket, // }
- TYPE.Tilde // ~
- ].forEach(function(key) {
- SYMBOL_TYPE[Number(key)] = PUNCTUATOR;
- PUNCTUATION[Number(key)] = PUNCTUATOR;
- });
- for (var i = 48; i <= 57; i++) {
- SYMBOL_TYPE[i] = NUMBER;
- }
- SYMBOL_TYPE[SPACE] = WHITESPACE;
- SYMBOL_TYPE[TAB] = WHITESPACE;
- SYMBOL_TYPE[N] = WHITESPACE;
- SYMBOL_TYPE[R] = WHITESPACE;
- SYMBOL_TYPE[F] = WHITESPACE;
- SYMBOL_TYPE[TYPE.Apostrophe] = STRING;
- SYMBOL_TYPE[TYPE.QuotationMark] = STRING;
- STOP_URL_RAW[SPACE] = 1;
- STOP_URL_RAW[TAB] = 1;
- STOP_URL_RAW[N] = 1;
- STOP_URL_RAW[R] = 1;
- STOP_URL_RAW[F] = 1;
- STOP_URL_RAW[TYPE.Apostrophe] = 1;
- STOP_URL_RAW[TYPE.QuotationMark] = 1;
- STOP_URL_RAW[TYPE.LeftParenthesis] = 1;
- STOP_URL_RAW[TYPE.RightParenthesis] = 1;
- // whitespace is punctuation ...
- PUNCTUATION[SPACE] = PUNCTUATOR;
- PUNCTUATION[TAB] = PUNCTUATOR;
- PUNCTUATION[N] = PUNCTUATOR;
- PUNCTUATION[R] = PUNCTUATOR;
- PUNCTUATION[F] = PUNCTUATOR;
- // ... hyper minus is not
- PUNCTUATION[TYPE.HyphenMinus] = 0;
- var _const = {
- TYPE: TYPE,
- NAME: NAME,
- SYMBOL_TYPE: SYMBOL_TYPE,
- PUNCTUATION: PUNCTUATION,
- STOP_URL_RAW: STOP_URL_RAW
- };
- var PUNCTUATION$1 = _const.PUNCTUATION;
- var STOP_URL_RAW$1 = _const.STOP_URL_RAW;
- var TYPE$1 = _const.TYPE;
- var FULLSTOP = TYPE$1.FullStop;
- var PLUSSIGN = TYPE$1.PlusSign;
- var HYPHENMINUS = TYPE$1.HyphenMinus;
- var PUNCTUATOR$1 = TYPE$1.Punctuator;
- var TAB$1 = 9;
- var N$1 = 10;
- var F$1 = 12;
- var R$1 = 13;
- var SPACE$1 = 32;
- var BACK_SLASH = 92;
- var E = 101; // 'e'.charCodeAt(0)
- function firstCharOffset(source) {
- // detect BOM (https://en.wikipedia.org/wiki/Byte_order_mark)
- if (source.charCodeAt(0) === 0xFEFF || // UTF-16BE
- source.charCodeAt(0) === 0xFFFE) { // UTF-16LE
- return 1;
- }
- return 0;
- }
- function isHex(code) {
- return (code >= 48 && code <= 57) || // 0 .. 9
- (code >= 65 && code <= 70) || // A .. F
- (code >= 97 && code <= 102); // a .. f
- }
- function isNumber(code) {
- return code >= 48 && code <= 57;
- }
- function isNewline(source, offset, code) {
- if (code === N$1 || code === F$1 || code === R$1) {
- if (code === R$1 && offset + 1 < source.length && source.charCodeAt(offset + 1) === N$1) {
- return 2;
- }
- return 1;
- }
- return 0;
- }
- function cmpChar(testStr, offset, referenceCode) {
- var code = testStr.charCodeAt(offset);
- // code.toLowerCase()
- if (code >= 65 && code <= 90) {
- code = code | 32;
- }
- return code === referenceCode;
- }
- function cmpStr(testStr, start, end, referenceStr) {
- if (end - start !== referenceStr.length) {
- return false;
- }
- if (start < 0 || end > testStr.length) {
- return false;
- }
- for (var i = start; i < end; i++) {
- var testCode = testStr.charCodeAt(i);
- var refCode = referenceStr.charCodeAt(i - start);
- // testStr[i].toLowerCase()
- if (testCode >= 65 && testCode <= 90) {
- testCode = testCode | 32;
- }
- if (testCode !== refCode) {
- return false;
- }
- }
- return true;
- }
- function endsWith(testStr, referenceStr) {
- return cmpStr(testStr, testStr.length - referenceStr.length, testStr.length, referenceStr);
- }
- function findLastNonSpaceLocation(scanner) {
- for (var i = scanner.source.length - 1; i >= 0; i--) {
- var code = scanner.source.charCodeAt(i);
- if (code !== SPACE$1 && code !== TAB$1 && code !== R$1 && code !== N$1 && code !== F$1) {
- break;
- }
- }
- return scanner.getLocation(i + 1);
- }
- function findWhiteSpaceEnd(source, offset) {
- for (; offset < source.length; offset++) {
- var code = source.charCodeAt(offset);
- if (code !== SPACE$1 && code !== TAB$1 && code !== R$1 && code !== N$1 && code !== F$1) {
- break;
- }
- }
- return offset;
- }
- function findCommentEnd(source, offset) {
- var commentEnd = source.indexOf('*/', offset);
- if (commentEnd === -1) {
- return source.length;
- }
- return commentEnd + 2;
- }
- function findStringEnd(source, offset, quote) {
- for (; offset < source.length; offset++) {
- var code = source.charCodeAt(offset);
- // TODO: bad string
- if (code === BACK_SLASH) {
- offset++;
- } else if (code === quote) {
- offset++;
- break;
- }
- }
- return offset;
- }
- function findDecimalNumberEnd(source, offset) {
- for (; offset < source.length; offset++) {
- var code = source.charCodeAt(offset);
- if (code < 48 || code > 57) { // not a 0 .. 9
- break;
- }
- }
- return offset;
- }
- function findNumberEnd(source, offset, allowFraction) {
- var code;
- offset = findDecimalNumberEnd(source, offset);
- // fraction: .\d+
- if (allowFraction && offset + 1 < source.length && source.charCodeAt(offset) === FULLSTOP) {
- code = source.charCodeAt(offset + 1);
- if (isNumber(code)) {
- offset = findDecimalNumberEnd(source, offset + 1);
- }
- }
- // exponent: e[+-]\d+
- if (offset + 1 < source.length) {
- if ((source.charCodeAt(offset) | 32) === E) { // case insensitive check for `e`
- code = source.charCodeAt(offset + 1);
- if (code === PLUSSIGN || code === HYPHENMINUS) {
- if (offset + 2 < source.length) {
- code = source.charCodeAt(offset + 2);
- }
- }
- if (isNumber(code)) {
- offset = findDecimalNumberEnd(source, offset + 2);
- }
- }
- }
- return offset;
- }
- // skip escaped unicode sequence that can ends with space
- // [0-9a-f]{1,6}(\r\n|[ \n\r\t\f])?
- function findEscaseEnd(source, offset) {
- for (var i = 0; i < 7 && offset + i < source.length; i++) {
- var code = source.charCodeAt(offset + i);
- if (i !== 6 && isHex(code)) {
- continue;
- }
- if (i > 0) {
- offset += i - 1 + isNewline(source, offset + i, code);
- if (code === SPACE$1 || code === TAB$1) {
- offset++;
- }
- }
- break;
- }
- return offset;
- }
- function findIdentifierEnd(source, offset) {
- for (; offset < source.length; offset++) {
- var code = source.charCodeAt(offset);
- if (code === BACK_SLASH) {
- offset = findEscaseEnd(source, offset + 1);
- } else if (code < 0x80 && PUNCTUATION$1[code] === PUNCTUATOR$1) {
- break;
- }
- }
- return offset;
- }
- function findUrlRawEnd(source, offset) {
- for (; offset < source.length; offset++) {
- var code = source.charCodeAt(offset);
- if (code === BACK_SLASH) {
- offset = findEscaseEnd(source, offset + 1);
- } else if (code < 0x80 && STOP_URL_RAW$1[code] === 1) {
- break;
- }
- }
- return offset;
- }
- var utils = {
- firstCharOffset: firstCharOffset,
- isHex: isHex,
- isNumber: isNumber,
- isNewline: isNewline,
- cmpChar: cmpChar,
- cmpStr: cmpStr,
- endsWith: endsWith,
- findLastNonSpaceLocation: findLastNonSpaceLocation,
- findWhiteSpaceEnd: findWhiteSpaceEnd,
- findCommentEnd: findCommentEnd,
- findStringEnd: findStringEnd,
- findDecimalNumberEnd: findDecimalNumberEnd,
- findNumberEnd: findNumberEnd,
- findEscaseEnd: findEscaseEnd,
- findIdentifierEnd: findIdentifierEnd,
- findUrlRawEnd: findUrlRawEnd
- };
- var TYPE$2 = _const.TYPE;
- var NAME$1 = _const.NAME;
- var SYMBOL_TYPE$1 = _const.SYMBOL_TYPE;
- var firstCharOffset$1 = utils.firstCharOffset;
- var cmpStr$1 = utils.cmpStr;
- var isNumber$1 = utils.isNumber;
- var findLastNonSpaceLocation$1 = utils.findLastNonSpaceLocation;
- var findWhiteSpaceEnd$1 = utils.findWhiteSpaceEnd;
- var findCommentEnd$1 = utils.findCommentEnd;
- var findStringEnd$1 = utils.findStringEnd;
- var findNumberEnd$1 = utils.findNumberEnd;
- var findIdentifierEnd$1 = utils.findIdentifierEnd;
- var findUrlRawEnd$1 = utils.findUrlRawEnd;
- var NULL = 0;
- var WHITESPACE$1 = TYPE$2.WhiteSpace;
- var IDENTIFIER$1 = TYPE$2.Identifier;
- var NUMBER$1 = TYPE$2.Number;
- var STRING$1 = TYPE$2.String;
- var COMMENT$1 = TYPE$2.Comment;
- var PUNCTUATOR$2 = TYPE$2.Punctuator;
- var CDO$1 = TYPE$2.CDO;
- var CDC$1 = TYPE$2.CDC;
- var ATRULE$1 = TYPE$2.Atrule;
- var FUNCTION$1 = TYPE$2.Function;
- var URL$1 = TYPE$2.Url;
- var RAW$1 = TYPE$2.Raw;
- var N$2 = 10;
- var F$2 = 12;
- var R$2 = 13;
- var STAR = TYPE$2.Asterisk;
- var SLASH = TYPE$2.Solidus;
- var FULLSTOP$1 = TYPE$2.FullStop;
- var PLUSSIGN$1 = TYPE$2.PlusSign;
- var HYPHENMINUS$1 = TYPE$2.HyphenMinus;
- var GREATERTHANSIGN = TYPE$2.GreaterThanSign;
- var LESSTHANSIGN = TYPE$2.LessThanSign;
- var EXCLAMATIONMARK = TYPE$2.ExclamationMark;
- var COMMERCIALAT = TYPE$2.CommercialAt;
- var QUOTATIONMARK = TYPE$2.QuotationMark;
- var APOSTROPHE = TYPE$2.Apostrophe;
- var LEFTPARENTHESIS = TYPE$2.LeftParenthesis;
- var RIGHTPARENTHESIS = TYPE$2.RightParenthesis;
- var LEFTCURLYBRACKET = TYPE$2.LeftCurlyBracket;
- var RIGHTCURLYBRACKET = TYPE$2.RightCurlyBracket;
- var LEFTSQUAREBRACKET = TYPE$2.LeftSquareBracket;
- var RIGHTSQUAREBRACKET = TYPE$2.RightSquareBracket;
- var MIN_BUFFER_SIZE = 16 * 1024;
- var OFFSET_MASK = 0x00FFFFFF;
- var TYPE_SHIFT = 24;
- var SafeUint32Array$1 = typeof Uint32Array !== 'undefined' ? Uint32Array : Array; // fallback on Array when TypedArray is not supported
- function computeLinesAndColumns(tokenizer, source) {
- var sourceLength = source.length;
- var start = firstCharOffset$1(source);
- var lines = tokenizer.lines;
- var line = tokenizer.startLine;
- var columns = tokenizer.columns;
- var column = tokenizer.startColumn;
- if (lines === null || lines.length < sourceLength + 1) {
- lines = new SafeUint32Array$1(Math.max(sourceLength + 1024, MIN_BUFFER_SIZE));
- columns = new SafeUint32Array$1(lines.length);
- }
- for (var i = start; i < sourceLength; i++) {
- var code = source.charCodeAt(i);
- lines[i] = line;
- columns[i] = column++;
- if (code === N$2 || code === R$2 || code === F$2) {
- if (code === R$2 && i + 1 < sourceLength && source.charCodeAt(i + 1) === N$2) {
- i++;
- lines[i] = line;
- columns[i] = column;
- }
- line++;
- column = 1;
- }
- }
- lines[i] = line;
- columns[i] = column;
- tokenizer.linesAnsColumnsComputed = true;
- tokenizer.lines = lines;
- tokenizer.columns = columns;
- }
- function tokenLayout(tokenizer, source, startPos) {
- var sourceLength = source.length;
- var offsetAndType = tokenizer.offsetAndType;
- var balance = tokenizer.balance;
- var tokenCount = 0;
- var prevType = 0;
- var offset = startPos;
- var anchor = 0;
- var balanceCloseCode = 0;
- var balanceStart = 0;
- var balancePrev = 0;
- if (offsetAndType === null || offsetAndType.length < sourceLength + 1) {
- offsetAndType = new SafeUint32Array$1(sourceLength + 1024);
- balance = new SafeUint32Array$1(sourceLength + 1024);
- }
- while (offset < sourceLength) {
- var code = source.charCodeAt(offset);
- var type = code < 0x80 ? SYMBOL_TYPE$1[code] : IDENTIFIER$1;
- balance[tokenCount] = sourceLength;
- switch (type) {
- case WHITESPACE$1:
- offset = findWhiteSpaceEnd$1(source, offset + 1);
- break;
- case PUNCTUATOR$2:
- switch (code) {
- case balanceCloseCode:
- balancePrev = balanceStart & OFFSET_MASK;
- balanceStart = balance[balancePrev];
- balanceCloseCode = balanceStart >> TYPE_SHIFT;
- balance[tokenCount] = balancePrev;
- balance[balancePrev++] = tokenCount;
- for (; balancePrev < tokenCount; balancePrev++) {
- if (balance[balancePrev] === sourceLength) {
- balance[balancePrev] = tokenCount;
- }
- }
- break;
- case LEFTSQUAREBRACKET:
- balance[tokenCount] = balanceStart;
- balanceCloseCode = RIGHTSQUAREBRACKET;
- balanceStart = (balanceCloseCode << TYPE_SHIFT) | tokenCount;
- break;
- case LEFTCURLYBRACKET:
- balance[tokenCount] = balanceStart;
- balanceCloseCode = RIGHTCURLYBRACKET;
- balanceStart = (balanceCloseCode << TYPE_SHIFT) | tokenCount;
- break;
- case LEFTPARENTHESIS:
- balance[tokenCount] = balanceStart;
- balanceCloseCode = RIGHTPARENTHESIS;
- balanceStart = (balanceCloseCode << TYPE_SHIFT) | tokenCount;
- break;
- }
- // /*
- if (code === STAR && prevType === SLASH) {
- type = COMMENT$1;
- offset = findCommentEnd$1(source, offset + 1);
- tokenCount--; // rewrite prev token
- break;
- }
- // edge case for -.123 and +.123
- if (code === FULLSTOP$1 && (prevType === PLUSSIGN$1 || prevType === HYPHENMINUS$1)) {
- if (offset + 1 < sourceLength && isNumber$1(source.charCodeAt(offset + 1))) {
- type = NUMBER$1;
- offset = findNumberEnd$1(source, offset + 2, false);
- tokenCount--; // rewrite prev token
- break;
- }
- }
- // <!--
- if (code === EXCLAMATIONMARK && prevType === LESSTHANSIGN) {
- if (offset + 2 < sourceLength &&
- source.charCodeAt(offset + 1) === HYPHENMINUS$1 &&
- source.charCodeAt(offset + 2) === HYPHENMINUS$1) {
- type = CDO$1;
- offset = offset + 3;
- tokenCount--; // rewrite prev token
- break;
- }
- }
- // -->
- if (code === HYPHENMINUS$1 && prevType === HYPHENMINUS$1) {
- if (offset + 1 < sourceLength && source.charCodeAt(offset + 1) === GREATERTHANSIGN) {
- type = CDC$1;
- offset = offset + 2;
- tokenCount--; // rewrite prev token
- break;
- }
- }
- // ident(
- if (code === LEFTPARENTHESIS && prevType === IDENTIFIER$1) {
- offset = offset + 1;
- tokenCount--; // rewrite prev token
- balance[tokenCount] = balance[tokenCount + 1];
- balanceStart--;
- // 4 char length identifier and equal to `url(` (case insensitive)
- if (offset - anchor === 4 && cmpStr$1(source, anchor, offset, 'url(')) {
- // special case for url() because it can contain any symbols sequence with few exceptions
- anchor = findWhiteSpaceEnd$1(source, offset);
- code = source.charCodeAt(anchor);
- if (code !== LEFTPARENTHESIS &&
- code !== RIGHTPARENTHESIS &&
- code !== QUOTATIONMARK &&
- code !== APOSTROPHE) {
- // url(
- offsetAndType[tokenCount++] = (URL$1 << TYPE_SHIFT) | offset;
- balance[tokenCount] = sourceLength;
- // ws*
- if (anchor !== offset) {
- offsetAndType[tokenCount++] = (WHITESPACE$1 << TYPE_SHIFT) | anchor;
- balance[tokenCount] = sourceLength;
- }
- // raw
- type = RAW$1;
- offset = findUrlRawEnd$1(source, anchor);
- } else {
- type = URL$1;
- }
- } else {
- type = FUNCTION$1;
- }
- break;
- }
- type = code;
- offset = offset + 1;
- break;
- case NUMBER$1:
- offset = findNumberEnd$1(source, offset + 1, prevType !== FULLSTOP$1);
- // merge number with a preceding dot, dash or plus
- if (prevType === FULLSTOP$1 ||
- prevType === HYPHENMINUS$1 ||
- prevType === PLUSSIGN$1) {
- tokenCount--; // rewrite prev token
- }
- break;
- case STRING$1:
- offset = findStringEnd$1(source, offset + 1, code);
- break;
- default:
- anchor = offset;
- offset = findIdentifierEnd$1(source, offset);
- // merge identifier with a preceding dash
- if (prevType === HYPHENMINUS$1) {
- // rewrite prev token
- tokenCount--;
- // restore prev prev token type
- // for case @-prefix-ident
- prevType = tokenCount === 0 ? 0 : offsetAndType[tokenCount - 1] >> TYPE_SHIFT;
- }
- if (prevType === COMMERCIALAT) {
- // rewrite prev token and change type to <at-keyword-token>
- tokenCount--;
- type = ATRULE$1;
- }
- }
- offsetAndType[tokenCount++] = (type << TYPE_SHIFT) | offset;
- prevType = type;
- }
- // finalize arrays
- offsetAndType[tokenCount] = offset;
- balance[tokenCount] = sourceLength;
- while (balanceStart !== 0) {
- balancePrev = balanceStart & OFFSET_MASK;
- balanceStart = balance[balancePrev];
- balance[balancePrev] = sourceLength;
- }
- tokenizer.offsetAndType = offsetAndType;
- tokenizer.tokenCount = tokenCount;
- tokenizer.balance = balance;
- }
- //
- // tokenizer
- //
- var Tokenizer = function(source, startOffset, startLine, startColumn) {
- this.offsetAndType = null;
- this.balance = null;
- this.lines = null;
- this.columns = null;
- this.setSource(source, startOffset, startLine, startColumn);
- };
- Tokenizer.prototype = {
- setSource: function(source, startOffset, startLine, startColumn) {
- var safeSource = String(source || '');
- var start = firstCharOffset$1(safeSource);
- this.source = safeSource;
- this.firstCharOffset = start;
- this.startOffset = typeof startOffset === 'undefined' ? 0 : startOffset;
- this.startLine = typeof startLine === 'undefined' ? 1 : startLine;
- this.startColumn = typeof startColumn === 'undefined' ? 1 : startColumn;
- this.linesAnsColumnsComputed = false;
- this.eof = false;
- this.currentToken = -1;
- this.tokenType = 0;
- this.tokenStart = start;
- this.tokenEnd = start;
- tokenLayout(this, safeSource, start);
- this.next();
- },
- lookupType: function(offset) {
- offset += this.currentToken;
- if (offset < this.tokenCount) {
- return this.offsetAndType[offset] >> TYPE_SHIFT;
- }
- return NULL;
- },
- lookupNonWSType: function(offset) {
- offset += this.currentToken;
- for (var type; offset < this.tokenCount; offset++) {
- type = this.offsetAndType[offset] >> TYPE_SHIFT;
- if (type !== WHITESPACE$1) {
- return type;
- }
- }
- return NULL;
- },
- lookupValue: function(offset, referenceStr) {
- offset += this.currentToken;
- if (offset < this.tokenCount) {
- return cmpStr$1(
- this.source,
- this.offsetAndType[offset - 1] & OFFSET_MASK,
- this.offsetAndType[offset] & OFFSET_MASK,
- referenceStr
- );
- }
- return false;
- },
- getTokenStart: function(tokenNum) {
- if (tokenNum === this.currentToken) {
- return this.tokenStart;
- }
- if (tokenNum > 0) {
- return tokenNum < this.tokenCount
- ? this.offsetAndType[tokenNum - 1] & OFFSET_MASK
- : this.offsetAndType[this.tokenCount] & OFFSET_MASK;
- }
- return this.firstCharOffset;
- },
- getOffsetExcludeWS: function() {
- if (this.currentToken > 0) {
- if ((this.offsetAndType[this.currentToken - 1] >> TYPE_SHIFT) === WHITESPACE$1) {
- return this.currentToken > 1
- ? this.offsetAndType[this.currentToken - 2] & OFFSET_MASK
- : this.firstCharOffset;
- }
- }
- return this.tokenStart;
- },
- getRawLength: function(startToken, endTokenType1, endTokenType2, includeTokenType2) {
- var cursor = startToken;
- var balanceEnd;
- loop:
- for (; cursor < this.tokenCount; cursor++) {
- balanceEnd = this.balance[cursor];
- // belance end points to offset before start
- if (balanceEnd < startToken) {
- break loop;
- }
- // check token is stop type
- switch (this.offsetAndType[cursor] >> TYPE_SHIFT) {
- case endTokenType1:
- break loop;
- case endTokenType2:
- if (includeTokenType2) {
- cursor++;
- }
- break loop;
- default:
- // fast forward to the end of balanced block
- if (this.balance[balanceEnd] === cursor) {
- cursor = balanceEnd;
- }
- }
- }
- return cursor - this.currentToken;
- },
- getTokenValue: function() {
- return this.source.substring(this.tokenStart, this.tokenEnd);
- },
- substrToCursor: function(start) {
- return this.source.substring(start, this.tokenStart);
- },
- skipWS: function() {
- for (var i = this.currentToken, skipTokenCount = 0; i < this.tokenCount; i++, skipTokenCount++) {
- if ((this.offsetAndType[i] >> TYPE_SHIFT) !== WHITESPACE$1) {
- break;
- }
- }
- if (skipTokenCount > 0) {
- this.skip(skipTokenCount);
- }
- },
- skipSC: function() {
- while (this.tokenType === WHITESPACE$1 || this.tokenType === COMMENT$1) {
- this.next();
- }
- },
- skip: function(tokenCount) {
- var next = this.currentToken + tokenCount;
- if (next < this.tokenCount) {
- this.currentToken = next;
- this.tokenStart = this.offsetAndType[next - 1] & OFFSET_MASK;
- next = this.offsetAndType[next];
- this.tokenType = next >> TYPE_SHIFT;
- this.tokenEnd = next & OFFSET_MASK;
- } else {
- this.currentToken = this.tokenCount;
- this.next();
- }
- },
- next: function() {
- var next = this.currentToken + 1;
- if (next < this.tokenCount) {
- this.currentToken = next;
- this.tokenStart = this.tokenEnd;
- next = this.offsetAndType[next];
- this.tokenType = next >> TYPE_SHIFT;
- this.tokenEnd = next & OFFSET_MASK;
- } else {
- this.currentToken = this.tokenCount;
- this.eof = true;
- this.tokenType = NULL;
- this.tokenStart = this.tokenEnd = this.source.length;
- }
- },
- eat: function(tokenType) {
- if (this.tokenType !== tokenType) {
- var offset = this.tokenStart;
- var message = NAME$1[tokenType] + ' is expected';
- // tweak message and offset
- if (tokenType === IDENTIFIER$1) {
- // when identifier is expected but there is a function or url
- if (this.tokenType === FUNCTION$1 || this.tokenType === URL$1) {
- offset = this.tokenEnd - 1;
- message += ' but function found';
- }
- } else {
- // when test type is part of another token show error for current position + 1
- // e.g. eat(HYPHENMINUS) will fail on "-foo", but pointing on "-" is odd
- if (this.source.charCodeAt(this.tokenStart) === tokenType) {
- offset = offset + 1;
- }
- }
- this.error(message, offset);
- }
- this.next();
- },
- eatNonWS: function(tokenType) {
- this.skipWS();
- this.eat(tokenType);
- },
- consume: function(tokenType) {
- var value = this.getTokenValue();
- this.eat(tokenType);
- return value;
- },
- consumeFunctionName: function() {
- var name = this.source.substring(this.tokenStart, this.tokenEnd - 1);
- this.eat(FUNCTION$1);
- return name;
- },
- consumeNonWS: function(tokenType) {
- this.skipWS();
- return this.consume(tokenType);
- },
- expectIdentifier: function(name) {
- if (this.tokenType !== IDENTIFIER$1 || cmpStr$1(this.source, this.tokenStart, this.tokenEnd, name) === false) {
- this.error('Identifier `' + name + '` is expected');
- }
- this.next();
- },
- getLocation: function(offset, filename) {
- if (!this.linesAnsColumnsComputed) {
- computeLinesAndColumns(this, this.source);
- }
- return {
- source: filename,
- offset: this.startOffset + offset,
- line: this.lines[offset],
- column: this.columns[offset]
- };
- },
- getLocationRange: function(start, end, filename) {
- if (!this.linesAnsColumnsComputed) {
- computeLinesAndColumns(this, this.source);
- }
- return {
- source: filename,
- start: {
- offset: this.startOffset + start,
- line: this.lines[start],
- column: this.columns[start]
- },
- end: {
- offset: this.startOffset + end,
- line: this.lines[end],
- column: this.columns[end]
- }
- };
- },
- error: function(message, offset) {
- var location = typeof offset !== 'undefined' && offset < this.source.length
- ? this.getLocation(offset)
- : this.eof
- ? findLastNonSpaceLocation$1(this)
- : this.getLocation(this.tokenStart);
- throw new error(
- message || 'Unexpected input',
- this.source,
- location.offset,
- location.line,
- location.column
- );
- },
- dump: function() {
- var offset = 0;
- return Array.prototype.slice.call(this.offsetAndType, 0, this.tokenCount).map(function(item, idx) {
- var start = offset;
- var end = item & OFFSET_MASK;
- offset = end;
- return {
- idx: idx,
- type: NAME$1[item >> TYPE_SHIFT],
- chunk: this.source.substring(start, end),
- balance: this.balance[idx]
- };
- }, this);
- }
- };
- // extend with error class
- Tokenizer.CssSyntaxError = error;
- // extend tokenizer with constants
- Object.keys(_const).forEach(function(key) {
- Tokenizer[key] = _const[key];
- });
- // extend tokenizer with static methods from utils
- Object.keys(utils).forEach(function(key) {
- Tokenizer[key] = utils[key];
- });
- // warm up tokenizer to elimitate code branches that never execute
- // fix soft deoptimizations (insufficient type feedback)
- new Tokenizer('\n\r\r\n\f<!---->//""\'\'/*\r\n\f*/1a;.\\31\t\+2{url(a);func();+1.2e3 -.4e-5 .6e+7}').getLocation();
- var Tokenizer_1 = Tokenizer;
- var tokenizer$1 = Tokenizer_1;
- //
- // item item item item
- // /------\ /------\ /------\ /------\
- // | data | | data | | data | | data |
- // null <--+-prev |<---+-prev |<---+-prev |<---+-prev |
- // | next-+--->| next-+--->| next-+--->| next-+--> null
- // \------/ \------/ \------/ \------/
- // ^ ^
- // | list |
- // | /------\ |
- // \--------------+-head | |
- // | tail-+--------------/
- // \------/
- //
- function createItem(data) {
- return {
- prev: null,
- next: null,
- data: data
- };
- }
- var cursors = null;
- var List = function() {
- this.cursor = null;
- this.head = null;
- this.tail = null;
- };
- List.createItem = createItem;
- List.prototype.createItem = createItem;
- List.prototype.getSize = function() {
- var size = 0;
- var cursor = this.head;
- while (cursor) {
- size++;
- cursor = cursor.next;
- }
- return size;
- };
- List.prototype.fromArray = function(array) {
- var cursor = null;
- this.head = null;
- for (var i = 0; i < array.length; i++) {
- var item = createItem(array[i]);
- if (cursor !== null) {
- cursor.next = item;
- } else {
- this.head = item;
- }
- item.prev = cursor;
- cursor = item;
- }
- this.tail = cursor;
- return this;
- };
- List.prototype.toArray = function() {
- var cursor = this.head;
- var result = [];
- while (cursor) {
- result.push(cursor.data);
- cursor = cursor.next;
- }
- return result;
- };
- List.prototype.toJSON = List.prototype.toArray;
- List.prototype.isEmpty = function() {
- return this.head === null;
- };
- List.prototype.first = function() {
- return this.head && this.head.data;
- };
- List.prototype.last = function() {
- return this.tail && this.tail.data;
- };
- function allocateCursor(node, prev, next) {
- var cursor;
- if (cursors !== null) {
- cursor = cursors;
- cursors = cursors.cursor;
- cursor.prev = prev;
- cursor.next = next;
- cursor.cursor = node.cursor;
- } else {
- cursor = {
- prev: prev,
- next: next,
- cursor: node.cursor
- };
- }
- node.cursor = cursor;
- return cursor;
- }
- function releaseCursor(node) {
- var cursor = node.cursor;
- node.cursor = cursor.cursor;
- cursor.prev = null;
- cursor.next = null;
- cursor.cursor = cursors;
- cursors = cursor;
- }
- List.prototype.each = function(fn, context) {
- var item;
- if (context === undefined) {
- context = this;
- }
- // push cursor
- var cursor = allocateCursor(this, null, this.head);
- while (cursor.next !== null) {
- item = cursor.next;
- cursor.next = item.next;
- fn.call(context, item.data, item, this);
- }
- // pop cursor
- releaseCursor(this);
- };
- List.prototype.eachRight = function(fn, context) {
- var item;
- if (context === undefined) {
- context = this;
- }
- // push cursor
- var cursor = allocateCursor(this, this.tail, null);
- while (cursor.prev !== null) {
- item = cursor.prev;
- cursor.prev = item.prev;
- fn.call(context, item.data, item, this);
- }
- // pop cursor
- releaseCursor(this);
- };
- List.prototype.nextUntil = function(start, fn, context) {
- if (start === null) {
- return;
- }
- var item;
- if (context === undefined) {
- context = this;
- }
- // push cursor
- var cursor = allocateCursor(this, null, start);
- while (cursor.next !== null) {
- item = cursor.next;
- cursor.next = item.next;
- if (fn.call(context, item.data, item, this)) {
- break;
- }
- }
- // pop cursor
- releaseCursor(this);
- };
- List.prototype.prevUntil = function(start, fn, context) {
- if (start === null) {
- return;
- }
- var item;
- if (context === undefined) {
- context = this;
- }
- // push cursor
- var cursor = allocateCursor(this, start, null);
- while (cursor.prev !== null) {
- item = cursor.prev;
- cursor.prev = item.prev;
- if (fn.call(context, item.data, item, this)) {
- break;
- }
- }
- // pop cursor
- releaseCursor(this);
- };
- List.prototype.some = function(fn, context) {
- var cursor = this.head;
- if (context === undefined) {
- context = this;
- }
- while (cursor !== null) {
- if (fn.call(context, cursor.data, cursor, this)) {
- return true;
- }
- cursor = cursor.next;
- }
- return false;
- };
- List.prototype.map = function(fn, context) {
- var result = [];
- var cursor = this.head;
- if (context === undefined) {
- context = this;
- }
- while (cursor !== null) {
- result.push(fn.call(context, cursor.data, cursor, this));
- cursor = cursor.next;
- }
- return result;
- };
- List.prototype.clear = function() {
- this.head = null;
- this.tail = null;
- };
- List.prototype.copy = function() {
- var result = new List();
- var cursor = this.head;
- while (cursor !== null) {
- result.insert(createItem(cursor.data));
- cursor = cursor.next;
- }
- return result;
- };
- List.prototype.updateCursors = function(prevOld, prevNew, nextOld, nextNew) {
- var cursor = this.cursor;
- while (cursor !== null) {
- if (cursor.prev === prevOld) {
- cursor.prev = prevNew;
- }
- if (cursor.next === nextOld) {
- cursor.next = nextNew;
- }
- cursor = cursor.cursor;
- }
- };
- List.prototype.prepend = function(item) {
- // head
- // ^
- // item
- this.updateCursors(null, item, this.head, item);
- // insert to the beginning of the list
- if (this.head !== null) {
- // new item <- first item
- this.head.prev = item;
- // new item -> first item
- item.next = this.head;
- } else {
- // if list has no head, then it also has no tail
- // in this case tail points to the new item
- this.tail = item;
- }
- // head always points to new item
- this.head = item;
- return this;
- };
- List.prototype.prependData = function(data) {
- return this.prepend(createItem(data));
- };
- List.prototype.append = function(item) {
- // tail
- // ^
- // item
- this.updateCursors(this.tail, item, null, item);
- // insert to the ending of the list
- if (this.tail !== null) {
- // last item -> new item
- this.tail.next = item;
- // last item <- new item
- item.prev = this.tail;
- } else {
- // if list has no tail, then it also has no head
- // in this case head points to new item
- this.head = item;
- }
- // tail always points to new item
- this.tail = item;
- return this;
- };
- List.prototype.appendData = function(data) {
- return this.append(createItem(data));
- };
- List.prototype.insert = function(item, before) {
- if (before !== undefined && before !== null) {
- // prev before
- // ^
- // item
- this.updateCursors(before.prev, item, before, item);
- if (before.prev === null) {
- // insert to the beginning of list
- if (this.head !== before) {
- throw new Error('before doesn\'t belong to list');
- }
- // since head points to before therefore list doesn't empty
- // no need to check tail
- this.head = item;
- before.prev = item;
- item.next = before;
- this.updateCursors(null, item);
- } else {
- // insert between two items
- before.prev.next = item;
- item.prev = before.prev;
- before.prev = item;
- item.next = before;
- }
- } else {
- this.append(item);
- }
- };
- List.prototype.insertData = function(data, before) {
- this.insert(createItem(data), before);
- };
- List.prototype.remove = function(item) {
- // item
- // ^
- // prev next
- this.updateCursors(item, item.prev, item, item.next);
- if (item.prev !== null) {
- item.prev.next = item.next;
- } else {
- if (this.head !== item) {
- throw new Error('item doesn\'t belong to list');
- }
- this.head = item.next;
- }
- if (item.next !== null) {
- item.next.prev = item.prev;
- } else {
- if (this.tail !== item) {
- throw new Error('item doesn\'t belong to list');
- }
- this.tail = item.prev;
- }
- item.prev = null;
- item.next = null;
- return item;
- };
- List.prototype.appendList = function(list) {
- // ignore empty lists
- if (list.head === null) {
- return;
- }
- this.updateCursors(this.tail, list.tail, null, list.head);
- // insert to end of the list
- if (this.tail !== null) {
- // if destination list has a tail, then it also has a head,
- // but head doesn't change
- // dest tail -> source head
- this.tail.next = list.head;
- // dest tail <- source head
- list.head.prev = this.tail;
- } else {
- // if list has no a tail, then it also has no a head
- // in this case points head to new item
- this.head = list.head;
- }
- // tail always start point to new item
- this.tail = list.tail;
- list.head = null;
- list.tail = null;
- };
- List.prototype.insertList = function(list, before) {
- if (before !== undefined && before !== null) {
- // ignore empty lists
- if (list.head === null) {
- return;
- }
- this.updateCursors(before.prev, list.tail, before, list.head);
- // insert in the middle of dist list
- if (before.prev !== null) {
- // before.prev <-> list.head
- before.prev.next = list.head;
- list.head.prev = before.prev;
- } else {
- this.head = list.head;
- }
- before.prev = list.tail;
- list.tail.next = before;
- list.head = null;
- list.tail = null;
- } else {
- this.appendList(list);
- }
- };
- List.prototype.replace = function(oldItem, newItemOrList) {
- if ('head' in newItemOrList) {
- this.insertList(newItemOrList, oldItem);
- } else {
- this.insert(newItemOrList, oldItem);
- }
- this.remove(oldItem);
- };
- var list = List;
- var TYPE$3 = tokenizer$1.TYPE;
- var WHITESPACE$2 = TYPE$3.WhiteSpace;
- var COMMENT$2 = TYPE$3.Comment;
- var sequence = function readSequence(recognizer) {
- var children = new list();
- var child = null;
- var context = {
- recognizer: recognizer,
- space: null,
- ignoreWS: false,
- ignoreWSAfter: false
- };
- this.scanner.skipSC();
- while (!this.scanner.eof) {
- switch (this.scanner.tokenType) {
- case COMMENT$2:
- this.scanner.next();
- continue;
- case WHITESPACE$2:
- if (context.ignoreWS) {
- this.scanner.next();
- } else {
- context.space = this.WhiteSpace();
- }
- continue;
- }
- child = recognizer.getNode.call(this, context);
- if (child === undefined) {
- break;
- }
- if (context.space !== null) {
- children.appendData(context.space);
- context.space = null;
- }
- children.appendData(child);
- if (context.ignoreWSAfter) {
- context.ignoreWSAfter = false;
- context.ignoreWS = true;
- } else {
- context.ignoreWS = false;
- }
- }
- return children;
- };
- var noop$1 = function() {};
- function createParseContext(name) {
- return function() {
- return this[name]();
- };
- }
- function processConfig(config) {
- var parserConfig = {
- context: {},
- scope: {},
- atrule: {},
- pseudo: {}
- };
- if (config.parseContext) {
- for (var name in config.parseContext) {
- switch (typeof config.parseContext[name]) {
- case 'function':
- parserConfig.context[name] = config.parseContext[name];
- break;
- case 'string':
- parserConfig.context[name] = createParseContext(config.parseContext[name]);
- break;
- }
- }
- }
- if (config.scope) {
- for (var name in config.scope) {
- parserConfig.scope[name] = config.scope[name];
- }
- }
- if (config.atrule) {
- for (var name in config.atrule) {
- var atrule = config.atrule[name];
- if (atrule.parse) {
- parserConfig.atrule[name] = atrule.parse;
- }
- }
- }
- if (config.pseudo) {
- for (var name in config.pseudo) {
- var pseudo = config.pseudo[name];
- if (pseudo.parse) {
- parserConfig.pseudo[name] = pseudo.parse;
- }
- }
- }
- if (config.node) {
- for (var name in config.node) {
- parserConfig[name] = config.node[name].parse;
- }
- }
- return parserConfig;
- }
- var create = function createParser(config) {
- var parser = {
- scanner: new tokenizer$1(),
- filename: '<unknown>',
- needPositions: false,
- tolerant: false,
- onParseError: noop$1,
- parseAtruleExpression: true,
- parseSelector: true,
- parseValue: true,
- parseCustomProperty: false,
- readSequence: sequence,
- tolerantParse: function(consumer, fallback) {
- if (this.tolerant) {
- var start = this.scanner.currentToken;
- try {
- return consumer.call(this);
- } catch (e) {
- this.onParseError(e);
- return fallback.call(this, start);
- }
- } else {
- return consumer.call(this);
- }
- },
- getLocation: function(start, end) {
- if (this.needPositions) {
- return this.scanner.getLocationRange(
- start,
- end,
- this.filename
- );
- }
- return null;
- },
- getLocationFromList: function(list) {
- if (this.needPositions) {
- return this.scanner.getLocationRange(
- list.head !== null ? list.first().loc.start.offset - this.scanner.startOffset : this.scanner.tokenStart,
- list.head !== null ? list.last().loc.end.offset - this.scanner.startOffset : this.scanner.tokenStart,
- this.filename
- );
- }
- return null;
- }
- };
- config = processConfig(config || {});
- for (var key in config) {
- parser[key] = config[key];
- }
- return function(source, options) {
- options = options || {};
- var context = options.context || 'default';
- var ast;
- parser.scanner.setSource(source, options.offset, options.line, options.column);
- parser.filename = options.filename || '<unknown>';
- parser.needPositions = Boolean(options.positions);
- parser.tolerant = Boolean(options.tolerant);
- parser.onParseError = typeof options.onParseError === 'function' ? options.onParseError : noop$1;
- parser.parseAtruleExpression = 'parseAtruleExpression' in options ? Boolean(options.parseAtruleExpression) : true;
- parser.parseSelector = 'parseSelector' in options ? Boolean(options.parseSelector) : true;
- parser.parseValue = 'parseValue' in options ? Boolean(options.parseValue) : true;
- parser.parseCustomProperty = 'parseCustomProperty' in options ? Boolean(options.parseCustomProperty) : false;
- if (!parser.context.hasOwnProperty(context)) {
- throw new Error('Unknown context `' + context + '`');
- }
- ast = parser.context[context].call(parser, options);
- if (!parser.scanner.eof) {
- parser.scanner.error();
- }
- // console.log(JSON.stringify(ast, null, 4));
- return ast;
- };
- };
- var cmpChar$1 = tokenizer$1.cmpChar;
- var TYPE$4 = tokenizer$1.TYPE;
- var IDENTIFIER$2 = TYPE$4.Identifier;
- var STRING$2 = TYPE$4.String;
- var NUMBER$2 = TYPE$4.Number;
- var FUNCTION$2 = TYPE$4.Function;
- var URL$2 = TYPE$4.Url;
- var NUMBERSIGN = TYPE$4.NumberSign;
- var LEFTPARENTHESIS$1 = TYPE$4.LeftParenthesis;
- var LEFTSQUAREBRACKET$1 = TYPE$4.LeftSquareBracket;
- var PLUSSIGN$2 = TYPE$4.PlusSign;
- var HYPHENMINUS$2 = TYPE$4.HyphenMinus;
- var COMMA = TYPE$4.Comma;
- var SOLIDUS = TYPE$4.Solidus;
- var ASTERISK = TYPE$4.Asterisk;
- var PERCENTSIGN = TYPE$4.PercentSign;
- var BACKSLASH = TYPE$4.Backslash;
- var U = 117; // 'u'.charCodeAt(0)
- var _default = function defaultRecognizer(context) {
- switch (this.scanner.tokenType) {
- case NUMBERSIGN:
- return this.HexColor();
- case COMMA:
- context.space = null;
- context.ignoreWSAfter = true;
- return this.Operator();
- case SOLIDUS:
- case ASTERISK:
- case PLUSSIGN$2:
- case HYPHENMINUS$2:
- return this.Operator();
- case LEFTPARENTHESIS$1:
- return this.Parentheses(this.readSequence, context.recognizer);
- case LEFTSQUAREBRACKET$1:
- return this.Brackets(this.readSequence, context.recognizer);
- case STRING$2:
- return this.String();
- case NUMBER$2:
- switch (this.scanner.lookupType(1)) {
- case PERCENTSIGN:
- return this.Percentage();
- case IDENTIFIER$2:
- // edge case: number with folowing \0 and \9 hack shouldn't to be a Dimension
- if (cmpChar$1(this.scanner.source, this.scanner.tokenEnd, BACKSLASH)) {
- return this.Number();
- } else {
- return this.Dimension();
- }
- default:
- return this.Number();
- }
- case FUNCTION$2:
- return this.Function(this.readSequence, context.recognizer);
- case URL$2:
- return this.Url();
- case IDENTIFIER$2:
- // check for unicode range, it should start with u+ or U+
- if (cmpChar$1(this.scanner.source, this.scanner.tokenStart, U) &&
- cmpChar$1(this.scanner.source, this.scanner.tokenStart + 1, PLUSSIGN$2)) {
- return this.UnicodeRange();
- } else {
- return this.Identifier();
- }
- }
- };
- var atruleExpression = {
- getNode: _default
- };
- var TYPE$5 = tokenizer$1.TYPE;
- var IDENTIFIER$3 = TYPE$5.Identifier;
- var NUMBER$3 = TYPE$5.Number;
- var NUMBERSIGN$1 = TYPE$5.NumberSign;
- var LEFTSQUAREBRACKET$2 = TYPE$5.LeftSquareBracket;
- var PLUSSIGN$3 = TYPE$5.PlusSign;
- var SOLIDUS$1 = TYPE$5.Solidus;
- var ASTERISK$1 = TYPE$5.Asterisk;
- var FULLSTOP$2 = TYPE$5.FullStop;
- var COLON = TYPE$5.Colon;
- var GREATERTHANSIGN$1 = TYPE$5.GreaterThanSign;
- var VERTICALLINE = TYPE$5.VerticalLine;
- var TILDE = TYPE$5.Tilde;
- function getNode(context) {
- switch (this.scanner.tokenType) {
- case PLUSSIGN$3:
- case GREATERTHANSIGN$1:
- case TILDE:
- context.space = null;
- context.ignoreWSAfter = true;
- return this.Combinator();
- case SOLIDUS$1: // /deep/
- return this.Combinator();
- case FULLSTOP$2:
- return this.ClassSelector();
- case LEFTSQUAREBRACKET$2:
- return this.AttributeSelector();
- case NUMBERSIGN$1:
- return this.IdSelector();
- case COLON:
- if (this.scanner.lookupType(1) === COLON) {
- return this.PseudoElementSelector();
- } else {
- return this.PseudoClassSelector();
- }
- case IDENTIFIER$3:
- case ASTERISK$1:
- case VERTICALLINE:
- return this.TypeSelector();
- case NUMBER$3:
- return this.Percentage();
- }
- }
- var selector = {
- getNode: getNode
- };
- // https://drafts.csswg.org/css-images-4/#element-notation
- // https://developer.mozilla.org/en-US/docs/Web/CSS/element
- var element = function() {
- this.scanner.skipSC();
- var id = this.IdSelector();
- this.scanner.skipSC();
- return new list().appendData(
- id
- );
- };
- // legacy IE function
- // expression '(' raw ')'
- var expression = function() {
- return new list().appendData(
- this.Raw(this.scanner.currentToken, 0, 0, false, false)
- );
- };
- var TYPE$6 = tokenizer$1.TYPE;
- var IDENTIFIER$4 = TYPE$6.Identifier;
- var COMMA$1 = TYPE$6.Comma;
- var SEMICOLON = TYPE$6.Semicolon;
- var HYPHENMINUS$3 = TYPE$6.HyphenMinus;
- var EXCLAMATIONMARK$1 = TYPE$6.ExclamationMark;
- // var '(' ident (',' <value>? )? ')'
- var _var = function() {
- var children = new list();
- this.scanner.skipSC();
- var identStart = this.scanner.tokenStart;
- this.scanner.eat(HYPHENMINUS$3);
- if (this.scanner.source.charCodeAt(this.scanner.tokenStart) !== HYPHENMINUS$3) {
- this.scanner.error('HyphenMinus is expected');
- }
- this.scanner.eat(IDENTIFIER$4);
- children.appendData({
- type: 'Identifier',
- loc: this.getLocation(identStart, this.scanner.tokenStart),
- name: this.scanner.substrToCursor(identStart)
- });
- this.scanner.skipSC();
- if (this.scanner.tokenType === COMMA$1) {
- children.appendData(this.Operator());
- children.appendData(this.parseCustomProperty
- ? this.Value(null)
- : this.Raw(this.scanner.currentToken, EXCLAMATIONMARK$1, SEMICOLON, false, false)
- );
- }
- return children;
- };
- var value = {
- getNode: _default,
- '-moz-element': element,
- 'element': element,
- 'expression': expression,
- 'var': _var
- };
- var scope = {
- AtruleExpression: atruleExpression,
- Selector: selector,
- Value: value
- };
- var fontFace = {
- parse: {
- expression: null,
- block: function() {
- return this.Block(this.Declaration);
- }
- }
- };
- var TYPE$7 = tokenizer$1.TYPE;
- var STRING$3 = TYPE$7.String;
- var IDENTIFIER$5 = TYPE$7.Identifier;
- var URL$3 = TYPE$7.Url;
- var LEFTPARENTHESIS$2 = TYPE$7.LeftParenthesis;
- var _import = {
- parse: {
- expression: function() {
- var children = new list();
- this.scanner.skipSC();
- switch (this.scanner.tokenType) {
- case STRING$3:
- children.appendData(this.String());
- break;
- case URL$3:
- children.appendData(this.Url());
- break;
- default:
- this.scanner.error('String or url() is expected');
- }
- if (this.scanner.lookupNonWSType(0) === IDENTIFIER$5 ||
- this.scanner.lookupNonWSType(0) === LEFTPARENTHESIS$2) {
- children.appendData(this.WhiteSpace());
- children.appendData(this.MediaQueryList());
- }
- return children;
- },
- block: null
- }
- };
- var media = {
- parse: {
- expression: function() {
- return new list().appendData(
- this.MediaQueryList()
- );
- },
- block: function() {
- return this.Block(this.Rule);
- }
- }
- };
- var TYPE$8 = tokenizer$1.TYPE;
- var LEFTCURLYBRACKET$1 = TYPE$8.LeftCurlyBracket;
- var page = {
- parse: {
- expression: function() {
- if (this.scanner.lookupNonWSType(0) === LEFTCURLYBRACKET$1) {
- return null;
- }
- return new list().appendData(
- this.SelectorList()
- );
- },
- block: function() {
- return this.Block(this.Declaration);
- }
- }
- };
- var TYPE$9 = tokenizer$1.TYPE;
- var WHITESPACE$3 = TYPE$9.WhiteSpace;
- var COMMENT$3 = TYPE$9.Comment;
- var IDENTIFIER$6 = TYPE$9.Identifier;
- var FUNCTION$3 = TYPE$9.Function;
- var LEFTPARENTHESIS$3 = TYPE$9.LeftParenthesis;
- var HYPHENMINUS$4 = TYPE$9.HyphenMinus;
- var COLON$1 = TYPE$9.Colon;
- function consumeRaw() {
- return new list().appendData(
- this.Raw(this.scanner.currentToken, 0, 0, false, false)
- );
- }
- function parentheses() {
- var index = 0;
- this.scanner.skipSC();
- // TODO: make it simplier
- if (this.scanner.tokenType === IDENTIFIER$6) {
- index = 1;
- } else if (this.scanner.tokenType === HYPHENMINUS$4 &&
- this.scanner.lookupType(1) === IDENTIFIER$6) {
- index = 2;
- }
- if (index !== 0 && this.scanner.lookupNonWSType(index) === COLON$1) {
- return new list().appendData(
- this.Declaration()
- );
- }
- return readSequence.call(this);
- }
- function readSequence() {
- var children = new list();
- var space = null;
- var child;
- this.scanner.skipSC();
- scan:
- while (!this.scanner.eof) {
- switch (this.scanner.tokenType) {
- case WHITESPACE$3:
- space = this.WhiteSpace();
- continue;
- case COMMENT$3:
- this.scanner.next();
- continue;
- case FUNCTION$3:
- child = this.Function(consumeRaw, this.scope.AtruleExpression);
- break;
- case IDENTIFIER$6:
- child = this.Identifier();
- break;
- case LEFTPARENTHESIS$3:
- child = this.Parentheses(parentheses, this.scope.AtruleExpression);
- break;
- default:
- break scan;
- }
- if (space !== null) {
- children.appendData(space);
- space = null;
- }
- children.appendData(child);
- }
- return children;
- }
- var supports = {
- parse: {
- expression: function() {
- var children = readSequence.call(this);
- if (children.isEmpty()) {
- this.scanner.error('Condition is expected');
- }
- return children;
- },
- block: function() {
- return this.Block(this.Rule);
- }
- }
- };
- var atrule = {
- 'font-face': fontFace,
- 'import': _import,
- 'media': media,
- 'page': page,
- 'supports': supports
- };
- var dir = {
- parse: function() {
- return new list().appendData(
- this.Identifier()
- );
- }
- };
- var has$1 = {
- parse: function() {
- return new list().appendData(
- this.SelectorList()
- );
- }
- };
- var lang = {
- parse: function() {
- return new list().appendData(
- this.Identifier()
- );
- }
- };
- var selectorList = {
- parse: function selectorList() {
- return new list().appendData(
- this.SelectorList()
- );
- }
- };
- var matches = selectorList;
- var not = selectorList;
- var ALLOW_OF_CLAUSE = true;
- var nthWithOfClause = {
- parse: function() {
- return new list().appendData(
- this.Nth(ALLOW_OF_CLAUSE)
- );
- }
- };
- var nthChild = nthWithOfClause;
- var nthLastChild = nthWithOfClause;
- var DISALLOW_OF_CLAUSE = false;
- var nth = {
- parse: function nth() {
- return new list().appendData(
- this.Nth(DISALLOW_OF_CLAUSE)
- );
- }
- };
- var nthLastOfType = nth;
- var nthOfType = nth;
- var slotted = {
- parse: function compoundSelector() {
- return new list().appendData(
- this.Selector()
- );
- }
- };
- var pseudo = {
- 'dir': dir,
- 'has': has$1,
- 'lang': lang,
- 'matches': matches,
- 'not': not,
- 'nth-child': nthChild,
- 'nth-last-child': nthLastChild,
- 'nth-last-of-type': nthLastOfType,
- 'nth-of-type': nthOfType,
- 'slotted': slotted
- };
- var cmpChar$2 = tokenizer$1.cmpChar;
- var isNumber$2 = tokenizer$1.isNumber;
- var TYPE$a = tokenizer$1.TYPE;
- var IDENTIFIER$7 = TYPE$a.Identifier;
- var NUMBER$4 = TYPE$a.Number;
- var PLUSSIGN$4 = TYPE$a.PlusSign;
- var HYPHENMINUS$5 = TYPE$a.HyphenMinus;
- var N$3 = 110; // 'n'.charCodeAt(0)
- var DISALLOW_SIGN = true;
- var ALLOW_SIGN = false;
- function checkTokenIsInteger(scanner, disallowSign) {
- var pos = scanner.tokenStart;
- if (scanner.source.charCodeAt(pos) === PLUSSIGN$4 ||
- scanner.source.charCodeAt(pos) === HYPHENMINUS$5) {
- if (disallowSign) {
- scanner.error();
- }
- pos++;
- }
- for (; pos < scanner.tokenEnd; pos++) {
- if (!isNumber$2(scanner.source.charCodeAt(pos))) {
- scanner.error('Unexpected input', pos);
- }
- }
- }
- // An+B microsyntax https://www.w3.org/TR/css-syntax-3/#anb
- var AnPlusB = {
- name: 'AnPlusB',
- structure: {
- a: [String, null],
- b: [String, null]
- },
- parse: function() {
- var start = this.scanner.tokenStart;
- var end = start;
- var prefix = '';
- var a = null;
- var b = null;
- if (this.scanner.tokenType === NUMBER$4 ||
- this.scanner.tokenType === PLUSSIGN$4) {
- checkTokenIsInteger(this.scanner, ALLOW_SIGN);
- prefix = this.scanner.getTokenValue();
- this.scanner.next();
- end = this.scanner.tokenStart;
- }
- if (this.scanner.tokenType === IDENTIFIER$7) {
- var bStart = this.scanner.tokenStart;
- if (cmpChar$2(this.scanner.source, bStart, HYPHENMINUS$5)) {
- if (prefix === '') {
- prefix = '-';
- bStart++;
- } else {
- this.scanner.error('Unexpected hyphen minus');
- }
- }
- if (!cmpChar$2(this.scanner.source, bStart, N$3)) {
- this.scanner.error();
- }
- a = prefix === '' ? '1' :
- prefix === '+' ? '+1' :
- prefix === '-' ? '-1' :
- prefix;
- var len = this.scanner.tokenEnd - bStart;
- if (len > 1) {
- // ..n-..
- if (this.scanner.source.charCodeAt(bStart + 1) !== HYPHENMINUS$5) {
- this.scanner.error('Unexpected input', bStart + 1);
- }
- if (len > 2) {
- // ..n-{number}..
- this.scanner.tokenStart = bStart + 2;
- } else {
- // ..n- {number}
- this.scanner.next();
- this.scanner.skipSC();
- }
- checkTokenIsInteger(this.scanner, DISALLOW_SIGN);
- b = '-' + this.scanner.getTokenValue();
- this.scanner.next();
- end = this.scanner.tokenStart;
- } else {
- prefix = '';
- this.scanner.next();
- end = this.scanner.tokenStart;
- this.scanner.skipSC();
- if (this.scanner.tokenType === HYPHENMINUS$5 ||
- this.scanner.tokenType === PLUSSIGN$4) {
- prefix = this.scanner.getTokenValue();
- this.scanner.next();
- this.scanner.skipSC();
- }
- if (this.scanner.tokenType === NUMBER$4) {
- checkTokenIsInteger(this.scanner, prefix !== '');
- if (!isNumber$2(this.scanner.source.charCodeAt(this.scanner.tokenStart))) {
- prefix = this.scanner.source.charAt(this.scanner.tokenStart);
- this.scanner.tokenStart++;
- }
- if (prefix === '') {
- // should be an operator before number
- this.scanner.error();
- } else if (prefix === '+') {
- // plus is using by default
- prefix = '';
- }
- b = prefix + this.scanner.getTokenValue();
- this.scanner.next();
- end = this.scanner.tokenStart;
- } else {
- if (prefix) {
- this.scanner.eat(NUMBER$4);
- }
- }
- }
- } else {
- if (prefix === '' || prefix === '+') { // no number
- this.scanner.error(
- 'Number or identifier is expected',
- this.scanner.tokenStart + (
- this.scanner.tokenType === PLUSSIGN$4 ||
- this.scanner.tokenType === HYPHENMINUS$5
- )
- );
- }
- b = prefix;
- }
- return {
- type: 'AnPlusB',
- loc: this.getLocation(start, end),
- a: a,
- b: b
- };
- },
- generate: function(processChunk, node) {
- var a = node.a !== null && node.a !== undefined;
- var b = node.b !== null && node.b !== undefined;
- if (a) {
- processChunk(
- node.a === '+1' ? '+n' :
- node.a === '1' ? 'n' :
- node.a === '-1' ? '-n' :
- node.a + 'n'
- );
- if (b) {
- b = String(node.b);
- if (b.charAt(0) === '-' || b.charAt(0) === '+') {
- processChunk(b.charAt(0));
- processChunk(b.substr(1));
- } else {
- processChunk('+');
- processChunk(b);
- }
- }
- } else {
- processChunk(String(node.b));
- }
- }
- };
- var TYPE$b = tokenizer$1.TYPE;
- var ATRULE$2 = TYPE$b.Atrule;
- var SEMICOLON$1 = TYPE$b.Semicolon;
- var LEFTCURLYBRACKET$2 = TYPE$b.LeftCurlyBracket;
- var RIGHTCURLYBRACKET$1 = TYPE$b.RightCurlyBracket;
- function isBlockAtrule() {
- for (var offset = 1, type; type = this.scanner.lookupType(offset); offset++) {
- if (type === RIGHTCURLYBRACKET$1) {
- return true;
- }
- if (type === LEFTCURLYBRACKET$2 ||
- type === ATRULE$2) {
- return false;
- }
- }
- this.scanner.skip(offset);
- this.scanner.eat(RIGHTCURLYBRACKET$1);
- }
- var Atrule = {
- name: 'Atrule',
- structure: {
- name: String,
- expression: ['AtruleExpression', null],
- block: ['Block', null]
- },
- parse: function() {
- var start = this.scanner.tokenStart;
- var name;
- var nameLowerCase;
- var expression = null;
- var block = null;
- this.scanner.eat(ATRULE$2);
- name = this.scanner.substrToCursor(start + 1);
- nameLowerCase = name.toLowerCase();
- this.scanner.skipSC();
- expression = this.AtruleExpression(name);
- // turn empty AtruleExpression into null
- if (expression.children.head === null) {
- expression = null;
- }
- this.scanner.skipSC();
- if (this.atrule.hasOwnProperty(nameLowerCase)) {
- if (typeof this.atrule[nameLowerCase].block === 'function') {
- if (this.scanner.tokenType !== LEFTCURLYBRACKET$2) {
- // FIXME: make tolerant
- this.scanner.error('Curly bracket is expected');
- }
- block = this.atrule[nameLowerCase].block.call(this);
- } else {
- if (!this.tolerant || !this.scanner.eof) {
- this.scanner.eat(SEMICOLON$1);
- }
- }
- } else {
- switch (this.scanner.tokenType) {
- case SEMICOLON$1:
- this.scanner.next();
- break;
- case LEFTCURLYBRACKET$2:
- // TODO: should consume block content as Raw?
- block = this.Block(isBlockAtrule.call(this) ? this.Declaration : this.Rule);
- break;
- default:
- if (!this.tolerant) {
- this.scanner.error('Semicolon or block is expected');
- }
- }
- }
- return {
- type: 'Atrule',
- loc: this.getLocation(start, this.scanner.tokenStart),
- name: name,
- expression: expression,
- block: block
- };
- },
- generate: function(processChunk, node) {
- processChunk('@');
- processChunk(node.name);
- if (node.expression !== null) {
- processChunk(' ');
- this.generate(processChunk, node.expression);
- }
- if (node.block) {
- this.generate(processChunk, node.block);
- } else {
- processChunk(';');
- }
- },
- walkContext: 'atrule'
- };
- var TYPE$c = tokenizer$1.TYPE;
- var SEMICOLON$2 = TYPE$c.Semicolon;
- var LEFTCURLYBRACKET$3 = TYPE$c.LeftCurlyBracket;
- function consumeRaw$1(startToken) {
- return new list().appendData(
- this.Raw(startToken, SEMICOLON$2, LEFTCURLYBRACKET$3, false, true)
- );
- }
- function consumeDefaultSequence() {
- return this.readSequence(this.scope.AtruleExpression);
- }
- var AtruleExpression = {
- name: 'AtruleExpression',
- structure: {
- children: [[]]
- },
- parse: function(name) {
- var children = null;
- var startToken = this.scanner.currentToken;
- if (name !== null) {
- name = name.toLowerCase();
- }
- if (this.parseAtruleExpression) {
- // custom consumer
- if (this.atrule.hasOwnProperty(name)) {
- if (typeof this.atrule[name].expression === 'function') {
- children = this.tolerantParse(this.atrule[name].expression, consumeRaw$1);
- }
- } else {
- // default consumer
- this.scanner.skipSC();
- children = this.tolerantParse(consumeDefaultSequence, consumeRaw$1);
- }
- if (this.tolerant) {
- if (this.scanner.eof || (this.scanner.tokenType !== SEMICOLON$2 && this.scanner.tokenType !== LEFTCURLYBRACKET$3)) {
- children = consumeRaw$1.call(this, startToken);
- }
- }
- } else {
- children = consumeRaw$1.call(this, startToken);
- }
- if (children === null) {
- children = new list();
- }
- return {
- type: 'AtruleExpression',
- loc: this.getLocationFromList(children),
- children: children
- };
- },
- generate: function(processChunk, node) {
- this.each(processChunk, node);
- },
- walkContext: 'atruleExpression'
- };
- var TYPE$d = tokenizer$1.TYPE;
- var IDENTIFIER$8 = TYPE$d.Identifier;
- var STRING$4 = TYPE$d.String;
- var DOLLARSIGN = TYPE$d.DollarSign;
- var ASTERISK$2 = TYPE$d.Asterisk;
- var COLON$2 = TYPE$d.Colon;
- var EQUALSSIGN = TYPE$d.EqualsSign;
- var LEFTSQUAREBRACKET$3 = TYPE$d.LeftSquareBracket;
- var RIGHTSQUAREBRACKET$1 = TYPE$d.RightSquareBracket;
- var CIRCUMFLEXACCENT = TYPE$d.CircumflexAccent;
- var VERTICALLINE$1 = TYPE$d.VerticalLine;
- var TILDE$1 = TYPE$d.Tilde;
- function getAttributeName() {
- if (this.scanner.eof) {
- this.scanner.error('Unexpected end of input');
- }
- var start = this.scanner.tokenStart;
- var expectIdentifier = false;
- var checkColon = true;
- if (this.scanner.tokenType === ASTERISK$2) {
- expectIdentifier = true;
- checkColon = false;
- this.scanner.next();
- } else if (this.scanner.tokenType !== VERTICALLINE$1) {
- this.scanner.eat(IDENTIFIER$8);
- }
- if (this.scanner.tokenType === VERTICALLINE$1) {
- if (this.scanner.lookupType(1) !== EQUALSSIGN) {
- this.scanner.next();
- this.scanner.eat(IDENTIFIER$8);
- } else if (expectIdentifier) {
- this.scanner.error('Identifier is expected', this.scanner.tokenEnd);
- }
- } else if (expectIdentifier) {
- this.scanner.error('Vertical line is expected');
- }
- if (checkColon && this.scanner.tokenType === COLON$2) {
- this.scanner.next();
- this.scanner.eat(IDENTIFIER$8);
- }
- return {
- type: 'Identifier',
- loc: this.getLocation(start, this.scanner.tokenStart),
- name: this.scanner.substrToCursor(start)
- };
- }
- function getOperator() {
- var start = this.scanner.tokenStart;
- var tokenType = this.scanner.tokenType;
- if (tokenType !== EQUALSSIGN && // =
- tokenType !== TILDE$1 && // ~=
- tokenType !== CIRCUMFLEXACCENT && // ^=
- tokenType !== DOLLARSIGN && // $=
- tokenType !== ASTERISK$2 && // *=
- tokenType !== VERTICALLINE$1 // |=
- ) {
- this.scanner.error('Attribute selector (=, ~=, ^=, $=, *=, |=) is expected');
- }
- if (tokenType === EQUALSSIGN) {
- this.scanner.next();
- } else {
- this.scanner.next();
- this.scanner.eat(EQUALSSIGN);
- }
- return this.scanner.substrToCursor(start);
- }
- // '[' S* attrib_name ']'
- // '[' S* attrib_name S* attrib_matcher S* [ IDENT | STRING ] S* attrib_flags? S* ']'
- var AttributeSelector = {
- name: 'AttributeSelector',
- structure: {
- name: 'Identifier',
- matcher: [String, null],
- value: ['String', 'Identifier', null],
- flags: [String, null]
- },
- parse: function() {
- var start = this.scanner.tokenStart;
- var name;
- var matcher = null;
- var value = null;
- var flags = null;
- this.scanner.eat(LEFTSQUAREBRACKET$3);
- this.scanner.skipSC();
- name = getAttributeName.call(this);
- this.scanner.skipSC();
- if (this.scanner.tokenType !== RIGHTSQUAREBRACKET$1) {
- // avoid case `[name i]`
- if (this.scanner.tokenType !== IDENTIFIER$8) {
- matcher = getOperator.call(this);
- this.scanner.skipSC();
- value = this.scanner.tokenType === STRING$4
- ? this.String()
- : this.Identifier();
- this.scanner.skipSC();
- }
- // attribute flags
- if (this.scanner.tokenType === IDENTIFIER$8) {
- flags = this.scanner.getTokenValue();
- this.scanner.next();
- this.scanner.skipSC();
- }
- }
- this.scanner.eat(RIGHTSQUAREBRACKET$1);
- return {
- type: 'AttributeSelector',
- loc: this.getLocation(start, this.scanner.tokenStart),
- name: name,
- matcher: matcher,
- value: value,
- flags: flags
- };
- },
- generate: function(processChunk, node) {
- var flagsPrefix = ' ';
- processChunk('[');
- this.generate(processChunk, node.name);
- if (node.matcher !== null) {
- processChunk(node.matcher);
- if (node.value !== null) {
- this.generate(processChunk, node.value);
- // space between string and flags is not required
- if (node.value.type === 'String') {
- flagsPrefix = '';
- }
- }
- }
- if (node.flags !== null) {
- processChunk(flagsPrefix);
- processChunk(node.flags);
- }
- processChunk(']');
- }
- };
- var TYPE$e = tokenizer$1.TYPE;
- var WHITESPACE$4 = TYPE$e.WhiteSpace;
- var COMMENT$4 = TYPE$e.Comment;
- var SEMICOLON$3 = TYPE$e.Semicolon;
- var ATRULE$3 = TYPE$e.Atrule;
- var LEFTCURLYBRACKET$4 = TYPE$e.LeftCurlyBracket;
- var RIGHTCURLYBRACKET$2 = TYPE$e.RightCurlyBracket;
- function consumeRaw$2(startToken) {
- return this.Raw(startToken, 0, SEMICOLON$3, true, true);
- }
- var Block = {
- name: 'Block',
- structure: {
- children: [['Atrule', 'Rule', 'Declaration']]
- },
- parse: function(defaultConsumer) {
- if (!defaultConsumer) {
- defaultConsumer = this.Declaration;
- }
- var start = this.scanner.tokenStart;
- var children = new list();
- this.scanner.eat(LEFTCURLYBRACKET$4);
- scan:
- while (!this.scanner.eof) {
- switch (this.scanner.tokenType) {
- case RIGHTCURLYBRACKET$2:
- break scan;
- case WHITESPACE$4:
- case COMMENT$4:
- case SEMICOLON$3:
- this.scanner.next();
- break;
- case ATRULE$3:
- children.appendData(this.tolerantParse(this.Atrule, consumeRaw$2));
- break;
- default:
- children.appendData(this.tolerantParse(defaultConsumer, consumeRaw$2));
- }
- }
- if (!this.tolerant || !this.scanner.eof) {
- this.scanner.eat(RIGHTCURLYBRACKET$2);
- }
- return {
- type: 'Block',
- loc: this.getLocation(start, this.scanner.tokenStart),
- children: children
- };
- },
- generate: function(processChunk, node) {
- processChunk('{');
- this.each(processChunk, node);
- processChunk('}');
- },
- walkContext: 'block'
- };
- var TYPE$f = tokenizer$1.TYPE;
- var LEFTSQUAREBRACKET$4 = TYPE$f.LeftSquareBracket;
- var RIGHTSQUAREBRACKET$2 = TYPE$f.RightSquareBracket;
- // currently only Grid Layout uses square brackets, but left it universal
- // https://drafts.csswg.org/css-grid/#track-sizing
- // [ ident* ]
- var Brackets = {
- name: 'Brackets',
- structure: {
- children: [[]]
- },
- parse: function(readSequence, recognizer) {
- var start = this.scanner.tokenStart;
- var children = null;
- this.scanner.eat(LEFTSQUAREBRACKET$4);
- children = readSequence.call(this, recognizer);
- this.scanner.eat(RIGHTSQUAREBRACKET$2);
- return {
- type: 'Brackets',
- loc: this.getLocation(start, this.scanner.tokenStart),
- children: children
- };
- },
- generate: function(processChunk, node) {
- processChunk('[');
- this.each(processChunk, node);
- processChunk(']');
- }
- };
- var CDC$2 = tokenizer$1.TYPE.CDC;
- var CDC_1 = {
- name: 'CDC',
- structure: [],
- parse: function() {
- var start = this.scanner.tokenStart;
- this.scanner.eat(CDC$2); // -->
- return {
- type: 'CDC',
- loc: this.getLocation(start, this.scanner.tokenStart)
- };
- },
- generate: function(processChunk) {
- processChunk('-->');
- }
- };
- var CDO$2 = tokenizer$1.TYPE.CDO;
- var CDO_1 = {
- name: 'CDO',
- structure: [],
- parse: function() {
- var start = this.scanner.tokenStart;
- this.scanner.eat(CDO$2); // <!--
- return {
- type: 'CDO',
- loc: this.getLocation(start, this.scanner.tokenStart)
- };
- },
- generate: function(processChunk) {
- processChunk('<!--');
- }
- };
- var TYPE$g = tokenizer$1.TYPE;
- var IDENTIFIER$9 = TYPE$g.Identifier;
- var FULLSTOP$3 = TYPE$g.FullStop;
- // '.' ident
- var ClassSelector = {
- name: 'ClassSelector',
- structure: {
- name: String
- },
- parse: function() {
- this.scanner.eat(FULLSTOP$3);
- return {
- type: 'ClassSelector',
- loc: this.getLocation(this.scanner.tokenStart - 1, this.scanner.tokenEnd),
- name: this.scanner.consume(IDENTIFIER$9)
- };
- },
- generate: function(processChunk, node) {
- processChunk('.');
- processChunk(node.name);
- }
- };
- var TYPE$h = tokenizer$1.TYPE;
- var PLUSSIGN$5 = TYPE$h.PlusSign;
- var SOLIDUS$2 = TYPE$h.Solidus;
- var GREATERTHANSIGN$2 = TYPE$h.GreaterThanSign;
- var TILDE$2 = TYPE$h.Tilde;
- // + | > | ~ | /deep/
- var Combinator = {
- name: 'Combinator',
- structure: {
- name: String
- },
- parse: function() {
- var start = this.scanner.tokenStart;
- switch (this.scanner.tokenType) {
- case GREATERTHANSIGN$2:
- case PLUSSIGN$5:
- case TILDE$2:
- this.scanner.next();
- break;
- case SOLIDUS$2:
- this.scanner.next();
- this.scanner.expectIdentifier('deep');
- this.scanner.eat(SOLIDUS$2);
- break;
- default:
- this.scanner.error('Combinator is expected');
- }
- return {
- type: 'Combinator',
- loc: this.getLocation(start, this.scanner.tokenStart),
- name: this.scanner.substrToCursor(start)
- };
- },
- generate: function(processChunk, node) {
- processChunk(node.name);
- }
- };
- var TYPE$i = tokenizer$1.TYPE;
- var ASTERISK$3 = TYPE$i.Asterisk;
- var SOLIDUS$3 = TYPE$i.Solidus;
- // '/*' .* '*/'
- var Comment = {
- name: 'Comment',
- structure: {
- value: String
- },
- parse: function() {
- var start = this.scanner.tokenStart;
- var end = this.scanner.tokenEnd;
- if ((end - start + 2) >= 2 &&
- this.scanner.source.charCodeAt(end - 2) === ASTERISK$3 &&
- this.scanner.source.charCodeAt(end - 1) === SOLIDUS$3) {
- end -= 2;
- }
- this.scanner.next();
- return {
- type: 'Comment',
- loc: this.getLocation(start, this.scanner.tokenStart),
- value: this.scanner.source.substring(start + 2, end)
- };
- },
- generate: function(processChunk, node) {
- processChunk('/*');
- processChunk(node.value);
- processChunk('*/');
- }
- };
- var TYPE$j = tokenizer$1.TYPE;
- var IDENTIFIER$a = TYPE$j.Identifier;
- var COLON$3 = TYPE$j.Colon;
- var EXCLAMATIONMARK$2 = TYPE$j.ExclamationMark;
- var SOLIDUS$4 = TYPE$j.Solidus;
- var ASTERISK$4 = TYPE$j.Asterisk;
- var DOLLARSIGN$1 = TYPE$j.DollarSign;
- var HYPHENMINUS$6 = TYPE$j.HyphenMinus;
- var SEMICOLON$4 = TYPE$j.Semicolon;
- var RIGHTCURLYBRACKET$3 = TYPE$j.RightCurlyBracket;
- var RIGHTPARENTHESIS$1 = TYPE$j.RightParenthesis;
- var PLUSSIGN$6 = TYPE$j.PlusSign;
- var NUMBERSIGN$2 = TYPE$j.NumberSign;
- var Declaration = {
- name: 'Declaration',
- structure: {
- important: [Boolean, String],
- property: String,
- value: ['Value', 'Raw']
- },
- parse: function() {
- var start = this.scanner.tokenStart;
- var property = readProperty.call(this);
- var important = false;
- var value;
- this.scanner.skipSC();
- this.scanner.eat(COLON$3);
- if (isCustomProperty(property) ? this.parseCustomProperty : this.parseValue) {
- value = this.Value(property);
- } else {
- value = this.Raw(this.scanner.currentToken, EXCLAMATIONMARK$2, SEMICOLON$4, false, false);
- }
- if (this.scanner.tokenType === EXCLAMATIONMARK$2) {
- important = getImportant(this.scanner);
- this.scanner.skipSC();
- }
- // TODO: include or not to include semicolon to range?
- // if (this.scanner.tokenType === SEMICOLON) {
- // this.scanner.next();
- // }
- if (!this.scanner.eof &&
- this.scanner.tokenType !== SEMICOLON$4 &&
- this.scanner.tokenType !== RIGHTPARENTHESIS$1 &&
- this.scanner.tokenType !== RIGHTCURLYBRACKET$3) {
- this.scanner.error();
- }
- return {
- type: 'Declaration',
- loc: this.getLocation(start, this.scanner.tokenStart),
- important: important,
- property: property,
- value: value
- };
- },
- generate: function(processChunk, node, item) {
- processChunk(node.property);
- processChunk(':');
- this.generate(processChunk, node.value);
- if (node.important) {
- processChunk(node.important === true ? '!important' : '!' + node.important);
- }
- if (item && item.next) {
- processChunk(';');
- }
- },
- walkContext: 'declaration'
- };
- function isCustomProperty(name) {
- return name.length >= 2 &&
- name.charCodeAt(0) === HYPHENMINUS$6 &&
- name.charCodeAt(1) === HYPHENMINUS$6;
- }
- function readProperty() {
- var start = this.scanner.tokenStart;
- var prefix = 0;
- // hacks
- switch (this.scanner.tokenType) {
- case ASTERISK$4:
- case DOLLARSIGN$1:
- case PLUSSIGN$6:
- case NUMBERSIGN$2:
- prefix = 1;
- break;
- // TODO: not sure we should support this hack
- case SOLIDUS$4:
- prefix = this.scanner.lookupType(1) === SOLIDUS$4 ? 2 : 1;
- break;
- }
- if (this.scanner.lookupType(prefix) === HYPHENMINUS$6) {
- prefix++;
- }
- if (prefix) {
- this.scanner.skip(prefix);
- }
- this.scanner.eat(IDENTIFIER$a);
- return this.scanner.substrToCursor(start);
- }
- // ! ws* important
- function getImportant(scanner) {
- scanner.eat(EXCLAMATIONMARK$2);
- scanner.skipSC();
- var important = scanner.consume(IDENTIFIER$a);
- // store original value in case it differ from `important`
- // for better original source restoring and hacks like `!ie` support
- return important === 'important' ? true : important;
- }
- var TYPE$k = tokenizer$1.TYPE;
- var WHITESPACE$5 = TYPE$k.WhiteSpace;
- var COMMENT$5 = TYPE$k.Comment;
- var SEMICOLON$5 = TYPE$k.Semicolon;
- function consumeRaw$3(startToken) {
- return this.Raw(startToken, 0, SEMICOLON$5, true, true);
- }
- var DeclarationList = {
- name: 'DeclarationList',
- structure: {
- children: [['Declaration']]
- },
- parse: function() {
- var children = new list();
- scan:
- while (!this.scanner.eof) {
- switch (this.scanner.tokenType) {
- case WHITESPACE$5:
- case COMMENT$5:
- case SEMICOLON$5:
- this.scanner.next();
- break;
- default:
- children.appendData(this.tolerantParse(this.Declaration, consumeRaw$3));
- }
- }
- return {
- type: 'DeclarationList',
- loc: this.getLocationFromList(children),
- children: children
- };
- },
- generate: function(processChunk, node) {
- this.each(processChunk, node);
- }
- };
- var NUMBER$5 = tokenizer$1.TYPE.Number;
- // special reader for units to avoid adjoined IE hacks (i.e. '1px\9')
- function readUnit(scanner) {
- var unit = scanner.getTokenValue();
- var backSlashPos = unit.indexOf('\\');
- if (backSlashPos > 0) {
- // patch token offset
- scanner.tokenStart += backSlashPos;
- // return part before backslash
- return unit.substring(0, backSlashPos);
- }
- // no backslash in unit name
- scanner.next();
- return unit;
- }
- // number ident
- var Dimension = {
- name: 'Dimension',
- structure: {
- value: String,
- unit: String
- },
- parse: function() {
- var start = this.scanner.tokenStart;
- var value = this.scanner.consume(NUMBER$5);
- var unit = readUnit(this.scanner);
- return {
- type: 'Dimension',
- loc: this.getLocation(start, this.scanner.tokenStart),
- value: value,
- unit: unit
- };
- },
- generate: function(processChunk, node) {
- processChunk(node.value);
- processChunk(node.unit);
- }
- };
- var TYPE$l = tokenizer$1.TYPE;
- var RIGHTPARENTHESIS$2 = TYPE$l.RightParenthesis;
- // <function-token> <sequence> ')'
- var _Function = {
- name: 'Function',
- structure: {
- name: String,
- children: [[]]
- },
- parse: function(readSequence, recognizer) {
- var start = this.scanner.tokenStart;
- var name = this.scanner.consumeFunctionName();
- var nameLowerCase = name.toLowerCase();
- var children;
- children = recognizer.hasOwnProperty(nameLowerCase)
- ? recognizer[nameLowerCase].call(this, recognizer)
- : readSequence.call(this, recognizer);
- this.scanner.eat(RIGHTPARENTHESIS$2);
- return {
- type: 'Function',
- loc: this.getLocation(start, this.scanner.tokenStart),
- name: name,
- children: children
- };
- },
- generate: function(processChunk, node) {
- processChunk(node.name);
- processChunk('(');
- this.each(processChunk, node);
- processChunk(')');
- },
- walkContext: 'function'
- };
- var isHex$1 = tokenizer$1.isHex;
- var TYPE$m = tokenizer$1.TYPE;
- var IDENTIFIER$b = TYPE$m.Identifier;
- var NUMBER$6 = TYPE$m.Number;
- var NUMBERSIGN$3 = TYPE$m.NumberSign;
- function consumeHexSequence(scanner, required) {
- if (!isHex$1(scanner.source.charCodeAt(scanner.tokenStart))) {
- if (required) {
- scanner.error('Unexpected input', scanner.tokenStart);
- } else {
- return;
- }
- }
- for (var pos = scanner.tokenStart + 1; pos < scanner.tokenEnd; pos++) {
- var code = scanner.source.charCodeAt(pos);
- // break on non-hex char
- if (!isHex$1(code)) {
- // break token, exclude symbol
- scanner.tokenStart = pos;
- return;
- }
- }
- // token is full hex sequence, go to next token
- scanner.next();
- }
- // # ident
- var HexColor = {
- name: 'HexColor',
- structure: {
- value: String
- },
- parse: function() {
- var start = this.scanner.tokenStart;
- this.scanner.eat(NUMBERSIGN$3);
- scan:
- switch (this.scanner.tokenType) {
- case NUMBER$6:
- consumeHexSequence(this.scanner, true);
- // if token is identifier then number consists of hex only,
- // try to add identifier to result
- if (this.scanner.tokenType === IDENTIFIER$b) {
- consumeHexSequence(this.scanner, false);
- }
- break;
- case IDENTIFIER$b:
- consumeHexSequence(this.scanner, true);
- break;
- default:
- this.scanner.error('Number or identifier is expected');
- }
- return {
- type: 'HexColor',
- loc: this.getLocation(start, this.scanner.tokenStart),
- value: this.scanner.substrToCursor(start + 1) // skip #
- };
- },
- generate: function(processChunk, node) {
- processChunk('#');
- processChunk(node.value);
- }
- };
- var TYPE$n = tokenizer$1.TYPE;
- var IDENTIFIER$c = TYPE$n.Identifier;
- var Identifier = {
- name: 'Identifier',
- structure: {
- name: String
- },
- parse: function() {
- return {
- type: 'Identifier',
- loc: this.getLocation(this.scanner.tokenStart, this.scanner.tokenEnd),
- name: this.scanner.consume(IDENTIFIER$c)
- };
- },
- generate: function(processChunk, node) {
- processChunk(node.name);
- }
- };
- var TYPE$o = tokenizer$1.TYPE;
- var IDENTIFIER$d = TYPE$o.Identifier;
- var NUMBERSIGN$4 = TYPE$o.NumberSign;
- // '#' ident
- var IdSelector = {
- name: 'IdSelector',
- structure: {
- name: String
- },
- parse: function() {
- this.scanner.eat(NUMBERSIGN$4);
- return {
- type: 'IdSelector',
- loc: this.getLocation(this.scanner.tokenStart - 1, this.scanner.tokenEnd),
- name: this.scanner.consume(IDENTIFIER$d)
- };
- },
- generate: function(processChunk, node) {
- processChunk('#');
- processChunk(node.name);
- }
- };
- var TYPE$p = tokenizer$1.TYPE;
- var IDENTIFIER$e = TYPE$p.Identifier;
- var NUMBER$7 = TYPE$p.Number;
- var LEFTPARENTHESIS$4 = TYPE$p.LeftParenthesis;
- var RIGHTPARENTHESIS$3 = TYPE$p.RightParenthesis;
- var COLON$4 = TYPE$p.Colon;
- var SOLIDUS$5 = TYPE$p.Solidus;
- var MediaFeature = {
- name: 'MediaFeature',
- structure: {
- name: String,
- value: ['Identifier', 'Number', 'Dimension', 'Ratio', null]
- },
- parse: function() {
- var start = this.scanner.tokenStart;
- var name;
- var value = null;
- this.scanner.eat(LEFTPARENTHESIS$4);
- this.scanner.skipSC();
- name = this.scanner.consume(IDENTIFIER$e);
- this.scanner.skipSC();
- if (this.scanner.tokenType !== RIGHTPARENTHESIS$3) {
- this.scanner.eat(COLON$4);
- this.scanner.skipSC();
- switch (this.scanner.tokenType) {
- case NUMBER$7:
- if (this.scanner.lookupType(1) === IDENTIFIER$e) {
- value = this.Dimension();
- } else if (this.scanner.lookupNonWSType(1) === SOLIDUS$5) {
- value = this.Ratio();
- } else {
- value = this.Number();
- }
- break;
- case IDENTIFIER$e:
- value = this.Identifier();
- break;
- default:
- this.scanner.error('Number, dimension, ratio or identifier is expected');
- }
- this.scanner.skipSC();
- }
- this.scanner.eat(RIGHTPARENTHESIS$3);
- return {
- type: 'MediaFeature',
- loc: this.getLocation(start, this.scanner.tokenStart),
- name: name,
- value: value
- };
- },
- generate: function(processChunk, node) {
- processChunk('(');
- processChunk(node.name);
- if (node.value !== null) {
- processChunk(':');
- this.generate(processChunk, node.value);
- }
- processChunk(')');
- }
- };
- var TYPE$q = tokenizer$1.TYPE;
- var WHITESPACE$6 = TYPE$q.WhiteSpace;
- var COMMENT$6 = TYPE$q.Comment;
- var IDENTIFIER$f = TYPE$q.Identifier;
- var LEFTPARENTHESIS$5 = TYPE$q.LeftParenthesis;
- var MediaQuery = {
- name: 'MediaQuery',
- structure: {
- children: [['Identifier', 'MediaFeature', 'WhiteSpace']]
- },
- parse: function() {
- this.scanner.skipSC();
- var children = new list();
- var child = null;
- var space = null;
- scan:
- while (!this.scanner.eof) {
- switch (this.scanner.tokenType) {
- case COMMENT$6:
- this.scanner.next();
- continue;
- case WHITESPACE$6:
- space = this.WhiteSpace();
- continue;
- case IDENTIFIER$f:
- child = this.Identifier();
- break;
- case LEFTPARENTHESIS$5:
- child = this.MediaFeature();
- break;
- default:
- break scan;
- }
- if (space !== null) {
- children.appendData(space);
- space = null;
- }
- children.appendData(child);
- }
- if (child === null) {
- this.scanner.error('Identifier or parenthesis is expected');
- }
- return {
- type: 'MediaQuery',
- loc: this.getLocationFromList(children),
- children: children
- };
- },
- generate: function(processChunk, node) {
- this.each(processChunk, node);
- }
- };
- var COMMA$2 = tokenizer$1.TYPE.Comma;
- var MediaQueryList = {
- name: 'MediaQueryList',
- structure: {
- children: [['MediaQuery']]
- },
- parse: function(relative) {
- var children = new list();
- this.scanner.skipSC();
- while (!this.scanner.eof) {
- children.appendData(this.MediaQuery(relative));
- if (this.scanner.tokenType !== COMMA$2) {
- break;
- }
- this.scanner.next();
- }
- return {
- type: 'MediaQueryList',
- loc: this.getLocationFromList(children),
- children: children
- };
- },
- generate: function(processChunk, node) {
- this.eachComma(processChunk, node);
- }
- };
- // https://drafts.csswg.org/css-syntax-3/#the-anb-type
- var Nth = {
- name: 'Nth',
- structure: {
- nth: ['AnPlusB', 'Identifier'],
- selector: ['SelectorList', null]
- },
- parse: function(allowOfClause) {
- this.scanner.skipSC();
- var start = this.scanner.tokenStart;
- var end = start;
- var selector = null;
- var query;
- if (this.scanner.lookupValue(0, 'odd') || this.scanner.lookupValue(0, 'even')) {
- query = this.Identifier();
- } else {
- query = this.AnPlusB();
- }
- this.scanner.skipSC();
- if (allowOfClause && this.scanner.lookupValue(0, 'of')) {
- this.scanner.next();
- selector = this.SelectorList();
- if (this.needPositions) {
- end = selector.children.last().loc.end.offset;
- }
- } else {
- if (this.needPositions) {
- end = query.loc.end.offset;
- }
- }
- return {
- type: 'Nth',
- loc: this.getLocation(start, end),
- nth: query,
- selector: selector
- };
- },
- generate: function(processChunk, node) {
- this.generate(processChunk, node.nth);
- if (node.selector !== null) {
- processChunk(' of ');
- this.generate(processChunk, node.selector);
- }
- }
- };
- var NUMBER$8 = tokenizer$1.TYPE.Number;
- var _Number = {
- name: 'Number',
- structure: {
- value: String
- },
- parse: function() {
- return {
- type: 'Number',
- loc: this.getLocation(this.scanner.tokenStart, this.scanner.tokenEnd),
- value: this.scanner.consume(NUMBER$8)
- };
- },
- generate: function(processChunk, node) {
- processChunk(node.value);
- }
- };
- // '/' | '*' | ',' | ':' | '+' | '-'
- var Operator = {
- name: 'Operator',
- structure: {
- value: String
- },
- parse: function() {
- var start = this.scanner.tokenStart;
- this.scanner.next();
- return {
- type: 'Operator',
- loc: this.getLocation(start, this.scanner.tokenStart),
- value: this.scanner.substrToCursor(start)
- };
- },
- generate: function(processChunk, node) {
- processChunk(node.value);
- }
- };
- var TYPE$r = tokenizer$1.TYPE;
- var LEFTPARENTHESIS$6 = TYPE$r.LeftParenthesis;
- var RIGHTPARENTHESIS$4 = TYPE$r.RightParenthesis;
- var Parentheses = {
- name: 'Parentheses',
- structure: {
- children: [[]]
- },
- parse: function(readSequence, recognizer) {
- var start = this.scanner.tokenStart;
- var children = null;
- this.scanner.eat(LEFTPARENTHESIS$6);
- children = readSequence.call(this, recognizer);
- this.scanner.eat(RIGHTPARENTHESIS$4);
- return {
- type: 'Parentheses',
- loc: this.getLocation(start, this.scanner.tokenStart),
- children: children
- };
- },
- generate: function(processChunk, node) {
- processChunk('(');
- this.each(processChunk, node);
- processChunk(')');
- }
- };
- var TYPE$s = tokenizer$1.TYPE;
- var NUMBER$9 = TYPE$s.Number;
- var PERCENTSIGN$1 = TYPE$s.PercentSign;
- var Percentage = {
- name: 'Percentage',
- structure: {
- value: String
- },
- parse: function() {
- var start = this.scanner.tokenStart;
- var number = this.scanner.consume(NUMBER$9);
- this.scanner.eat(PERCENTSIGN$1);
- return {
- type: 'Percentage',
- loc: this.getLocation(start, this.scanner.tokenStart),
- value: number
- };
- },
- generate: function(processChunk, node) {
- processChunk(node.value);
- processChunk('%');
- }
- };
- var TYPE$t = tokenizer$1.TYPE;
- var IDENTIFIER$g = TYPE$t.Identifier;
- var FUNCTION$4 = TYPE$t.Function;
- var COLON$5 = TYPE$t.Colon;
- var RIGHTPARENTHESIS$5 = TYPE$t.RightParenthesis;
- // : ident [ '(' .. ')' ]?
- var PseudoClassSelector = {
- name: 'PseudoClassSelector',
- structure: {
- name: String,
- children: [['Raw'], null]
- },
- parse: function() {
- var start = this.scanner.tokenStart;
- var children = null;
- var name;
- var nameLowerCase;
- this.scanner.eat(COLON$5);
- if (this.scanner.tokenType === FUNCTION$4) {
- name = this.scanner.consumeFunctionName();
- nameLowerCase = name.toLowerCase();
- if (this.pseudo.hasOwnProperty(nameLowerCase)) {
- this.scanner.skipSC();
- children = this.pseudo[nameLowerCase].call(this);
- this.scanner.skipSC();
- } else {
- children = new list().appendData(
- this.Raw(this.scanner.currentToken, 0, 0, false, false)
- );
- }
- this.scanner.eat(RIGHTPARENTHESIS$5);
- } else {
- name = this.scanner.consume(IDENTIFIER$g);
- }
- return {
- type: 'PseudoClassSelector',
- loc: this.getLocation(start, this.scanner.tokenStart),
- name: name,
- children: children
- };
- },
- generate: function(processChunk, node) {
- processChunk(':');
- processChunk(node.name);
- if (node.children !== null) {
- processChunk('(');
- this.each(processChunk, node);
- processChunk(')');
- }
- },
- walkContext: 'function'
- };
- var TYPE$u = tokenizer$1.TYPE;
- var IDENTIFIER$h = TYPE$u.Identifier;
- var FUNCTION$5 = TYPE$u.Function;
- var COLON$6 = TYPE$u.Colon;
- var RIGHTPARENTHESIS$6 = TYPE$u.RightParenthesis;
- // :: ident [ '(' .. ')' ]?
- var PseudoElementSelector = {
- name: 'PseudoElementSelector',
- structure: {
- name: String,
- children: [['Raw'], null]
- },
- parse: function() {
- var start = this.scanner.tokenStart;
- var children = null;
- var name;
- var nameLowerCase;
- this.scanner.eat(COLON$6);
- this.scanner.eat(COLON$6);
- if (this.scanner.tokenType === FUNCTION$5) {
- name = this.scanner.consumeFunctionName();
- nameLowerCase = name.toLowerCase();
- if (this.pseudo.hasOwnProperty(nameLowerCase)) {
- this.scanner.skipSC();
- children = this.pseudo[nameLowerCase].call(this);
- this.scanner.skipSC();
- } else {
- children = new list().appendData(
- this.Raw(this.scanner.currentToken, 0, 0, false, false)
- );
- }
- this.scanner.eat(RIGHTPARENTHESIS$6);
- } else {
- name = this.scanner.consume(IDENTIFIER$h);
- }
- return {
- type: 'PseudoElementSelector',
- loc: this.getLocation(start, this.scanner.tokenStart),
- name: name,
- children: children
- };
- },
- generate: function(processChunk, node) {
- processChunk('::');
- processChunk(node.name);
- if (node.children !== null) {
- processChunk('(');
- this.each(processChunk, node);
- processChunk(')');
- }
- },
- walkContext: 'function'
- };
- var isNumber$3 = tokenizer$1.isNumber;
- var TYPE$v = tokenizer$1.TYPE;
- var NUMBER$a = TYPE$v.Number;
- var SOLIDUS$6 = TYPE$v.Solidus;
- var FULLSTOP$4 = TYPE$v.FullStop;
- // Terms of <ratio> should to be a positive number (not zero or negative)
- // (see https://drafts.csswg.org/mediaqueries-3/#values)
- // However, -o-min-device-pixel-ratio takes fractional values as a ratio's term
- // and this is using by various sites. Therefore we relax checking on parse
- // to test a term is unsigned number without exponent part.
- // Additional checks may to be applied on lexer validation.
- function consumeNumber(scanner) {
- var value = scanner.consumeNonWS(NUMBER$a);
- for (var i = 0; i < value.length; i++) {
- var code = value.charCodeAt(i);
- if (!isNumber$3(code) && code !== FULLSTOP$4) {
- scanner.error('Unsigned number is expected', scanner.tokenStart - value.length + i);
- }
- }
- if (Number(value) === 0) {
- scanner.error('Zero number is not allowed', scanner.tokenStart - value.length);
- }
- return value;
- }
- // <positive-integer> S* '/' S* <positive-integer>
- var Ratio = {
- name: 'Ratio',
- structure: {
- left: String,
- right: String
- },
- parse: function() {
- var start = this.scanner.tokenStart;
- var left = consumeNumber(this.scanner);
- var right;
- this.scanner.eatNonWS(SOLIDUS$6);
- right = consumeNumber(this.scanner);
- return {
- type: 'Ratio',
- loc: this.getLocation(start, this.scanner.tokenStart),
- left: left,
- right: right
- };
- },
- generate: function(processChunk, node) {
- processChunk(node.left);
- processChunk('/');
- processChunk(node.right);
- }
- };
- var Raw = {
- name: 'Raw',
- structure: {
- value: String
- },
- parse: function(startToken, endTokenType1, endTokenType2, includeTokenType2, excludeWhiteSpace) {
- var startOffset = this.scanner.getTokenStart(startToken);
- var endOffset;
- this.scanner.skip(
- this.scanner.getRawLength(
- startToken,
- endTokenType1,
- endTokenType2,
- includeTokenType2
- )
- );
- if (excludeWhiteSpace && this.scanner.tokenStart > startOffset) {
- endOffset = this.scanner.getOffsetExcludeWS();
- } else {
- endOffset = this.scanner.tokenStart;
- }
- return {
- type: 'Raw',
- loc: this.getLocation(startOffset, endOffset),
- value: this.scanner.source.substring(startOffset, endOffset)
- };
- },
- generate: function(processChunk, node) {
- processChunk(node.value);
- }
- };
- var TYPE$w = tokenizer$1.TYPE;
- var LEFTCURLYBRACKET$5 = TYPE$w.LeftCurlyBracket;
- function consumeRaw$4(startToken) {
- return this.Raw(startToken, LEFTCURLYBRACKET$5, 0, false, true);
- }
- var Rule = {
- name: 'Rule',
- structure: {
- selector: ['SelectorList', 'Raw'],
- block: ['Block']
- },
- parse: function() {
- var startToken = this.scanner.currentToken;
- var startOffset = this.scanner.tokenStart;
- var selector = this.parseSelector
- ? this.tolerantParse(this.SelectorList, consumeRaw$4)
- : consumeRaw$4.call(this, startToken);
- var block = this.Block(this.Declaration);
- return {
- type: 'Rule',
- loc: this.getLocation(startOffset, this.scanner.tokenStart),
- selector: selector,
- block: block
- };
- },
- generate: function(processChunk, node) {
- this.generate(processChunk, node.selector);
- this.generate(processChunk, node.block);
- },
- walkContext: 'rule'
- };
- var Selector = {
- name: 'Selector',
- structure: {
- children: [[
- 'TypeSelector',
- 'IdSelector',
- 'ClassSelector',
- 'AttributeSelector',
- 'PseudoClassSelector',
- 'PseudoElementSelector',
- 'Combinator',
- 'WhiteSpace'
- ]]
- },
- parse: function() {
- var children = this.readSequence(this.scope.Selector);
- // nothing were consumed
- if (children.isEmpty()) {
- this.scanner.error('Selector is expected');
- }
- return {
- type: 'Selector',
- loc: this.getLocationFromList(children),
- children: children
- };
- },
- generate: function(processChunk, node) {
- this.each(processChunk, node);
- }
- };
- var TYPE$x = tokenizer$1.TYPE;
- var COMMA$3 = TYPE$x.Comma;
- var LEFTCURLYBRACKET$6 = TYPE$x.LeftCurlyBracket;
- var SelectorList = {
- name: 'SelectorList',
- structure: {
- children: [['Selector', 'Raw']]
- },
- parse: function() {
- var children = new list();
- while (!this.scanner.eof) {
- children.appendData(this.parseSelector
- ? this.Selector()
- : this.Raw(this.scanner.currentToken, COMMA$3, LEFTCURLYBRACKET$6, false, false)
- );
- if (this.scanner.tokenType === COMMA$3) {
- this.scanner.next();
- continue;
- }
- break;
- }
- return {
- type: 'SelectorList',
- loc: this.getLocationFromList(children),
- children: children
- };
- },
- generate: function(processChunk, node) {
- this.eachComma(processChunk, node);
- },
- walkContext: 'selector'
- };
- var STRING$5 = tokenizer$1.TYPE.String;
- var _String = {
- name: 'String',
- structure: {
- value: String
- },
- parse: function() {
- return {
- type: 'String',
- loc: this.getLocation(this.scanner.tokenStart, this.scanner.tokenEnd),
- value: this.scanner.consume(STRING$5)
- };
- },
- generate: function(processChunk, node) {
- processChunk(node.value);
- }
- };
- var TYPE$y = tokenizer$1.TYPE;
- var WHITESPACE$7 = TYPE$y.WhiteSpace;
- var COMMENT$7 = TYPE$y.Comment;
- var EXCLAMATIONMARK$3 = TYPE$y.ExclamationMark;
- var ATRULE$4 = TYPE$y.Atrule;
- var CDO$3 = TYPE$y.CDO;
- var CDC$3 = TYPE$y.CDC;
- function consumeRaw$5(startToken) {
- return this.Raw(startToken, 0, 0, false, false);
- }
- var StyleSheet = {
- name: 'StyleSheet',
- structure: {
- children: [['Comment', 'Atrule', 'Rule', 'Raw']]
- },
- parse: function() {
- var start = this.scanner.tokenStart;
- var children = new list();
- var child;
- scan:
- while (!this.scanner.eof) {
- switch (this.scanner.tokenType) {
- case WHITESPACE$7:
- this.scanner.next();
- continue;
- case COMMENT$7:
- // ignore comments except exclamation comments (i.e. /*! .. */) on top level
- if (this.scanner.source.charCodeAt(this.scanner.tokenStart + 2) !== EXCLAMATIONMARK$3) {
- this.scanner.next();
- continue;
- }
- child = this.Comment();
- break;
- case CDO$3: // <!--
- child = this.CDO();
- break;
- case CDC$3: // -->
- child = this.CDC();
- break;
- // CSS Syntax Module Level 3
- // §2.2 Error handling
- // At the "top level" of a stylesheet, an <at-keyword-token> starts an at-rule.
- case ATRULE$4:
- child = this.Atrule();
- break;
- // Anything else starts a qualified rule ...
- default:
- child = this.tolerantParse(this.Rule, consumeRaw$5);
- }
- children.appendData(child);
- }
- return {
- type: 'StyleSheet',
- loc: this.getLocation(start, this.scanner.tokenStart),
- children: children
- };
- },
- generate: function(processChunk, node) {
- this.each(processChunk, node);
- },
- walkContext: 'stylesheet'
- };
- var TYPE$z = tokenizer$1.TYPE;
- var IDENTIFIER$i = TYPE$z.Identifier;
- var ASTERISK$5 = TYPE$z.Asterisk;
- var VERTICALLINE$2 = TYPE$z.VerticalLine;
- function eatIdentifierOrAsterisk() {
- if (this.scanner.tokenType !== IDENTIFIER$i &&
- this.scanner.tokenType !== ASTERISK$5) {
- this.scanner.error('Identifier or asterisk is expected');
- }
- this.scanner.next();
- }
- // ident
- // ident|ident
- // ident|*
- // *
- // *|ident
- // *|*
- // |ident
- // |*
- var TypeSelector = {
- name: 'TypeSelector',
- structure: {
- name: String
- },
- parse: function() {
- var start = this.scanner.tokenStart;
- if (this.scanner.tokenType === VERTICALLINE$2) {
- this.scanner.next();
- eatIdentifierOrAsterisk.call(this);
- } else {
- eatIdentifierOrAsterisk.call(this);
- if (this.scanner.tokenType === VERTICALLINE$2) {
- this.scanner.next();
- eatIdentifierOrAsterisk.call(this);
- }
- }
- return {
- type: 'TypeSelector',
- loc: this.getLocation(start, this.scanner.tokenStart),
- name: this.scanner.substrToCursor(start)
- };
- },
- generate: function(processChunk, node) {
- processChunk(node.name);
- }
- };
- var isHex$2 = tokenizer$1.isHex;
- var TYPE$A = tokenizer$1.TYPE;
- var IDENTIFIER$j = TYPE$A.Identifier;
- var NUMBER$b = TYPE$A.Number;
- var PLUSSIGN$7 = TYPE$A.PlusSign;
- var HYPHENMINUS$7 = TYPE$A.HyphenMinus;
- var FULLSTOP$5 = TYPE$A.FullStop;
- var QUESTIONMARK = TYPE$A.QuestionMark;
- function scanUnicodeNumber(scanner) {
- for (var pos = scanner.tokenStart + 1; pos < scanner.tokenEnd; pos++) {
- var code = scanner.source.charCodeAt(pos);
- // break on fullstop or hyperminus/plussign after exponent
- if (code === FULLSTOP$5 || code === PLUSSIGN$7) {
- // break token, exclude symbol
- scanner.tokenStart = pos;
- return false;
- }
- }
- return true;
- }
- // https://drafts.csswg.org/css-syntax-3/#urange
- function scanUnicodeRange(scanner) {
- var hexStart = scanner.tokenStart + 1; // skip +
- var hexLength = 0;
- scan: {
- if (scanner.tokenType === NUMBER$b) {
- if (scanner.source.charCodeAt(scanner.tokenStart) !== FULLSTOP$5 && scanUnicodeNumber(scanner)) {
- scanner.next();
- } else if (scanner.source.charCodeAt(scanner.tokenStart) !== HYPHENMINUS$7) {
- break scan;
- }
- } else {
- scanner.next(); // PLUSSIGN
- }
- if (scanner.tokenType === HYPHENMINUS$7) {
- scanner.next();
- }
- if (scanner.tokenType === NUMBER$b) {
- scanner.next();
- }
- if (scanner.tokenType === IDENTIFIER$j) {
- scanner.next();
- }
- if (scanner.tokenStart === hexStart) {
- scanner.error('Unexpected input', hexStart);
- }
- }
- // validate for U+x{1,6} or U+x{1,6}-x{1,6}
- // where x is [0-9a-fA-F]
- for (var i = hexStart, wasHyphenMinus = false; i < scanner.tokenStart; i++) {
- var code = scanner.source.charCodeAt(i);
- if (isHex$2(code) === false && (code !== HYPHENMINUS$7 || wasHyphenMinus)) {
- scanner.error('Unexpected input', i);
- }
- if (code === HYPHENMINUS$7) {
- // hex sequence shouldn't be an empty
- if (hexLength === 0) {
- scanner.error('Unexpected input', i);
- }
- wasHyphenMinus = true;
- hexLength = 0;
- } else {
- hexLength++;
- // too long hex sequence
- if (hexLength > 6) {
- scanner.error('Too long hex sequence', i);
- }
- }
- }
- // check we have a non-zero sequence
- if (hexLength === 0) {
- scanner.error('Unexpected input', i - 1);
- }
- // U+abc???
- if (!wasHyphenMinus) {
- // consume as many U+003F QUESTION MARK (?) code points as possible
- for (; hexLength < 6 && !scanner.eof; scanner.next()) {
- if (scanner.tokenType !== QUESTIONMARK) {
- break;
- }
- hexLength++;
- }
- }
- }
- var UnicodeRange = {
- name: 'UnicodeRange',
- structure: {
- value: String
- },
- parse: function() {
- var start = this.scanner.tokenStart;
- this.scanner.next(); // U or u
- scanUnicodeRange(this.scanner);
- return {
- type: 'UnicodeRange',
- loc: this.getLocation(start, this.scanner.tokenStart),
- value: this.scanner.substrToCursor(start)
- };
- },
- generate: function(processChunk, node) {
- processChunk(node.value);
- }
- };
- var TYPE$B = tokenizer$1.TYPE;
- var STRING$6 = TYPE$B.String;
- var URL$4 = TYPE$B.Url;
- var RAW$2 = TYPE$B.Raw;
- var RIGHTPARENTHESIS$7 = TYPE$B.RightParenthesis;
- // url '(' S* (string | raw) S* ')'
- var Url = {
- name: 'Url',
- structure: {
- value: ['String', 'Raw']
- },
- parse: function() {
- var start = this.scanner.tokenStart;
- var value;
- this.scanner.eat(URL$4);
- this.scanner.skipSC();
- switch (this.scanner.tokenType) {
- case STRING$6:
- value = this.String();
- break;
- case RAW$2:
- value = this.Raw(this.scanner.currentToken, 0, RAW$2, true, false);
- break;
- default:
- this.scanner.error('String or Raw is expected');
- }
- this.scanner.skipSC();
- this.scanner.eat(RIGHTPARENTHESIS$7);
- return {
- type: 'Url',
- loc: this.getLocation(start, this.scanner.tokenStart),
- value: value
- };
- },
- generate: function(processChunk, node) {
- processChunk('url');
- processChunk('(');
- this.generate(processChunk, node.value);
- processChunk(')');
- }
- };
- var endsWith$1 = tokenizer$1.endsWith;
- var TYPE$C = tokenizer$1.TYPE;
- var WHITESPACE$8 = TYPE$C.WhiteSpace;
- var COMMENT$8 = TYPE$C.Comment;
- var FUNCTION$6 = TYPE$C.Function;
- var COLON$7 = TYPE$C.Colon;
- var SEMICOLON$6 = TYPE$C.Semicolon;
- var EXCLAMATIONMARK$4 = TYPE$C.ExclamationMark;
- // 'progid:' ws* 'DXImageTransform.Microsoft.' ident ws* '(' .* ')'
- function checkProgid(scanner) {
- var offset = 0;
- for (var type; type = scanner.lookupType(offset); offset++) {
- if (type !== WHITESPACE$8 && type !== COMMENT$8) {
- break;
- }
- }
- if (scanner.lookupValue(offset, 'alpha(') ||
- scanner.lookupValue(offset, 'chroma(') ||
- scanner.lookupValue(offset, 'dropshadow(')) {
- if (scanner.lookupType(offset) !== FUNCTION$6) {
- return false;
- }
- } else {
- if (scanner.lookupValue(offset, 'progid') === false ||
- scanner.lookupType(offset + 1) !== COLON$7) {
- return false;
- }
- }
- return true;
- }
- var Value = {
- name: 'Value',
- structure: {
- children: [[]]
- },
- parse: function(property) {
- // special parser for filter property since it can contains non-standart syntax for old IE
- if (property !== null && endsWith$1(property, 'filter') && checkProgid(this.scanner)) {
- this.scanner.skipSC();
- return this.Raw(this.scanner.currentToken, EXCLAMATIONMARK$4, SEMICOLON$6, false, false);
- }
- var start = this.scanner.tokenStart;
- var children = this.readSequence(this.scope.Value);
- return {
- type: 'Value',
- loc: this.getLocation(start, this.scanner.tokenStart),
- children: children
- };
- },
- generate: function(processChunk, node) {
- this.each(processChunk, node);
- }
- };
- var WHITESPACE$9 = tokenizer$1.TYPE.WhiteSpace;
- var SPACE$2 = Object.freeze({
- type: 'WhiteSpace',
- loc: null,
- value: ' '
- });
- var WhiteSpace = {
- name: 'WhiteSpace',
- structure: {
- value: String
- },
- parse: function() {
- this.scanner.eat(WHITESPACE$9);
- return SPACE$2;
- // return {
- // type: 'WhiteSpace',
- // loc: this.getLocation(this.scanner.tokenStart, this.scanner.tokenEnd),
- // value: this.scanner.consume(WHITESPACE)
- // };
- },
- generate: function(processChunk, node) {
- processChunk(node.value);
- }
- };
- var node = {
- AnPlusB: AnPlusB,
- Atrule: Atrule,
- AtruleExpression: AtruleExpression,
- AttributeSelector: AttributeSelector,
- Block: Block,
- Brackets: Brackets,
- CDC: CDC_1,
- CDO: CDO_1,
- ClassSelector: ClassSelector,
- Combinator: Combinator,
- Comment: Comment,
- Declaration: Declaration,
- DeclarationList: DeclarationList,
- Dimension: Dimension,
- Function: _Function,
- HexColor: HexColor,
- Identifier: Identifier,
- IdSelector: IdSelector,
- MediaFeature: MediaFeature,
- MediaQuery: MediaQuery,
- MediaQueryList: MediaQueryList,
- Nth: Nth,
- Number: _Number,
- Operator: Operator,
- Parentheses: Parentheses,
- Percentage: Percentage,
- PseudoClassSelector: PseudoClassSelector,
- PseudoElementSelector: PseudoElementSelector,
- Ratio: Ratio,
- Raw: Raw,
- Rule: Rule,
- Selector: Selector,
- SelectorList: SelectorList,
- String: _String,
- StyleSheet: StyleSheet,
- TypeSelector: TypeSelector,
- UnicodeRange: UnicodeRange,
- Url: Url,
- Value: Value,
- WhiteSpace: WhiteSpace
- };
- var parser = {
- parseContext: {
- default: 'StyleSheet',
- stylesheet: 'StyleSheet',
- atrule: 'Atrule',
- atruleExpression: function(options) {
- return this.AtruleExpression(options.atrule ? String(options.atrule) : null);
- },
- mediaQueryList: 'MediaQueryList',
- mediaQuery: 'MediaQuery',
- rule: 'Rule',
- selectorList: 'SelectorList',
- selector: 'Selector',
- block: function() {
- return this.Block(this.Declaration);
- },
- declarationList: 'DeclarationList',
- declaration: 'Declaration',
- value: function(options) {
- return this.Value(options.property ? String(options.property) : null);
- }
- },
- scope: scope,
- atrule: atrule,
- pseudo: pseudo,
- node: node
- };
- var parser$1 = create(parser);
- function walk ( ast, ref) {
- var enter = ref.enter;
- var leave = ref.leave;
- visit( ast, null, enter, leave );
- }
- var shouldSkip = false;
- var context = { skip: function () { return shouldSkip = true; } };
- var childKeys = {};
- var toString$1 = Object.prototype.toString;
- function isArray$1 ( thing ) {
- return toString$1.call( thing ) === '[object Array]';
- }
- function visit ( node, parent, enter, leave, prop, index ) {
- if ( !node ) { return; }
- if ( enter ) {
- var _shouldSkip = shouldSkip;
- shouldSkip = false;
- enter.call( context, node, parent, prop, index );
- var skipped = shouldSkip;
- shouldSkip = _shouldSkip;
- if ( skipped ) { return; }
- }
- var keys = childKeys[ node.type ] || (
- childKeys[ node.type ] = Object.keys( node ).filter( function (key) { return typeof node[ key ] === 'object'; } )
- );
- for ( var i = 0; i < keys.length; i += 1 ) {
- var key = keys[i];
- var value = node[ key ];
- if ( isArray$1( value ) ) {
- for ( var j = 0; j < value.length; j += 1 ) {
- visit( value[j], node, enter, leave, key, j );
- }
- }
- else if ( value && value.type ) {
- visit( value, node, enter, leave, key, null );
- }
- }
- if ( leave ) {
- leave( node, parent, prop, index );
- }
- }
- function readStyle(parser, start, attributes) {
- const contentStart = parser.index;
- const styles = parser.readUntil(/<\/style>/);
- const contentEnd = parser.index;
- let ast;
- try {
- ast = parser$1(styles, {
- positions: true,
- offset: contentStart,
- });
- }
- catch (err) {
- if (err.name === 'CssSyntaxError') {
- parser.error({
- code: `css-syntax-error`,
- message: err.message
- }, err.offset);
- }
- else {
- throw err;
- }
- }
- ast = JSON.parse(JSON.stringify(ast));
- // tidy up AST
- walk(ast, {
- enter: (node) => {
- // replace `ref:a` nodes
- if (node.type === 'Selector') {
- for (let i = 0; i < node.children.length; i += 1) {
- const a = node.children[i];
- const b = node.children[i + 1];
- if (isRefSelector(a, b)) {
- node.children.splice(i, 2, {
- type: 'RefSelector',
- start: a.loc.start.offset,
- end: b.loc.end.offset,
- name: b.name
- });
- }
- }
- }
- if (node.loc) {
- node.start = node.loc.start.offset;
- node.end = node.loc.end.offset;
- delete node.loc;
- }
- }
- });
- parser.eat('</style>', true);
- const end = parser.index;
- return {
- start,
- end,
- attributes,
- children: ast.children,
- content: {
- start: contentStart,
- end: contentEnd,
- styles,
- },
- };
- }
- function isRefSelector(a, b) {
- if (!b)
- return false;
- return (a.type === 'TypeSelector' &&
- a.name === 'ref' &&
- b.type === 'PseudoClassSelector');
- }
- const DIRECTIVES = {
- Ref: {
- names: ['ref'],
- attribute(start, end, type, name) {
- return { start, end, type, name };
- },
- allowedExpressionTypes: [],
- error: 'ref directives cannot have a value'
- },
- EventHandler: {
- names: ['on'],
- attribute(start, end, type, lhs, expression) {
- const [name, ...modifiers] = lhs.split('|');
- return { start, end, type, name, modifiers, expression };
- },
- allowedExpressionTypes: ['CallExpression'],
- error: 'Expected a method call'
- },
- Binding: {
- names: ['bind'],
- attribute(start, end, type, name, expression) {
- return {
- start, end, type, name,
- value: expression || {
- type: 'Identifier',
- start: start + 5,
- end,
- name,
- }
- };
- },
- allowedExpressionTypes: ['Identifier', 'MemberExpression'],
- error: 'Can only bind to an identifier (e.g. `foo`) or a member expression (e.g. `foo.bar` or `foo[baz]`)'
- },
- Transition: {
- names: ['in', 'out', 'transition'],
- attribute(start, end, type, name, expression, directiveName) {
- return {
- start, end, type, name, expression,
- intro: directiveName === 'in' || directiveName === 'transition',
- outro: directiveName === 'out' || directiveName === 'transition',
- };
- },
- allowedExpressionTypes: ['ObjectExpression'],
- error: 'Transition argument must be an object literal, e.g. `{ duration: 400 }`'
- },
- Animation: {
- names: ['animate'],
- attribute(start, end, type, name, expression) {
- return { start, end, type, name, expression };
- },
- allowedExpressionTypes: ['ObjectExpression'],
- error: 'Animation argument must be an object literal, e.g. `{ duration: 400 }`'
- },
- Action: {
- names: ['use'],
- attribute(start, end, type, name, expression) {
- return { start, end, type, name, expression };
- },
- allowedExpressionTypes: ['*'],
- error: 'Data passed to actions must be an identifier (e.g. `foo`), a member expression ' +
- '(e.g. `foo.bar` or `foo[baz]`), a method call (e.g. `foo()`), or a literal (e.g. `true` or `\'a string\'`'
- },
- Class: {
- names: ['class'],
- attribute(start, end, type, name, expression) {
- return { start, end, type, name, expression };
- },
- allowedExpressionTypes: ['*'],
- error: 'Data passed to class directives must be an expression'
- },
- };
- const lookupByName = {};
- Object.keys(DIRECTIVES).forEach(name => {
- const directive = DIRECTIVES[name];
- directive.names.forEach(type => lookupByName[type] = name);
- });
- function readExpression$1(parser, start, quoteMark) {
- let i = start;
- let escaped = false;
- for (; i < parser.template.length; i += 1) {
- const char = parser.template[i];
- if (quoteMark) {
- if (char === quoteMark) {
- if (!escaped)
- break;
- }
- else if (escaped) {
- escaped = false;
- }
- else if (char === '\\') {
- escaped = true;
- }
- }
- else if (/[\s\/>]/.test(char)) {
- break;
- }
- }
- const expression = parseExpressionAt(parser.template.slice(0, i), start, {
- ecmaVersion: 9,
- });
- parser.index = expression.end;
- parser.allowWhitespace();
- if (quoteMark)
- parser.eat(quoteMark, true);
- return expression;
- }
- function readDirective(parser, start, attrName) {
- const [directiveName, name] = attrName.split(':');
- if (name === undefined)
- return; // No colon in the name
- if (directiveName === '') {
- // not a directive — :foo is short for foo={{foo}}
- return {
- start: start,
- end: start + name.length + 1,
- type: 'Attribute',
- name,
- value: getShorthandValue(start + 1, name)
- };
- }
- const type = lookupByName[directiveName];
- if (!type)
- return; // not a registered directive
- const directive = DIRECTIVES[type];
- let expression = null;
- if (parser.eat('=')) {
- const quoteMark = parser.eat(`'`) ? `'` : parser.eat(`"`) ? `"` : null;
- const expressionStart = parser.index;
- try {
- expression = readExpression$1(parser, expressionStart, quoteMark);
- const allowed = directive.allowedExpressionTypes;
- if (allowed[0] !== '*' && allowed.indexOf(expression.type) === -1) {
- parser.error({
- code: `invalid-directive-value`,
- message: directive.error
- }, expressionStart);
- }
- }
- catch (err) {
- if (parser.template[expressionStart] === '{') {
- // assume the mistake was wrapping the directive arguments.
- // this could yield false positives! but hopefully not too many
- let message = 'directive values should not be wrapped';
- const expressionEnd = parser.template.indexOf('}', expressionStart);
- if (expressionEnd !== -1) {
- const value = parser.template.slice(expressionStart + 1, expressionEnd);
- message += ` — use '${value}', not '{${value}}'`;
- }
- parser.error({
- code: `invalid-directive-value`,
- message
- }, expressionStart);
- }
- throw err;
- }
- }
- return directive.attribute(start, parser.index, type, name, expression, directiveName);
- }
- function getShorthandValue(start, name) {
- const end = start + name.length;
- return [
- {
- type: 'AttributeShorthand',
- start,
- end,
- expression: {
- type: 'Identifier',
- start,
- end,
- name,
- },
- },
- ];
- }
- // https://dev.w3.org/html5/html-author/charref
- var htmlEntities = {
- CounterClockwiseContourIntegral: 8755,
- ClockwiseContourIntegral: 8754,
- DoubleLongLeftRightArrow: 10234,
- DiacriticalDoubleAcute: 733,
- NotSquareSupersetEqual: 8931,
- CloseCurlyDoubleQuote: 8221,
- DoubleContourIntegral: 8751,
- FilledVerySmallSquare: 9642,
- NegativeVeryThinSpace: 8203,
- NotPrecedesSlantEqual: 8928,
- NotRightTriangleEqual: 8941,
- NotSucceedsSlantEqual: 8929,
- CapitalDifferentialD: 8517,
- DoubleLeftRightArrow: 8660,
- DoubleLongRightArrow: 10233,
- EmptyVerySmallSquare: 9643,
- NestedGreaterGreater: 8811,
- NotDoubleVerticalBar: 8742,
- NotLeftTriangleEqual: 8940,
- NotSquareSubsetEqual: 8930,
- OpenCurlyDoubleQuote: 8220,
- ReverseUpEquilibrium: 10607,
- DoubleLongLeftArrow: 10232,
- DownLeftRightVector: 10576,
- LeftArrowRightArrow: 8646,
- NegativeMediumSpace: 8203,
- RightArrowLeftArrow: 8644,
- SquareSupersetEqual: 8850,
- leftrightsquigarrow: 8621,
- DownRightTeeVector: 10591,
- DownRightVectorBar: 10583,
- LongLeftRightArrow: 10231,
- Longleftrightarrow: 10234,
- NegativeThickSpace: 8203,
- PrecedesSlantEqual: 8828,
- ReverseEquilibrium: 8651,
- RightDoubleBracket: 10215,
- RightDownTeeVector: 10589,
- RightDownVectorBar: 10581,
- RightTriangleEqual: 8885,
- SquareIntersection: 8851,
- SucceedsSlantEqual: 8829,
- blacktriangleright: 9656,
- longleftrightarrow: 10231,
- DoubleUpDownArrow: 8661,
- DoubleVerticalBar: 8741,
- DownLeftTeeVector: 10590,
- DownLeftVectorBar: 10582,
- FilledSmallSquare: 9724,
- GreaterSlantEqual: 10878,
- LeftDoubleBracket: 10214,
- LeftDownTeeVector: 10593,
- LeftDownVectorBar: 10585,
- LeftTriangleEqual: 8884,
- NegativeThinSpace: 8203,
- NotReverseElement: 8716,
- NotTildeFullEqual: 8775,
- RightAngleBracket: 10217,
- RightUpDownVector: 10575,
- SquareSubsetEqual: 8849,
- VerticalSeparator: 10072,
- blacktriangledown: 9662,
- blacktriangleleft: 9666,
- leftrightharpoons: 8651,
- rightleftharpoons: 8652,
- twoheadrightarrow: 8608,
- DiacriticalAcute: 180,
- DiacriticalGrave: 96,
- DiacriticalTilde: 732,
- DoubleRightArrow: 8658,
- DownArrowUpArrow: 8693,
- EmptySmallSquare: 9723,
- GreaterEqualLess: 8923,
- GreaterFullEqual: 8807,
- LeftAngleBracket: 10216,
- LeftUpDownVector: 10577,
- LessEqualGreater: 8922,
- NonBreakingSpace: 160,
- NotRightTriangle: 8939,
- NotSupersetEqual: 8841,
- RightTriangleBar: 10704,
- RightUpTeeVector: 10588,
- RightUpVectorBar: 10580,
- UnderParenthesis: 9181,
- UpArrowDownArrow: 8645,
- circlearrowright: 8635,
- downharpoonright: 8642,
- ntrianglerighteq: 8941,
- rightharpoondown: 8641,
- rightrightarrows: 8649,
- twoheadleftarrow: 8606,
- vartriangleright: 8883,
- CloseCurlyQuote: 8217,
- ContourIntegral: 8750,
- DoubleDownArrow: 8659,
- DoubleLeftArrow: 8656,
- DownRightVector: 8641,
- LeftRightVector: 10574,
- LeftTriangleBar: 10703,
- LeftUpTeeVector: 10592,
- LeftUpVectorBar: 10584,
- LowerRightArrow: 8600,
- NotGreaterEqual: 8817,
- NotGreaterTilde: 8821,
- NotLeftTriangle: 8938,
- OverParenthesis: 9180,
- RightDownVector: 8642,
- ShortRightArrow: 8594,
- UpperRightArrow: 8599,
- bigtriangledown: 9661,
- circlearrowleft: 8634,
- curvearrowright: 8631,
- downharpoonleft: 8643,
- leftharpoondown: 8637,
- leftrightarrows: 8646,
- nLeftrightarrow: 8654,
- nleftrightarrow: 8622,
- ntrianglelefteq: 8940,
- rightleftarrows: 8644,
- rightsquigarrow: 8605,
- rightthreetimes: 8908,
- straightepsilon: 1013,
- trianglerighteq: 8885,
- vartriangleleft: 8882,
- DiacriticalDot: 729,
- DoubleRightTee: 8872,
- DownLeftVector: 8637,
- GreaterGreater: 10914,
- HorizontalLine: 9472,
- InvisibleComma: 8291,
- InvisibleTimes: 8290,
- LeftDownVector: 8643,
- LeftRightArrow: 8596,
- Leftrightarrow: 8660,
- LessSlantEqual: 10877,
- LongRightArrow: 10230,
- Longrightarrow: 10233,
- LowerLeftArrow: 8601,
- NestedLessLess: 8810,
- NotGreaterLess: 8825,
- NotLessGreater: 8824,
- NotSubsetEqual: 8840,
- NotVerticalBar: 8740,
- OpenCurlyQuote: 8216,
- ReverseElement: 8715,
- RightTeeVector: 10587,
- RightVectorBar: 10579,
- ShortDownArrow: 8595,
- ShortLeftArrow: 8592,
- SquareSuperset: 8848,
- TildeFullEqual: 8773,
- UpperLeftArrow: 8598,
- ZeroWidthSpace: 8203,
- curvearrowleft: 8630,
- doublebarwedge: 8966,
- downdownarrows: 8650,
- hookrightarrow: 8618,
- leftleftarrows: 8647,
- leftrightarrow: 8596,
- leftthreetimes: 8907,
- longrightarrow: 10230,
- looparrowright: 8620,
- nshortparallel: 8742,
- ntriangleright: 8939,
- rightarrowtail: 8611,
- rightharpoonup: 8640,
- trianglelefteq: 8884,
- upharpoonright: 8638,
- ApplyFunction: 8289,
- DifferentialD: 8518,
- DoubleLeftTee: 10980,
- DoubleUpArrow: 8657,
- LeftTeeVector: 10586,
- LeftVectorBar: 10578,
- LessFullEqual: 8806,
- LongLeftArrow: 10229,
- Longleftarrow: 10232,
- NotTildeEqual: 8772,
- NotTildeTilde: 8777,
- Poincareplane: 8460,
- PrecedesEqual: 10927,
- PrecedesTilde: 8830,
- RightArrowBar: 8677,
- RightTeeArrow: 8614,
- RightTriangle: 8883,
- RightUpVector: 8638,
- SucceedsEqual: 10928,
- SucceedsTilde: 8831,
- SupersetEqual: 8839,
- UpEquilibrium: 10606,
- VerticalTilde: 8768,
- VeryThinSpace: 8202,
- bigtriangleup: 9651,
- blacktriangle: 9652,
- divideontimes: 8903,
- fallingdotseq: 8786,
- hookleftarrow: 8617,
- leftarrowtail: 8610,
- leftharpoonup: 8636,
- longleftarrow: 10229,
- looparrowleft: 8619,
- measuredangle: 8737,
- ntriangleleft: 8938,
- shortparallel: 8741,
- smallsetminus: 8726,
- triangleright: 9657,
- upharpoonleft: 8639,
- DownArrowBar: 10515,
- DownTeeArrow: 8615,
- ExponentialE: 8519,
- GreaterEqual: 8805,
- GreaterTilde: 8819,
- HilbertSpace: 8459,
- HumpDownHump: 8782,
- Intersection: 8898,
- LeftArrowBar: 8676,
- LeftTeeArrow: 8612,
- LeftTriangle: 8882,
- LeftUpVector: 8639,
- NotCongruent: 8802,
- NotLessEqual: 8816,
- NotLessTilde: 8820,
- Proportional: 8733,
- RightCeiling: 8969,
- RoundImplies: 10608,
- ShortUpArrow: 8593,
- SquareSubset: 8847,
- UnderBracket: 9141,
- VerticalLine: 124,
- blacklozenge: 10731,
- exponentiale: 8519,
- risingdotseq: 8787,
- triangledown: 9663,
- triangleleft: 9667,
- CircleMinus: 8854,
- CircleTimes: 8855,
- Equilibrium: 8652,
- GreaterLess: 8823,
- LeftCeiling: 8968,
- LessGreater: 8822,
- MediumSpace: 8287,
- NotPrecedes: 8832,
- NotSucceeds: 8833,
- OverBracket: 9140,
- RightVector: 8640,
- Rrightarrow: 8667,
- RuleDelayed: 10740,
- SmallCircle: 8728,
- SquareUnion: 8852,
- SubsetEqual: 8838,
- UpDownArrow: 8597,
- Updownarrow: 8661,
- VerticalBar: 8739,
- backepsilon: 1014,
- blacksquare: 9642,
- circledcirc: 8858,
- circleddash: 8861,
- curlyeqprec: 8926,
- curlyeqsucc: 8927,
- diamondsuit: 9830,
- eqslantless: 10901,
- expectation: 8496,
- nRightarrow: 8655,
- nrightarrow: 8603,
- preccurlyeq: 8828,
- precnapprox: 10937,
- quaternions: 8461,
- straightphi: 981,
- succcurlyeq: 8829,
- succnapprox: 10938,
- thickapprox: 8776,
- updownarrow: 8597,
- Bernoullis: 8492,
- CirclePlus: 8853,
- EqualTilde: 8770,
- Fouriertrf: 8497,
- ImaginaryI: 8520,
- Laplacetrf: 8466,
- LeftVector: 8636,
- Lleftarrow: 8666,
- NotElement: 8713,
- NotGreater: 8815,
- Proportion: 8759,
- RightArrow: 8594,
- RightFloor: 8971,
- Rightarrow: 8658,
- TildeEqual: 8771,
- TildeTilde: 8776,
- UnderBrace: 9183,
- UpArrowBar: 10514,
- UpTeeArrow: 8613,
- circledast: 8859,
- complement: 8705,
- curlywedge: 8911,
- eqslantgtr: 10902,
- gtreqqless: 10892,
- lessapprox: 10885,
- lesseqqgtr: 10891,
- lmoustache: 9136,
- longmapsto: 10236,
- mapstodown: 8615,
- mapstoleft: 8612,
- nLeftarrow: 8653,
- nleftarrow: 8602,
- precapprox: 10935,
- rightarrow: 8594,
- rmoustache: 9137,
- sqsubseteq: 8849,
- sqsupseteq: 8850,
- subsetneqq: 10955,
- succapprox: 10936,
- supsetneqq: 10956,
- upuparrows: 8648,
- varepsilon: 949,
- varnothing: 8709,
- Backslash: 8726,
- CenterDot: 183,
- CircleDot: 8857,
- Congruent: 8801,
- Coproduct: 8720,
- DoubleDot: 168,
- DownArrow: 8595,
- DownBreve: 785,
- Downarrow: 8659,
- HumpEqual: 8783,
- LeftArrow: 8592,
- LeftFloor: 8970,
- Leftarrow: 8656,
- LessTilde: 8818,
- Mellintrf: 8499,
- MinusPlus: 8723,
- NotCupCap: 8813,
- NotExists: 8708,
- OverBrace: 9182,
- PlusMinus: 177,
- Therefore: 8756,
- ThinSpace: 8201,
- TripleDot: 8411,
- UnionPlus: 8846,
- backprime: 8245,
- backsimeq: 8909,
- bigotimes: 10754,
- centerdot: 183,
- checkmark: 10003,
- complexes: 8450,
- dotsquare: 8865,
- downarrow: 8595,
- gtrapprox: 10886,
- gtreqless: 8923,
- heartsuit: 9829,
- leftarrow: 8592,
- lesseqgtr: 8922,
- nparallel: 8742,
- nshortmid: 8740,
- nsubseteq: 8840,
- nsupseteq: 8841,
- pitchfork: 8916,
- rationals: 8474,
- spadesuit: 9824,
- subseteqq: 10949,
- subsetneq: 8842,
- supseteqq: 10950,
- supsetneq: 8843,
- therefore: 8756,
- triangleq: 8796,
- varpropto: 8733,
- DDotrahd: 10513,
- DotEqual: 8784,
- Integral: 8747,
- LessLess: 10913,
- NotEqual: 8800,
- NotTilde: 8769,
- PartialD: 8706,
- Precedes: 8826,
- RightTee: 8866,
- Succeeds: 8827,
- SuchThat: 8715,
- Superset: 8835,
- Uarrocir: 10569,
- UnderBar: 818,
- andslope: 10840,
- angmsdaa: 10664,
- angmsdab: 10665,
- angmsdac: 10666,
- angmsdad: 10667,
- angmsdae: 10668,
- angmsdaf: 10669,
- angmsdag: 10670,
- angmsdah: 10671,
- angrtvbd: 10653,
- approxeq: 8778,
- awconint: 8755,
- backcong: 8780,
- barwedge: 8965,
- bbrktbrk: 9142,
- bigoplus: 10753,
- bigsqcup: 10758,
- biguplus: 10756,
- bigwedge: 8896,
- boxminus: 8863,
- boxtimes: 8864,
- capbrcup: 10825,
- circledR: 174,
- circledS: 9416,
- cirfnint: 10768,
- clubsuit: 9827,
- cupbrcap: 10824,
- curlyvee: 8910,
- cwconint: 8754,
- doteqdot: 8785,
- dotminus: 8760,
- drbkarow: 10512,
- dzigrarr: 10239,
- elinters: 9191,
- emptyset: 8709,
- eqvparsl: 10725,
- fpartint: 10765,
- geqslant: 10878,
- gesdotol: 10884,
- gnapprox: 10890,
- hksearow: 10533,
- hkswarow: 10534,
- imagline: 8464,
- imagpart: 8465,
- infintie: 10717,
- integers: 8484,
- intercal: 8890,
- intlarhk: 10775,
- laemptyv: 10676,
- ldrushar: 10571,
- leqslant: 10877,
- lesdotor: 10883,
- llcorner: 8990,
- lnapprox: 10889,
- lrcorner: 8991,
- lurdshar: 10570,
- mapstoup: 8613,
- multimap: 8888,
- naturals: 8469,
- otimesas: 10806,
- parallel: 8741,
- plusacir: 10787,
- pointint: 10773,
- precneqq: 10933,
- precnsim: 8936,
- profalar: 9006,
- profline: 8978,
- profsurf: 8979,
- raemptyv: 10675,
- realpart: 8476,
- rppolint: 10770,
- rtriltri: 10702,
- scpolint: 10771,
- setminus: 8726,
- shortmid: 8739,
- smeparsl: 10724,
- sqsubset: 8847,
- sqsupset: 8848,
- subseteq: 8838,
- succneqq: 10934,
- succnsim: 8937,
- supseteq: 8839,
- thetasym: 977,
- thicksim: 8764,
- timesbar: 10801,
- triangle: 9653,
- triminus: 10810,
- trpezium: 9186,
- ulcorner: 8988,
- urcorner: 8989,
- varkappa: 1008,
- varsigma: 962,
- vartheta: 977,
- Because: 8757,
- Cayleys: 8493,
- Cconint: 8752,
- Cedilla: 184,
- Diamond: 8900,
- DownTee: 8868,
- Element: 8712,
- Epsilon: 917,
- Implies: 8658,
- LeftTee: 8867,
- NewLine: 10,
- NoBreak: 8288,
- NotLess: 8814,
- Omicron: 927,
- OverBar: 175,
- Product: 8719,
- UpArrow: 8593,
- Uparrow: 8657,
- Upsilon: 933,
- alefsym: 8501,
- angrtvb: 8894,
- angzarr: 9084,
- asympeq: 8781,
- backsim: 8765,
- because: 8757,
- bemptyv: 10672,
- between: 8812,
- bigcirc: 9711,
- bigodot: 10752,
- bigstar: 9733,
- boxplus: 8862,
- ccupssm: 10832,
- cemptyv: 10674,
- cirscir: 10690,
- coloneq: 8788,
- congdot: 10861,
- cudarrl: 10552,
- cudarrr: 10549,
- cularrp: 10557,
- curarrm: 10556,
- dbkarow: 10511,
- ddagger: 8225,
- ddotseq: 10871,
- demptyv: 10673,
- diamond: 8900,
- digamma: 989,
- dotplus: 8724,
- dwangle: 10662,
- epsilon: 949,
- eqcolon: 8789,
- equivDD: 10872,
- gesdoto: 10882,
- gtquest: 10876,
- gtrless: 8823,
- harrcir: 10568,
- intprod: 10812,
- isindot: 8949,
- larrbfs: 10527,
- larrsim: 10611,
- lbrksld: 10639,
- lbrkslu: 10637,
- ldrdhar: 10599,
- lesdoto: 10881,
- lessdot: 8918,
- lessgtr: 8822,
- lesssim: 8818,
- lotimes: 10804,
- lozenge: 9674,
- ltquest: 10875,
- luruhar: 10598,
- maltese: 10016,
- minusdu: 10794,
- napprox: 8777,
- natural: 9838,
- nearrow: 8599,
- nexists: 8708,
- notinva: 8713,
- notinvb: 8951,
- notinvc: 8950,
- notniva: 8716,
- notnivb: 8958,
- notnivc: 8957,
- npolint: 10772,
- nsqsube: 8930,
- nsqsupe: 8931,
- nvinfin: 10718,
- nwarrow: 8598,
- olcross: 10683,
- omicron: 959,
- orderof: 8500,
- orslope: 10839,
- pertenk: 8241,
- planckh: 8462,
- pluscir: 10786,
- plussim: 10790,
- plustwo: 10791,
- precsim: 8830,
- quatint: 10774,
- questeq: 8799,
- rarrbfs: 10528,
- rarrsim: 10612,
- rbrksld: 10638,
- rbrkslu: 10640,
- rdldhar: 10601,
- realine: 8475,
- rotimes: 10805,
- ruluhar: 10600,
- searrow: 8600,
- simplus: 10788,
- simrarr: 10610,
- subedot: 10947,
- submult: 10945,
- subplus: 10943,
- subrarr: 10617,
- succsim: 8831,
- supdsub: 10968,
- supedot: 10948,
- suphsub: 10967,
- suplarr: 10619,
- supmult: 10946,
- supplus: 10944,
- swarrow: 8601,
- topfork: 10970,
- triplus: 10809,
- tritime: 10811,
- uparrow: 8593,
- upsilon: 965,
- uwangle: 10663,
- vzigzag: 10650,
- zigrarr: 8669,
- Aacute: 193,
- Abreve: 258,
- Agrave: 192,
- Assign: 8788,
- Atilde: 195,
- Barwed: 8966,
- Bumpeq: 8782,
- Cacute: 262,
- Ccaron: 268,
- Ccedil: 199,
- Colone: 10868,
- Conint: 8751,
- CupCap: 8781,
- Dagger: 8225,
- Dcaron: 270,
- DotDot: 8412,
- Dstrok: 272,
- Eacute: 201,
- Ecaron: 282,
- Egrave: 200,
- Exists: 8707,
- ForAll: 8704,
- Gammad: 988,
- Gbreve: 286,
- Gcedil: 290,
- HARDcy: 1066,
- Hstrok: 294,
- Iacute: 205,
- Igrave: 204,
- Itilde: 296,
- Jsercy: 1032,
- Kcedil: 310,
- Lacute: 313,
- Lambda: 923,
- Lcaron: 317,
- Lcedil: 315,
- Lmidot: 319,
- Lstrok: 321,
- Nacute: 323,
- Ncaron: 327,
- Ncedil: 325,
- Ntilde: 209,
- Oacute: 211,
- Odblac: 336,
- Ograve: 210,
- Oslash: 216,
- Otilde: 213,
- Otimes: 10807,
- Racute: 340,
- Rarrtl: 10518,
- Rcaron: 344,
- Rcedil: 342,
- SHCHcy: 1065,
- SOFTcy: 1068,
- Sacute: 346,
- Scaron: 352,
- Scedil: 350,
- Square: 9633,
- Subset: 8912,
- Supset: 8913,
- Tcaron: 356,
- Tcedil: 354,
- Tstrok: 358,
- Uacute: 218,
- Ubreve: 364,
- Udblac: 368,
- Ugrave: 217,
- Utilde: 360,
- Vdashl: 10982,
- Verbar: 8214,
- Vvdash: 8874,
- Yacute: 221,
- Zacute: 377,
- Zcaron: 381,
- aacute: 225,
- abreve: 259,
- agrave: 224,
- andand: 10837,
- angmsd: 8737,
- angsph: 8738,
- apacir: 10863,
- approx: 8776,
- atilde: 227,
- barvee: 8893,
- barwed: 8965,
- becaus: 8757,
- bernou: 8492,
- bigcap: 8898,
- bigcup: 8899,
- bigvee: 8897,
- bkarow: 10509,
- bottom: 8869,
- bowtie: 8904,
- boxbox: 10697,
- bprime: 8245,
- brvbar: 166,
- bullet: 8226,
- bumpeq: 8783,
- cacute: 263,
- capand: 10820,
- capcap: 10827,
- capcup: 10823,
- capdot: 10816,
- ccaron: 269,
- ccedil: 231,
- circeq: 8791,
- cirmid: 10991,
- colone: 8788,
- commat: 64,
- compfn: 8728,
- conint: 8750,
- coprod: 8720,
- copysr: 8471,
- cularr: 8630,
- cupcap: 10822,
- cupcup: 10826,
- cupdot: 8845,
- curarr: 8631,
- curren: 164,
- cylcty: 9005,
- dagger: 8224,
- daleth: 8504,
- dcaron: 271,
- dfisht: 10623,
- divide: 247,
- divonx: 8903,
- dlcorn: 8990,
- dlcrop: 8973,
- dollar: 36,
- drcorn: 8991,
- drcrop: 8972,
- dstrok: 273,
- eacute: 233,
- easter: 10862,
- ecaron: 283,
- ecolon: 8789,
- egrave: 232,
- egsdot: 10904,
- elsdot: 10903,
- emptyv: 8709,
- emsp13: 8196,
- emsp14: 8197,
- eparsl: 10723,
- eqcirc: 8790,
- equals: 61,
- equest: 8799,
- female: 9792,
- ffilig: 64259,
- ffllig: 64260,
- forall: 8704,
- frac12: 189,
- frac13: 8531,
- frac14: 188,
- frac15: 8533,
- frac16: 8537,
- frac18: 8539,
- frac23: 8532,
- frac25: 8534,
- frac34: 190,
- frac35: 8535,
- frac38: 8540,
- frac45: 8536,
- frac56: 8538,
- frac58: 8541,
- frac78: 8542,
- gacute: 501,
- gammad: 989,
- gbreve: 287,
- gesdot: 10880,
- gesles: 10900,
- gtlPar: 10645,
- gtrarr: 10616,
- gtrdot: 8919,
- gtrsim: 8819,
- hairsp: 8202,
- hamilt: 8459,
- hardcy: 1098,
- hearts: 9829,
- hellip: 8230,
- hercon: 8889,
- homtht: 8763,
- horbar: 8213,
- hslash: 8463,
- hstrok: 295,
- hybull: 8259,
- hyphen: 8208,
- iacute: 237,
- igrave: 236,
- iiiint: 10764,
- iinfin: 10716,
- incare: 8453,
- inodot: 305,
- intcal: 8890,
- iquest: 191,
- isinsv: 8947,
- itilde: 297,
- jsercy: 1112,
- kappav: 1008,
- kcedil: 311,
- kgreen: 312,
- lAtail: 10523,
- lacute: 314,
- lagran: 8466,
- lambda: 955,
- langle: 10216,
- larrfs: 10525,
- larrhk: 8617,
- larrlp: 8619,
- larrpl: 10553,
- larrtl: 8610,
- latail: 10521,
- lbrace: 123,
- lbrack: 91,
- lcaron: 318,
- lcedil: 316,
- ldquor: 8222,
- lesdot: 10879,
- lesges: 10899,
- lfisht: 10620,
- lfloor: 8970,
- lharul: 10602,
- llhard: 10603,
- lmidot: 320,
- lmoust: 9136,
- loplus: 10797,
- lowast: 8727,
- lowbar: 95,
- lparlt: 10643,
- lrhard: 10605,
- lsaquo: 8249,
- lsquor: 8218,
- lstrok: 322,
- lthree: 8907,
- ltimes: 8905,
- ltlarr: 10614,
- ltrPar: 10646,
- mapsto: 8614,
- marker: 9646,
- mcomma: 10793,
- midast: 42,
- midcir: 10992,
- middot: 183,
- minusb: 8863,
- minusd: 8760,
- mnplus: 8723,
- models: 8871,
- mstpos: 8766,
- nVDash: 8879,
- nVdash: 8878,
- nacute: 324,
- ncaron: 328,
- ncedil: 326,
- nearhk: 10532,
- nequiv: 8802,
- nesear: 10536,
- nexist: 8708,
- nltrie: 8940,
- nprcue: 8928,
- nrtrie: 8941,
- nsccue: 8929,
- nsimeq: 8772,
- ntilde: 241,
- numero: 8470,
- nvDash: 8877,
- nvHarr: 10500,
- nvdash: 8876,
- nvlArr: 10498,
- nvrArr: 10499,
- nwarhk: 10531,
- nwnear: 10535,
- oacute: 243,
- odblac: 337,
- odsold: 10684,
- ograve: 242,
- ominus: 8854,
- origof: 8886,
- oslash: 248,
- otilde: 245,
- otimes: 8855,
- parsim: 10995,
- percnt: 37,
- period: 46,
- permil: 8240,
- phmmat: 8499,
- planck: 8463,
- plankv: 8463,
- plusdo: 8724,
- plusdu: 10789,
- plusmn: 177,
- preceq: 10927,
- primes: 8473,
- prnsim: 8936,
- propto: 8733,
- prurel: 8880,
- puncsp: 8200,
- qprime: 8279,
- rAtail: 10524,
- racute: 341,
- rangle: 10217,
- rarrap: 10613,
- rarrfs: 10526,
- rarrhk: 8618,
- rarrlp: 8620,
- rarrpl: 10565,
- rarrtl: 8611,
- ratail: 10522,
- rbrace: 125,
- rbrack: 93,
- rcaron: 345,
- rcedil: 343,
- rdquor: 8221,
- rfisht: 10621,
- rfloor: 8971,
- rharul: 10604,
- rmoust: 9137,
- roplus: 10798,
- rpargt: 10644,
- rsaquo: 8250,
- rsquor: 8217,
- rthree: 8908,
- rtimes: 8906,
- sacute: 347,
- scaron: 353,
- scedil: 351,
- scnsim: 8937,
- searhk: 10533,
- seswar: 10537,
- sfrown: 8994,
- shchcy: 1097,
- sigmaf: 962,
- sigmav: 962,
- simdot: 10858,
- smashp: 10803,
- softcy: 1100,
- solbar: 9023,
- spades: 9824,
- sqsube: 8849,
- sqsupe: 8850,
- square: 9633,
- squarf: 9642,
- ssetmn: 8726,
- ssmile: 8995,
- sstarf: 8902,
- subdot: 10941,
- subset: 8834,
- subsim: 10951,
- subsub: 10965,
- subsup: 10963,
- succeq: 10928,
- supdot: 10942,
- supset: 8835,
- supsim: 10952,
- supsub: 10964,
- supsup: 10966,
- swarhk: 10534,
- swnwar: 10538,
- target: 8982,
- tcaron: 357,
- tcedil: 355,
- telrec: 8981,
- there4: 8756,
- thetav: 977,
- thinsp: 8201,
- thksim: 8764,
- timesb: 8864,
- timesd: 10800,
- topbot: 9014,
- topcir: 10993,
- tprime: 8244,
- tridot: 9708,
- tstrok: 359,
- uacute: 250,
- ubreve: 365,
- udblac: 369,
- ufisht: 10622,
- ugrave: 249,
- ulcorn: 8988,
- ulcrop: 8975,
- urcorn: 8989,
- urcrop: 8974,
- utilde: 361,
- vangrt: 10652,
- varphi: 966,
- varrho: 1009,
- veebar: 8891,
- vellip: 8942,
- verbar: 124,
- wedbar: 10847,
- wedgeq: 8793,
- weierp: 8472,
- wreath: 8768,
- xoplus: 10753,
- xotime: 10754,
- xsqcup: 10758,
- xuplus: 10756,
- xwedge: 8896,
- yacute: 253,
- zacute: 378,
- zcaron: 382,
- zeetrf: 8488,
- AElig: 198,
- Acirc: 194,
- Alpha: 913,
- Amacr: 256,
- Aogon: 260,
- Aring: 197,
- Breve: 728,
- Ccirc: 264,
- Colon: 8759,
- Cross: 10799,
- Dashv: 10980,
- Delta: 916,
- Ecirc: 202,
- Emacr: 274,
- Eogon: 280,
- Equal: 10869,
- Gamma: 915,
- Gcirc: 284,
- Hacek: 711,
- Hcirc: 292,
- IJlig: 306,
- Icirc: 206,
- Imacr: 298,
- Iogon: 302,
- Iukcy: 1030,
- Jcirc: 308,
- Jukcy: 1028,
- Kappa: 922,
- OElig: 338,
- Ocirc: 212,
- Omacr: 332,
- Omega: 937,
- Prime: 8243,
- RBarr: 10512,
- Scirc: 348,
- Sigma: 931,
- THORN: 222,
- TRADE: 8482,
- TSHcy: 1035,
- Theta: 920,
- Tilde: 8764,
- Ubrcy: 1038,
- Ucirc: 219,
- Umacr: 362,
- Union: 8899,
- Uogon: 370,
- UpTee: 8869,
- Uring: 366,
- VDash: 8875,
- Vdash: 8873,
- Wcirc: 372,
- Wedge: 8896,
- Ycirc: 374,
- acirc: 226,
- acute: 180,
- aelig: 230,
- aleph: 8501,
- alpha: 945,
- amacr: 257,
- amalg: 10815,
- angle: 8736,
- angrt: 8735,
- angst: 8491,
- aogon: 261,
- aring: 229,
- asymp: 8776,
- awint: 10769,
- bcong: 8780,
- bdquo: 8222,
- bepsi: 1014,
- blank: 9251,
- blk12: 9618,
- blk14: 9617,
- blk34: 9619,
- block: 9608,
- boxDL: 9559,
- boxDR: 9556,
- boxDl: 9558,
- boxDr: 9555,
- boxHD: 9574,
- boxHU: 9577,
- boxHd: 9572,
- boxHu: 9575,
- boxUL: 9565,
- boxUR: 9562,
- boxUl: 9564,
- boxUr: 9561,
- boxVH: 9580,
- boxVL: 9571,
- boxVR: 9568,
- boxVh: 9579,
- boxVl: 9570,
- boxVr: 9567,
- boxdL: 9557,
- boxdR: 9554,
- boxdl: 9488,
- boxdr: 9484,
- boxhD: 9573,
- boxhU: 9576,
- boxhd: 9516,
- boxhu: 9524,
- boxuL: 9563,
- boxuR: 9560,
- boxul: 9496,
- boxur: 9492,
- boxvH: 9578,
- boxvL: 9569,
- boxvR: 9566,
- boxvh: 9532,
- boxvl: 9508,
- boxvr: 9500,
- breve: 728,
- bsemi: 8271,
- bsime: 8909,
- bsolb: 10693,
- bumpE: 10926,
- bumpe: 8783,
- caret: 8257,
- caron: 711,
- ccaps: 10829,
- ccirc: 265,
- ccups: 10828,
- cedil: 184,
- check: 10003,
- clubs: 9827,
- colon: 58,
- comma: 44,
- crarr: 8629,
- cross: 10007,
- csube: 10961,
- csupe: 10962,
- ctdot: 8943,
- cuepr: 8926,
- cuesc: 8927,
- cupor: 10821,
- cuvee: 8910,
- cuwed: 8911,
- cwint: 8753,
- dashv: 8867,
- dblac: 733,
- ddarr: 8650,
- delta: 948,
- dharl: 8643,
- dharr: 8642,
- diams: 9830,
- disin: 8946,
- doteq: 8784,
- dtdot: 8945,
- dtrif: 9662,
- duarr: 8693,
- duhar: 10607,
- eDDot: 10871,
- ecirc: 234,
- efDot: 8786,
- emacr: 275,
- empty: 8709,
- eogon: 281,
- eplus: 10865,
- epsiv: 949,
- eqsim: 8770,
- equiv: 8801,
- erDot: 8787,
- erarr: 10609,
- esdot: 8784,
- exist: 8707,
- fflig: 64256,
- filig: 64257,
- fllig: 64258,
- fltns: 9649,
- forkv: 10969,
- frasl: 8260,
- frown: 8994,
- gamma: 947,
- gcirc: 285,
- gescc: 10921,
- gimel: 8503,
- gneqq: 8809,
- gnsim: 8935,
- grave: 96,
- gsime: 10894,
- gsiml: 10896,
- gtcir: 10874,
- gtdot: 8919,
- harrw: 8621,
- hcirc: 293,
- hoarr: 8703,
- icirc: 238,
- iexcl: 161,
- iiint: 8749,
- iiota: 8489,
- ijlig: 307,
- imacr: 299,
- image: 8465,
- imath: 305,
- imped: 437,
- infin: 8734,
- iogon: 303,
- iprod: 10812,
- isinE: 8953,
- isins: 8948,
- isinv: 8712,
- iukcy: 1110,
- jcirc: 309,
- jmath: 567,
- jukcy: 1108,
- kappa: 954,
- lAarr: 8666,
- lBarr: 10510,
- langd: 10641,
- laquo: 171,
- larrb: 8676,
- lbarr: 10508,
- lbbrk: 10098,
- lbrke: 10635,
- lceil: 8968,
- ldquo: 8220,
- lescc: 10920,
- lhard: 8637,
- lharu: 8636,
- lhblk: 9604,
- llarr: 8647,
- lltri: 9722,
- lneqq: 8808,
- lnsim: 8934,
- loang: 10220,
- loarr: 8701,
- lobrk: 10214,
- lopar: 10629,
- lrarr: 8646,
- lrhar: 8651,
- lrtri: 8895,
- lsime: 10893,
- lsimg: 10895,
- lsquo: 8216,
- ltcir: 10873,
- ltdot: 8918,
- ltrie: 8884,
- ltrif: 9666,
- mDDot: 8762,
- mdash: 8212,
- micro: 181,
- minus: 8722,
- mumap: 8888,
- nabla: 8711,
- napos: 329,
- natur: 9838,
- ncong: 8775,
- ndash: 8211,
- neArr: 8663,
- nearr: 8599,
- ngsim: 8821,
- nhArr: 8654,
- nharr: 8622,
- nhpar: 10994,
- nlArr: 8653,
- nlarr: 8602,
- nless: 8814,
- nlsim: 8820,
- nltri: 8938,
- notin: 8713,
- notni: 8716,
- nprec: 8832,
- nrArr: 8655,
- nrarr: 8603,
- nrtri: 8939,
- nsime: 8772,
- nsmid: 8740,
- nspar: 8742,
- nsube: 8840,
- nsucc: 8833,
- nsupe: 8841,
- numsp: 8199,
- nwArr: 8662,
- nwarr: 8598,
- ocirc: 244,
- odash: 8861,
- oelig: 339,
- ofcir: 10687,
- ohbar: 10677,
- olarr: 8634,
- olcir: 10686,
- oline: 8254,
- omacr: 333,
- omega: 969,
- operp: 10681,
- oplus: 8853,
- orarr: 8635,
- order: 8500,
- ovbar: 9021,
- parsl: 11005,
- phone: 9742,
- plusb: 8862,
- pluse: 10866,
- pound: 163,
- prcue: 8828,
- prime: 8242,
- prnap: 10937,
- prsim: 8830,
- quest: 63,
- rAarr: 8667,
- rBarr: 10511,
- radic: 8730,
- rangd: 10642,
- range: 10661,
- raquo: 187,
- rarrb: 8677,
- rarrc: 10547,
- rarrw: 8605,
- ratio: 8758,
- rbarr: 10509,
- rbbrk: 10099,
- rbrke: 10636,
- rceil: 8969,
- rdquo: 8221,
- reals: 8477,
- rhard: 8641,
- rharu: 8640,
- rlarr: 8644,
- rlhar: 8652,
- rnmid: 10990,
- roang: 10221,
- roarr: 8702,
- robrk: 10215,
- ropar: 10630,
- rrarr: 8649,
- rsquo: 8217,
- rtrie: 8885,
- rtrif: 9656,
- sbquo: 8218,
- sccue: 8829,
- scirc: 349,
- scnap: 10938,
- scsim: 8831,
- sdotb: 8865,
- sdote: 10854,
- seArr: 8664,
- searr: 8600,
- setmn: 8726,
- sharp: 9839,
- sigma: 963,
- simeq: 8771,
- simgE: 10912,
- simlE: 10911,
- simne: 8774,
- slarr: 8592,
- smile: 8995,
- sqcap: 8851,
- sqcup: 8852,
- sqsub: 8847,
- sqsup: 8848,
- srarr: 8594,
- starf: 9733,
- strns: 175,
- subnE: 10955,
- subne: 8842,
- supnE: 10956,
- supne: 8843,
- swArr: 8665,
- swarr: 8601,
- szlig: 223,
- theta: 952,
- thkap: 8776,
- thorn: 254,
- tilde: 732,
- times: 215,
- trade: 8482,
- trisb: 10701,
- tshcy: 1115,
- twixt: 8812,
- ubrcy: 1118,
- ucirc: 251,
- udarr: 8645,
- udhar: 10606,
- uharl: 8639,
- uharr: 8638,
- uhblk: 9600,
- ultri: 9720,
- umacr: 363,
- uogon: 371,
- uplus: 8846,
- upsih: 978,
- uring: 367,
- urtri: 9721,
- utdot: 8944,
- utrif: 9652,
- uuarr: 8648,
- vBarv: 10985,
- vDash: 8872,
- varpi: 982,
- vdash: 8866,
- veeeq: 8794,
- vltri: 8882,
- vprop: 8733,
- vrtri: 8883,
- wcirc: 373,
- wedge: 8743,
- xcirc: 9711,
- xdtri: 9661,
- xhArr: 10234,
- xharr: 10231,
- xlArr: 10232,
- xlarr: 10229,
- xodot: 10752,
- xrArr: 10233,
- xrarr: 10230,
- xutri: 9651,
- ycirc: 375,
- Aopf: 120120,
- Ascr: 119964,
- Auml: 196,
- Barv: 10983,
- Beta: 914,
- Bopf: 120121,
- Bscr: 8492,
- CHcy: 1063,
- COPY: 169,
- Cdot: 266,
- Copf: 8450,
- Cscr: 119966,
- DJcy: 1026,
- DScy: 1029,
- DZcy: 1039,
- Darr: 8609,
- Dopf: 120123,
- Dscr: 119967,
- Edot: 278,
- Eopf: 120124,
- Escr: 8496,
- Esim: 10867,
- Euml: 203,
- Fopf: 120125,
- Fscr: 8497,
- GJcy: 1027,
- Gdot: 288,
- Gopf: 120126,
- Gscr: 119970,
- Hopf: 8461,
- Hscr: 8459,
- IEcy: 1045,
- IOcy: 1025,
- Idot: 304,
- Iopf: 120128,
- Iota: 921,
- Iscr: 8464,
- Iuml: 207,
- Jopf: 120129,
- Jscr: 119973,
- KHcy: 1061,
- KJcy: 1036,
- Kopf: 120130,
- Kscr: 119974,
- LJcy: 1033,
- Lang: 10218,
- Larr: 8606,
- Lopf: 120131,
- Lscr: 8466,
- Mopf: 120132,
- Mscr: 8499,
- NJcy: 1034,
- Nopf: 8469,
- Nscr: 119977,
- Oopf: 120134,
- Oscr: 119978,
- Ouml: 214,
- Popf: 8473,
- Pscr: 119979,
- QUOT: 34,
- Qopf: 8474,
- Qscr: 119980,
- Rang: 10219,
- Rarr: 8608,
- Ropf: 8477,
- Rscr: 8475,
- SHcy: 1064,
- Sopf: 120138,
- Sqrt: 8730,
- Sscr: 119982,
- Star: 8902,
- TScy: 1062,
- Topf: 120139,
- Tscr: 119983,
- Uarr: 8607,
- Uopf: 120140,
- Upsi: 978,
- Uscr: 119984,
- Uuml: 220,
- Vbar: 10987,
- Vert: 8214,
- Vopf: 120141,
- Vscr: 119985,
- Wopf: 120142,
- Wscr: 119986,
- Xopf: 120143,
- Xscr: 119987,
- YAcy: 1071,
- YIcy: 1031,
- YUcy: 1070,
- Yopf: 120144,
- Yscr: 119988,
- Yuml: 376,
- ZHcy: 1046,
- Zdot: 379,
- Zeta: 918,
- Zopf: 8484,
- Zscr: 119989,
- andd: 10844,
- andv: 10842,
- ange: 10660,
- aopf: 120146,
- apid: 8779,
- apos: 39,
- ascr: 119990,
- auml: 228,
- bNot: 10989,
- bbrk: 9141,
- beta: 946,
- beth: 8502,
- bnot: 8976,
- bopf: 120147,
- boxH: 9552,
- boxV: 9553,
- boxh: 9472,
- boxv: 9474,
- bscr: 119991,
- bsim: 8765,
- bsol: 92,
- bull: 8226,
- bump: 8782,
- cdot: 267,
- cent: 162,
- chcy: 1095,
- cirE: 10691,
- circ: 710,
- cire: 8791,
- comp: 8705,
- cong: 8773,
- copf: 120148,
- copy: 169,
- cscr: 119992,
- csub: 10959,
- csup: 10960,
- dArr: 8659,
- dHar: 10597,
- darr: 8595,
- dash: 8208,
- diam: 8900,
- djcy: 1106,
- dopf: 120149,
- dscr: 119993,
- dscy: 1109,
- dsol: 10742,
- dtri: 9663,
- dzcy: 1119,
- eDot: 8785,
- ecir: 8790,
- edot: 279,
- emsp: 8195,
- ensp: 8194,
- eopf: 120150,
- epar: 8917,
- epsi: 1013,
- escr: 8495,
- esim: 8770,
- euml: 235,
- euro: 8364,
- excl: 33,
- flat: 9837,
- fnof: 402,
- fopf: 120151,
- fork: 8916,
- fscr: 119995,
- gdot: 289,
- geqq: 8807,
- gjcy: 1107,
- gnap: 10890,
- gneq: 10888,
- gopf: 120152,
- gscr: 8458,
- gsim: 8819,
- gtcc: 10919,
- hArr: 8660,
- half: 189,
- harr: 8596,
- hbar: 8463,
- hopf: 120153,
- hscr: 119997,
- iecy: 1077,
- imof: 8887,
- iocy: 1105,
- iopf: 120154,
- iota: 953,
- iscr: 119998,
- isin: 8712,
- iuml: 239,
- jopf: 120155,
- jscr: 119999,
- khcy: 1093,
- kjcy: 1116,
- kopf: 120156,
- kscr: 120000,
- lArr: 8656,
- lHar: 10594,
- lang: 10216,
- larr: 8592,
- late: 10925,
- lcub: 123,
- ldca: 10550,
- ldsh: 8626,
- leqq: 8806,
- ljcy: 1113,
- lnap: 10889,
- lneq: 10887,
- lopf: 120157,
- lozf: 10731,
- lpar: 40,
- lscr: 120001,
- lsim: 8818,
- lsqb: 91,
- ltcc: 10918,
- ltri: 9667,
- macr: 175,
- male: 9794,
- malt: 10016,
- mlcp: 10971,
- mldr: 8230,
- mopf: 120158,
- mscr: 120002,
- nbsp: 160,
- ncap: 10819,
- ncup: 10818,
- ngeq: 8817,
- ngtr: 8815,
- nisd: 8954,
- njcy: 1114,
- nldr: 8229,
- nleq: 8816,
- nmid: 8740,
- nopf: 120159,
- npar: 8742,
- nscr: 120003,
- nsim: 8769,
- nsub: 8836,
- nsup: 8837,
- ntgl: 8825,
- ntlg: 8824,
- oast: 8859,
- ocir: 8858,
- odiv: 10808,
- odot: 8857,
- ogon: 731,
- oint: 8750,
- omid: 10678,
- oopf: 120160,
- opar: 10679,
- ordf: 170,
- ordm: 186,
- oror: 10838,
- oscr: 8500,
- osol: 8856,
- ouml: 246,
- para: 182,
- part: 8706,
- perp: 8869,
- phiv: 966,
- plus: 43,
- popf: 120161,
- prap: 10935,
- prec: 8826,
- prnE: 10933,
- prod: 8719,
- prop: 8733,
- pscr: 120005,
- qint: 10764,
- qopf: 120162,
- qscr: 120006,
- quot: 34,
- rArr: 8658,
- rHar: 10596,
- race: 10714,
- rang: 10217,
- rarr: 8594,
- rcub: 125,
- rdca: 10551,
- rdsh: 8627,
- real: 8476,
- rect: 9645,
- rhov: 1009,
- ring: 730,
- ropf: 120163,
- rpar: 41,
- rscr: 120007,
- rsqb: 93,
- rtri: 9657,
- scap: 10936,
- scnE: 10934,
- sdot: 8901,
- sect: 167,
- semi: 59,
- sext: 10038,
- shcy: 1096,
- sime: 8771,
- simg: 10910,
- siml: 10909,
- smid: 8739,
- smte: 10924,
- solb: 10692,
- sopf: 120164,
- spar: 8741,
- squf: 9642,
- sscr: 120008,
- star: 9734,
- subE: 10949,
- sube: 8838,
- succ: 8827,
- sung: 9834,
- sup1: 185,
- sup2: 178,
- sup3: 179,
- supE: 10950,
- supe: 8839,
- tbrk: 9140,
- tdot: 8411,
- tint: 8749,
- toea: 10536,
- topf: 120165,
- tosa: 10537,
- trie: 8796,
- tscr: 120009,
- tscy: 1094,
- uArr: 8657,
- uHar: 10595,
- uarr: 8593,
- uopf: 120166,
- upsi: 965,
- uscr: 120010,
- utri: 9653,
- uuml: 252,
- vArr: 8661,
- vBar: 10984,
- varr: 8597,
- vert: 124,
- vopf: 120167,
- vscr: 120011,
- wopf: 120168,
- wscr: 120012,
- xcap: 8898,
- xcup: 8899,
- xmap: 10236,
- xnis: 8955,
- xopf: 120169,
- xscr: 120013,
- xvee: 8897,
- yacy: 1103,
- yicy: 1111,
- yopf: 120170,
- yscr: 120014,
- yucy: 1102,
- yuml: 255,
- zdot: 380,
- zeta: 950,
- zhcy: 1078,
- zopf: 120171,
- zscr: 120015,
- zwnj: 8204,
- AMP: 38,
- Acy: 1040,
- Afr: 120068,
- And: 10835,
- Bcy: 1041,
- Bfr: 120069,
- Cap: 8914,
- Cfr: 8493,
- Chi: 935,
- Cup: 8915,
- Dcy: 1044,
- Del: 8711,
- Dfr: 120071,
- Dot: 168,
- ENG: 330,
- ETH: 208,
- Ecy: 1069,
- Efr: 120072,
- Eta: 919,
- Fcy: 1060,
- Ffr: 120073,
- Gcy: 1043,
- Gfr: 120074,
- Hat: 94,
- Hfr: 8460,
- Icy: 1048,
- Ifr: 8465,
- Int: 8748,
- Jcy: 1049,
- Jfr: 120077,
- Kcy: 1050,
- Kfr: 120078,
- Lcy: 1051,
- Lfr: 120079,
- Lsh: 8624,
- Map: 10501,
- Mcy: 1052,
- Mfr: 120080,
- Ncy: 1053,
- Nfr: 120081,
- Not: 10988,
- Ocy: 1054,
- Ofr: 120082,
- Pcy: 1055,
- Pfr: 120083,
- Phi: 934,
- Psi: 936,
- Qfr: 120084,
- REG: 174,
- Rcy: 1056,
- Rfr: 8476,
- Rho: 929,
- Rsh: 8625,
- Scy: 1057,
- Sfr: 120086,
- Sub: 8912,
- Sum: 8721,
- Sup: 8913,
- Tab: 9,
- Tau: 932,
- Tcy: 1058,
- Tfr: 120087,
- Ucy: 1059,
- Ufr: 120088,
- Vcy: 1042,
- Vee: 8897,
- Vfr: 120089,
- Wfr: 120090,
- Xfr: 120091,
- Ycy: 1067,
- Yfr: 120092,
- Zcy: 1047,
- Zfr: 8488,
- acd: 8767,
- acy: 1072,
- afr: 120094,
- amp: 38,
- and: 8743,
- ang: 8736,
- apE: 10864,
- ape: 8778,
- ast: 42,
- bcy: 1073,
- bfr: 120095,
- bot: 8869,
- cap: 8745,
- cfr: 120096,
- chi: 967,
- cir: 9675,
- cup: 8746,
- dcy: 1076,
- deg: 176,
- dfr: 120097,
- die: 168,
- div: 247,
- dot: 729,
- ecy: 1101,
- efr: 120098,
- egs: 10902,
- ell: 8467,
- els: 10901,
- eng: 331,
- eta: 951,
- eth: 240,
- fcy: 1092,
- ffr: 120099,
- gEl: 10892,
- gap: 10886,
- gcy: 1075,
- gel: 8923,
- geq: 8805,
- ges: 10878,
- gfr: 120100,
- ggg: 8921,
- glE: 10898,
- gla: 10917,
- glj: 10916,
- gnE: 8809,
- gne: 10888,
- hfr: 120101,
- icy: 1080,
- iff: 8660,
- ifr: 120102,
- int: 8747,
- jcy: 1081,
- jfr: 120103,
- kcy: 1082,
- kfr: 120104,
- lEg: 10891,
- lap: 10885,
- lat: 10923,
- lcy: 1083,
- leg: 8922,
- leq: 8804,
- les: 10877,
- lfr: 120105,
- lgE: 10897,
- lnE: 8808,
- lne: 10887,
- loz: 9674,
- lrm: 8206,
- lsh: 8624,
- map: 8614,
- mcy: 1084,
- mfr: 120106,
- mho: 8487,
- mid: 8739,
- nap: 8777,
- ncy: 1085,
- nfr: 120107,
- nge: 8817,
- ngt: 8815,
- nis: 8956,
- niv: 8715,
- nle: 8816,
- nlt: 8814,
- not: 172,
- npr: 8832,
- nsc: 8833,
- num: 35,
- ocy: 1086,
- ofr: 120108,
- ogt: 10689,
- ohm: 8486,
- olt: 10688,
- ord: 10845,
- orv: 10843,
- par: 8741,
- pcy: 1087,
- pfr: 120109,
- phi: 966,
- piv: 982,
- prE: 10931,
- pre: 10927,
- psi: 968,
- qfr: 120110,
- rcy: 1088,
- reg: 174,
- rfr: 120111,
- rho: 961,
- rlm: 8207,
- rsh: 8625,
- scE: 10932,
- sce: 10928,
- scy: 1089,
- sfr: 120112,
- shy: 173,
- sim: 8764,
- smt: 10922,
- sol: 47,
- squ: 9633,
- sub: 8834,
- sum: 8721,
- sup: 8835,
- tau: 964,
- tcy: 1090,
- tfr: 120113,
- top: 8868,
- ucy: 1091,
- ufr: 120114,
- uml: 168,
- vcy: 1074,
- vee: 8744,
- vfr: 120115,
- wfr: 120116,
- xfr: 120117,
- ycy: 1099,
- yen: 165,
- yfr: 120118,
- zcy: 1079,
- zfr: 120119,
- zwj: 8205,
- DD: 8517,
- GT: 62,
- Gg: 8921,
- Gt: 8811,
- Im: 8465,
- LT: 60,
- Ll: 8920,
- Lt: 8810,
- Mu: 924,
- Nu: 925,
- Or: 10836,
- Pi: 928,
- Pr: 10939,
- Re: 8476,
- Sc: 10940,
- Xi: 926,
- ac: 8766,
- af: 8289,
- ap: 8776,
- dd: 8518,
- ee: 8519,
- eg: 10906,
- el: 10905,
- gE: 8807,
- ge: 8805,
- gg: 8811,
- gl: 8823,
- gt: 62,
- ic: 8291,
- ii: 8520,
- in: 8712,
- it: 8290,
- lE: 8806,
- le: 8804,
- lg: 8822,
- ll: 8810,
- lt: 60,
- mp: 8723,
- mu: 956,
- ne: 8800,
- ni: 8715,
- nu: 957,
- oS: 9416,
- or: 8744,
- pi: 960,
- pm: 177,
- pr: 8826,
- rx: 8478,
- sc: 8827,
- wp: 8472,
- wr: 8768,
- xi: 958,
- };
- const windows1252 = [
- 8364,
- 129,
- 8218,
- 402,
- 8222,
- 8230,
- 8224,
- 8225,
- 710,
- 8240,
- 352,
- 8249,
- 338,
- 141,
- 381,
- 143,
- 144,
- 8216,
- 8217,
- 8220,
- 8221,
- 8226,
- 8211,
- 8212,
- 732,
- 8482,
- 353,
- 8250,
- 339,
- 157,
- 382,
- 376,
- ];
- const entityPattern = new RegExp(`&(#?(?:x[\\w\\d]+|\\d+|${Object.keys(htmlEntities).join('|')}));?`, 'g');
- function decodeCharacterReferences(html) {
- return html.replace(entityPattern, (match, entity) => {
- let code;
- // Handle named entities
- if (entity[0] !== '#') {
- code = htmlEntities[entity];
- }
- else if (entity[1] === 'x') {
- code = parseInt(entity.substring(2), 16);
- }
- else {
- code = parseInt(entity.substring(1), 10);
- }
- if (!code) {
- return match;
- }
- return String.fromCodePoint(validateCode(code));
- });
- }
- const NUL = 0;
- // some code points are verboten. If we were inserting HTML, the browser would replace the illegal
- // code points with alternatives in some cases - since we're bypassing that mechanism, we need
- // to replace them ourselves
- //
- // Source: http://en.wikipedia.org/wiki/Character_encodings_in_HTML#Illegal_characters
- function validateCode(code) {
- // line feed becomes generic whitespace
- if (code === 10) {
- return 32;
- }
- // ASCII range. (Why someone would use HTML entities for ASCII characters I don't know, but...)
- if (code < 128) {
- return code;
- }
- // code points 128-159 are dealt with leniently by browsers, but they're incorrect. We need
- // to correct the mistake or we'll end up with missing € signs and so on
- if (code <= 159) {
- return windows1252[code - 128];
- }
- // basic multilingual plane
- if (code < 55296) {
- return code;
- }
- // UTF-16 surrogate halves
- if (code <= 57343) {
- return NUL;
- }
- // rest of the basic multilingual plane
- if (code <= 65535) {
- return code;
- }
- // supplementary multilingual plane 0x10000 - 0x1ffff
- if (code >= 65536 && code <= 131071) {
- return code;
- }
- // supplementary ideographic plane 0x20000 - 0x2ffff
- if (code >= 131072 && code <= 196607) {
- return code;
- }
- return NUL;
- }
- const voidElementNames = /^(?:area|base|br|col|command|embed|hr|img|input|keygen|link|meta|param|source|track|wbr)$/;
- function isVoidElementName(name) {
- return voidElementNames.test(name) || name.toLowerCase() === '!doctype';
- }
- const validTagName = /^\!?[a-zA-Z]{1,}:?[a-zA-Z0-9\-]*/;
- const metaTags = new Map([
- ['svelte:document', 'Document'],
- ['svelte:window', 'Window'],
- ['svelte:head', 'Head']
- ]);
- const specials = new Map([
- [
- 'script',
- {
- read: readScript,
- property: 'js',
- },
- ],
- [
- 'style',
- {
- read: readStyle,
- property: 'css',
- },
- ],
- ]);
- const SELF = 'svelte:self';
- const COMPONENT = 'svelte:component';
- // based on http://developers.whatwg.org/syntax.html#syntax-tag-omission
- const disallowedContents = new Map([
- ['li', new Set(['li'])],
- ['dt', new Set(['dt', 'dd'])],
- ['dd', new Set(['dt', 'dd'])],
- [
- 'p',
- new Set('address article aside blockquote div dl fieldset footer form h1 h2 h3 h4 h5 h6 header hgroup hr main menu nav ol p pre section table ul'.split(' ')),
- ],
- ['rt', new Set(['rt', 'rp'])],
- ['rp', new Set(['rt', 'rp'])],
- ['optgroup', new Set(['optgroup'])],
- ['option', new Set(['option', 'optgroup'])],
- ['thead', new Set(['tbody', 'tfoot'])],
- ['tbody', new Set(['tbody', 'tfoot'])],
- ['tfoot', new Set(['tbody'])],
- ['tr', new Set(['tr', 'tbody'])],
- ['td', new Set(['td', 'th', 'tr'])],
- ['th', new Set(['td', 'th', 'tr'])],
- ]);
- function parentIsHead(stack) {
- let i = stack.length;
- while (i--) {
- const { type } = stack[i];
- if (type === 'Head')
- return true;
- if (type === 'Element' || type === 'InlineComponent')
- return false;
- }
- return false;
- }
- function tag(parser) {
- const start = parser.index++;
- let parent = parser.current();
- if (parser.eat('!--')) {
- const data = parser.readUntil(/-->/);
- parser.eat('-->', true, 'comment was left open, expected -->');
- parser.current().children.push({
- start,
- end: parser.index,
- type: 'Comment',
- data,
- });
- return;
- }
- const isClosingTag = parser.eat('/');
- const name = readTagName(parser);
- if (metaTags.has(name)) {
- const slug = metaTags.get(name).toLowerCase();
- if (isClosingTag) {
- if ((name === 'svelte:window' || name === 'svelte:document') &&
- parser.current().children.length) {
- parser.error({
- code: `invalid-${name.slice(7)}-content`,
- message: `<${name}> cannot have children`
- }, parser.current().children[0].start);
- }
- }
- else {
- if (name in parser.metaTags) {
- parser.error({
- code: `duplicate-${slug}`,
- message: `A component can only have one <${name}> tag`
- }, start);
- }
- if (parser.stack.length > 1) {
- parser.error({
- code: `invalid-${slug}-placement`,
- message: `<${name}> tags cannot be inside elements or blocks`
- }, start);
- }
- parser.metaTags[name] = true;
- }
- }
- const type = metaTags.has(name)
- ? metaTags.get(name)
- : (/[A-Z]/.test(name[0]) || name === 'svelte:self' || name === 'svelte:component') ? 'InlineComponent'
- : name === 'title' && parentIsHead(parser.stack) ? 'Title'
- : name === 'slot' && !parser.customElement ? 'Slot' : 'Element';
- const element = {
- start,
- end: null,
- type,
- name,
- attributes: [],
- children: [],
- };
- parser.allowWhitespace();
- if (isClosingTag) {
- if (isVoidElementName(name)) {
- parser.error({
- code: `invalid-void-content`,
- message: `<${name}> is a void element and cannot have children, or a closing tag`
- }, start);
- }
- parser.eat('>', true);
- // close any elements that don't have their own closing tags, e.g. <div><p></div>
- while (parent.name !== name) {
- if (parent.type !== 'Element')
- parser.error({
- code: `invalid-closing-tag`,
- message: `</${name}> attempted to close an element that was not open`
- }, start);
- parent.end = start;
- parser.stack.pop();
- parent = parser.current();
- }
- parent.end = parser.index;
- parser.stack.pop();
- return;
- }
- else if (disallowedContents.has(parent.name)) {
- // can this be a child of the parent element, or does it implicitly
- // close it, like `<li>one<li>two`?
- if (disallowedContents.get(parent.name).has(name)) {
- parent.end = start;
- parser.stack.pop();
- }
- }
- if (name === 'slot') {
- let i = parser.stack.length;
- while (i--) {
- const item = parser.stack[i];
- if (item.type === 'EachBlock') {
- parser.error({
- code: `invalid-slot-placement`,
- message: `<slot> cannot be a child of an each-block`
- }, start);
- }
- }
- }
- const uniqueNames = new Set();
- let attribute;
- while ((attribute = readAttribute(parser, uniqueNames))) {
- if (attribute.type === 'Binding' && !parser.allowBindings) {
- parser.error({
- code: `binding-disabled`,
- message: `Two-way binding is disabled`
- }, attribute.start);
- }
- element.attributes.push(attribute);
- parser.allowWhitespace();
- }
- if (name === 'svelte:component') {
- // TODO post v2, treat this just as any other attribute
- const index = element.attributes.findIndex(attr => attr.name === 'this');
- if (!~index) {
- parser.error({
- code: `missing-component-definition`,
- message: `<svelte:component> must have a 'this' attribute`
- }, start);
- }
- const definition = element.attributes.splice(index, 1)[0];
- if (definition.value === true || definition.value.length !== 1 || definition.value[0].type === 'Text') {
- parser.error({
- code: `invalid-component-definition`,
- message: `invalid component definition`
- }, definition.start);
- }
- element.expression = definition.value[0].expression;
- }
- // special cases – top-level <script> and <style>
- if (specials.has(name) && parser.stack.length === 1) {
- const special = specials.get(name);
- if (parser[special.property]) {
- parser.index = start;
- parser.error({
- code: `duplicate-${name}`,
- message: `You can only have one top-level <${name}> tag per component`
- });
- }
- parser.eat('>', true);
- parser[special.property] = special.read(parser, start, element.attributes);
- return;
- }
- parser.current().children.push(element);
- const selfClosing = parser.eat('/') || isVoidElementName(name);
- parser.eat('>', true);
- if (selfClosing) {
- // don't push self-closing elements onto the stack
- element.end = parser.index;
- }
- else if (name === 'textarea') {
- // special case
- element.children = readSequence$1(parser, () => parser.template.slice(parser.index, parser.index + 11) === '</textarea>');
- parser.read(/<\/textarea>/);
- element.end = parser.index;
- }
- else if (name === 'script') {
- // special case
- const start = parser.index;
- const data = parser.readUntil(/<\/script>/);
- const end = parser.index;
- element.children.push({ start, end, type: 'Text', data });
- parser.eat('</script>', true);
- element.end = parser.index;
- }
- else if (name === 'style') {
- // special case
- const start = parser.index;
- const data = parser.readUntil(/<\/style>/);
- const end = parser.index;
- element.children.push({ start, end, type: 'Text', data });
- parser.eat('</style>', true);
- }
- else {
- parser.stack.push(element);
- }
- }
- function readTagName(parser) {
- const start = parser.index;
- if (parser.eat(SELF)) {
- // check we're inside a block, otherwise this
- // will cause infinite recursion
- let i = parser.stack.length;
- let legal = false;
- while (i--) {
- const fragment = parser.stack[i];
- if (fragment.type === 'IfBlock' || fragment.type === 'EachBlock') {
- legal = true;
- break;
- }
- }
- if (!legal) {
- parser.error({
- code: `invalid-self-placement`,
- message: `<${SELF}> components can only exist inside if-blocks or each-blocks`
- }, start);
- }
- return SELF;
- }
- if (parser.eat(COMPONENT))
- return COMPONENT;
- const name = parser.readUntil(/(\s|\/|>)/);
- if (metaTags.has(name))
- return name;
- if (!validTagName.test(name)) {
- parser.error({
- code: `invalid-tag-name`,
- message: `Expected valid tag name`
- }, start);
- }
- return name;
- }
- function readAttribute(parser, uniqueNames) {
- const start = parser.index;
- if (parser.eat('{')) {
- parser.allowWhitespace();
- if (parser.eat('...')) {
- const expression = readExpression(parser);
- parser.allowWhitespace();
- parser.eat('}', true);
- return {
- start,
- end: parser.index,
- type: 'Spread',
- expression
- };
- }
- else {
- const valueStart = parser.index;
- const name = parser.readIdentifier();
- parser.allowWhitespace();
- parser.eat('}', true);
- return {
- start,
- end: parser.index,
- type: 'Attribute',
- name,
- value: [{
- start: valueStart,
- end: valueStart + name.length,
- type: 'AttributeShorthand',
- expression: {
- start: valueStart,
- end: valueStart + name.length,
- type: 'Identifier',
- name
- }
- }]
- };
- }
- }
- let name = parser.readUntil(/(\s|=|\/|>)/);
- if (!name)
- return null;
- if (uniqueNames.has(name)) {
- parser.error({
- code: `duplicate-attribute`,
- message: 'Attributes need to be unique'
- }, start);
- }
- uniqueNames.add(name);
- parser.allowWhitespace();
- const directive = readDirective(parser, start, name);
- if (directive)
- return directive;
- let value = parser.eat('=') ? readAttributeValue(parser) : true;
- return {
- start,
- end: parser.index,
- type: 'Attribute',
- name,
- value,
- };
- }
- function readAttributeValue(parser) {
- const quoteMark = parser.eat(`'`) ? `'` : parser.eat(`"`) ? `"` : null;
- const regex = (quoteMark === `'` ? /'/ :
- quoteMark === `"` ? /"/ :
- /(\/>|[\s"'=<>`])/);
- const value = readSequence$1(parser, () => !!parser.matchRegex(regex));
- if (quoteMark)
- parser.index += 1;
- return value;
- }
- function readSequence$1(parser, done) {
- let currentChunk = {
- start: parser.index,
- end: null,
- type: 'Text',
- data: '',
- };
- const chunks = [];
- while (parser.index < parser.template.length) {
- const index = parser.index;
- if (done()) {
- currentChunk.end = parser.index;
- if (currentChunk.data)
- chunks.push(currentChunk);
- chunks.forEach(chunk => {
- if (chunk.type === 'Text')
- chunk.data = decodeCharacterReferences(chunk.data);
- });
- return chunks;
- }
- else if (parser.eat('{')) {
- if (currentChunk.data) {
- currentChunk.end = index;
- chunks.push(currentChunk);
- }
- parser.allowWhitespace();
- const expression = readExpression(parser);
- parser.allowWhitespace();
- parser.eat('}', true);
- chunks.push({
- start: index,
- end: parser.index,
- type: 'MustacheTag',
- expression,
- });
- currentChunk = {
- start: parser.index,
- end: null,
- type: 'Text',
- data: '',
- };
- }
- else {
- currentChunk.data += parser.template[parser.index++];
- }
- }
- parser.error({
- code: `unexpected-eof`,
- message: `Unexpected end of input`
- });
- }
- function errorOnAssignmentPattern(parser) {
- if (parser.eat('=')) {
- parser.error({
- code: 'invalid-assignment-pattern',
- message: 'Assignment patterns are not supported'
- }, parser.index - 1);
- }
- }
- function readContext(parser) {
- const context = {
- start: parser.index,
- end: null,
- type: null
- };
- if (parser.eat('[')) {
- context.type = 'ArrayPattern';
- context.elements = [];
- do {
- parser.allowWhitespace();
- if (parser.template[parser.index] === ',') {
- context.elements.push(null);
- }
- else {
- context.elements.push(readContext(parser));
- parser.allowWhitespace();
- }
- } while (parser.eat(','));
- errorOnAssignmentPattern(parser);
- parser.eat(']', true);
- context.end = parser.index;
- }
- else if (parser.eat('{')) {
- context.type = 'ObjectPattern';
- context.properties = [];
- do {
- parser.allowWhitespace();
- const start = parser.index;
- const name = parser.readIdentifier();
- const key = {
- start,
- end: parser.index,
- type: 'Identifier',
- name
- };
- parser.allowWhitespace();
- const value = parser.eat(':')
- ? (parser.allowWhitespace(), readContext(parser))
- : key;
- const property = {
- start,
- end: value.end,
- type: 'Property',
- kind: 'init',
- shorthand: value.type === 'Identifier' && value.name === name,
- key,
- value
- };
- context.properties.push(property);
- parser.allowWhitespace();
- } while (parser.eat(','));
- errorOnAssignmentPattern(parser);
- parser.eat('}', true);
- context.end = parser.index;
- }
- else {
- const name = parser.readIdentifier();
- if (name) {
- context.type = 'Identifier';
- context.end = parser.index;
- context.name = name;
- }
- else {
- parser.error({
- code: 'invalid-context',
- message: 'Expected a name, array pattern or object pattern'
- });
- }
- errorOnAssignmentPattern(parser);
- }
- return context;
- }
- const whitespace = /[ \t\r\n]/;
- const dimensions = /^(?:offset|client)(?:Width|Height)$/;
- function trimStart(str) {
- let i = 0;
- while (whitespace.test(str[i]))
- i += 1;
- return str.slice(i);
- }
- function trimEnd(str) {
- let i = str.length;
- while (whitespace.test(str[i - 1]))
- i -= 1;
- return str.slice(0, i);
- }
- function trimWhitespace(block, trimBefore, trimAfter) {
- if (!block.children || block.children.length === 0)
- return; // AwaitBlock
- const firstChild = block.children[0];
- const lastChild = block.children[block.children.length - 1];
- if (firstChild.type === 'Text' && trimBefore) {
- firstChild.data = trimStart(firstChild.data);
- if (!firstChild.data)
- block.children.shift();
- }
- if (lastChild.type === 'Text' && trimAfter) {
- lastChild.data = trimEnd(lastChild.data);
- if (!lastChild.data)
- block.children.pop();
- }
- if (block.else) {
- trimWhitespace(block.else, trimBefore, trimAfter);
- }
- if (firstChild.elseif) {
- trimWhitespace(firstChild, trimBefore, trimAfter);
- }
- }
- function mustache(parser) {
- const start = parser.index;
- parser.index += 1;
- parser.allowWhitespace();
- // {/if} or {/each}
- if (parser.eat('/')) {
- let block = parser.current();
- let expected;
- if (block.type === 'ElseBlock' || block.type === 'PendingBlock' || block.type === 'ThenBlock' || block.type === 'CatchBlock') {
- block.end = start;
- parser.stack.pop();
- block = parser.current();
- expected = 'await';
- }
- if (block.type === 'IfBlock') {
- expected = 'if';
- }
- else if (block.type === 'EachBlock') {
- expected = 'each';
- }
- else if (block.type === 'AwaitBlock') {
- expected = 'await';
- }
- else {
- parser.error({
- code: `unexpected-block-close`,
- message: `Unexpected block closing tag`
- });
- }
- parser.eat(expected, true);
- parser.allowWhitespace();
- parser.eat('}', true);
- while (block.elseif) {
- block.end = parser.index;
- parser.stack.pop();
- block = parser.current();
- if (block.else) {
- block.else.end = start;
- }
- }
- // strip leading/trailing whitespace as necessary
- const charBefore = parser.template[block.start - 1];
- const charAfter = parser.template[parser.index];
- const trimBefore = !charBefore || whitespace.test(charBefore);
- const trimAfter = !charAfter || whitespace.test(charAfter);
- trimWhitespace(block, trimBefore, trimAfter);
- block.end = parser.index;
- parser.stack.pop();
- }
- else if (parser.eat(':elseif')) {
- const block = parser.current();
- if (block.type !== 'IfBlock')
- parser.error({
- code: `invalid-elseif-placement`,
- message: 'Cannot have an {:elseif ...} block outside an {#if ...} block'
- });
- parser.requireWhitespace();
- const expression = readExpression(parser);
- parser.allowWhitespace();
- parser.eat('}', true);
- block.else = {
- start: parser.index,
- end: null,
- type: 'ElseBlock',
- children: [
- {
- start: parser.index,
- end: null,
- type: 'IfBlock',
- elseif: true,
- expression,
- children: [],
- },
- ],
- };
- parser.stack.push(block.else.children[0]);
- }
- else if (parser.eat(':else')) {
- const block = parser.current();
- if (block.type !== 'IfBlock' && block.type !== 'EachBlock') {
- parser.error({
- code: `invalid-else-placement`,
- message: 'Cannot have an {:else} block outside an {#if ...} or {#each ...} block'
- });
- }
- parser.allowWhitespace();
- parser.eat('}', true);
- block.else = {
- start: parser.index,
- end: null,
- type: 'ElseBlock',
- children: [],
- };
- parser.stack.push(block.else);
- }
- else if (parser.eat(':then')) {
- // TODO DRY out this and the next section
- const pendingBlock = parser.current();
- if (pendingBlock.type === 'PendingBlock') {
- pendingBlock.end = start;
- parser.stack.pop();
- const awaitBlock = parser.current();
- if (!parser.eat('}')) {
- parser.requireWhitespace();
- awaitBlock.value = parser.readIdentifier();
- parser.allowWhitespace();
- parser.eat('}', true);
- }
- const thenBlock = {
- start,
- end: null,
- type: 'ThenBlock',
- children: []
- };
- awaitBlock.then = thenBlock;
- parser.stack.push(thenBlock);
- }
- }
- else if (parser.eat(':catch')) {
- const thenBlock = parser.current();
- if (thenBlock.type === 'ThenBlock') {
- thenBlock.end = start;
- parser.stack.pop();
- const awaitBlock = parser.current();
- if (!parser.eat('}')) {
- parser.requireWhitespace();
- awaitBlock.error = parser.readIdentifier();
- parser.allowWhitespace();
- parser.eat('}', true);
- }
- const catchBlock = {
- start,
- end: null,
- type: 'CatchBlock',
- children: []
- };
- awaitBlock.catch = catchBlock;
- parser.stack.push(catchBlock);
- }
- }
- else if (parser.eat('#')) {
- // {#if foo}, {#each foo} or {#await foo}
- let type;
- if (parser.eat('if')) {
- type = 'IfBlock';
- }
- else if (parser.eat('each')) {
- type = 'EachBlock';
- }
- else if (parser.eat('await')) {
- type = 'AwaitBlock';
- }
- else {
- parser.error({
- code: `expected-block-type`,
- message: `Expected if, each or await`
- });
- }
- parser.requireWhitespace();
- const expression = readExpression(parser);
- const block = type === 'AwaitBlock' ?
- {
- start,
- end: null,
- type,
- expression,
- value: null,
- error: null,
- pending: {
- start: null,
- end: null,
- type: 'PendingBlock',
- children: []
- },
- then: {
- start: null,
- end: null,
- type: 'ThenBlock',
- children: []
- },
- catch: {
- start: null,
- end: null,
- type: 'CatchBlock',
- children: []
- },
- } :
- {
- start,
- end: null,
- type,
- expression,
- children: [],
- };
- parser.allowWhitespace();
- // {#each} blocks must declare a context – {#each list as item}
- if (type === 'EachBlock') {
- parser.eat('as', true);
- parser.requireWhitespace();
- block.context = readContext(parser);
- parser.allowWhitespace();
- if (parser.eat(',')) {
- parser.allowWhitespace();
- block.index = parser.readIdentifier();
- if (!block.index)
- parser.error({
- code: `expected-name`,
- message: `Expected name`
- });
- parser.allowWhitespace();
- }
- if (parser.eat('(')) {
- parser.allowWhitespace();
- block.key = readExpression(parser);
- parser.allowWhitespace();
- parser.eat(')', true);
- parser.allowWhitespace();
- }
- else if (parser.eat('@')) {
- block.key = parser.readIdentifier();
- if (!block.key)
- parser.error({
- code: `expected-name`,
- message: `Expected name`
- });
- parser.allowWhitespace();
- }
- }
- let awaitBlockShorthand = type === 'AwaitBlock' && parser.eat('then');
- if (awaitBlockShorthand) {
- parser.requireWhitespace();
- block.value = parser.readIdentifier();
- parser.allowWhitespace();
- }
- parser.eat('}', true);
- parser.current().children.push(block);
- parser.stack.push(block);
- if (type === 'AwaitBlock') {
- const childBlock = awaitBlockShorthand ? block.then : block.pending;
- childBlock.start = parser.index;
- parser.stack.push(childBlock);
- }
- }
- else if (parser.eat('@html')) {
- // {@html content} tag
- const expression = readExpression(parser);
- parser.allowWhitespace();
- parser.eat('}', true);
- parser.current().children.push({
- start,
- end: parser.index,
- type: 'RawMustacheTag',
- expression,
- });
- }
- else if (parser.eat('@debug')) {
- let identifiers;
- // Implies {@debug} which indicates "debug all"
- if (parser.read(/\s*}/)) {
- identifiers = [];
- }
- else {
- const expression = readExpression(parser);
- identifiers = expression.type === 'SequenceExpression'
- ? expression.expressions
- : [expression];
- identifiers.forEach(node => {
- if (node.type !== 'Identifier') {
- parser.error({
- code: 'invalid-debug-args',
- message: '{@debug ...} arguments must be identifiers, not arbitrary expressions'
- }, node.start);
- }
- });
- parser.allowWhitespace();
- parser.eat('}', true);
- }
- parser.current().children.push({
- start,
- end: parser.index,
- type: 'DebugTag',
- identifiers
- });
- }
- else {
- const expression = readExpression(parser);
- parser.allowWhitespace();
- parser.eat('}', true);
- parser.current().children.push({
- start,
- end: parser.index,
- type: 'MustacheTag',
- expression,
- });
- }
- }
- function text(parser) {
- const start = parser.index;
- let data = '';
- while (parser.index < parser.template.length &&
- !parser.match('<') &&
- !parser.match('{')) {
- data += parser.template[parser.index++];
- }
- parser.current().children.push({
- start,
- end: parser.index,
- type: 'Text',
- data: decodeCharacterReferences(data),
- });
- }
- function fragment(parser) {
- if (parser.match('<')) {
- return tag;
- }
- if (parser.match('{')) {
- return mustache;
- }
- return text;
- }
- const reservedNames = new Set([
- 'arguments',
- 'await',
- 'break',
- 'case',
- 'catch',
- 'class',
- 'const',
- 'continue',
- 'debugger',
- 'default',
- 'delete',
- 'do',
- 'else',
- 'enum',
- 'eval',
- 'export',
- 'extends',
- 'false',
- 'finally',
- 'for',
- 'function',
- 'if',
- 'implements',
- 'import',
- 'in',
- 'instanceof',
- 'interface',
- 'let',
- 'new',
- 'null',
- 'package',
- 'private',
- 'protected',
- 'public',
- 'return',
- 'static',
- 'super',
- 'switch',
- 'this',
- 'throw',
- 'true',
- 'try',
- 'typeof',
- 'var',
- 'void',
- 'while',
- 'with',
- 'yield',
- ]);
- // Adapted from https://github.com/acornjs/acorn/blob/6584815dca7440e00de841d1dad152302fdd7ca5/src/tokenize.js
- // Reproduced under MIT License https://github.com/acornjs/acorn/blob/master/LICENSE
- function fullCharCodeAt(str, i) {
- let code = str.charCodeAt(i);
- if (code <= 0xd7ff || code >= 0xe000)
- return code;
- let next = str.charCodeAt(i + 1);
- return (code << 10) + next - 0x35fdc00;
- }
- function getLocator(source, options) {
- if (options === void 0) { options = {}; }
- var offsetLine = options.offsetLine || 0;
- var offsetColumn = options.offsetColumn || 0;
- var originalLines = source.split('\n');
- var start = 0;
- var lineRanges = originalLines.map(function (line, i) {
- var end = start + line.length + 1;
- var range = { start: start, end: end, line: i };
- start = end;
- return range;
- });
- var i = 0;
- function rangeContains(range, index) {
- return range.start <= index && index < range.end;
- }
- function getLocation(range, index) {
- return { line: offsetLine + range.line, column: offsetColumn + index - range.start, character: index };
- }
- function locate(search, startIndex) {
- if (typeof search === 'string') {
- search = source.indexOf(search, startIndex || 0);
- }
- var range = lineRanges[i];
- var d = search >= range.end ? 1 : -1;
- while (range) {
- if (rangeContains(range, search))
- return getLocation(range, search);
- i += d;
- range = lineRanges[i];
- }
- }
- return locate;
- }
- function locate(source, search, options) {
- if (typeof options === 'number') {
- throw new Error('locate takes a { startIndex, offsetLine, offsetColumn } object as the third argument');
- }
- return getLocator(source, options)(search, options && options.startIndex);
- }
- function tabsToSpaces(str) {
- return str.replace(/^\t+/, match => match.split('\t').join(' '));
- }
- function getCodeFrame(source, line, column) {
- const lines = source.split('\n');
- const frameStart = Math.max(0, line - 2);
- const frameEnd = Math.min(line + 3, lines.length);
- const digits = String(frameEnd + 1).length;
- return lines
- .slice(frameStart, frameEnd)
- .map((str, i) => {
- const isErrorLine = frameStart + i === line;
- let lineNum = String(i + frameStart + 1);
- while (lineNum.length < digits)
- lineNum = ` ${lineNum}`;
- if (isErrorLine) {
- const indicator = repeat(' ', digits + 2 + tabsToSpaces(str.slice(0, column)).length) + '^';
- return `${lineNum}: ${tabsToSpaces(str)}\n${indicator}`;
- }
- return `${lineNum}: ${tabsToSpaces(str)}`;
- })
- .join('\n');
- }
- class CompileError extends Error {
- toString() {
- return `${this.message} (${this.start.line}:${this.start.column})\n${this.frame}`;
- }
- }
- function error$1(message, props) {
- const error = new CompileError(message);
- error.name = props.name;
- const start = locate(props.source, props.start, { offsetLine: 1 });
- const end = locate(props.source, props.end || props.start, { offsetLine: 1 });
- error.code = props.code;
- error.start = start;
- error.end = end;
- error.pos = props.start;
- error.filename = props.filename;
- error.frame = getCodeFrame(props.source, start.line - 1, start.column);
- throw error;
- }
- class Parser$1 {
- constructor(template, options) {
- if (typeof template !== 'string') {
- throw new TypeError('Template must be a string');
- }
- this.template = template.replace(/\s+$/, '');
- this.filename = options.filename;
- this.customElement = options.customElement;
- this.allowBindings = options.bind !== false;
- this.index = 0;
- this.stack = [];
- this.metaTags = {};
- this.html = {
- start: null,
- end: null,
- type: 'Fragment',
- children: [],
- };
- this.css = null;
- this.js = null;
- this.stack.push(this.html);
- let state = fragment;
- while (this.index < this.template.length) {
- state = state(this) || fragment;
- }
- if (this.stack.length > 1) {
- const current = this.current();
- const type = current.type === 'Element' ? `<${current.name}>` : 'Block';
- const slug = current.type === 'Element' ? 'element' : 'block';
- this.error({
- code: `unclosed-${slug}`,
- message: `${type} was left open`
- }, current.start);
- }
- if (state !== fragment) {
- this.error({
- code: `unexpected-eof`,
- message: 'Unexpected end of input'
- });
- }
- if (this.html.children.length) {
- let start = this.html.children[0] && this.html.children[0].start;
- while (/\s/.test(template[start]))
- start += 1;
- let end = this.html.children[this.html.children.length - 1] && this.html.children[this.html.children.length - 1].end;
- while (/\s/.test(template[end - 1]))
- end -= 1;
- this.html.start = start;
- this.html.end = end;
- }
- else {
- this.html.start = this.html.end = null;
- }
- }
- current() {
- return this.stack[this.stack.length - 1];
- }
- acornError(err) {
- this.error({
- code: `parse-error`,
- message: err.message.replace(/ \(\d+:\d+\)$/, '')
- }, err.pos);
- }
- error({ code, message }, index = this.index) {
- error$1(message, {
- name: 'ParseError',
- code,
- source: this.template,
- start: index,
- filename: this.filename
- });
- }
- eat(str, required, message) {
- if (this.match(str)) {
- this.index += str.length;
- return true;
- }
- if (required) {
- this.error({
- code: `unexpected-${this.index === this.template.length ? 'eof' : 'token'}`,
- message: message || `Expected ${str}`
- });
- }
- return false;
- }
- match(str) {
- return this.template.slice(this.index, this.index + str.length) === str;
- }
- matchRegex(pattern) {
- const match = pattern.exec(this.template.slice(this.index));
- if (!match || match.index !== 0)
- return null;
- return match[0];
- }
- allowWhitespace() {
- while (this.index < this.template.length &&
- whitespace.test(this.template[this.index])) {
- this.index++;
- }
- }
- read(pattern) {
- const result = this.matchRegex(pattern);
- if (result)
- this.index += result.length;
- return result;
- }
- readIdentifier() {
- const start = this.index;
- let i = this.index;
- const code = fullCharCodeAt(this.template, i);
- if (!isIdentifierStart(code, true))
- return null;
- i += code <= 0xffff ? 1 : 2;
- while (i < this.template.length) {
- const code = fullCharCodeAt(this.template, i);
- if (!isIdentifierChar(code, true))
- break;
- i += code <= 0xffff ? 1 : 2;
- }
- const identifier = this.template.slice(this.index, this.index = i);
- if (reservedNames.has(identifier)) {
- this.error({
- code: `unexpected-reserved-word`,
- message: `'${identifier}' is a reserved word in JavaScript and cannot be used here`
- }, start);
- }
- return identifier;
- }
- readUntil(pattern) {
- if (this.index >= this.template.length)
- this.error({
- code: `unexpected-eof`,
- message: 'Unexpected end of input'
- });
- const start = this.index;
- const match = pattern.exec(this.template.slice(start));
- if (match) {
- this.index = start + match.index;
- return this.template.slice(start, this.index);
- }
- this.index = this.template.length;
- return this.template.slice(start);
- }
- remaining() {
- return this.template.slice(this.index);
- }
- requireWhitespace() {
- if (!whitespace.test(this.template[this.index])) {
- this.error({
- code: `missing-whitespace`,
- message: `Expected whitespace`
- });
- }
- this.allowWhitespace();
- }
- }
- function parse$1(template, options = {}) {
- const parser = new Parser$1(template, options);
- return {
- html: parser.html,
- css: parser.css,
- js: parser.js,
- };
- }
- const start = /\n(\t+)/;
- function deindent(strings, ...values) {
- const indentation = start.exec(strings[0])[1];
- const pattern = new RegExp(`^${indentation}`, 'gm');
- let result = strings[0].replace(start, '').replace(pattern, '');
- let trailingIndentation = getTrailingIndentation(result);
- for (let i = 1; i < strings.length; i += 1) {
- let expression = values[i - 1];
- const string = strings[i].replace(pattern, '');
- if (Array.isArray(expression)) {
- expression = expression.length ? expression.join('\n') : null;
- }
- if (expression || expression === '') {
- const value = String(expression).replace(/\n/g, `\n${trailingIndentation}`);
- result += value + string;
- }
- else {
- let c = result.length;
- while (/\s/.test(result[c - 1]))
- c -= 1;
- result = result.slice(0, c) + string;
- }
- trailingIndentation = getTrailingIndentation(result);
- }
- return result.trim().replace(/\t+$/gm, '');
- }
- function getTrailingIndentation(str) {
- let i = str.length;
- while (str[i - 1] === ' ' || str[i - 1] === '\t')
- i -= 1;
- return str.slice(i, str.length);
- }
- function stringify(data, options = {}) {
- return JSON.stringify(escape$1(data, options));
- }
- function escape$1(data, { onlyEscapeAtSymbol = false } = {}) {
- return data.replace(onlyEscapeAtSymbol ? /(%+|@+)/g : /(%+|@+|#+)/g, (match) => {
- return match + match[0];
- });
- }
- const escaped$1 = {
- '&': '&',
- '<': '<',
- '>': '>',
- };
- function escapeHTML(html) {
- return String(html).replace(/[&<>]/g, match => escaped$1[match]);
- }
- function escapeTemplate(str) {
- return str.replace(/(\${|`|\\)/g, '\\$1');
- }
- var ChunkType;
- (function (ChunkType) {
- ChunkType[ChunkType["Line"] = 0] = "Line";
- ChunkType[ChunkType["Block"] = 1] = "Block";
- })(ChunkType || (ChunkType = {}));
- class CodeBuilder {
- constructor(str = '') {
- this.result = str;
- const initial = str
- ? /\n/.test(str) ? ChunkType.Block : ChunkType.Line
- : null;
- this.first = initial;
- this.last = initial;
- this.lastCondition = null;
- this.conditionStack = [];
- this.indent = '';
- }
- addConditional(condition, body) {
- this.reifyConditions();
- body = body.replace(/^/gm, `${this.indent}\t`);
- if (condition === this.lastCondition) {
- this.result += `\n${body}`;
- }
- else {
- if (this.lastCondition) {
- this.result += `\n${this.indent}}`;
- }
- this.result += `${this.last === ChunkType.Block ? '\n\n' : '\n'}${this.indent}if (${condition}) {\n${body}`;
- this.lastCondition = condition;
- }
- this.last = ChunkType.Block;
- }
- addLine(line) {
- this.reifyConditions();
- if (this.lastCondition) {
- this.result += `\n${this.indent}}`;
- this.lastCondition = null;
- }
- if (this.last === ChunkType.Block) {
- this.result += `\n\n${this.indent}${line}`;
- }
- else if (this.last === ChunkType.Line) {
- this.result += `\n${this.indent}${line}`;
- }
- else {
- this.result += line;
- }
- this.last = ChunkType.Line;
- if (!this.first)
- this.first = ChunkType.Line;
- }
- addLineAtStart(line) {
- this.reifyConditions();
- if (this.first === ChunkType.Block) {
- this.result = `${line}\n\n${this.indent}${this.result}`;
- }
- else if (this.first === ChunkType.Line) {
- this.result = `${line}\n${this.indent}${this.result}`;
- }
- else {
- this.result += line;
- }
- this.first = ChunkType.Line;
- if (!this.last)
- this.last = ChunkType.Line;
- }
- addBlock(block) {
- this.reifyConditions();
- if (this.indent)
- block = block.replace(/^/gm, `${this.indent}`);
- if (this.lastCondition) {
- this.result += `\n${this.indent}}`;
- this.lastCondition = null;
- }
- if (this.result) {
- this.result += `\n\n${this.indent}${block}`;
- }
- else {
- this.result += block;
- }
- this.last = ChunkType.Block;
- if (!this.first)
- this.first = ChunkType.Block;
- }
- addBlockAtStart(block) {
- this.reifyConditions();
- if (this.result) {
- this.result = `${block}\n\n${this.indent}${this.result}`;
- }
- else {
- this.result += block;
- }
- this.first = ChunkType.Block;
- if (!this.last)
- this.last = ChunkType.Block;
- }
- isEmpty() {
- return this.result === '';
- }
- pushCondition(condition) {
- this.conditionStack.push({ condition, used: false });
- }
- popCondition() {
- const { used } = this.conditionStack.pop();
- this.indent = repeat('\t', this.conditionStack.length);
- if (used)
- this.addLine('}');
- }
- reifyConditions() {
- for (let i = 0; i < this.conditionStack.length; i += 1) {
- const condition = this.conditionStack[i];
- if (!condition.used) {
- const line = `if (${condition.condition}) {`;
- if (this.last === ChunkType.Block) {
- this.result += `\n\n${this.indent}${line}`;
- }
- else if (this.last === ChunkType.Line) {
- this.result += `\n${this.indent}${line}`;
- }
- else {
- this.result += line;
- }
- this.last = ChunkType.Line;
- if (!this.first)
- this.first = ChunkType.Line;
- this.indent = repeat('\t', this.conditionStack.length);
- condition.used = true;
- }
- }
- }
- toString() {
- return this.result.trim() + (this.lastCondition ? `\n}` : ``);
- }
- }
- var globalWhitelist = new Set([
- 'Array',
- 'Boolean',
- 'console',
- 'Date',
- 'decodeURI',
- 'decodeURIComponent',
- 'encodeURI',
- 'encodeURIComponent',
- 'Infinity',
- 'Intl',
- 'isFinite',
- 'isNaN',
- 'JSON',
- 'Map',
- 'Math',
- 'NaN',
- 'Number',
- 'Object',
- 'parseFloat',
- 'parseInt',
- 'Promise',
- 'RegExp',
- 'Set',
- 'String',
- 'undefined',
- ]);
- class Block$1 {
- constructor(options) {
- this.parent = options.parent;
- this.renderer = options.renderer;
- this.name = options.name;
- this.comment = options.comment;
- this.wrappers = [];
- // for keyed each blocks
- this.key = options.key;
- this.first = null;
- this.dependencies = new Set();
- this.bindings = options.bindings;
- this.contextOwners = options.contextOwners;
- this.builders = {
- init: new CodeBuilder(),
- create: new CodeBuilder(),
- claim: new CodeBuilder(),
- hydrate: new CodeBuilder(),
- mount: new CodeBuilder(),
- measure: new CodeBuilder(),
- fix: new CodeBuilder(),
- animate: new CodeBuilder(),
- intro: new CodeBuilder(),
- update: new CodeBuilder(),
- outro: new CodeBuilder(),
- destroy: new CodeBuilder(),
- };
- this.hasAnimation = false;
- this.hasIntroMethod = false; // a block could have an intro method but not intro transitions, e.g. if a sibling block has intros
- this.hasOutroMethod = false;
- this.outros = 0;
- this.getUniqueName = this.renderer.component.getUniqueNameMaker();
- this.variables = new Map();
- this.aliases = new Map()
- .set('component', this.getUniqueName('component'))
- .set('ctx', this.getUniqueName('ctx'));
- if (this.key)
- this.aliases.set('key', this.getUniqueName('key'));
- this.hasUpdateMethod = false; // determined later
- }
- assignVariableNames() {
- const seen = new Set();
- const dupes = new Set();
- let i = this.wrappers.length;
- while (i--) {
- const wrapper = this.wrappers[i];
- if (!wrapper.var)
- continue;
- if (wrapper.parent && wrapper.parent.canUseInnerHTML)
- continue;
- if (seen.has(wrapper.var)) {
- dupes.add(wrapper.var);
- }
- seen.add(wrapper.var);
- }
- const counts = new Map();
- i = this.wrappers.length;
- while (i--) {
- const wrapper = this.wrappers[i];
- if (!wrapper.var)
- continue;
- if (dupes.has(wrapper.var)) {
- const i = counts.get(wrapper.var) || 0;
- counts.set(wrapper.var, i + 1);
- wrapper.var = this.getUniqueName(wrapper.var + i);
- }
- else {
- wrapper.var = this.getUniqueName(wrapper.var);
- }
- }
- }
- addDependencies(dependencies) {
- dependencies.forEach(dependency => {
- this.dependencies.add(dependency);
- });
- }
- addElement(name, renderStatement, claimStatement, parentNode, noDetach) {
- this.addVariable(name);
- this.builders.create.addLine(`${name} = ${renderStatement};`);
- this.builders.claim.addLine(`${name} = ${claimStatement || renderStatement};`);
- if (parentNode) {
- this.builders.mount.addLine(`@append(${parentNode}, ${name});`);
- if (parentNode === 'document.head')
- this.builders.destroy.addLine(`@detachNode(${name});`);
- }
- else {
- this.builders.mount.addLine(`@insert(#target, ${name}, anchor);`);
- if (!noDetach)
- this.builders.destroy.addConditional('detach', `@detachNode(${name});`);
- }
- }
- addIntro() {
- this.hasIntros = this.hasIntroMethod = this.renderer.hasIntroTransitions = true;
- }
- addOutro() {
- this.hasOutros = this.hasOutroMethod = this.renderer.hasOutroTransitions = true;
- this.outros += 1;
- }
- addAnimation() {
- this.hasAnimation = true;
- }
- addVariable(name, init) {
- if (name[0] === '#') {
- name = this.alias(name.slice(1));
- }
- if (this.variables.has(name) && this.variables.get(name) !== init) {
- throw new Error(`Variable '${name}' already initialised with a different value`);
- }
- this.variables.set(name, init);
- }
- alias(name) {
- if (!this.aliases.has(name)) {
- this.aliases.set(name, this.getUniqueName(name));
- }
- return this.aliases.get(name);
- }
- child(options) {
- return new Block$1(Object.assign({}, this, { key: null }, options, { parent: this }));
- }
- toString() {
- const { dev } = this.renderer.options;
- if (this.hasIntroMethod || this.hasOutroMethod) {
- this.addVariable('#current');
- if (!this.builders.mount.isEmpty()) {
- this.builders.mount.addLine(`#current = true;`);
- }
- if (!this.builders.outro.isEmpty()) {
- this.builders.outro.addLine(`#current = false;`);
- }
- }
- if (this.autofocus) {
- this.builders.mount.addLine(`${this.autofocus}.focus();`);
- }
- const properties = new CodeBuilder();
- let localKey;
- if (this.key) {
- localKey = this.getUniqueName('key');
- properties.addBlock(`key: ${localKey},`);
- }
- if (this.first) {
- properties.addBlock(`first: null,`);
- this.builders.hydrate.addLine(`this.first = ${this.first};`);
- }
- if (this.builders.create.isEmpty() && this.builders.hydrate.isEmpty()) {
- properties.addBlock(`c: @noop,`);
- }
- else {
- const hydrate = !this.builders.hydrate.isEmpty() && (this.renderer.options.hydratable
- ? `this.h()`
- : this.builders.hydrate);
- properties.addBlock(deindent `
- ${dev ? 'c: function create' : 'c'}() {
- ${this.builders.create}
- ${hydrate}
- },
- `);
- }
- if (this.renderer.options.hydratable) {
- if (this.builders.claim.isEmpty() && this.builders.hydrate.isEmpty()) {
- properties.addBlock(`l: @noop,`);
- }
- else {
- properties.addBlock(deindent `
- ${dev ? 'l: function claim' : 'l'}(nodes) {
- ${this.builders.claim}
- ${!this.builders.hydrate.isEmpty() && `this.h();`}
- },
- `);
- }
- }
- if (this.renderer.options.hydratable && !this.builders.hydrate.isEmpty()) {
- properties.addBlock(deindent `
- ${dev ? 'h: function hydrate' : 'h'}() {
- ${this.builders.hydrate}
- },
- `);
- }
- if (this.builders.mount.isEmpty()) {
- properties.addBlock(`m: @noop,`);
- }
- else {
- properties.addBlock(deindent `
- ${dev ? 'm: function mount' : 'm'}(#target, anchor) {
- ${this.builders.mount}
- },
- `);
- }
- if (this.hasUpdateMethod || this.maintainContext) {
- if (this.builders.update.isEmpty() && !this.maintainContext) {
- properties.addBlock(`p: @noop,`);
- }
- else {
- properties.addBlock(deindent `
- ${dev ? 'p: function update' : 'p'}(changed, ${this.maintainContext ? '_ctx' : 'ctx'}) {
- ${this.maintainContext && `ctx = _ctx;`}
- ${this.builders.update}
- },
- `);
- }
- }
- if (this.hasAnimation) {
- properties.addBlock(deindent `
- ${dev ? `r: function measure` : `r`}() {
- ${this.builders.measure}
- },
- ${dev ? `f: function fix` : `f`}() {
- ${this.builders.fix}
- },
- ${dev ? `a: function animate` : `a`}() {
- ${this.builders.animate}
- },
- `);
- }
- if (this.hasIntroMethod || this.hasOutroMethod) {
- if (this.builders.mount.isEmpty()) {
- properties.addBlock(`i: @noop,`);
- }
- else {
- properties.addBlock(deindent `
- ${dev ? 'i: function intro' : 'i'}(#target, anchor) {
- if (#current) return;
- ${this.builders.intro}
- this.m(#target, anchor);
- },
- `);
- }
- if (this.builders.outro.isEmpty()) {
- properties.addBlock(`o: @run,`);
- }
- else {
- properties.addBlock(deindent `
- ${dev ? 'o: function outro' : 'o'}(#outrocallback) {
- if (!#current) return;
- ${this.outros > 1 && `#outrocallback = @callAfter(#outrocallback, ${this.outros});`}
- ${this.builders.outro}
- },
- `);
- }
- }
- if (this.builders.destroy.isEmpty()) {
- properties.addBlock(`d: @noop`);
- }
- else {
- properties.addBlock(deindent `
- ${dev ? 'd: function destroy' : 'd'}(detach) {
- ${this.builders.destroy}
- }
- `);
- }
- return deindent `
- ${this.comment && `// ${escape$1(this.comment)}`}
- function ${this.name}(#component${this.key ? `, ${localKey}` : ''}, ctx) {
- ${this.variables.size > 0 &&
- `var ${Array.from(this.variables.keys())
- .map(key => {
- const init = this.variables.get(key);
- return init !== undefined ? `${key} = ${init}` : key;
- })
- .join(', ')};`}
- ${!this.builders.init.isEmpty() && this.builders.init}
- return {
- ${properties}
- };
- }
- `.replace(/(#+)(\w*)/g, (match, sigil, name) => {
- return sigil === '#' ? this.alias(name) : sigil.slice(1) + name;
- });
- }
- }
- class Wrapper {
- constructor(renderer, block, parent, node) {
- this.node = node;
- // make these non-enumerable so that they can be logged sensibly
- // (TODO in dev only?)
- Object.defineProperties(this, {
- renderer: {
- value: renderer
- },
- parent: {
- value: parent
- }
- });
- this.canUseInnerHTML = !renderer.options.hydratable;
- block.wrappers.push(this);
- }
- cannotUseInnerHTML() {
- this.canUseInnerHTML = false;
- if (this.parent)
- this.parent.cannotUseInnerHTML();
- }
- // TODO do we still need equivalent method on Node?
- findNearest(pattern) {
- if (pattern.test(this.node.type))
- return this;
- return this.parent && this.parent.findNearest(pattern);
- }
- getOrCreateAnchor(block, parentNode, parentNodes) {
- // TODO use this in EachBlock and IfBlock — tricky because
- // children need to be created first
- const needsAnchor = this.next ? !this.next.isDomNode() : !parentNode || !this.parent.isDomNode();
- const anchor = needsAnchor
- ? block.getUniqueName(`${this.var}_anchor`)
- : (this.next && this.next.var) || 'null';
- if (needsAnchor) {
- block.addElement(anchor, `@createComment()`, parentNodes && `@createComment()`, parentNode);
- }
- return anchor;
- }
- getUpdateMountNode(anchor) {
- return (this.parent && this.parent.isDomNode())
- ? this.parent.var
- : `${anchor}.parentNode`;
- }
- isDomNode() {
- return (this.node.type === 'Element' ||
- this.node.type === 'Text' ||
- this.node.type === 'MustacheTag');
- }
- render(block, parentNode, parentNodes) {
- throw new Error(`render method not implemented by subclass ${this.node.type}`);
- }
- remount(name) {
- return `${this.var}.m(${name}._slotted.default, null);`;
- }
- }
- function createDebuggingComment(node, component) {
- const { locate, source } = component;
- let c = node.start;
- if (node.type === 'ElseBlock') {
- while (source[c - 1] !== '{')
- c -= 1;
- while (source[c - 1] === '{')
- c -= 1;
- }
- let d = node.expression ? node.expression.node.end : c;
- while (source[d] !== '}')
- d += 1;
- while (source[d] === '}')
- d += 1;
- const start = locate(c);
- const loc = `(${start.line + 1}:${start.column})`;
- return `${loc} ${source.slice(c, d)}`.replace(/\s/g, ' ');
- }
- class AwaitBlockBranch extends Wrapper {
- constructor(status, renderer, block, parent, node, stripWhitespace, nextSibling) {
- super(renderer, block, parent, node);
- this.var = null;
- this.block = block.child({
- comment: createDebuggingComment(node, this.renderer.component),
- name: this.renderer.component.getUniqueName(`create_${status}_block`)
- });
- this.fragment = new FragmentWrapper(renderer, this.block, this.node.children, parent, stripWhitespace, nextSibling);
- this.isDynamic = this.block.dependencies.size > 0;
- }
- }
- class AwaitBlockWrapper extends Wrapper {
- constructor(renderer, block, parent, node, stripWhitespace, nextSibling) {
- super(renderer, block, parent, node);
- this.var = 'await_block';
- this.cannotUseInnerHTML();
- block.addDependencies(this.node.expression.dependencies);
- let isDynamic = false;
- let hasIntros = false;
- let hasOutros = false;
- ['pending', 'then', 'catch'].forEach(status => {
- const child = this.node[status];
- const branch = new AwaitBlockBranch(status, renderer, block, parent, child, stripWhitespace, nextSibling);
- renderer.blocks.push(branch.block);
- if (branch.isDynamic) {
- isDynamic = true;
- // TODO should blocks update their own parents?
- block.addDependencies(branch.block.dependencies);
- }
- if (branch.block.hasIntros)
- hasIntros = true;
- if (branch.block.hasOutros)
- hasOutros = true;
- this[status] = branch;
- });
- this.pending.block.hasUpdateMethod = isDynamic;
- this.then.block.hasUpdateMethod = isDynamic;
- this.catch.block.hasUpdateMethod = isDynamic;
- this.pending.block.hasIntroMethod = hasIntros;
- this.then.block.hasIntroMethod = hasIntros;
- this.catch.block.hasIntroMethod = hasIntros;
- this.pending.block.hasOutroMethod = hasOutros;
- this.then.block.hasOutroMethod = hasOutros;
- this.catch.block.hasOutroMethod = hasOutros;
- if (hasOutros && this.renderer.options.nestedTransitions) {
- block.addOutro();
- }
- }
- render(block, parentNode, parentNodes) {
- const anchor = this.getOrCreateAnchor(block, parentNode, parentNodes);
- const updateMountNode = this.getUpdateMountNode(anchor);
- const { snippet } = this.node.expression;
- const info = block.getUniqueName(`info`);
- const promise = block.getUniqueName(`promise`);
- block.addVariable(promise);
- block.maintainContext = true;
- const infoProps = [
- block.alias('component') === 'component' ? 'component' : `component: #component`,
- 'ctx',
- 'current: null',
- this.pending.block.name && `pending: ${this.pending.block.name}`,
- this.then.block.name && `then: ${this.then.block.name}`,
- this.catch.block.name && `catch: ${this.catch.block.name}`,
- this.then.block.name && `value: '${this.node.value}'`,
- this.catch.block.name && `error: '${this.node.error}'`,
- this.pending.block.hasOutroMethod && `blocks: Array(3)`
- ].filter(Boolean);
- block.builders.init.addBlock(deindent `
- let ${info} = {
- ${infoProps.join(',\n')}
- };
- `);
- block.builders.init.addBlock(deindent `
- @handlePromise(${promise} = ${snippet}, ${info});
- `);
- block.builders.create.addBlock(deindent `
- ${info}.block.c();
- `);
- if (parentNodes) {
- block.builders.claim.addBlock(deindent `
- ${info}.block.l(${parentNodes});
- `);
- }
- const initialMountNode = parentNode || '#target';
- const anchorNode = parentNode ? 'null' : 'anchor';
- const hasTransitions = this.pending.block.hasIntroMethod || this.pending.block.hasOutroMethod;
- block.builders.mount.addBlock(deindent `
- ${info}.block.${hasTransitions ? 'i' : 'm'}(${initialMountNode}, ${info}.anchor = ${anchorNode});
- ${info}.mount = () => ${updateMountNode};
- `);
- const conditions = [];
- if (this.node.expression.dependencies.size > 0) {
- conditions.push(`(${[...this.node.expression.dependencies].map(dep => `'${dep}' in changed`).join(' || ')})`);
- }
- conditions.push(`${promise} !== (${promise} = ${snippet})`, `@handlePromise(${promise}, ${info})`);
- block.builders.update.addLine(`${info}.ctx = ctx;`);
- if (this.pending.block.hasUpdateMethod) {
- block.builders.update.addBlock(deindent `
- if (${conditions.join(' && ')}) {
- // nothing
- } else {
- ${info}.block.p(changed, @assign(@assign({}, ctx), ${info}.resolved));
- }
- `);
- }
- else {
- block.builders.update.addBlock(deindent `
- ${conditions.join(' && ')}
- `);
- }
- if (this.pending.block.hasOutroMethod && this.renderer.options.nestedTransitions) {
- const countdown = block.getUniqueName('countdown');
- block.builders.outro.addBlock(deindent `
- const ${countdown} = @callAfter(#outrocallback, 3);
- for (let #i = 0; #i < 3; #i += 1) {
- const block = ${info}.blocks[#i];
- if (block) block.o(${countdown});
- else ${countdown}();
- }
- `);
- }
- block.builders.destroy.addBlock(deindent `
- ${info}.block.d(${parentNode ? '' : 'detach'});
- ${info} = null;
- `);
- [this.pending, this.then, this.catch].forEach(branch => {
- branch.fragment.render(branch.block, null, 'nodes');
- });
- }
- }
- function addToSet(a, b) {
- b.forEach(item => {
- a.add(item);
- });
- }
- class DebugTagWrapper extends Wrapper {
- constructor(renderer, block, parent, node, stripWhitespace, nextSibling) {
- super(renderer, block, parent, node);
- }
- render(block, parentNode, parentNodes) {
- const { renderer } = this;
- const { component } = renderer;
- if (!renderer.options.dev)
- return;
- const { code } = component;
- if (this.node.expressions.length === 0) {
- // Debug all
- code.overwrite(this.node.start + 1, this.node.start + 7, 'debugger', {
- storeName: true
- });
- const statement = `[✂${this.node.start + 1}-${this.node.start + 7}✂];`;
- block.builders.create.addLine(statement);
- block.builders.update.addLine(statement);
- }
- else {
- const { code } = component;
- code.overwrite(this.node.start + 1, this.node.start + 7, 'log', {
- storeName: true
- });
- const log = `[✂${this.node.start + 1}-${this.node.start + 7}✂]`;
- const dependencies = new Set();
- this.node.expressions.forEach(expression => {
- addToSet(dependencies, expression.dependencies);
- });
- const condition = [...dependencies].map(d => `changed.${d}`).join(' || ');
- const identifiers = this.node.expressions.map(e => e.node.name).join(', ');
- block.builders.update.addBlock(deindent `
- if (${condition}) {
- const { ${identifiers} } = ctx;
- console.${log}({ ${identifiers} });
- debugger;
- }
- `);
- block.builders.create.addBlock(deindent `
- {
- const { ${identifiers} } = ctx;
- console.${log}({ ${identifiers} });
- debugger;
- }
- `);
- }
- }
- }
- class DocumentWrapper extends Wrapper {
- constructor(renderer, block, parent, node) {
- super(renderer, block, parent, node);
- }
- render(block, parentNode, parentNodes) {
- const { renderer } = this;
- const { component } = renderer;
- this.node.handlers.forEach(handler => {
- // TODO verify that it's a valid callee (i.e. built-in or declared method)
- component.addSourcemapLocations(handler.expression);
- const isCustomEvent = component.events.has(handler.name);
- let usesState = handler.dependencies.size > 0;
- handler.render(component, block, 'document', false); // TODO hoist?
- const handlerName = block.getUniqueName(`onwindow${handler.name}`);
- const handlerBody = deindent `
- ${usesState && `var ctx = #component.get();`}
- ${handler.snippet};
- `;
- if (isCustomEvent) {
- // TODO dry this out
- block.addVariable(handlerName);
- block.builders.hydrate.addBlock(deindent `
- ${handlerName} = %events-${handler.name}.call(#component, document, function(event) {
- ${handlerBody}
- });
- `);
- block.builders.destroy.addLine(deindent `
- ${handlerName}.destroy();
- `);
- }
- else {
- block.builders.init.addBlock(deindent `
- function ${handlerName}(event) {
- ${handlerBody}
- }
- document.addEventListener("${handler.name}", ${handlerName});
- `);
- block.builders.destroy.addBlock(deindent `
- document.removeEventListener("${handler.name}", ${handlerName});
- `);
- }
- });
- }
- }
- class ElseBlockWrapper extends Wrapper {
- constructor(renderer, block, parent, node, stripWhitespace, nextSibling) {
- super(renderer, block, parent, node);
- this.var = null;
- this.block = block.child({
- comment: createDebuggingComment(node, this.renderer.component),
- name: this.renderer.component.getUniqueName(`create_else_block`)
- });
- this.fragment = new FragmentWrapper(renderer, this.block, this.node.children, parent, stripWhitespace, nextSibling);
- this.isDynamic = this.block.dependencies.size > 0;
- if (this.isDynamic) {
- // TODO this can't be right
- this.block.hasUpdateMethod = true;
- }
- }
- }
- class EachBlockWrapper extends Wrapper {
- constructor(renderer, block, parent, node, stripWhitespace, nextSibling) {
- super(renderer, block, parent, node);
- this.var = 'each';
- this.hasBinding = false;
- this.cannotUseInnerHTML();
- const { dependencies } = node.expression;
- block.addDependencies(dependencies);
- this.block = block.child({
- comment: createDebuggingComment(this.node, this.renderer.component),
- name: renderer.component.getUniqueName('create_each_block'),
- key: node.key,
- bindings: new Map(block.bindings),
- contextOwners: new Map(block.contextOwners)
- });
- // TODO this seems messy
- this.block.hasAnimation = this.node.hasAnimation;
- this.indexName = this.node.index || renderer.component.getUniqueName(`${this.node.context}_index`);
- node.contexts.forEach(prop => {
- this.block.contextOwners.set(prop.key.name, this);
- // TODO this doesn't feel great
- this.block.bindings.set(prop.key.name, () => `ctx.${this.vars.each_block_value}[ctx.${this.indexName}]${prop.tail}`);
- });
- if (this.node.index) {
- this.block.getUniqueName(this.node.index); // this prevents name collisions (#1254)
- }
- renderer.blocks.push(this.block);
- this.fragment = new FragmentWrapper(renderer, this.block, node.children, this, stripWhitespace, nextSibling);
- if (this.node.else) {
- this.else = new ElseBlockWrapper(renderer, block, this, this.node.else, stripWhitespace, nextSibling);
- renderer.blocks.push(this.else.block);
- if (this.else.isDynamic) {
- this.block.addDependencies(this.else.block.dependencies);
- }
- }
- block.addDependencies(this.block.dependencies);
- this.block.hasUpdateMethod = this.block.dependencies.size > 0; // TODO should this logic be in Block?
- if (this.block.hasOutros || (this.else && this.else.block.hasOutros)) {
- block.addOutro();
- }
- }
- render(block, parentNode, parentNodes) {
- if (this.fragment.nodes.length === 0)
- return;
- const { renderer } = this;
- const { component } = renderer;
- // hack the sourcemap, so that if data is missing the bug
- // is easy to find
- let c = this.node.start + 2;
- while (component.source[c] !== 'e')
- c += 1;
- component.code.overwrite(c, c + 4, 'length');
- const length = `[✂${c}-${c + 4}✂]`;
- const needsAnchor = this.next
- ? !this.next.isDomNode() :
- !parentNode || !this.parent.isDomNode();
- this.vars = {
- anchor: needsAnchor
- ? block.getUniqueName(`${this.var}_anchor`)
- : (this.next && this.next.var) || 'null',
- create_each_block: this.block.name,
- each_block_value: renderer.component.getUniqueName(`${this.var}_value`),
- get_each_context: renderer.component.getUniqueName(`get_${this.var}_context`),
- iterations: block.getUniqueName(`${this.var}_blocks`),
- length: `[✂${c}-${c + 4}✂]`,
- mountOrIntro: (this.block.hasIntroMethod || this.block.hasOutroMethod)
- ? 'i'
- : 'm'
- };
- this.contextProps = this.node.contexts.map(prop => `child_ctx.${prop.key.name} = list[i]${prop.tail};`);
- if (this.hasBinding)
- this.contextProps.push(`child_ctx.${this.vars.each_block_value} = list;`);
- if (this.hasBinding || this.node.index)
- this.contextProps.push(`child_ctx.${this.indexName} = i;`);
- const { snippet } = this.node.expression;
- block.builders.init.addLine(`var ${this.vars.each_block_value} = ${snippet};`);
- renderer.blocks.push(deindent `
- function ${this.vars.get_each_context}(ctx, list, i) {
- const child_ctx = Object.create(ctx);
- ${this.contextProps}
- return child_ctx;
- }
- `);
- if (this.node.key) {
- this.renderKeyed(block, parentNode, parentNodes, snippet);
- }
- else {
- this.renderUnkeyed(block, parentNode, parentNodes, snippet);
- }
- if (needsAnchor) {
- block.addElement(this.vars.anchor, `@createComment()`, parentNodes && `@createComment()`, parentNode);
- }
- if (this.else) {
- const each_block_else = component.getUniqueName(`${this.var}_else`);
- const mountOrIntro = (this.else.block.hasIntroMethod || this.else.block.hasOutroMethod) ? 'i' : 'm';
- block.builders.init.addLine(`var ${each_block_else} = null;`);
- // TODO neaten this up... will end up with an empty line in the block
- block.builders.init.addBlock(deindent `
- if (!${this.vars.each_block_value}.${length}) {
- ${each_block_else} = ${this.else.block.name}(#component, ctx);
- ${each_block_else}.c();
- }
- `);
- block.builders.mount.addBlock(deindent `
- if (${each_block_else}) {
- ${each_block_else}.${mountOrIntro}(${parentNode || '#target'}, null);
- }
- `);
- const initialMountNode = parentNode || `${this.vars.anchor}.parentNode`;
- if (this.else.block.hasUpdateMethod) {
- block.builders.update.addBlock(deindent `
- if (!${this.vars.each_block_value}.${length} && ${each_block_else}) {
- ${each_block_else}.p(changed, ctx);
- } else if (!${this.vars.each_block_value}.${length}) {
- ${each_block_else} = ${this.else.block.name}(#component, ctx);
- ${each_block_else}.c();
- ${each_block_else}.${mountOrIntro}(${initialMountNode}, ${this.vars.anchor});
- } else if (${each_block_else}) {
- ${each_block_else}.d(1);
- ${each_block_else} = null;
- }
- `);
- }
- else {
- block.builders.update.addBlock(deindent `
- if (${this.vars.each_block_value}.${length}) {
- if (${each_block_else}) {
- ${each_block_else}.d(1);
- ${each_block_else} = null;
- }
- } else if (!${each_block_else}) {
- ${each_block_else} = ${this.else.block.name}(#component, ctx);
- ${each_block_else}.c();
- ${each_block_else}.${mountOrIntro}(${initialMountNode}, ${this.vars.anchor});
- }
- `);
- }
- block.builders.destroy.addBlock(deindent `
- if (${each_block_else}) ${each_block_else}.d(${parentNode ? '' : 'detach'});
- `);
- }
- this.fragment.render(this.block, null, 'nodes');
- if (this.else) {
- this.else.fragment.render(this.else.block, null, 'nodes');
- }
- }
- renderKeyed(block, parentNode, parentNodes, snippet) {
- const { create_each_block, length, anchor, mountOrIntro, } = this.vars;
- const get_key = block.getUniqueName('get_key');
- const blocks = block.getUniqueName(`${this.var}_blocks`);
- const lookup = block.getUniqueName(`${this.var}_lookup`);
- block.addVariable(blocks, '[]');
- block.addVariable(lookup, `@blankObject()`);
- if (this.fragment.nodes[0].isDomNode()) {
- this.block.first = this.fragment.nodes[0].var;
- }
- else {
- this.block.first = this.block.getUniqueName('first');
- this.block.addElement(this.block.first, `@createComment()`, parentNodes && `@createComment()`, null);
- }
- block.builders.init.addBlock(deindent `
- const ${get_key} = ctx => ${this.node.key.snippet};
- for (var #i = 0; #i < ${this.vars.each_block_value}.${length}; #i += 1) {
- let child_ctx = ${this.vars.get_each_context}(ctx, ${this.vars.each_block_value}, #i);
- let key = ${get_key}(child_ctx);
- ${blocks}[#i] = ${lookup}[key] = ${create_each_block}(#component, key, child_ctx);
- }
- `);
- const initialMountNode = parentNode || '#target';
- const updateMountNode = this.getUpdateMountNode(anchor);
- const anchorNode = parentNode ? 'null' : 'anchor';
- block.builders.create.addBlock(deindent `
- for (#i = 0; #i < ${blocks}.length; #i += 1) ${blocks}[#i].c();
- `);
- if (parentNodes) {
- block.builders.claim.addBlock(deindent `
- for (#i = 0; #i < ${blocks}.length; #i += 1) ${blocks}[#i].l(${parentNodes});
- `);
- }
- block.builders.mount.addBlock(deindent `
- for (#i = 0; #i < ${blocks}.length; #i += 1) ${blocks}[#i].${mountOrIntro}(${initialMountNode}, ${anchorNode});
- `);
- const dynamic = this.block.hasUpdateMethod;
- const rects = block.getUniqueName('rects');
- const destroy = this.node.hasAnimation
- ? `@fixAndOutroAndDestroyBlock`
- : this.block.hasOutros
- ? `@outroAndDestroyBlock`
- : `@destroyBlock`;
- block.builders.update.addBlock(deindent `
- const ${this.vars.each_block_value} = ${snippet};
- ${this.block.hasOutros && `@groupOutros();`}
- ${this.node.hasAnimation && `for (let #i = 0; #i < ${blocks}.length; #i += 1) ${blocks}[#i].r();`}
- ${blocks} = @updateKeyedEach(${blocks}, #component, changed, ${get_key}, ${dynamic ? '1' : '0'}, ctx, ${this.vars.each_block_value}, ${lookup}, ${updateMountNode}, ${destroy}, ${create_each_block}, "${mountOrIntro}", ${anchor}, ${this.vars.get_each_context});
- ${this.node.hasAnimation && `for (let #i = 0; #i < ${blocks}.length; #i += 1) ${blocks}[#i].a();`}
- `);
- if (this.block.hasOutros && this.renderer.component.options.nestedTransitions) {
- const countdown = block.getUniqueName('countdown');
- block.builders.outro.addBlock(deindent `
- const ${countdown} = @callAfter(#outrocallback, ${blocks}.length);
- for (#i = 0; #i < ${blocks}.length; #i += 1) ${blocks}[#i].o(${countdown});
- `);
- }
- block.builders.destroy.addBlock(deindent `
- for (#i = 0; #i < ${blocks}.length; #i += 1) ${blocks}[#i].d(${parentNode ? '' : 'detach'});
- `);
- }
- renderUnkeyed(block, parentNode, parentNodes, snippet) {
- const { create_each_block, length, iterations, anchor, mountOrIntro, } = this.vars;
- block.builders.init.addBlock(deindent `
- var ${iterations} = [];
- for (var #i = 0; #i < ${this.vars.each_block_value}.${length}; #i += 1) {
- ${iterations}[#i] = ${create_each_block}(#component, ${this.vars.get_each_context}(ctx, ${this.vars.each_block_value}, #i));
- }
- `);
- const initialMountNode = parentNode || '#target';
- const updateMountNode = this.getUpdateMountNode(anchor);
- const anchorNode = parentNode ? 'null' : 'anchor';
- block.builders.create.addBlock(deindent `
- for (var #i = 0; #i < ${iterations}.length; #i += 1) {
- ${iterations}[#i].c();
- }
- `);
- if (parentNodes) {
- block.builders.claim.addBlock(deindent `
- for (var #i = 0; #i < ${iterations}.length; #i += 1) {
- ${iterations}[#i].l(${parentNodes});
- }
- `);
- }
- block.builders.mount.addBlock(deindent `
- for (var #i = 0; #i < ${iterations}.length; #i += 1) {
- ${iterations}[#i].${mountOrIntro}(${initialMountNode}, ${anchorNode});
- }
- `);
- const allDependencies = new Set(this.block.dependencies);
- const { dependencies } = this.node.expression;
- dependencies.forEach((dependency) => {
- allDependencies.add(dependency);
- });
- const outroBlock = this.block.hasOutros && block.getUniqueName('outroBlock');
- if (outroBlock) {
- block.builders.init.addBlock(deindent `
- function ${outroBlock}(i, detach, fn) {
- if (${iterations}[i]) {
- ${iterations}[i].o(() => {
- if (detach) {
- ${iterations}[i].d(detach);
- ${iterations}[i] = null;
- }
- if (fn) fn();
- });
- }
- }
- `);
- }
- // TODO do this for keyed blocks as well
- const condition = Array.from(allDependencies)
- .map(dependency => `changed.${dependency}`)
- .join(' || ');
- if (condition !== '') {
- const forLoopBody = this.block.hasUpdateMethod
- ? (this.block.hasIntros || this.block.hasOutros)
- ? deindent `
- if (${iterations}[#i]) {
- ${iterations}[#i].p(changed, child_ctx);
- } else {
- ${iterations}[#i] = ${create_each_block}(#component, child_ctx);
- ${iterations}[#i].c();
- }
- ${iterations}[#i].i(${updateMountNode}, ${anchor});
- `
- : deindent `
- if (${iterations}[#i]) {
- ${iterations}[#i].p(changed, child_ctx);
- } else {
- ${iterations}[#i] = ${create_each_block}(#component, child_ctx);
- ${iterations}[#i].c();
- ${iterations}[#i].m(${updateMountNode}, ${anchor});
- }
- `
- : deindent `
- ${iterations}[#i] = ${create_each_block}(#component, child_ctx);
- ${iterations}[#i].c();
- ${iterations}[#i].${mountOrIntro}(${updateMountNode}, ${anchor});
- `;
- const start = this.block.hasUpdateMethod ? '0' : `${iterations}.length`;
- let destroy;
- if (this.block.hasOutros) {
- destroy = deindent `
- @groupOutros();
- for (; #i < ${iterations}.length; #i += 1) ${outroBlock}(#i, 1);
- `;
- }
- else {
- destroy = deindent `
- for (${this.block.hasUpdateMethod ? `` : `#i = ${this.vars.each_block_value}.${length}`}; #i < ${iterations}.length; #i += 1) {
- ${iterations}[#i].d(1);
- }
- ${iterations}.length = ${this.vars.each_block_value}.${length};
- `;
- }
- block.builders.update.addBlock(deindent `
- if (${condition}) {
- ${this.vars.each_block_value} = ${snippet};
- for (var #i = ${start}; #i < ${this.vars.each_block_value}.${length}; #i += 1) {
- const child_ctx = ${this.vars.get_each_context}(ctx, ${this.vars.each_block_value}, #i);
- ${forLoopBody}
- }
- ${destroy}
- }
- `);
- }
- if (outroBlock && this.renderer.component.options.nestedTransitions) {
- const countdown = block.getUniqueName('countdown');
- block.builders.outro.addBlock(deindent `
- ${iterations} = ${iterations}.filter(Boolean);
- const ${countdown} = @callAfter(#outrocallback, ${iterations}.length);
- for (let #i = 0; #i < ${iterations}.length; #i += 1) ${outroBlock}(#i, 0, ${countdown});`);
- }
- block.builders.destroy.addBlock(`@destroyEach(${iterations}, detach);`);
- }
- remount(name) {
- // TODO consider keyed blocks
- return `for (var #i = 0; #i < ${this.vars.iterations}.length; #i += 1) ${this.vars.iterations}[#i].m(${name}._slotted.default, null);`;
- }
- }
- function isValidIdentifier(str) {
- let i = 0;
- while (i < str.length) {
- const code = fullCharCodeAt(str, i);
- if (!(i === 0 ? isIdentifierStart : isIdentifierChar)(code, true))
- return false;
- i += code <= 0xffff ? 1 : 2;
- }
- return true;
- }
- function quoteNameIfNecessary(name) {
- if (!isValidIdentifier(name))
- return `"${name}"`;
- return name;
- }
- function quotePropIfNecessary(name) {
- if (!isValidIdentifier(name))
- return `["${name}"]`;
- return `.${name}`;
- }
- const svgAttributes = 'accent-height accumulate additive alignment-baseline allowReorder alphabetic amplitude arabic-form ascent attributeName attributeType autoReverse azimuth baseFrequency baseline-shift baseProfile bbox begin bias by calcMode cap-height class clip clipPathUnits clip-path clip-rule color color-interpolation color-interpolation-filters color-profile color-rendering contentScriptType contentStyleType cursor cx cy d decelerate descent diffuseConstant direction display divisor dominant-baseline dur dx dy edgeMode elevation enable-background end exponent externalResourcesRequired fill fill-opacity fill-rule filter filterRes filterUnits flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight format from fr fx fy g1 g2 glyph-name glyph-orientation-horizontal glyph-orientation-vertical glyphRef gradientTransform gradientUnits hanging height href horiz-adv-x horiz-origin-x id ideographic image-rendering in in2 intercept k k1 k2 k3 k4 kernelMatrix kernelUnitLength kerning keyPoints keySplines keyTimes lang lengthAdjust letter-spacing lighting-color limitingConeAngle local marker-end marker-mid marker-start markerHeight markerUnits markerWidth mask maskContentUnits maskUnits mathematical max media method min mode name numOctaves offset onabort onactivate onbegin onclick onend onerror onfocusin onfocusout onload onmousedown onmousemove onmouseout onmouseover onmouseup onrepeat onresize onscroll onunload opacity operator order orient orientation origin overflow overline-position overline-thickness panose-1 paint-order pathLength patternContentUnits patternTransform patternUnits pointer-events points pointsAtX pointsAtY pointsAtZ preserveAlpha preserveAspectRatio primitiveUnits r radius refX refY rendering-intent repeatCount repeatDur requiredExtensions requiredFeatures restart result rotate rx ry scale seed shape-rendering slope spacing specularConstant specularExponent speed spreadMethod startOffset stdDeviation stemh stemv stitchTiles stop-color stop-opacity strikethrough-position strikethrough-thickness string stroke stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width style surfaceScale systemLanguage tabindex tableValues target targetX targetY text-anchor text-decoration text-rendering textLength to transform type u1 u2 underline-position underline-thickness unicode unicode-bidi unicode-range units-per-em v-alphabetic v-hanging v-ideographic v-mathematical values version vert-adv-y vert-origin-x vert-origin-y viewBox viewTarget visibility width widths word-spacing writing-mode x x-height x1 x2 xChannelSelector xlink:actuate xlink:arcrole xlink:href xlink:role xlink:show xlink:title xlink:type xml:base xml:lang xml:space y y1 y2 yChannelSelector z zoomAndPan'.split(' ');
- const svgAttributeLookup = new Map();
- svgAttributes.forEach(name => {
- svgAttributeLookup.set(name.toLowerCase(), name);
- });
- function fixAttributeCasing(name) {
- name = name.toLowerCase();
- return svgAttributeLookup.get(name) || name;
- }
- const html = 'http://www.w3.org/1999/xhtml';
- const mathml = 'http://www.w3.org/1998/Math/MathML';
- const svg = 'http://www.w3.org/2000/svg';
- const xlink = 'http://www.w3.org/1999/xlink';
- const xml = 'http://www.w3.org/XML/1998/namespace';
- const xmlns = 'http://www.w3.org/2000/xmlns';
- const validNamespaces = [
- 'html',
- 'mathml',
- 'svg',
- 'xlink',
- 'xml',
- 'xmlns',
- html,
- mathml,
- svg,
- xlink,
- xml,
- xmlns,
- ];
- const namespaces = { html, mathml, svg, xlink, xml, xmlns };
- class AttributeWrapper {
- constructor(parent, block, node) {
- this.node = node;
- this.parent = parent;
- if (node.dependencies.size > 0) {
- parent.cannotUseInnerHTML();
- block.addDependencies(node.dependencies);
- // special case — <option value={foo}> — see below
- if (this.parent.node.name === 'option' && node.name === 'value') {
- let select = this.parent;
- while (select && (select.node.type !== 'Element' || select.node.name !== 'select'))
- select = select.parent;
- if (select && select.selectBindingDependencies) {
- select.selectBindingDependencies.forEach(prop => {
- this.node.dependencies.forEach((dependency) => {
- this.parent.renderer.component.indirectDependencies.get(prop).add(dependency);
- });
- });
- }
- }
- }
- }
- render(block) {
- const element = this.parent;
- const name = fixAttributeCasing(this.node.name);
- let metadata = element.node.namespace ? null : attributeLookup[name];
- if (metadata && metadata.appliesTo && !~metadata.appliesTo.indexOf(element.node.name))
- metadata = null;
- const isIndirectlyBoundValue = name === 'value' &&
- (element.node.name === 'option' || // TODO check it's actually bound
- (element.node.name === 'input' &&
- element.node.bindings.find((binding) => /checked|group/.test(binding.name))));
- const propertyName = isIndirectlyBoundValue
- ? '__value'
- : metadata && metadata.propertyName;
- // xlink is a special case... we could maybe extend this to generic
- // namespaced attributes but I'm not sure that's applicable in
- // HTML5?
- const method = /-/.test(element.node.name)
- ? '@setCustomElementData'
- : name.slice(0, 6) === 'xlink:'
- ? '@setXlinkAttribute'
- : '@setAttribute';
- const isLegacyInputType = element.renderer.component.options.legacy && name === 'type' && this.parent.node.name === 'input';
- const isDataSet = /^data-/.test(name) && !element.renderer.component.options.legacy && !element.node.namespace;
- const camelCaseName = isDataSet ? name.replace('data-', '').replace(/(-\w)/g, function (m) {
- return m[1].toUpperCase();
- }) : name;
- if (this.node.isDynamic) {
- let value;
- // TODO some of this code is repeated in Tag.ts — would be good to
- // DRY it out if that's possible without introducing crazy indirection
- if (this.node.chunks.length === 1) {
- // single {tag} — may be a non-string
- value = this.node.chunks[0].snippet;
- }
- else {
- // '{foo} {bar}' — treat as string concatenation
- value =
- (this.node.chunks[0].type === 'Text' ? '' : `"" + `) +
- this.node.chunks
- .map((chunk) => {
- if (chunk.type === 'Text') {
- return stringify(chunk.data);
- }
- else {
- return chunk.getPrecedence() <= 13
- ? `(${chunk.snippet})`
- : chunk.snippet;
- }
- })
- .join(' + ');
- }
- const isSelectValueAttribute = name === 'value' && element.node.name === 'select';
- const shouldCache = this.node.shouldCache || isSelectValueAttribute;
- const last = shouldCache && block.getUniqueName(`${element.var}_${name.replace(/[^a-zA-Z_$]/g, '_')}_value`);
- if (shouldCache)
- block.addVariable(last);
- let updater;
- const init = shouldCache ? `${last} = ${value}` : value;
- if (isLegacyInputType) {
- block.builders.hydrate.addLine(`@setInputType(${element.var}, ${init});`);
- updater = `@setInputType(${element.var}, ${shouldCache ? last : value});`;
- }
- else if (isSelectValueAttribute) {
- // annoying special case
- const isMultipleSelect = element.getStaticAttributeValue('multiple');
- const i = block.getUniqueName('i');
- const option = block.getUniqueName('option');
- const ifStatement = isMultipleSelect
- ? deindent `
- ${option}.selected = ~${last}.indexOf(${option}.__value);`
- : deindent `
- if (${option}.__value === ${last}) {
- ${option}.selected = true;
- break;
- }`;
- updater = deindent `
- for (var ${i} = 0; ${i} < ${element.var}.options.length; ${i} += 1) {
- var ${option} = ${element.var}.options[${i}];
- ${ifStatement}
- }
- `;
- block.builders.mount.addBlock(deindent `
- ${last} = ${value};
- ${updater}
- `);
- }
- else if (propertyName) {
- block.builders.hydrate.addLine(`${element.var}.${propertyName} = ${init};`);
- updater = `${element.var}.${propertyName} = ${shouldCache ? last : value};`;
- }
- else if (isDataSet) {
- block.builders.hydrate.addLine(`${element.var}.dataset.${camelCaseName} = ${init};`);
- updater = `${element.var}.dataset.${camelCaseName} = ${shouldCache ? last : value};`;
- }
- else {
- block.builders.hydrate.addLine(`${method}(${element.var}, "${name}", ${init});`);
- updater = `${method}(${element.var}, "${name}", ${shouldCache ? last : value});`;
- }
- if (this.node.dependencies.size || isSelectValueAttribute) {
- const dependencies = Array.from(this.node.dependencies);
- const changedCheck = ((block.hasOutros ? `!#current || ` : '') +
- dependencies.map(dependency => `changed.${dependency}`).join(' || '));
- const updateCachedValue = `${last} !== (${last} = ${value})`;
- const condition = shouldCache ?
- (dependencies.length ? `(${changedCheck}) && ${updateCachedValue}` : updateCachedValue) :
- changedCheck;
- block.builders.update.addConditional(condition, updater);
- }
- }
- else {
- const value = this.node.getValue();
- const statement = (isLegacyInputType
- ? `@setInputType(${element.var}, ${value});`
- : propertyName
- ? `${element.var}.${propertyName} = ${value};`
- : isDataSet
- ? `${element.var}.dataset.${camelCaseName} = ${value};`
- : `${method}(${element.var}, "${name}", ${value});`);
- block.builders.hydrate.addLine(statement);
- // special case – autofocus. has to be handled in a bit of a weird way
- if (this.node.isTrue && name === 'autofocus') {
- block.autofocus = element.var;
- }
- }
- if (isIndirectlyBoundValue) {
- const updateValue = `${element.var}.value = ${element.var}.__value;`;
- block.builders.hydrate.addLine(updateValue);
- if (this.node.isDynamic)
- block.builders.update.addLine(updateValue);
- }
- }
- stringify() {
- const value = this.node.chunks;
- if (value === true)
- return '';
- if (value.length === 0)
- return `=""`;
- return `="${value.map(chunk => {
- return chunk.type === 'Text'
- ? chunk.data.replace(/"/g, '\\"')
- : `\${${chunk.snippet}}`;
- })}"`;
- }
- }
- // source: https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes
- const attributeLookup = {
- accept: { appliesTo: ['form', 'input'] },
- 'accept-charset': { propertyName: 'acceptCharset', appliesTo: ['form'] },
- accesskey: { propertyName: 'accessKey' },
- action: { appliesTo: ['form'] },
- align: {
- appliesTo: [
- 'applet',
- 'caption',
- 'col',
- 'colgroup',
- 'hr',
- 'iframe',
- 'img',
- 'table',
- 'tbody',
- 'td',
- 'tfoot',
- 'th',
- 'thead',
- 'tr',
- ],
- },
- allowfullscreen: { propertyName: 'allowFullscreen', appliesTo: ['iframe'] },
- alt: { appliesTo: ['applet', 'area', 'img', 'input'] },
- async: { appliesTo: ['script'] },
- autocomplete: { appliesTo: ['form', 'input'] },
- autofocus: { appliesTo: ['button', 'input', 'keygen', 'select', 'textarea'] },
- autoplay: { appliesTo: ['audio', 'video'] },
- autosave: { appliesTo: ['input'] },
- bgcolor: {
- propertyName: 'bgColor',
- appliesTo: [
- 'body',
- 'col',
- 'colgroup',
- 'marquee',
- 'table',
- 'tbody',
- 'tfoot',
- 'td',
- 'th',
- 'tr',
- ],
- },
- border: { appliesTo: ['img', 'object', 'table'] },
- buffered: { appliesTo: ['audio', 'video'] },
- challenge: { appliesTo: ['keygen'] },
- charset: { appliesTo: ['meta', 'script'] },
- checked: { appliesTo: ['command', 'input'] },
- cite: { appliesTo: ['blockquote', 'del', 'ins', 'q'] },
- class: { propertyName: 'className' },
- code: { appliesTo: ['applet'] },
- codebase: { propertyName: 'codeBase', appliesTo: ['applet'] },
- color: { appliesTo: ['basefont', 'font', 'hr'] },
- cols: { appliesTo: ['textarea'] },
- colspan: { propertyName: 'colSpan', appliesTo: ['td', 'th'] },
- content: { appliesTo: ['meta'] },
- contenteditable: { propertyName: 'contentEditable' },
- contextmenu: {},
- controls: { appliesTo: ['audio', 'video'] },
- coords: { appliesTo: ['area'] },
- data: { appliesTo: ['object'] },
- datetime: { propertyName: 'dateTime', appliesTo: ['del', 'ins', 'time'] },
- default: { appliesTo: ['track'] },
- defer: { appliesTo: ['script'] },
- dir: {},
- dirname: { propertyName: 'dirName', appliesTo: ['input', 'textarea'] },
- disabled: {
- appliesTo: [
- 'button',
- 'command',
- 'fieldset',
- 'input',
- 'keygen',
- 'optgroup',
- 'option',
- 'select',
- 'textarea',
- ],
- },
- download: { appliesTo: ['a', 'area'] },
- draggable: {},
- dropzone: {},
- enctype: { appliesTo: ['form'] },
- for: { propertyName: 'htmlFor', appliesTo: ['label', 'output'] },
- form: {
- appliesTo: [
- 'button',
- 'fieldset',
- 'input',
- 'keygen',
- 'label',
- 'meter',
- 'object',
- 'output',
- 'progress',
- 'select',
- 'textarea',
- ],
- },
- formaction: { appliesTo: ['input', 'button'] },
- headers: { appliesTo: ['td', 'th'] },
- height: {
- appliesTo: ['canvas', 'embed', 'iframe', 'img', 'input', 'object', 'video'],
- },
- hidden: {},
- high: { appliesTo: ['meter'] },
- href: { appliesTo: ['a', 'area', 'base', 'link'] },
- hreflang: { appliesTo: ['a', 'area', 'link'] },
- 'http-equiv': { propertyName: 'httpEquiv', appliesTo: ['meta'] },
- icon: { appliesTo: ['command'] },
- id: {},
- indeterminate: { appliesTo: ['input'] },
- ismap: { propertyName: 'isMap', appliesTo: ['img'] },
- itemprop: {},
- keytype: { appliesTo: ['keygen'] },
- kind: { appliesTo: ['track'] },
- label: { appliesTo: ['track'] },
- lang: {},
- language: { appliesTo: ['script'] },
- loop: { appliesTo: ['audio', 'bgsound', 'marquee', 'video'] },
- low: { appliesTo: ['meter'] },
- manifest: { appliesTo: ['html'] },
- max: { appliesTo: ['input', 'meter', 'progress'] },
- maxlength: { propertyName: 'maxLength', appliesTo: ['input', 'textarea'] },
- media: { appliesTo: ['a', 'area', 'link', 'source', 'style'] },
- method: { appliesTo: ['form'] },
- min: { appliesTo: ['input', 'meter'] },
- multiple: { appliesTo: ['input', 'select'] },
- muted: { appliesTo: ['audio', 'video'] },
- name: {
- appliesTo: [
- 'button',
- 'form',
- 'fieldset',
- 'iframe',
- 'input',
- 'keygen',
- 'object',
- 'output',
- 'select',
- 'textarea',
- 'map',
- 'meta',
- 'param',
- ],
- },
- novalidate: { propertyName: 'noValidate', appliesTo: ['form'] },
- open: { appliesTo: ['details'] },
- optimum: { appliesTo: ['meter'] },
- pattern: { appliesTo: ['input'] },
- ping: { appliesTo: ['a', 'area'] },
- placeholder: { appliesTo: ['input', 'textarea'] },
- poster: { appliesTo: ['video'] },
- preload: { appliesTo: ['audio', 'video'] },
- radiogroup: { appliesTo: ['command'] },
- readonly: { propertyName: 'readOnly', appliesTo: ['input', 'textarea'] },
- rel: { appliesTo: ['a', 'area', 'link'] },
- required: { appliesTo: ['input', 'select', 'textarea'] },
- reversed: { appliesTo: ['ol'] },
- rows: { appliesTo: ['textarea'] },
- rowspan: { propertyName: 'rowSpan', appliesTo: ['td', 'th'] },
- sandbox: { appliesTo: ['iframe'] },
- scope: { appliesTo: ['th'] },
- scoped: { appliesTo: ['style'] },
- seamless: { appliesTo: ['iframe'] },
- selected: { appliesTo: ['option'] },
- shape: { appliesTo: ['a', 'area'] },
- size: { appliesTo: ['input', 'select'] },
- sizes: { appliesTo: ['link', 'img', 'source'] },
- span: { appliesTo: ['col', 'colgroup'] },
- spellcheck: {},
- src: {
- appliesTo: [
- 'audio',
- 'embed',
- 'iframe',
- 'img',
- 'input',
- 'script',
- 'source',
- 'track',
- 'video',
- ],
- },
- srcdoc: { appliesTo: ['iframe'] },
- srclang: { appliesTo: ['track'] },
- srcset: { appliesTo: ['img'] },
- start: { appliesTo: ['ol'] },
- step: { appliesTo: ['input'] },
- style: { propertyName: 'style.cssText' },
- summary: { appliesTo: ['table'] },
- tabindex: { propertyName: 'tabIndex' },
- target: { appliesTo: ['a', 'area', 'base', 'form'] },
- title: {},
- type: {
- appliesTo: [
- 'button',
- 'command',
- 'embed',
- 'object',
- 'script',
- 'source',
- 'style',
- 'menu',
- ],
- },
- usemap: { propertyName: 'useMap', appliesTo: ['img', 'input', 'object'] },
- value: {
- appliesTo: [
- 'button',
- 'option',
- 'input',
- 'li',
- 'meter',
- 'progress',
- 'param',
- 'select',
- 'textarea',
- ],
- },
- volume: { appliesTo: ['audio', 'video'] },
- width: {
- appliesTo: ['canvas', 'embed', 'iframe', 'img', 'input', 'object', 'video'],
- },
- wrap: { appliesTo: ['textarea'] },
- };
- Object.keys(attributeLookup).forEach(name => {
- const metadata = attributeLookup[name];
- if (!metadata.propertyName)
- metadata.propertyName = name;
- });
- class StyleAttributeWrapper extends AttributeWrapper {
- render(block) {
- const styleProps = optimizeStyle(this.node.chunks);
- if (!styleProps)
- return super.render(block);
- styleProps.forEach((prop) => {
- let value;
- if (isDynamic(prop.value)) {
- const propDependencies = new Set();
- value =
- ((prop.value.length === 1 || prop.value[0].type === 'Text') ? '' : `"" + `) +
- prop.value
- .map((chunk) => {
- if (chunk.type === 'Text') {
- return stringify(chunk.data);
- }
- else {
- const { dependencies, snippet } = chunk;
- dependencies.forEach(d => {
- propDependencies.add(d);
- });
- return chunk.getPrecedence() <= 13 ? `(${snippet})` : snippet;
- }
- })
- .join(' + ');
- if (propDependencies.size) {
- const dependencies = Array.from(propDependencies);
- const condition = ((block.hasOutros ? `!#current || ` : '') +
- dependencies.map(dependency => `changed.${dependency}`).join(' || '));
- block.builders.update.addConditional(condition, `@setStyle(${this.parent.var}, "${prop.key}", ${value});`);
- }
- }
- else {
- value = stringify(prop.value[0].data);
- }
- block.builders.hydrate.addLine(`@setStyle(${this.parent.var}, "${prop.key}", ${value});`);
- });
- }
- }
- function optimizeStyle(value) {
- const props = [];
- let chunks = value.slice();
- while (chunks.length) {
- const chunk = chunks[0];
- if (chunk.type !== 'Text')
- return null;
- const keyMatch = /^\s*([\w-]+):\s*/.exec(chunk.data);
- if (!keyMatch)
- return null;
- const key = keyMatch[1];
- const offset = keyMatch.index + keyMatch[0].length;
- const remainingData = chunk.data.slice(offset);
- if (remainingData) {
- chunks[0] = {
- start: chunk.start + offset,
- end: chunk.end,
- type: 'Text',
- data: remainingData
- };
- }
- else {
- chunks.shift();
- }
- const result = getStyleValue(chunks);
- if (!result)
- return null;
- props.push({ key, value: result.value });
- chunks = result.chunks;
- }
- return props;
- }
- function getStyleValue(chunks) {
- const value = [];
- let inUrl = false;
- let quoteMark = null;
- let escaped = false;
- while (chunks.length) {
- const chunk = chunks.shift();
- if (chunk.type === 'Text') {
- let c = 0;
- while (c < chunk.data.length) {
- const char = chunk.data[c];
- if (escaped) {
- escaped = false;
- }
- else if (char === '\\') {
- escaped = true;
- }
- else if (char === quoteMark) ;
- else if (char === '"' || char === "'") {
- quoteMark = char;
- }
- else if (char === ')' && inUrl) {
- inUrl = false;
- }
- else if (char === 'u' && chunk.data.slice(c, c + 4) === 'url(') {
- inUrl = true;
- }
- else if (char === ';' && !inUrl && !quoteMark) {
- break;
- }
- c += 1;
- }
- if (c > 0) {
- value.push({
- type: 'Text',
- start: chunk.start,
- end: chunk.start + c,
- data: chunk.data.slice(0, c)
- });
- }
- while (/[;\s]/.test(chunk.data[c]))
- c += 1;
- const remainingData = chunk.data.slice(c);
- if (remainingData) {
- chunks.unshift({
- start: chunk.start + c,
- end: chunk.end,
- type: 'Text',
- data: remainingData
- });
- break;
- }
- }
- else {
- value.push(chunk);
- }
- }
- return {
- chunks,
- value
- };
- }
- function isDynamic(value) {
- return value.length > 1 || value[0].type !== 'Text';
- }
- function getObject(node) {
- while (node.type === 'MemberExpression')
- node = node.object;
- return node;
- }
- function flattenReference(node) {
- if (node.type === 'Expression')
- throw new Error('bad');
- const nodes = [];
- const parts = [];
- const propEnd = node.end;
- while (node.type === 'MemberExpression') {
- if (node.computed)
- return null;
- nodes.unshift(node.property);
- parts.unshift(node.property.name);
- node = node.object;
- }
- const propStart = node.end;
- const name = node.type === 'Identifier'
- ? node.name
- : node.type === 'ThisExpression' ? 'this' : null;
- if (!name)
- return null;
- parts.unshift(name);
- nodes.unshift(node);
- return { name, nodes, parts, keypath: `${name}[✂${propStart}-${propEnd}✂]` };
- }
- function getTailSnippet(node) {
- const end = node.end;
- while (node.type === 'MemberExpression')
- node = node.object;
- const start = node.end;
- return `[✂${start}-${end}✂]`;
- }
- // TODO this should live in a specific binding
- const readOnlyMediaAttributes = new Set([
- 'duration',
- 'buffered',
- 'seekable',
- 'played'
- ]);
- class BindingWrapper {
- constructor(block, node, parent) {
- this.node = node;
- this.parent = parent;
- const { dependencies } = this.node.value;
- block.addDependencies(dependencies);
- // TODO does this also apply to e.g. `<input type='checkbox' bind:group='foo'>`?
- if (parent.node.name === 'select') {
- parent.selectBindingDependencies = dependencies;
- dependencies.forEach((prop) => {
- parent.renderer.component.indirectDependencies.set(prop, new Set());
- });
- }
- if (node.isContextual) {
- // we need to ensure that the each block creates a context including
- // the list and the index, if they're not otherwise referenced
- const { name } = getObject(this.node.value.node);
- const eachBlock = block.contextOwners.get(name);
- eachBlock.hasBinding = true;
- }
- }
- isReadOnlyMediaAttribute() {
- return readOnlyMediaAttributes.has(this.node.name);
- }
- munge(block) {
- const { parent } = this;
- const { renderer } = parent;
- const needsLock = (parent.node.name !== 'input' ||
- !/radio|checkbox|range|color/.test(parent.node.getStaticAttributeValue('type')));
- const isReadOnly = ((parent.node.isMediaNode() && readOnlyMediaAttributes.has(this.node.name)) ||
- dimensions.test(this.node.name));
- let updateConditions = [];
- const { name } = getObject(this.node.value.node);
- const { snippet } = this.node.value;
- // special case: if you have e.g. `<input type=checkbox bind:checked=selected.done>`
- // and `selected` is an object chosen with a <select>, then when `checked` changes,
- // we need to tell the component to update all the values `selected` might be
- // pointing to
- // TODO should this happen in preprocess?
- const dependencies = new Set(this.node.value.dependencies);
- this.node.value.dependencies.forEach((prop) => {
- const indirectDependencies = renderer.component.indirectDependencies.get(prop);
- if (indirectDependencies) {
- indirectDependencies.forEach(indirectDependency => {
- dependencies.add(indirectDependency);
- });
- }
- });
- // view to model
- const valueFromDom = getValueFromDom(renderer, this.parent, this);
- const handler = getEventHandler(this, renderer, block, name, snippet, dependencies, valueFromDom);
- // model to view
- let updateDom = getDomUpdater(parent, this, snippet);
- let initialUpdate = updateDom;
- // special cases
- if (this.node.name === 'group') {
- const bindingGroup = getBindingGroup(renderer, this.node.value.node);
- block.builders.hydrate.addLine(`#component._bindingGroups[${bindingGroup}].push(${parent.var});`);
- block.builders.destroy.addLine(`#component._bindingGroups[${bindingGroup}].splice(#component._bindingGroups[${bindingGroup}].indexOf(${parent.var}), 1);`);
- }
- if (this.node.name === 'currentTime' || this.node.name === 'volume') {
- updateConditions.push(`!isNaN(${snippet})`);
- if (this.node.name === 'currentTime')
- initialUpdate = null;
- }
- if (this.node.name === 'paused') {
- // this is necessary to prevent audio restarting by itself
- const last = block.getUniqueName(`${parent.var}_is_paused`);
- block.addVariable(last, 'true');
- updateConditions.push(`${last} !== (${last} = ${snippet})`);
- updateDom = `${parent.var}[${last} ? "pause" : "play"]();`;
- initialUpdate = null;
- }
- // bind:offsetWidth and bind:offsetHeight
- if (dimensions.test(this.node.name)) {
- initialUpdate = null;
- updateDom = null;
- }
- const dependencyArray = [...this.node.value.dependencies];
- if (dependencyArray.length === 1) {
- updateConditions.push(`changed.${dependencyArray[0]}`);
- }
- else if (dependencyArray.length > 1) {
- updateConditions.push(`(${dependencyArray.map(prop => `changed.${prop}`).join(' || ')})`);
- }
- return {
- name: this.node.name,
- object: name,
- handler: handler,
- usesContext: handler.usesContext,
- updateDom: updateDom,
- initialUpdate: initialUpdate,
- needsLock: !isReadOnly && needsLock,
- updateCondition: updateConditions.length ? updateConditions.join(' && ') : undefined,
- isReadOnlyMediaAttribute: this.isReadOnlyMediaAttribute()
- };
- }
- }
- function getDomUpdater(element, binding, snippet) {
- const { node } = element;
- if (binding.isReadOnlyMediaAttribute()) {
- return null;
- }
- if (node.name === 'select') {
- return node.getStaticAttributeValue('multiple') === true ?
- `@selectOptions(${element.var}, ${snippet})` :
- `@selectOption(${element.var}, ${snippet})`;
- }
- if (binding.node.name === 'group') {
- const type = node.getStaticAttributeValue('type');
- const condition = type === 'checkbox'
- ? `~${snippet}.indexOf(${element.var}.__value)`
- : `${element.var}.__value === ${snippet}`;
- return `${element.var}.checked = ${condition};`;
- }
- return `${element.var}.${binding.node.name} = ${snippet};`;
- }
- function getBindingGroup(renderer, value) {
- const { parts } = flattenReference(value); // TODO handle cases involving computed member expressions
- const keypath = parts.join('.');
- // TODO handle contextual bindings — `keypath` should include unique ID of
- // each block that provides context
- let index = renderer.bindingGroups.indexOf(keypath);
- if (index === -1) {
- index = renderer.bindingGroups.length;
- renderer.bindingGroups.push(keypath);
- }
- return index;
- }
- function getEventHandler(binding, renderer, block, name, snippet, dependencies, value) {
- const storeDependencies = [...dependencies].filter(prop => prop[0] === '$').map(prop => prop.slice(1));
- let dependenciesArray = [...dependencies].filter(prop => prop[0] !== '$');
- if (binding.node.isContextual) {
- const tail = binding.node.value.node.type === 'MemberExpression'
- ? getTailSnippet(binding.node.value.node)
- : '';
- const head = block.bindings.get(name);
- return {
- usesContext: true,
- usesState: true,
- usesStore: storeDependencies.length > 0,
- mutation: `${head()}${tail} = ${value};`,
- props: dependenciesArray.map(prop => `${prop}: ctx.${prop}`),
- storeProps: storeDependencies.map(prop => `${prop}: $.${prop}`)
- };
- }
- if (binding.node.value.node.type === 'MemberExpression') {
- // This is a little confusing, and should probably be tidied up
- // at some point. It addresses a tricky bug (#893), wherein
- // Svelte tries to `set()` a computed property, which throws an
- // error in dev mode. a) it's possible that we should be
- // replacing computations with *their* dependencies, and b)
- // we should probably populate `component.target.readonly` sooner so
- // that we don't have to do the `.some()` here
- dependenciesArray = dependenciesArray.filter(prop => !renderer.component.computations.some(computation => computation.key === prop));
- return {
- usesContext: false,
- usesState: true,
- usesStore: storeDependencies.length > 0,
- mutation: `${snippet} = ${value}`,
- props: dependenciesArray.map((prop) => `${prop}: ctx.${prop}`),
- storeProps: storeDependencies.map(prop => `${prop}: $.${prop}`)
- };
- }
- let props;
- let storeProps;
- if (name[0] === '$') {
- props = [];
- storeProps = [`${name.slice(1)}: ${value}`];
- }
- else {
- props = [`${name}: ${value}`];
- storeProps = [];
- }
- return {
- usesContext: false,
- usesState: false,
- usesStore: false,
- mutation: null,
- props,
- storeProps
- };
- }
- function getValueFromDom(renderer, element, binding) {
- const { node } = element;
- const { name } = binding.node;
- // <select bind:value='selected>
- if (node.name === 'select') {
- return node.getStaticAttributeValue('multiple') === true ?
- `@selectMultipleValue(${element.var})` :
- `@selectValue(${element.var})`;
- }
- const type = node.getStaticAttributeValue('type');
- // <input type='checkbox' bind:group='foo'>
- if (name === 'group') {
- const bindingGroup = getBindingGroup(renderer, binding.node.value.node);
- if (type === 'checkbox') {
- return `@getBindingGroupValue(#component._bindingGroups[${bindingGroup}])`;
- }
- return `${element.var}.__value`;
- }
- // <input type='range|number' bind:value>
- if (type === 'range' || type === 'number') {
- return `@toNumber(${element.var}.${name})`;
- }
- if ((name === 'buffered' || name === 'seekable' || name === 'played')) {
- return `@timeRangesToArray(${element.var}.${name})`;
- }
- // everything else
- return `${element.var}.${name}`;
- }
- const events = [
- {
- eventNames: ['input'],
- filter: (node, name) => node.name === 'textarea' ||
- node.name === 'input' && !/radio|checkbox|range/.test(node.getStaticAttributeValue('type'))
- },
- {
- eventNames: ['change'],
- filter: (node, name) => node.name === 'select' ||
- node.name === 'input' && /radio|checkbox/.test(node.getStaticAttributeValue('type'))
- },
- {
- eventNames: ['change', 'input'],
- filter: (node, name) => node.name === 'input' && node.getStaticAttributeValue('type') === 'range'
- },
- {
- eventNames: ['resize'],
- filter: (node, name) => dimensions.test(name)
- },
- // media events
- {
- eventNames: ['timeupdate'],
- filter: (node, name) => node.isMediaNode() &&
- (name === 'currentTime' || name === 'played')
- },
- {
- eventNames: ['durationchange'],
- filter: (node, name) => node.isMediaNode() &&
- name === 'duration'
- },
- {
- eventNames: ['play', 'pause'],
- filter: (node, name) => node.isMediaNode() &&
- name === 'paused'
- },
- {
- eventNames: ['progress'],
- filter: (node, name) => node.isMediaNode() &&
- name === 'buffered'
- },
- {
- eventNames: ['loadedmetadata'],
- filter: (node, name) => node.isMediaNode() &&
- (name === 'buffered' || name === 'seekable')
- },
- {
- eventNames: ['volumechange'],
- filter: (node, name) => node.isMediaNode() &&
- name === 'volume'
- }
- ];
- class ElementWrapper extends Wrapper {
- constructor(renderer, block, parent, node, stripWhitespace, nextSibling) {
- super(renderer, block, parent, node);
- this.var = node.name.replace(/[^a-zA-Z0-9_$]/g, '_');
- this.classDependencies = [];
- this.attributes = this.node.attributes.map(attribute => {
- if (attribute.name === 'slot') {
- // TODO make separate subclass for this?
- let owner = this.parent;
- while (owner) {
- if (owner.node.type === 'InlineComponent') {
- break;
- }
- if (owner.node.type === 'Element' && /-/.test(owner.node.name)) {
- break;
- }
- owner = owner.parent;
- }
- if (owner && owner.node.type === 'InlineComponent') {
- this.slotOwner = owner;
- owner._slots.add(attribute.getStaticValue());
- }
- }
- if (attribute.name === 'style') {
- return new StyleAttributeWrapper(this, block, attribute);
- }
- return new AttributeWrapper(this, block, attribute);
- });
- let has_bindings;
- const binding_lookup = {};
- this.node.bindings.forEach(binding => {
- binding_lookup[binding.name] = binding;
- has_bindings = true;
- });
- const type = this.node.getStaticAttributeValue('type');
- // ordinarily, there'll only be one... but we need to handle
- // the rare case where an element can have multiple bindings,
- // e.g. <audio bind:paused bind:currentTime>
- this.bindings = this.node.bindings.map(binding => new BindingWrapper(block, binding, this));
- // TODO remove this, it's just useful during refactoring
- if (has_bindings && !this.bindings.length) {
- throw new Error(`no binding was created`);
- }
- if (node.intro || node.outro) {
- if (node.intro)
- block.addIntro();
- if (node.outro)
- block.addOutro();
- }
- if (node.animation) {
- block.addAnimation();
- }
- // add directive and handler dependencies
- [node.animation, node.outro, ...node.actions, ...node.classes].forEach(directive => {
- if (directive && directive.expression) {
- block.addDependencies(directive.expression.dependencies);
- }
- });
- node.handlers.forEach(handler => {
- block.addDependencies(handler.dependencies);
- });
- if (this.parent) {
- if (node.actions.length > 0)
- this.parent.cannotUseInnerHTML();
- if (node.animation)
- this.parent.cannotUseInnerHTML();
- if (node.bindings.length > 0)
- this.parent.cannotUseInnerHTML();
- if (node.classes.length > 0)
- this.parent.cannotUseInnerHTML();
- if (node.intro || node.outro)
- this.parent.cannotUseInnerHTML();
- if (node.handlers.length > 0)
- this.parent.cannotUseInnerHTML();
- if (node.ref)
- this.parent.cannotUseInnerHTML();
- if (this.node.name === 'option')
- this.parent.cannotUseInnerHTML();
- if (renderer.options.dev) {
- this.parent.cannotUseInnerHTML(); // need to use addLoc
- }
- }
- this.fragment = new FragmentWrapper(renderer, block, node.children, this, stripWhitespace, nextSibling);
- }
- render(block, parentNode, parentNodes) {
- const { renderer } = this;
- if (this.node.name === 'slot') {
- const slotName = this.getStaticAttributeValue('name') || 'default';
- renderer.slots.add(slotName);
- }
- if (this.node.name === 'noscript')
- return;
- const node = this.var;
- const nodes = parentNodes && block.getUniqueName(`${this.var}_nodes`); // if we're in unclaimable territory, i.e. <head>, parentNodes is null
- const slot = this.node.attributes.find((attribute) => attribute.name === 'slot');
- const prop = slot && quotePropIfNecessary(slot.chunks[0].data);
- let initialMountNode;
- if (this.slotOwner) {
- initialMountNode = `${this.slotOwner.var}._slotted${prop}`;
- }
- else {
- initialMountNode = parentNode;
- }
- block.addVariable(node);
- const renderStatement = this.getRenderStatement();
- block.builders.create.addLine(`${node} = ${renderStatement};`);
- if (renderer.options.hydratable) {
- if (parentNodes) {
- block.builders.claim.addBlock(deindent `
- ${node} = ${this.getClaimStatement(parentNodes)};
- var ${nodes} = @children(${this.node.name === 'template' ? `${node}.content` : node});
- `);
- }
- else {
- block.builders.claim.addLine(`${node} = ${renderStatement};`);
- }
- }
- if (initialMountNode) {
- block.builders.mount.addLine(`@append(${initialMountNode}, ${node});`);
- if (initialMountNode === 'document.head') {
- block.builders.destroy.addLine(`@detachNode(${node});`);
- }
- }
- else {
- block.builders.mount.addLine(`@insert(#target, ${node}, anchor);`);
- // TODO we eventually need to consider what happens to elements
- // that belong to the same outgroup as an outroing element...
- block.builders.destroy.addConditional('detach', `@detachNode(${node});`);
- }
- // insert static children with textContent or innerHTML
- if (!this.node.namespace && this.canUseInnerHTML && this.fragment.nodes.length > 0) {
- if (this.fragment.nodes.length === 1 && this.fragment.nodes[0].node.type === 'Text') {
- block.builders.create.addLine(`${node}.textContent = ${stringify(this.fragment.nodes[0].data)};`);
- }
- else {
- const innerHTML = escape$1(this.fragment.nodes
- .map(toHTML)
- .join(''));
- block.builders.create.addLine(`${node}.innerHTML = \`${innerHTML}\`;`);
- }
- }
- else {
- this.fragment.nodes.forEach((child) => {
- child.render(block, this.node.name === 'template' ? `${node}.content` : node, nodes);
- });
- }
- let hasHoistedEventHandlerOrBinding = (
- //(this.hasAncestor('EachBlock') && this.bindings.length > 0) ||
- this.node.handlers.some(handler => handler.shouldHoist));
- const eventHandlerOrBindingUsesComponent = (this.bindings.length > 0 ||
- this.node.handlers.some(handler => handler.usesComponent));
- const eventHandlerOrBindingUsesContext = (this.bindings.some(binding => binding.node.usesContext) ||
- this.node.handlers.some(handler => handler.usesContext));
- if (hasHoistedEventHandlerOrBinding) {
- const initialProps = [];
- if (eventHandlerOrBindingUsesComponent) {
- const component = block.alias('component');
- initialProps.push(component === 'component' ? 'component' : `component: ${component}`);
- }
- if (eventHandlerOrBindingUsesContext) {
- initialProps.push(`ctx`);
- block.builders.update.addLine(`${node}._svelte.ctx = ctx;`);
- block.maintainContext = true;
- }
- if (initialProps.length) {
- block.builders.hydrate.addBlock(deindent `
- ${node}._svelte = { ${initialProps.join(', ')} };
- `);
- }
- }
- else {
- if (eventHandlerOrBindingUsesContext) {
- block.maintainContext = true;
- }
- }
- this.addBindings(block);
- this.addEventHandlers(block);
- if (this.node.ref)
- this.addRef(block);
- this.addAttributes(block);
- this.addTransitions(block);
- this.addAnimation(block);
- this.addActions(block);
- this.addClasses(block);
- if (this.initialUpdate) {
- block.builders.mount.addBlock(this.initialUpdate);
- }
- if (nodes) {
- block.builders.claim.addLine(`${nodes}.forEach(@detachNode);`);
- }
- function toHTML(wrapper) {
- if (wrapper.node.type === 'Text') {
- const { parent } = wrapper.node;
- const raw = parent && (parent.name === 'script' ||
- parent.name === 'style');
- return raw
- ? wrapper.node.data
- : escapeHTML(wrapper.node.data)
- .replace(/\\/g, '\\\\')
- .replace(/`/g, '\\`')
- .replace(/\$/g, '\\$');
- }
- if (wrapper.node.name === 'noscript')
- return '';
- let open = `<${wrapper.node.name}`;
- wrapper.attributes.forEach((attr) => {
- open += ` ${fixAttributeCasing(attr.node.name)}${attr.stringify()}`;
- });
- if (isVoidElementName(wrapper.node.name))
- return open + '>';
- return `${open}>${wrapper.fragment.nodes.map(toHTML).join('')}</${wrapper.node.name}>`;
- }
- if (renderer.options.dev) {
- const loc = renderer.locate(this.node.start);
- block.builders.hydrate.addLine(`@addLoc(${this.var}, ${renderer.fileVar}, ${loc.line}, ${loc.column}, ${this.node.start});`);
- }
- }
- getRenderStatement() {
- const { name, namespace } = this.node;
- if (namespace === 'http://www.w3.org/2000/svg') {
- return `@createSvgElement("${name}")`;
- }
- if (namespace) {
- return `document.createElementNS("${namespace}", "${name}")`;
- }
- return `@createElement("${name}")`;
- }
- getClaimStatement(nodes) {
- const attributes = this.node.attributes
- .filter((attr) => attr.type === 'Attribute')
- .map((attr) => `${quoteNameIfNecessary(attr.name)}: true`)
- .join(', ');
- const name = this.node.namespace
- ? this.node.name
- : this.node.name.toUpperCase();
- return `@claimElement(${nodes}, "${name}", ${attributes
- ? `{ ${attributes} }`
- : `{}`}, ${this.node.namespace === namespaces.svg ? true : false})`;
- }
- addBindings(block) {
- const { renderer } = this;
- if (this.bindings.length === 0)
- return;
- if (this.node.name === 'select' || this.isMediaNode()) {
- this.renderer.hasComplexBindings = true;
- }
- const needsLock = this.node.name !== 'input' || !/radio|checkbox|range|color/.test(this.getStaticAttributeValue('type'));
- // TODO munge in constructor
- const mungedBindings = this.bindings.map(binding => binding.munge(block));
- const lock = mungedBindings.some(binding => binding.needsLock) ?
- block.getUniqueName(`${this.var}_updating`) :
- null;
- if (lock)
- block.addVariable(lock, 'false');
- const groups = events
- .map(event => {
- return {
- events: event.eventNames,
- bindings: mungedBindings.filter(binding => event.filter(this.node, binding.name))
- };
- })
- .filter(group => group.bindings.length);
- groups.forEach(group => {
- const handler = block.getUniqueName(`${this.var}_${group.events.join('_')}_handler`);
- const needsLock = group.bindings.some(binding => binding.needsLock);
- group.bindings.forEach(binding => {
- if (!binding.updateDom)
- return;
- const updateConditions = needsLock ? [`!${lock}`] : [];
- if (binding.updateCondition)
- updateConditions.push(binding.updateCondition);
- block.builders.update.addLine(updateConditions.length ? `if (${updateConditions.join(' && ')}) ${binding.updateDom}` : binding.updateDom);
- });
- const usesStore = group.bindings.some(binding => binding.handler.usesStore);
- const mutations = group.bindings.map(binding => binding.handler.mutation).filter(Boolean).join('\n');
- const props = new Set();
- const storeProps = new Set();
- group.bindings.forEach(binding => {
- binding.handler.props.forEach(prop => {
- props.add(prop);
- });
- binding.handler.storeProps.forEach(prop => {
- storeProps.add(prop);
- });
- }); // TODO use stringifyProps here, once indenting is fixed
- // media bindings — awkward special case. The native timeupdate events
- // fire too infrequently, so we need to take matters into our
- // own hands
- let animation_frame;
- if (group.events[0] === 'timeupdate') {
- animation_frame = block.getUniqueName(`${this.var}_animationframe`);
- block.addVariable(animation_frame);
- }
- block.builders.init.addBlock(deindent `
- function ${handler}() {
- ${animation_frame && deindent `
- cancelAnimationFrame(${animation_frame});
- if (!${this.var}.paused) ${animation_frame} = requestAnimationFrame(${handler});`}
- ${usesStore && `var $ = #component.store.get();`}
- ${needsLock && `${lock} = true;`}
- ${mutations.length > 0 && mutations}
- ${props.size > 0 && `#component.set({ ${Array.from(props).join(', ')} });`}
- ${storeProps.size > 0 && `#component.store.set({ ${Array.from(storeProps).join(', ')} });`}
- ${needsLock && `${lock} = false;`}
- }
- `);
- group.events.forEach(name => {
- if (name === 'resize') {
- // special case
- const resize_listener = block.getUniqueName(`${this.var}_resize_listener`);
- block.addVariable(resize_listener);
- block.builders.mount.addLine(`${resize_listener} = @addResizeListener(${this.var}, ${handler});`);
- block.builders.destroy.addLine(`${resize_listener}.cancel();`);
- }
- else {
- block.builders.hydrate.addLine(`@addListener(${this.var}, "${name}", ${handler});`);
- block.builders.destroy.addLine(`@removeListener(${this.var}, "${name}", ${handler});`);
- }
- });
- const allInitialStateIsDefined = group.bindings
- .map(binding => `'${binding.object}' in ctx`)
- .join(' && ');
- if (this.node.name === 'select' || group.bindings.find(binding => binding.name === 'indeterminate' || binding.isReadOnlyMediaAttribute)) {
- renderer.hasComplexBindings = true;
- block.builders.hydrate.addLine(`if (!(${allInitialStateIsDefined})) #component.root._beforecreate.push(${handler});`);
- }
- if (group.events[0] === 'resize') {
- renderer.hasComplexBindings = true;
- block.builders.hydrate.addLine(`#component.root._beforecreate.push(${handler});`);
- }
- });
- this.initialUpdate = mungedBindings.map(binding => binding.initialUpdate).filter(Boolean).join('\n');
- }
- addAttributes(block) {
- if (this.node.attributes.find(attr => attr.type === 'Spread')) {
- this.addSpreadAttributes(block);
- return;
- }
- this.attributes.forEach((attribute) => {
- if (attribute.node.name === 'class' && attribute.node.isDynamic) {
- this.classDependencies.push(...attribute.node.dependencies);
- }
- attribute.render(block);
- });
- }
- addSpreadAttributes(block) {
- const levels = block.getUniqueName(`${this.var}_levels`);
- const data = block.getUniqueName(`${this.var}_data`);
- const initialProps = [];
- const updates = [];
- this.node.attributes
- .filter(attr => attr.type === 'Attribute' || attr.type === 'Spread')
- .forEach(attr => {
- const condition = attr.dependencies.size > 0
- ? `(${[...attr.dependencies].map(d => `changed.${d}`).join(' || ')})`
- : null;
- if (attr.isSpread) {
- const { snippet, dependencies } = attr.expression;
- initialProps.push(snippet);
- updates.push(condition ? `${condition} && ${snippet}` : snippet);
- }
- else {
- const snippet = `{ ${quoteNameIfNecessary(attr.name)}: ${attr.getValue()} }`;
- initialProps.push(snippet);
- updates.push(condition ? `${condition} && ${snippet}` : snippet);
- }
- });
- block.builders.init.addBlock(deindent `
- var ${levels} = [
- ${initialProps.join(',\n')}
- ];
- var ${data} = {};
- for (var #i = 0; #i < ${levels}.length; #i += 1) {
- ${data} = @assign(${data}, ${levels}[#i]);
- }
- `);
- block.builders.hydrate.addLine(`@setAttributes(${this.var}, ${data});`);
- block.builders.update.addBlock(deindent `
- @setAttributes(${this.var}, @getSpreadUpdate(${levels}, [
- ${updates.join(',\n')}
- ]));
- `);
- }
- addEventHandlers(block) {
- const { renderer } = this;
- const { component } = renderer;
- this.node.handlers.forEach(handler => {
- const isCustomEvent = component.events.has(handler.name);
- if (handler.callee) {
- // TODO move handler render method into a wrapper
- handler.render(this.renderer.component, block, this.var, handler.shouldHoist);
- }
- const target = handler.shouldHoist ? 'this' : this.var;
- // get a name for the event handler that is globally unique
- // if hoisted, locally unique otherwise
- const handlerName = (handler.shouldHoist ? component : block).getUniqueName(`${handler.name.replace(/[^a-zA-Z0-9_$]/g, '_')}_handler`);
- const component_name = block.alias('component'); // can't use #component, might be hoisted
- // create the handler body
- const handlerBody = deindent `
- ${handler.shouldHoist && (handler.usesComponent || handler.usesContext
- ? `const { ${[handler.usesComponent && 'component', handler.usesContext && 'ctx'].filter(Boolean).join(', ')} } = ${target}._svelte;`
- : null)}
- ${handler.snippet ?
- handler.snippet :
- `${component_name}.fire("${handler.name}", event);`}
- `;
- if (isCustomEvent) {
- block.addVariable(handlerName);
- block.builders.hydrate.addBlock(deindent `
- ${handlerName} = %events-${handler.name}.call(${component_name}, ${this.var}, function(event) {
- ${handlerBody}
- });
- `);
- block.builders.destroy.addLine(deindent `
- ${handlerName}.destroy();
- `);
- }
- else {
- const modifiers = [];
- if (handler.modifiers.has('preventDefault'))
- modifiers.push('event.preventDefault();');
- if (handler.modifiers.has('stopPropagation'))
- modifiers.push('event.stopPropagation();');
- const handlerFunction = deindent `
- function ${handlerName}(event) {
- ${modifiers}
- ${handlerBody}
- }
- `;
- if (handler.shouldHoist) {
- renderer.blocks.push(handlerFunction);
- }
- else {
- block.builders.init.addBlock(handlerFunction);
- }
- const opts = ['passive', 'once', 'capture'].filter(mod => handler.modifiers.has(mod));
- if (opts.length) {
- const optString = (opts.length === 1 && opts[0] === 'capture')
- ? 'true'
- : `{ ${opts.map(opt => `${opt}: true`).join(', ')} }`;
- block.builders.hydrate.addLine(`@addListener(${this.var}, "${handler.name}", ${handlerName}, ${optString});`);
- block.builders.destroy.addLine(`@removeListener(${this.var}, "${handler.name}", ${handlerName}, ${optString});`);
- }
- else {
- block.builders.hydrate.addLine(`@addListener(${this.var}, "${handler.name}", ${handlerName});`);
- block.builders.destroy.addLine(`@removeListener(${this.var}, "${handler.name}", ${handlerName});`);
- }
- }
- });
- }
- addRef(block) {
- const ref = `#component.refs.${this.node.ref.name}`;
- block.builders.mount.addLine(`${ref} = ${this.var};`);
- block.builders.destroy.addLine(`if (${ref} === ${this.var}) ${ref} = null;`);
- }
- addTransitions(block) {
- const { intro, outro } = this.node;
- if (!intro && !outro)
- return;
- if (intro === outro) {
- const name = block.getUniqueName(`${this.var}_transition`);
- const snippet = intro.expression
- ? intro.expression.snippet
- : '{}';
- block.addVariable(name);
- const fn = `%transitions-${intro.name}`;
- block.builders.intro.addConditional(`#component.root._intro`, deindent `
- if (${name}) ${name}.invalidate();
- #component.root._aftercreate.push(() => {
- if (!${name}) ${name} = @wrapTransition(#component, ${this.var}, ${fn}, ${snippet}, true);
- ${name}.run(1);
- });
- `);
- block.builders.outro.addBlock(deindent `
- if (!${name}) ${name} = @wrapTransition(#component, ${this.var}, ${fn}, ${snippet}, false);
- ${name}.run(0, () => {
- #outrocallback();
- ${name} = null;
- });
- `);
- block.builders.destroy.addConditional('detach', `if (${name}) ${name}.abort();`);
- }
- else {
- const introName = intro && block.getUniqueName(`${this.var}_intro`);
- const outroName = outro && block.getUniqueName(`${this.var}_outro`);
- if (intro) {
- block.addVariable(introName);
- const snippet = intro.expression
- ? intro.expression.snippet
- : '{}';
- const fn = `%transitions-${intro.name}`; // TODO add built-in transitions?
- if (outro) {
- block.builders.intro.addBlock(deindent `
- if (${introName}) ${introName}.abort(1);
- if (${outroName}) ${outroName}.abort(1);
- `);
- }
- block.builders.intro.addConditional(`#component.root._intro`, deindent `
- #component.root._aftercreate.push(() => {
- ${introName} = @wrapTransition(#component, ${this.var}, ${fn}, ${snippet}, true);
- ${introName}.run(1);
- });
- `);
- }
- if (outro) {
- block.addVariable(outroName);
- const snippet = outro.expression
- ? outro.expression.snippet
- : '{}';
- const fn = `%transitions-${outro.name}`;
- block.builders.intro.addBlock(deindent `
- if (${outroName}) ${outroName}.abort(1);
- `);
- // TODO hide elements that have outro'd (unless they belong to a still-outroing
- // group) prior to their removal from the DOM
- block.builders.outro.addBlock(deindent `
- ${outroName} = @wrapTransition(#component, ${this.var}, ${fn}, ${snippet}, false);
- ${outroName}.run(0, #outrocallback);
- `);
- block.builders.destroy.addConditional('detach', `if (${outroName}) ${outroName}.abort();`);
- }
- }
- }
- addAnimation(block) {
- if (!this.node.animation)
- return;
- const rect = block.getUniqueName('rect');
- const animation = block.getUniqueName('animation');
- block.addVariable(rect);
- block.addVariable(animation);
- block.builders.measure.addBlock(deindent `
- ${rect} = ${this.var}.getBoundingClientRect();
- `);
- block.builders.fix.addBlock(deindent `
- @fixPosition(${this.var});
- if (${animation}) ${animation}.stop();
- `);
- const params = this.node.animation.expression ? this.node.animation.expression.snippet : '{}';
- block.builders.animate.addBlock(deindent `
- if (${animation}) ${animation}.stop();
- ${animation} = @wrapAnimation(${this.var}, ${rect}, %animations-${this.node.animation.name}, ${params});
- `);
- }
- addActions(block) {
- this.node.actions.forEach(action => {
- const { expression } = action;
- let snippet, dependencies;
- if (expression) {
- snippet = expression.snippet;
- dependencies = expression.dependencies;
- }
- const name = block.getUniqueName(`${action.name.replace(/[^a-zA-Z0-9_$]/g, '_')}_action`);
- block.addVariable(name);
- const fn = `%actions-${action.name}`;
- block.builders.mount.addLine(`${name} = ${fn}.call(#component, ${this.var}${snippet ? `, ${snippet}` : ''}) || {};`);
- if (dependencies && dependencies.size > 0) {
- let conditional = `typeof ${name}.update === 'function' && `;
- const deps = [...dependencies].map(dependency => `changed.${dependency}`).join(' || ');
- conditional += dependencies.size > 1 ? `(${deps})` : deps;
- block.builders.update.addConditional(conditional, `${name}.update.call(#component, ${snippet});`);
- }
- block.builders.destroy.addLine(`if (${name} && typeof ${name}.destroy === 'function') ${name}.destroy.call(#component);`);
- });
- }
- addClasses(block) {
- this.node.classes.forEach(classDir => {
- const { expression, name } = classDir;
- let snippet, dependencies;
- if (expression) {
- snippet = expression.snippet;
- dependencies = expression.dependencies;
- }
- else {
- snippet = `ctx${quotePropIfNecessary(name)}`;
- dependencies = new Set([name]);
- }
- const updater = `@toggleClass(${this.var}, "${name}", ${snippet});`;
- block.builders.hydrate.addLine(updater);
- if ((dependencies && dependencies.size > 0) || this.classDependencies.length) {
- const allDeps = this.classDependencies.concat(...dependencies);
- const deps = allDeps.map(dependency => `changed${quotePropIfNecessary(dependency)}`).join(' || ');
- const condition = allDeps.length > 1 ? `(${deps})` : deps;
- block.builders.update.addConditional(condition, updater);
- }
- });
- }
- getStaticAttributeValue(name) {
- const attribute = this.node.attributes.find((attr) => attr.type === 'Attribute' && attr.name.toLowerCase() === name);
- if (!attribute)
- return null;
- if (attribute.isTrue)
- return true;
- if (attribute.chunks.length === 0)
- return '';
- if (attribute.chunks.length === 1 && attribute.chunks[0].type === 'Text') {
- return attribute.chunks[0].data;
- }
- return null;
- }
- isMediaNode() {
- return this.node.name === 'audio' || this.node.name === 'video';
- }
- remount(name) {
- const slot = this.attributes.find(attribute => attribute.name === 'slot');
- if (slot) {
- const prop = quotePropIfNecessary(slot.chunks[0].data);
- return `@append(${name}._slotted${prop}, ${this.var});`;
- }
- return `@append(${name}._slotted.default, ${this.var});`;
- }
- addCssClass(className = this.component.stylesheet.id) {
- const classAttribute = this.attributes.find(a => a.name === 'class');
- if (classAttribute && !classAttribute.isTrue) {
- if (classAttribute.chunks.length === 1 && classAttribute.chunks[0].type === 'Text') {
- classAttribute.chunks[0].data += ` ${className}`;
- }
- else {
- classAttribute.chunks.push(new Text(this.component, this, this.scope, {
- type: 'Text',
- data: ` ${className}`
- }));
- }
- }
- else {
- this.attributes.push(new Attribute(this.component, this, this.scope, {
- type: 'Attribute',
- name: 'class',
- value: [{ type: 'Text', data: className }]
- }));
- }
- }
- }
- class HeadWrapper extends Wrapper {
- constructor(renderer, block, parent, node, stripWhitespace, nextSibling) {
- super(renderer, block, parent, node);
- this.canUseInnerHTML = false;
- this.fragment = new FragmentWrapper(renderer, block, node.children, this, stripWhitespace, nextSibling);
- }
- render(block, parentNode, parentNodes) {
- this.fragment.render(block, 'document.head', null);
- }
- }
- function isElseIf(node) {
- return (node && node.children.length === 1 && node.children[0].type === 'IfBlock');
- }
- class IfBlockBranch extends Wrapper {
- constructor(renderer, block, parent, node, stripWhitespace, nextSibling) {
- super(renderer, block, parent, node);
- this.var = null;
- this.condition = node.expression && node.expression.snippet;
- this.block = block.child({
- comment: createDebuggingComment(node, parent.renderer.component),
- name: parent.renderer.component.getUniqueName(node.expression ? `create_if_block` : `create_else_block`)
- });
- this.fragment = new FragmentWrapper(renderer, this.block, node.children, parent, stripWhitespace, nextSibling);
- this.isDynamic = this.block.dependencies.size > 0;
- }
- }
- class IfBlockWrapper extends Wrapper {
- constructor(renderer, block, parent, node, stripWhitespace, nextSibling) {
- super(renderer, block, parent, node);
- this.var = 'if_block';
- const { component } = renderer;
- this.cannotUseInnerHTML();
- this.branches = [];
- const blocks = [];
- let isDynamic = false;
- let hasIntros = false;
- let hasOutros = false;
- const createBranches = (node) => {
- const branch = new IfBlockBranch(renderer, block, this, node, stripWhitespace, nextSibling);
- this.branches.push(branch);
- blocks.push(branch.block);
- block.addDependencies(node.expression.dependencies);
- if (branch.block.dependencies.size > 0) {
- isDynamic = true;
- block.addDependencies(branch.block.dependencies);
- }
- if (branch.block.hasIntros)
- hasIntros = true;
- if (branch.block.hasOutros)
- hasOutros = true;
- if (isElseIf(node.else)) {
- createBranches(node.else.children[0]);
- }
- else if (node.else) {
- const branch = new IfBlockBranch(renderer, block, this, node.else, stripWhitespace, nextSibling);
- this.branches.push(branch);
- blocks.push(branch.block);
- if (branch.block.dependencies.size > 0) {
- isDynamic = true;
- block.addDependencies(branch.block.dependencies);
- }
- if (branch.block.hasIntros)
- hasIntros = true;
- if (branch.block.hasOutros)
- hasOutros = true;
- }
- };
- createBranches(this.node);
- if (component.options.nestedTransitions) {
- if (hasIntros)
- block.addIntro();
- if (hasOutros)
- block.addOutro();
- }
- blocks.forEach(block => {
- block.hasUpdateMethod = isDynamic;
- block.hasIntroMethod = hasIntros;
- block.hasOutroMethod = hasOutros;
- });
- renderer.blocks.push(...blocks);
- }
- render(block, parentNode, parentNodes) {
- const name = this.var;
- const needsAnchor = this.next ? !this.next.isDomNode() : !parentNode || !this.parent.isDomNode();
- const anchor = needsAnchor
- ? block.getUniqueName(`${name}_anchor`)
- : (this.next && this.next.var) || 'null';
- const hasElse = !(this.branches[this.branches.length - 1].condition);
- const if_name = hasElse ? '' : `if (${name}) `;
- const dynamic = this.branches[0].block.hasUpdateMethod; // can use [0] as proxy for all, since they necessarily have the same value
- const hasOutros = this.branches[0].block.hasOutroMethod;
- const vars = { name, anchor, if_name, hasElse };
- if (this.node.else) {
- if (hasOutros) {
- this.renderCompoundWithOutros(block, parentNode, parentNodes, dynamic, vars);
- if (this.renderer.options.nestedTransitions) {
- block.builders.outro.addBlock(deindent `
- if (${name}) ${name}.o(#outrocallback);
- else #outrocallback();
- `);
- }
- }
- else {
- this.renderCompound(block, parentNode, parentNodes, dynamic, vars);
- }
- }
- else {
- this.renderSimple(block, parentNode, parentNodes, dynamic, vars);
- if (hasOutros && this.renderer.options.nestedTransitions) {
- block.builders.outro.addBlock(deindent `
- if (${name}) ${name}.o(#outrocallback);
- else #outrocallback();
- `);
- }
- }
- block.builders.create.addLine(`${if_name}${name}.c();`);
- if (parentNodes) {
- block.builders.claim.addLine(`${if_name}${name}.l(${parentNodes});`);
- }
- if (needsAnchor) {
- block.addElement(anchor, `@createComment()`, parentNodes && `@createComment()`, parentNode);
- }
- this.branches.forEach(branch => {
- branch.fragment.render(branch.block, null, 'nodes');
- });
- }
- renderCompound(block, parentNode, parentNodes, dynamic, { name, anchor, hasElse, if_name }) {
- const select_block_type = this.renderer.component.getUniqueName(`select_block_type`);
- const current_block_type = block.getUniqueName(`current_block_type`);
- const current_block_type_and = hasElse ? '' : `${current_block_type} && `;
- block.builders.init.addBlock(deindent `
- function ${select_block_type}(ctx) {
- ${this.branches
- .map(({ condition, block }) => `${condition ? `if (${condition}) ` : ''}return ${block.name};`)
- .join('\n')}
- }
- `);
- block.builders.init.addBlock(deindent `
- var ${current_block_type} = ${select_block_type}(ctx);
- var ${name} = ${current_block_type_and}${current_block_type}(#component, ctx);
- `);
- const mountOrIntro = this.branches[0].block.hasIntroMethod ? 'i' : 'm';
- const initialMountNode = parentNode || '#target';
- const anchorNode = parentNode ? 'null' : 'anchor';
- block.builders.mount.addLine(`${if_name}${name}.${mountOrIntro}(${initialMountNode}, ${anchorNode});`);
- const updateMountNode = this.getUpdateMountNode(anchor);
- const changeBlock = deindent `
- ${if_name}${name}.d(1);
- ${name} = ${current_block_type_and}${current_block_type}(#component, ctx);
- ${if_name}${name}.c();
- ${if_name}${name}.${mountOrIntro}(${updateMountNode}, ${anchor});
- `;
- if (dynamic) {
- block.builders.update.addBlock(deindent `
- if (${current_block_type} === (${current_block_type} = ${select_block_type}(ctx)) && ${name}) {
- ${name}.p(changed, ctx);
- } else {
- ${changeBlock}
- }
- `);
- }
- else {
- block.builders.update.addBlock(deindent `
- if (${current_block_type} !== (${current_block_type} = ${select_block_type}(ctx))) {
- ${changeBlock}
- }
- `);
- }
- block.builders.destroy.addLine(`${if_name}${name}.d(${parentNode ? '' : 'detach'});`);
- }
- // if any of the siblings have outros, we need to keep references to the blocks
- // (TODO does this only apply to bidi transitions?)
- renderCompoundWithOutros(block, parentNode, parentNodes, dynamic, { name, anchor, hasElse }) {
- const select_block_type = this.renderer.component.getUniqueName(`select_block_type`);
- const current_block_type_index = block.getUniqueName(`current_block_type_index`);
- const previous_block_index = block.getUniqueName(`previous_block_index`);
- const if_block_creators = block.getUniqueName(`if_block_creators`);
- const if_blocks = block.getUniqueName(`if_blocks`);
- const if_current_block_type_index = hasElse
- ? ''
- : `if (~${current_block_type_index}) `;
- block.addVariable(current_block_type_index);
- block.addVariable(name);
- block.builders.init.addBlock(deindent `
- var ${if_block_creators} = [
- ${this.branches.map(branch => branch.block.name).join(',\n')}
- ];
- var ${if_blocks} = [];
- function ${select_block_type}(ctx) {
- ${this.branches
- .map(({ condition }, i) => `${condition ? `if (${condition}) ` : ''}return ${i};`)
- .join('\n')}
- ${!hasElse && `return -1;`}
- }
- `);
- if (hasElse) {
- block.builders.init.addBlock(deindent `
- ${current_block_type_index} = ${select_block_type}(ctx);
- ${name} = ${if_blocks}[${current_block_type_index}] = ${if_block_creators}[${current_block_type_index}](#component, ctx);
- `);
- }
- else {
- block.builders.init.addBlock(deindent `
- if (~(${current_block_type_index} = ${select_block_type}(ctx))) {
- ${name} = ${if_blocks}[${current_block_type_index}] = ${if_block_creators}[${current_block_type_index}](#component, ctx);
- }
- `);
- }
- const mountOrIntro = this.branches[0].block.hasIntroMethod ? 'i' : 'm';
- const initialMountNode = parentNode || '#target';
- const anchorNode = parentNode ? 'null' : 'anchor';
- block.builders.mount.addLine(`${if_current_block_type_index}${if_blocks}[${current_block_type_index}].${mountOrIntro}(${initialMountNode}, ${anchorNode});`);
- const updateMountNode = this.getUpdateMountNode(anchor);
- const destroyOldBlock = deindent `
- @groupOutros();
- ${name}.o(function() {
- ${if_blocks}[${previous_block_index}].d(1);
- ${if_blocks}[${previous_block_index}] = null;
- });
- `;
- const createNewBlock = deindent `
- ${name} = ${if_blocks}[${current_block_type_index}];
- if (!${name}) {
- ${name} = ${if_blocks}[${current_block_type_index}] = ${if_block_creators}[${current_block_type_index}](#component, ctx);
- ${name}.c();
- }
- ${name}.${mountOrIntro}(${updateMountNode}, ${anchor});
- `;
- const changeBlock = hasElse
- ? deindent `
- ${destroyOldBlock}
- ${createNewBlock}
- `
- : deindent `
- if (${name}) {
- ${destroyOldBlock}
- }
- if (~${current_block_type_index}) {
- ${createNewBlock}
- } else {
- ${name} = null;
- }
- `;
- if (dynamic) {
- block.builders.update.addBlock(deindent `
- var ${previous_block_index} = ${current_block_type_index};
- ${current_block_type_index} = ${select_block_type}(ctx);
- if (${current_block_type_index} === ${previous_block_index}) {
- ${if_current_block_type_index}${if_blocks}[${current_block_type_index}].p(changed, ctx);
- } else {
- ${changeBlock}
- }
- `);
- }
- else {
- block.builders.update.addBlock(deindent `
- var ${previous_block_index} = ${current_block_type_index};
- ${current_block_type_index} = ${select_block_type}(ctx);
- if (${current_block_type_index} !== ${previous_block_index}) {
- ${changeBlock}
- }
- `);
- }
- block.builders.destroy.addLine(deindent `
- ${if_current_block_type_index}${if_blocks}[${current_block_type_index}].d(${parentNode ? '' : 'detach'});
- `);
- }
- renderSimple(block, parentNode, parentNodes, dynamic, { name, anchor, if_name }) {
- const branch = this.branches[0];
- block.builders.init.addBlock(deindent `
- var ${name} = (${branch.condition}) && ${branch.block.name}(#component, ctx);
- `);
- const mountOrIntro = branch.block.hasIntroMethod ? 'i' : 'm';
- const initialMountNode = parentNode || '#target';
- const anchorNode = parentNode ? 'null' : 'anchor';
- block.builders.mount.addLine(`if (${name}) ${name}.${mountOrIntro}(${initialMountNode}, ${anchorNode});`);
- const updateMountNode = this.getUpdateMountNode(anchor);
- const enter = dynamic
- ? (branch.block.hasIntroMethod || branch.block.hasOutroMethod)
- ? deindent `
- if (${name}) {
- ${name}.p(changed, ctx);
- } else {
- ${name} = ${branch.block.name}(#component, ctx);
- if (${name}) ${name}.c();
- }
- ${name}.i(${updateMountNode}, ${anchor});
- `
- : deindent `
- if (${name}) {
- ${name}.p(changed, ctx);
- } else {
- ${name} = ${branch.block.name}(#component, ctx);
- ${name}.c();
- ${name}.m(${updateMountNode}, ${anchor});
- }
- `
- : (branch.block.hasIntroMethod || branch.block.hasOutroMethod)
- ? deindent `
- if (!${name}) {
- ${name} = ${branch.block.name}(#component, ctx);
- ${name}.c();
- }
- ${name}.i(${updateMountNode}, ${anchor});
- `
- : deindent `
- if (!${name}) {
- ${name} = ${branch.block.name}(#component, ctx);
- ${name}.c();
- ${name}.m(${updateMountNode}, ${anchor});
- }
- `;
- // no `p()` here — we don't want to update outroing nodes,
- // as that will typically result in glitching
- const exit = branch.block.hasOutroMethod
- ? deindent `
- @groupOutros();
- ${name}.o(function() {
- ${name}.d(1);
- ${name} = null;
- });
- `
- : deindent `
- ${name}.d(1);
- ${name} = null;
- `;
- block.builders.update.addBlock(deindent `
- if (${branch.condition}) {
- ${enter}
- } else if (${name}) {
- ${exit}
- }
- `);
- block.builders.destroy.addLine(`${if_name}${name}.d(${parentNode ? '' : 'detach'});`);
- }
- }
- function stringifyProps(props) {
- if (!props.length)
- return '{}';
- const joined = props.join(', ');
- if (joined.length > 40) {
- // make larger data objects readable
- return `{\n\t${props.join(',\n\t')}\n}`;
- }
- return `{ ${joined} }`;
- }
- class InlineComponentWrapper extends Wrapper {
- constructor(renderer, block, parent, node, stripWhitespace, nextSibling) {
- super(renderer, block, parent, node);
- this.cannotUseInnerHTML();
- if (this.node.expression) {
- block.addDependencies(this.node.expression.dependencies);
- }
- this.node.attributes.forEach(attr => {
- block.addDependencies(attr.dependencies);
- });
- this.node.bindings.forEach(binding => {
- if (binding.isContextual) {
- // we need to ensure that the each block creates a context including
- // the list and the index, if they're not otherwise referenced
- const { name } = getObject(binding.value.node);
- const eachBlock = block.contextOwners.get(name);
- eachBlock.hasBinding = true;
- }
- block.addDependencies(binding.value.dependencies);
- });
- this.node.handlers.forEach(handler => {
- block.addDependencies(handler.dependencies);
- });
- this.var = (this.node.name === 'svelte:self' ? renderer.component.name :
- this.node.name === 'svelte:component' ? 'switch_instance' :
- this.node.name).toLowerCase();
- if (this.node.children.length) {
- this._slots = new Set(['default']);
- this.fragment = new FragmentWrapper(renderer, block, node.children, this, stripWhitespace, nextSibling);
- }
- if (renderer.component.options.nestedTransitions) {
- block.addOutro();
- }
- }
- render(block, parentNode, parentNodes) {
- const { renderer } = this;
- const { component } = renderer;
- const name = this.var;
- const componentInitProperties = [
- `root: #component.root`,
- `store: #component.store`
- ];
- if (this.fragment) {
- const slots = Array.from(this._slots).map(name => `${quoteNameIfNecessary(name)}: @createFragment()`);
- componentInitProperties.push(`slots: { ${slots.join(', ')} }`);
- this.fragment.nodes.forEach((child) => {
- child.render(block, `${this.var}._slotted.default`, 'nodes');
- });
- }
- const statements = [];
- const name_initial_data = block.getUniqueName(`${name}_initial_data`);
- const name_changes = block.getUniqueName(`${name}_changes`);
- let name_updating;
- let beforecreate = null;
- const updates = [];
- const usesSpread = !!this.node.attributes.find(a => a.isSpread);
- const attributeObject = usesSpread
- ? '{}'
- : stringifyProps(this.node.attributes.map(attr => `${quoteNameIfNecessary(attr.name)}: ${attr.getValue()}`));
- if (this.node.attributes.length || this.node.bindings.length) {
- componentInitProperties.push(`data: ${name_initial_data}`);
- }
- if (!usesSpread && (this.node.attributes.filter(a => a.isDynamic).length || this.node.bindings.length)) {
- updates.push(`var ${name_changes} = {};`);
- }
- if (this.node.attributes.length) {
- if (usesSpread) {
- const levels = block.getUniqueName(`${this.var}_spread_levels`);
- const initialProps = [];
- const changes = [];
- const allDependencies = new Set();
- this.node.attributes.forEach(attr => {
- addToSet(allDependencies, attr.dependencies);
- });
- this.node.attributes.forEach(attr => {
- const { name, dependencies } = attr;
- const condition = dependencies.size > 0 && (dependencies.size !== allDependencies.size)
- ? `(${[...dependencies].map(d => `changed.${d}`).join(' || ')})`
- : null;
- if (attr.isSpread) {
- const value = attr.expression.snippet;
- initialProps.push(value);
- changes.push(condition ? `${condition} && ${value}` : value);
- }
- else {
- const obj = `{ ${quoteNameIfNecessary(name)}: ${attr.getValue()} }`;
- initialProps.push(obj);
- changes.push(condition ? `${condition} && ${obj}` : obj);
- }
- });
- block.builders.init.addBlock(deindent `
- var ${levels} = [
- ${initialProps.join(',\n')}
- ];
- `);
- statements.push(deindent `
- for (var #i = 0; #i < ${levels}.length; #i += 1) {
- ${name_initial_data} = @assign(${name_initial_data}, ${levels}[#i]);
- }
- `);
- const conditions = [...allDependencies].map(dep => `changed.${dep}`).join(' || ');
- updates.push(deindent `
- var ${name_changes} = ${allDependencies.size === 1 ? `${conditions}` : `(${conditions})`} ? @getSpreadUpdate(${levels}, [
- ${changes.join(',\n')}
- ]) : {};
- `);
- }
- else {
- this.node.attributes
- .filter((attribute) => attribute.isDynamic)
- .forEach((attribute) => {
- if (attribute.dependencies.size > 0) {
- updates.push(deindent `
- if (${[...attribute.dependencies]
- .map(dependency => `changed.${dependency}`)
- .join(' || ')}) ${name_changes}${quotePropIfNecessary(attribute.name)} = ${attribute.getValue()};
- `);
- }
- });
- }
- }
- if (this.node.bindings.length) {
- renderer.hasComplexBindings = true;
- name_updating = block.alias(`${name}_updating`);
- block.addVariable(name_updating, '{}');
- let hasLocalBindings = false;
- let hasStoreBindings = false;
- const builder = new CodeBuilder();
- this.node.bindings.forEach((binding) => {
- let { name: key } = getObject(binding.value.node);
- let setFromChild;
- if (binding.isContextual) {
- const computed = isComputed(binding.value.node);
- const tail = binding.value.node.type === 'MemberExpression' ? getTailSnippet(binding.value.node) : '';
- const head = block.bindings.get(key);
- const lhs = binding.value.node.type === 'MemberExpression'
- ? binding.value.snippet
- : `${head()}${tail} = childState${quotePropIfNecessary(binding.name)}`;
- setFromChild = deindent `
- ${lhs} = childState${quotePropIfNecessary(binding.name)};
- ${[...binding.value.dependencies]
- .map((name) => {
- const isStoreProp = name[0] === '$';
- const prop = isStoreProp ? name.slice(1) : name;
- const newState = isStoreProp ? 'newStoreState' : 'newState';
- if (isStoreProp)
- hasStoreBindings = true;
- else
- hasLocalBindings = true;
- return `${newState}${quotePropIfNecessary(prop)} = ctx${quotePropIfNecessary(name)};`;
- })}
- `;
- }
- else {
- const isStoreProp = key[0] === '$';
- const prop = isStoreProp ? key.slice(1) : key;
- const newState = isStoreProp ? 'newStoreState' : 'newState';
- if (isStoreProp)
- hasStoreBindings = true;
- else
- hasLocalBindings = true;
- if (binding.value.node.type === 'MemberExpression') {
- setFromChild = deindent `
- ${binding.value.snippet} = childState${quotePropIfNecessary(binding.name)};
- ${newState}${quotePropIfNecessary(prop)} = ctx${quotePropIfNecessary(key)};
- `;
- }
- else {
- setFromChild = `${newState}${quotePropIfNecessary(prop)} = childState${quotePropIfNecessary(binding.name)};`;
- }
- }
- statements.push(deindent `
- if (${binding.value.snippet} !== void 0) {
- ${name_initial_data}${quotePropIfNecessary(binding.name)} = ${binding.value.snippet};
- ${name_updating}${quotePropIfNecessary(binding.name)} = true;
- }`);
- builder.addConditional(`!${name_updating}${quotePropIfNecessary(binding.name)} && changed${quotePropIfNecessary(binding.name)}`, setFromChild);
- updates.push(deindent `
- if (!${name_updating}${quotePropIfNecessary(binding.name)} && ${[...binding.value.dependencies].map((dependency) => `changed.${dependency}`).join(' || ')}) {
- ${name_changes}${quotePropIfNecessary(binding.name)} = ${binding.value.snippet};
- ${name_updating}${quotePropIfNecessary(binding.name)} = ${binding.value.snippet} !== void 0;
- }
- `);
- });
- block.maintainContext = true; // TODO put this somewhere more logical
- const initialisers = [
- hasLocalBindings && 'newState = {}',
- hasStoreBindings && 'newStoreState = {}',
- ].filter(Boolean).join(', ');
- // TODO use component.on('state', ...) instead of _bind
- componentInitProperties.push(deindent `
- _bind(changed, childState) {
- var ${initialisers};
- ${builder}
- ${hasStoreBindings && `#component.store.set(newStoreState);`}
- ${hasLocalBindings && `#component._set(newState);`}
- ${name_updating} = {};
- }
- `);
- beforecreate = deindent `
- #component.root._beforecreate.push(() => {
- ${name}._bind({ ${this.node.bindings.map(b => `${quoteNameIfNecessary(b.name)}: 1`).join(', ')} }, ${name}.get());
- });
- `;
- }
- this.node.handlers.forEach(handler => {
- handler.var = block.getUniqueName(`${this.var}_${handler.name}`); // TODO this is hacky
- handler.render(component, block, this.var, false); // TODO hoist when possible
- if (handler.usesContext)
- block.maintainContext = true; // TODO is there a better place to put this?
- });
- if (this.node.name === 'svelte:component') {
- const switch_value = block.getUniqueName('switch_value');
- const switch_props = block.getUniqueName('switch_props');
- const { snippet } = this.node.expression;
- block.builders.init.addBlock(deindent `
- var ${switch_value} = ${snippet};
- function ${switch_props}(ctx) {
- ${(this.node.attributes.length || this.node.bindings.length) && deindent `
- var ${name_initial_data} = ${attributeObject};`}
- ${statements}
- return {
- ${componentInitProperties.join(',\n')}
- };
- }
- if (${switch_value}) {
- var ${name} = new ${switch_value}(${switch_props}(ctx));
- ${beforecreate}
- }
- ${this.node.handlers.map(handler => deindent `
- function ${handler.var}(event) {
- ${handler.snippet || `#component.fire("${handler.name}", event);`}
- }
- if (${name}) ${name}.on("${handler.name}", ${handler.var});
- `)}
- `);
- block.builders.create.addLine(`if (${name}) ${name}._fragment.c();`);
- if (parentNodes) {
- block.builders.claim.addLine(`if (${name}) ${name}._fragment.l(${parentNodes});`);
- }
- block.builders.mount.addBlock(deindent `
- if (${name}) {
- ${name}._mount(${parentNode || '#target'}, ${parentNode ? 'null' : 'anchor'});
- ${this.node.ref && `#component.refs.${this.node.ref.name} = ${name};`}
- }
- `);
- const anchor = this.getOrCreateAnchor(block, parentNode, parentNodes);
- const updateMountNode = this.getUpdateMountNode(anchor);
- if (updates.length) {
- block.builders.update.addBlock(deindent `
- ${updates}
- `);
- }
- block.builders.update.addBlock(deindent `
- if (${switch_value} !== (${switch_value} = ${snippet})) {
- if (${name}) {
- ${component.options.nestedTransitions
- ? deindent `
- @groupOutros();
- const old_component = ${name};
- old_component._fragment.o(() => {
- old_component.destroy();
- });`
- : `${name}.destroy();`}
- }
- if (${switch_value}) {
- ${name} = new ${switch_value}(${switch_props}(ctx));
- ${this.node.bindings.length > 0 && deindent `
- #component.root._beforecreate.push(() => {
- const changed = {};
- ${this.node.bindings.map(binding => deindent `
- if (${binding.value.snippet} === void 0) changed.${binding.name} = 1;`)}
- ${name}._bind(changed, ${name}.get());
- });`}
- ${name}._fragment.c();
- ${this.fragment && this.fragment.nodes.map(child => child.remount(name))}
- ${name}._mount(${updateMountNode}, ${anchor});
- ${this.node.handlers.map(handler => deindent `
- ${name}.on("${handler.name}", ${handler.var});
- `)}
- ${this.node.ref && `#component.refs.${this.node.ref.name} = ${name};`}
- } else {
- ${name} = null;
- ${this.node.ref && deindent `
- if (#component.refs.${this.node.ref.name} === ${name}) {
- #component.refs.${this.node.ref.name} = null;
- }`}
- }
- }
- `);
- if (updates.length) {
- block.builders.update.addBlock(deindent `
- else if (${switch_value}) {
- ${name}._set(${name_changes});
- ${this.node.bindings.length && `${name_updating} = {};`}
- }
- `);
- }
- block.builders.destroy.addLine(`if (${name}) ${name}.destroy(${parentNode ? '' : 'detach'});`);
- }
- else {
- const expression = this.node.name === 'svelte:self'
- ? component.name
- : `%components-${this.node.name}`;
- block.builders.init.addBlock(deindent `
- ${(this.node.attributes.length || this.node.bindings.length) && deindent `
- var ${name_initial_data} = ${attributeObject};`}
- ${statements}
- var ${name} = new ${expression}({
- ${componentInitProperties.join(',\n')}
- });
- ${beforecreate}
- ${this.node.handlers.map(handler => deindent `
- ${name}.on("${handler.name}", function(event) {
- ${handler.snippet || `#component.fire("${handler.name}", event);`}
- });
- `)}
- ${this.node.ref && `#component.refs.${this.node.ref.name} = ${name};`}
- `);
- block.builders.create.addLine(`${name}._fragment.c();`);
- if (parentNodes) {
- block.builders.claim.addLine(`${name}._fragment.l(${parentNodes});`);
- }
- block.builders.mount.addLine(`${name}._mount(${parentNode || '#target'}, ${parentNode ? 'null' : 'anchor'});`);
- if (updates.length) {
- block.builders.update.addBlock(deindent `
- ${updates}
- ${name}._set(${name_changes});
- ${this.node.bindings.length && `${name_updating} = {};`}
- `);
- }
- block.builders.destroy.addLine(deindent `
- ${name}.destroy(${parentNode ? '' : 'detach'});
- ${this.node.ref && `if (#component.refs.${this.node.ref.name} === ${name}) #component.refs.${this.node.ref.name} = null;`}
- `);
- }
- if (component.options.nestedTransitions) {
- block.builders.outro.addLine(`if (${name}) ${name}._fragment.o(#outrocallback);`);
- }
- }
- remount(name) {
- return `${this.var}._mount(${name}._slotted.default, null);`;
- }
- }
- function isComputed(node) {
- while (node.type === 'MemberExpression') {
- if (node.computed)
- return true;
- node = node.object;
- }
- return false;
- }
- class Tag extends Wrapper {
- constructor(renderer, block, parent, node) {
- super(renderer, block, parent, node);
- this.cannotUseInnerHTML();
- block.addDependencies(node.expression.dependencies);
- }
- render(block, parentNode, parentNodes) {
- const { init } = this.renameThisMethod(block, value => `@setData(${this.var}, ${value});`);
- block.addElement(this.var, `@createText(${init})`, parentNodes && `@claimText(${parentNodes}, ${init})`, parentNode);
- }
- renameThisMethod(block, update) {
- const { snippet, dependencies } = this.node.expression;
- const value = this.node.shouldCache && block.getUniqueName(`${this.var}_value`);
- const content = this.node.shouldCache ? value : snippet;
- if (this.node.shouldCache)
- block.addVariable(value, snippet);
- if (dependencies.size) {
- const changedCheck = ((block.hasOutros ? `!#current || ` : '') +
- [...dependencies].map((dependency) => `changed.${dependency}`).join(' || '));
- const updateCachedValue = `${value} !== (${value} = ${snippet})`;
- const condition = this.node.shouldCache ?
- (dependencies.size ? `(${changedCheck}) && ${updateCachedValue}` : updateCachedValue) :
- changedCheck;
- block.builders.update.addConditional(condition, update(content));
- }
- return { init: content };
- }
- remount(name) {
- return `@append(${name}._slotted.default, ${this.var});`;
- }
- }
- class MustacheTagWrapper extends Tag {
- constructor(renderer, block, parent, node) {
- super(renderer, block, parent, node);
- this.var = 'text';
- this.cannotUseInnerHTML();
- }
- render(block, parentNode, parentNodes) {
- const { init } = this.renameThisMethod(block, value => `@setData(${this.var}, ${value});`);
- block.addElement(this.var, `@createText(${init})`, parentNodes && `@claimText(${parentNodes}, ${init})`, parentNode);
- }
- }
- class RawMustacheTagWrapper extends Tag {
- constructor(renderer, block, parent, node) {
- super(renderer, block, parent, node);
- this.var = 'raw';
- this.cannotUseInnerHTML();
- }
- render(block, parentNode, parentNodes) {
- const name = this.var;
- // TODO use isDomNode instead of type === 'Element'?
- const needsAnchorBefore = this.prev ? this.prev.node.type !== 'Element' : !parentNode;
- const needsAnchorAfter = this.next ? this.next.node.type !== 'Element' : !parentNode;
- const anchorBefore = needsAnchorBefore
- ? block.getUniqueName(`${name}_before`)
- : (this.prev && this.prev.var) || 'null';
- const anchorAfter = needsAnchorAfter
- ? block.getUniqueName(`${name}_after`)
- : (this.next && this.next.var) || 'null';
- let detach;
- let insert;
- let useInnerHTML = false;
- if (anchorBefore === 'null' && anchorAfter === 'null') {
- useInnerHTML = true;
- detach = `${parentNode}.innerHTML = '';`;
- insert = content => `${parentNode}.innerHTML = ${content};`;
- }
- else if (anchorBefore === 'null') {
- detach = `@detachBefore(${anchorAfter});`;
- insert = content => `${anchorAfter}.insertAdjacentHTML("beforebegin", ${content});`;
- }
- else if (anchorAfter === 'null') {
- detach = `@detachAfter(${anchorBefore});`;
- insert = content => `${anchorBefore}.insertAdjacentHTML("afterend", ${content});`;
- }
- else {
- detach = `@detachBetween(${anchorBefore}, ${anchorAfter});`;
- insert = content => `${anchorBefore}.insertAdjacentHTML("afterend", ${content});`;
- }
- const { init } = this.renameThisMethod(block, content => deindent `
- ${!useInnerHTML && detach}
- ${insert(content)}
- `);
- // we would have used comments here, but the `insertAdjacentHTML` api only
- // exists for `Element`s.
- if (needsAnchorBefore) {
- block.addElement(anchorBefore, `@createElement('noscript')`, parentNodes && `@createElement('noscript')`, parentNode, true);
- }
- function addAnchorAfter() {
- block.addElement(anchorAfter, `@createElement('noscript')`, parentNodes && `@createElement('noscript')`, parentNode);
- }
- if (needsAnchorAfter && anchorBefore === 'null') {
- // anchorAfter needs to be in the DOM before we
- // insert the HTML...
- addAnchorAfter();
- }
- block.builders.mount.addLine(insert(init));
- if (!parentNode) {
- block.builders.destroy.addConditional('detach', needsAnchorBefore
- ? `${detach}\n@detachNode(${anchorBefore});`
- : detach);
- }
- if (needsAnchorAfter && anchorBefore !== 'null') {
- // ...otherwise it should go afterwards
- addAnchorAfter();
- }
- }
- }
- function sanitize(name) {
- return name.replace(/[^a-zA-Z]+/g, '_').replace(/^_/, '').replace(/_$/, '');
- }
- class SlotWrapper extends Wrapper {
- constructor(renderer, block, parent, node, stripWhitespace, nextSibling) {
- super(renderer, block, parent, node);
- this.var = 'slot';
- this.cannotUseInnerHTML();
- this.fragment = new FragmentWrapper(renderer, block, node.children, parent, stripWhitespace, nextSibling);
- }
- render(block, parentNode, parentNodes) {
- const { renderer } = this;
- const slotName = this.node.getStaticAttributeValue('name') || 'default';
- renderer.slots.add(slotName);
- const content_name = block.getUniqueName(`slot_content_${sanitize(slotName)}`);
- const prop = quotePropIfNecessary(slotName);
- block.addVariable(content_name, `#component._slotted${prop}`);
- // TODO can we use isDomNode instead of type === 'Element'?
- const needsAnchorBefore = this.prev ? this.prev.node.type !== 'Element' : !parentNode;
- const needsAnchorAfter = this.next ? this.next.node.type !== 'Element' : !parentNode;
- const anchorBefore = needsAnchorBefore
- ? block.getUniqueName(`${content_name}_before`)
- : (this.prev && this.prev.var) || 'null';
- const anchorAfter = needsAnchorAfter
- ? block.getUniqueName(`${content_name}_after`)
- : (this.next && this.next.var) || 'null';
- if (needsAnchorBefore)
- block.addVariable(anchorBefore);
- if (needsAnchorAfter)
- block.addVariable(anchorAfter);
- let mountBefore = block.builders.mount.toString();
- let destroyBefore = block.builders.destroy.toString();
- block.builders.create.pushCondition(`!${content_name}`);
- block.builders.hydrate.pushCondition(`!${content_name}`);
- block.builders.mount.pushCondition(`!${content_name}`);
- block.builders.update.pushCondition(`!${content_name}`);
- block.builders.destroy.pushCondition(`!${content_name}`);
- this.fragment.render(block, parentNode, parentNodes);
- block.builders.create.popCondition();
- block.builders.hydrate.popCondition();
- block.builders.mount.popCondition();
- block.builders.update.popCondition();
- block.builders.destroy.popCondition();
- const mountLeadin = block.builders.mount.toString() !== mountBefore
- ? `else`
- : `if (${content_name})`;
- if (parentNode) {
- block.builders.mount.addBlock(deindent `
- ${mountLeadin} {
- ${needsAnchorBefore && `@append(${parentNode}, ${anchorBefore} || (${anchorBefore} = @createComment()));`}
- @append(${parentNode}, ${content_name});
- ${needsAnchorAfter && `@append(${parentNode}, ${anchorAfter} || (${anchorAfter} = @createComment()));`}
- }
- `);
- }
- else {
- block.builders.mount.addBlock(deindent `
- ${mountLeadin} {
- ${needsAnchorBefore && `@insert(#target, ${anchorBefore} || (${anchorBefore} = @createComment()), anchor);`}
- @insert(#target, ${content_name}, anchor);
- ${needsAnchorAfter && `@insert(#target, ${anchorAfter} || (${anchorAfter} = @createComment()), anchor);`}
- }
- `);
- }
- // if the slot is unmounted, move nodes back into the document fragment,
- // so that it can be reinserted later
- // TODO so that this can work with public API, component._slotted should
- // be all fragments, derived from options.slots. Not === options.slots
- const unmountLeadin = block.builders.destroy.toString() !== destroyBefore
- ? `else`
- : `if (${content_name})`;
- if (anchorBefore === 'null' && anchorAfter === 'null') {
- block.builders.destroy.addBlock(deindent `
- ${unmountLeadin} {
- @reinsertChildren(${parentNode}, ${content_name});
- }
- `);
- }
- else if (anchorBefore === 'null') {
- block.builders.destroy.addBlock(deindent `
- ${unmountLeadin} {
- @reinsertBefore(${anchorAfter}, ${content_name});
- }
- `);
- }
- else if (anchorAfter === 'null') {
- block.builders.destroy.addBlock(deindent `
- ${unmountLeadin} {
- @reinsertAfter(${anchorBefore}, ${content_name});
- }
- `);
- }
- else {
- block.builders.destroy.addBlock(deindent `
- ${unmountLeadin} {
- @reinsertBetween(${anchorBefore}, ${anchorAfter}, ${content_name});
- @detachNode(${anchorBefore});
- @detachNode(${anchorAfter});
- }
- `);
- }
- }
- }
- // Whitespace inside one of these elements will not result in
- // a whitespace node being created in any circumstances. (This
- // list is almost certainly very incomplete)
- const elementsWithoutText = new Set([
- 'audio',
- 'datalist',
- 'dl',
- 'optgroup',
- 'select',
- 'video',
- ]);
- // TODO this should probably be in Fragment
- function shouldSkip$1(node) {
- if (/\S/.test(node.data))
- return false;
- const parentElement = node.findNearest(/(?:Element|InlineComponent|Head)/);
- if (!parentElement)
- return false;
- if (parentElement.type === 'Head')
- return true;
- if (parentElement.type === 'InlineComponent')
- return parentElement.children.length === 1 && node === parentElement.children[0];
- return parentElement.namespace || elementsWithoutText.has(parentElement.name);
- }
- class TextWrapper extends Wrapper {
- constructor(renderer, block, parent, node, data) {
- super(renderer, block, parent, node);
- this.skip = shouldSkip$1(this.node);
- this.data = data;
- this.var = this.skip ? null : 'text';
- }
- render(block, parentNode, parentNodes) {
- if (this.skip)
- return;
- block.addElement(this.var, `@createText(${stringify(this.data)})`, parentNodes && `@claimText(${parentNodes}, ${stringify(this.data)})`, parentNode);
- }
- remount(name) {
- return `@append(${name}._slotted.default, ${this.var});`;
- }
- }
- class TitleWrapper extends Wrapper {
- constructor(renderer, block, parent, node, stripWhitespace, nextSibling) {
- super(renderer, block, parent, node);
- }
- render(block, parentNode, parentNodes) {
- const isDynamic = !!this.node.children.find(node => node.type !== 'Text');
- if (isDynamic) {
- let value;
- const allDependencies = new Set();
- // TODO some of this code is repeated in Tag.ts — would be good to
- // DRY it out if that's possible without introducing crazy indirection
- if (this.node.children.length === 1) {
- // single {tag} — may be a non-string
- const { expression } = this.node.children[0];
- const { dependencies, snippet } = this.node.children[0].expression;
- value = snippet;
- dependencies.forEach(d => {
- allDependencies.add(d);
- });
- }
- else {
- // '{foo} {bar}' — treat as string concatenation
- value =
- (this.node.children[0].type === 'Text' ? '' : `"" + `) +
- this.node.children
- .map((chunk) => {
- if (chunk.type === 'Text') {
- return stringify(chunk.data);
- }
- else {
- const { dependencies, snippet } = chunk.expression;
- dependencies.forEach(d => {
- allDependencies.add(d);
- });
- return chunk.expression.getPrecedence() <= 13 ? `(${snippet})` : snippet;
- }
- })
- .join(' + ');
- }
- const last = this.node.shouldCache && block.getUniqueName(`title_value`);
- if (this.node.shouldCache)
- block.addVariable(last);
- let updater;
- const init = this.node.shouldCache ? `${last} = ${value}` : value;
- block.builders.init.addLine(`document.title = ${init};`);
- updater = `document.title = ${this.node.shouldCache ? last : value};`;
- if (allDependencies.size) {
- const dependencies = Array.from(allDependencies);
- const changedCheck = ((block.hasOutros ? `!#current || ` : '') +
- dependencies.map(dependency => `changed.${dependency}`).join(' || '));
- const updateCachedValue = `${last} !== (${last} = ${value})`;
- const condition = this.node.shouldCache ?
- (dependencies.length ? `(${changedCheck}) && ${updateCachedValue}` : updateCachedValue) :
- changedCheck;
- block.builders.update.addConditional(condition, updater);
- }
- }
- else {
- const value = stringify(this.node.children[0].data);
- block.builders.hydrate.addLine(`document.title = ${value};`);
- }
- }
- }
- const associatedEvents = {
- innerWidth: 'resize',
- innerHeight: 'resize',
- outerWidth: 'resize',
- outerHeight: 'resize',
- scrollX: 'scroll',
- scrollY: 'scroll',
- };
- const properties = {
- scrollX: 'pageXOffset',
- scrollY: 'pageYOffset'
- };
- const readonly = new Set([
- 'innerWidth',
- 'innerHeight',
- 'outerWidth',
- 'outerHeight',
- 'online',
- ]);
- class WindowWrapper extends Wrapper {
- constructor(renderer, block, parent, node) {
- super(renderer, block, parent, node);
- }
- render(block, parentNode, parentNodes) {
- const { renderer } = this;
- const { component } = renderer;
- const events = {};
- const bindings = {};
- this.node.handlers.forEach(handler => {
- // TODO verify that it's a valid callee (i.e. built-in or declared method)
- component.addSourcemapLocations(handler.expression);
- const isCustomEvent = component.events.has(handler.name);
- let usesState = handler.dependencies.size > 0;
- handler.render(component, block, 'window', false); // TODO hoist?
- const handlerName = block.getUniqueName(`onwindow${handler.name}`);
- const handlerBody = deindent `
- ${usesState && `var ctx = #component.get();`}
- ${handler.snippet};
- `;
- if (isCustomEvent) {
- // TODO dry this out
- block.addVariable(handlerName);
- block.builders.hydrate.addBlock(deindent `
- ${handlerName} = %events-${handler.name}.call(#component, window, function(event) {
- ${handlerBody}
- });
- `);
- block.builders.destroy.addLine(deindent `
- ${handlerName}.destroy();
- `);
- }
- else {
- block.builders.init.addBlock(deindent `
- function ${handlerName}(event) {
- ${handlerBody}
- }
- window.addEventListener("${handler.name}", ${handlerName});
- `);
- block.builders.destroy.addBlock(deindent `
- window.removeEventListener("${handler.name}", ${handlerName});
- `);
- }
- });
- this.node.bindings.forEach(binding => {
- // in dev mode, throw if read-only values are written to
- if (readonly.has(binding.name)) {
- renderer.readonly.add(binding.value.node.name);
- }
- bindings[binding.name] = binding.value.node.name;
- // bind:online is a special case, we need to listen for two separate events
- if (binding.name === 'online')
- return;
- const associatedEvent = associatedEvents[binding.name];
- const property = properties[binding.name] || binding.name;
- if (!events[associatedEvent])
- events[associatedEvent] = [];
- events[associatedEvent].push({
- name: binding.value.node.name,
- value: property
- });
- });
- const lock = block.getUniqueName(`window_updating`);
- const clear = block.getUniqueName(`clear_window_updating`);
- const timeout = block.getUniqueName(`window_updating_timeout`);
- Object.keys(events).forEach(event => {
- const handlerName = block.getUniqueName(`onwindow${event}`);
- const props = events[event];
- if (event === 'scroll') {
- // TODO other bidirectional bindings...
- block.addVariable(lock, 'false');
- block.addVariable(clear, `function() { ${lock} = false; }`);
- block.addVariable(timeout);
- const condition = [
- bindings.scrollX && `"${bindings.scrollX}" in this._state`,
- bindings.scrollY && `"${bindings.scrollY}" in this._state`
- ].filter(Boolean).join(' || ');
- const x = bindings.scrollX && `this._state.${bindings.scrollX}`;
- const y = bindings.scrollY && `this._state.${bindings.scrollY}`;
- renderer.metaBindings.addBlock(deindent `
- if (${condition}) {
- window.scrollTo(${x || 'window.pageXOffset'}, ${y || 'window.pageYOffset'});
- }
- ${x && `${x} = window.pageXOffset;`}
- ${y && `${y} = window.pageYOffset;`}
- `);
- }
- else {
- props.forEach(prop => {
- renderer.metaBindings.addLine(`this._state.${prop.name} = window.${prop.value};`);
- });
- }
- const handlerBody = deindent `
- ${event === 'scroll' && deindent `
- if (${lock}) return;
- ${lock} = true;
- `}
- ${component.options.dev && `component._updatingReadonlyProperty = true;`}
- #component.set({
- ${props.map(prop => `${prop.name}: this.${prop.value}`)}
- });
- ${component.options.dev && `component._updatingReadonlyProperty = false;`}
- ${event === 'scroll' && `${lock} = false;`}
- `;
- block.builders.init.addBlock(deindent `
- function ${handlerName}(event) {
- ${handlerBody}
- }
- window.addEventListener("${event}", ${handlerName});
- `);
- block.builders.destroy.addBlock(deindent `
- window.removeEventListener("${event}", ${handlerName});
- `);
- });
- // special case... might need to abstract this out if we add more special cases
- if (bindings.scrollX || bindings.scrollY) {
- block.builders.init.addBlock(deindent `
- #component.on("state", ({ changed, current }) => {
- if (${[bindings.scrollX, bindings.scrollY].map(binding => binding && `changed["${binding}"]`).filter(Boolean).join(' || ')} && !${lock}) {
- ${lock} = true;
- clearTimeout(${timeout});
- window.scrollTo(${bindings.scrollX ? `current["${bindings.scrollX}"]` : `window.pageXOffset`}, ${bindings.scrollY ? `current["${bindings.scrollY}"]` : `window.pageYOffset`});
- ${timeout} = setTimeout(${clear}, 100);
- }
- });
- `);
- }
- // another special case. (I'm starting to think these are all special cases.)
- if (bindings.online) {
- const handlerName = block.getUniqueName(`onlinestatuschanged`);
- block.builders.init.addBlock(deindent `
- function ${handlerName}(event) {
- ${component.options.dev && `component._updatingReadonlyProperty = true;`}
- #component.set({ ${bindings.online}: navigator.onLine });
- ${component.options.dev && `component._updatingReadonlyProperty = false;`}
- }
- window.addEventListener("online", ${handlerName});
- window.addEventListener("offline", ${handlerName});
- `);
- // add initial value
- renderer.metaBindings.addLine(`this._state.${bindings.online} = navigator.onLine;`);
- block.builders.destroy.addBlock(deindent `
- window.removeEventListener("online", ${handlerName});
- window.removeEventListener("offline", ${handlerName});
- `);
- }
- }
- }
- const wrappers = {
- AwaitBlock: AwaitBlockWrapper,
- Comment: null,
- Document: DocumentWrapper,
- DebugTag: DebugTagWrapper,
- EachBlock: EachBlockWrapper,
- Element: ElementWrapper,
- Head: HeadWrapper,
- IfBlock: IfBlockWrapper,
- InlineComponent: InlineComponentWrapper,
- MustacheTag: MustacheTagWrapper,
- RawMustacheTag: RawMustacheTagWrapper,
- Slot: SlotWrapper,
- Text: TextWrapper,
- Title: TitleWrapper,
- Window: WindowWrapper
- };
- function link(next, prev) {
- prev.next = next;
- if (next)
- next.prev = prev;
- }
- class FragmentWrapper {
- constructor(renderer, block, nodes, parent, stripWhitespace, nextSibling) {
- this.nodes = [];
- let lastChild;
- let windowWrapper;
- let i = nodes.length;
- while (i--) {
- const child = nodes[i];
- if (!(child.type in wrappers)) {
- throw new Error(`TODO implement ${child.type}`);
- }
- // special case — this is an easy way to remove whitespace surrounding
- // <svelte:window/>. lil hacky but it works
- if (child.type === 'Window') {
- windowWrapper = new WindowWrapper(renderer, block, parent, child);
- continue;
- }
- if (child.type === 'Text') {
- let { data } = child;
- // We want to remove trailing whitespace inside an element/component/block,
- // *unless* there is no whitespace between this node and its next sibling
- if (this.nodes.length === 0) {
- const shouldTrim = (nextSibling ? (nextSibling.node.type === 'Text' && /^\s/.test(nextSibling.data)) : !child.hasAncestor('EachBlock'));
- if (shouldTrim) {
- data = trimEnd(data);
- if (!data)
- continue;
- }
- }
- // glue text nodes (which could e.g. be separated by comments) together
- if (lastChild && lastChild.node.type === 'Text') {
- lastChild.data = data + lastChild.data;
- continue;
- }
- const wrapper = new TextWrapper(renderer, block, parent, child, data);
- if (wrapper.skip)
- continue;
- this.nodes.unshift(wrapper);
- link(lastChild, lastChild = wrapper);
- }
- else {
- const Wrapper = wrappers[child.type];
- if (!Wrapper)
- continue;
- const wrapper = new Wrapper(renderer, block, parent, child, stripWhitespace, lastChild || nextSibling);
- this.nodes.unshift(wrapper);
- link(lastChild, lastChild = wrapper);
- }
- }
- if (stripWhitespace) {
- const first = this.nodes[0];
- if (first && first.node.type === 'Text') {
- first.data = trimStart(first.data);
- if (!first.data) {
- first.var = null;
- this.nodes.shift();
- if (this.nodes[0]) {
- this.nodes[0].prev = null;
- }
- }
- }
- }
- if (windowWrapper) {
- this.nodes.unshift(windowWrapper);
- link(lastChild, windowWrapper);
- }
- }
- render(block, parentNode, parentNodes) {
- for (let i = 0; i < this.nodes.length; i += 1) {
- this.nodes[i].render(block, parentNode, parentNodes);
- }
- }
- }
- class Renderer {
- constructor(component, options) {
- this.component = component;
- this.options = options;
- this.locate = component.locate; // TODO messy
- this.readonly = new Set();
- this.slots = new Set();
- this.usedNames = new Set();
- this.fileVar = options.dev && this.component.getUniqueName('file');
- // initial values for e.g. window.innerWidth, if there's a <svelte:window> meta tag
- this.metaBindings = new CodeBuilder();
- this.bindingGroups = [];
- // main block
- this.block = new Block$1({
- renderer: this,
- name: '@create_main_fragment',
- key: null,
- bindings: new Map(),
- contextOwners: new Map(),
- dependencies: new Set(),
- });
- this.block.hasUpdateMethod = true;
- this.blocks = [];
- this.fragment = new FragmentWrapper(this, this.block, component.fragment.children, null, true, null);
- this.blocks.push(this.block);
- this.blocks.forEach(block => {
- if (typeof block !== 'string') {
- block.assignVariableNames();
- }
- });
- this.fragment.render(this.block, null, 'nodes');
- }
- }
- function dom(component, options) {
- const format = options.format || 'es';
- const { computations, name, templateProperties } = component;
- const renderer = new Renderer(component, options);
- const { block } = renderer;
- if (component.options.nestedTransitions) {
- block.hasOutroMethod = true;
- }
- // prevent fragment being created twice (#1063)
- if (options.customElement)
- block.builders.create.addLine(`this.c = @noop;`);
- const builder = new CodeBuilder();
- const computationBuilder = new CodeBuilder();
- const computationDeps = new Set();
- if (computations.length) {
- computations.forEach(({ key, deps, hasRestParam }) => {
- if (renderer.readonly.has(key)) {
- // <svelte:window> bindings
- throw new Error(`Cannot have a computed value '${key}' that clashes with a read-only property`);
- }
- renderer.readonly.add(key);
- if (deps) {
- deps.forEach(dep => {
- computationDeps.add(dep);
- });
- const condition = `${deps.map(dep => `changed.${dep}`).join(' || ')}`;
- const statement = `if (this._differs(state.${key}, (state.${key} = %computed-${key}(state)))) changed.${key} = true;`;
- computationBuilder.addConditional(condition, statement);
- }
- else {
- // computed property depends on entire state object —
- // these must go at the end
- computationBuilder.addLine(`if (this._differs(state.${key}, (state.${key} = %computed-${key}(@exclude(state, "${key}"))))) changed.${key} = true;`);
- }
- });
- }
- if (component.javascript) {
- const componentDefinition = new CodeBuilder();
- component.declarations.forEach(declaration => {
- componentDefinition.addBlock(declaration.block);
- });
- const js = (component.javascript[0] +
- componentDefinition +
- component.javascript[1]);
- builder.addBlock(js);
- }
- if (component.options.dev) {
- builder.addLine(`const ${renderer.fileVar} = ${JSON.stringify(component.file)};`);
- }
- const css = component.stylesheet.render(options.filename, !component.customElement);
- const styles = component.stylesheet.hasStyles && stringify(options.dev ?
- `${css.code}\n/*# sourceMappingURL=${css.map.toUrl()} */` :
- css.code, { onlyEscapeAtSymbol: true });
- if (styles && component.options.css !== false && !component.customElement) {
- builder.addBlock(deindent `
- function @add_css() {
- var style = @createElement("style");
- style.id = '${component.stylesheet.id}-style';
- style.textContent = ${styles};
- @append(document.head, style);
- }
- `);
- }
- // fix order
- // TODO the deconflicted names of blocks are reversed... should set them here
- const blocks = renderer.blocks.slice().reverse();
- blocks.forEach(block => {
- builder.addBlock(block.toString());
- });
- const sharedPath = options.shared === true
- ? 'svelte/shared.js'
- : options.shared || '';
- const proto = sharedPath
- ? `@proto`
- : deindent `
- {
- ${['destroy', 'get', 'fire', 'on', 'set', '_set', '_stage', '_mount', '_differs']
- .map(n => `${n}: @${n}`)
- .join(',\n')}
- }`;
- const debugName = `<${component.customElement ? component.tag : name}>`;
- // generate initial state object
- const expectedProperties = Array.from(component.expectedProperties);
- const globals = expectedProperties.filter(prop => globalWhitelist.has(prop));
- const storeProps = expectedProperties.filter(prop => prop[0] === '$');
- const initialState = [];
- if (globals.length > 0) {
- initialState.push(`{ ${globals.map(prop => `${prop} : ${prop}`).join(', ')} }`);
- }
- if (storeProps.length > 0) {
- initialState.push(`this.store._init([${storeProps.map(prop => `"${prop.slice(1)}"`)}])`);
- }
- if (templateProperties.data) {
- initialState.push(`%data()`);
- }
- else if (globals.length === 0 && storeProps.length === 0) {
- initialState.push('{}');
- }
- initialState.push(`options.data`);
- const hasInitHooks = !!(templateProperties.oncreate || templateProperties.onstate || templateProperties.onupdate);
- const constructorBody = deindent `
- ${options.dev && deindent `
- this._debugName = '${debugName}';
- ${!component.customElement && deindent `
- if (!options || (!options.target && !options.root)) {
- throw new Error("'target' is a required option");
- }`}
- ${storeProps.length > 0 && !templateProperties.store && deindent `
- if (!options.store) {
- throw new Error("${debugName} references store properties, but no store was provided");
- }`}
- `}
- @init(this, options);
- ${templateProperties.store && `this.store = %store();`}
- ${component.refs.size > 0 && `this.refs = {};`}
- this._state = ${initialState.reduce((state, piece) => `@assign(${state}, ${piece})`)};
- ${storeProps.length > 0 && `this.store._add(this, [${storeProps.map(prop => `"${prop.slice(1)}"`)}]);`}
- ${renderer.metaBindings}
- ${computations.length && `this._recompute({ ${Array.from(computationDeps).map(dep => `${dep}: 1`).join(', ')} }, this._state);`}
- ${options.dev &&
- Array.from(component.expectedProperties).map(prop => {
- if (globalWhitelist.has(prop))
- return;
- if (computations.find(c => c.key === prop))
- return;
- const message = component.components.has(prop) ?
- `${debugName} expected to find '${prop}' in \`data\`, but found it in \`components\` instead` :
- `${debugName} was created without expected data property '${prop}'`;
- const conditions = [`!('${prop}' in this._state)`];
- if (component.customElement)
- conditions.push(`!('${prop}' in this.attributes)`);
- return `if (${conditions.join(' && ')}) console.warn("${message}");`;
- })}
- ${renderer.bindingGroups.length &&
- `this._bindingGroups = [${Array(renderer.bindingGroups.length).fill('[]').join(', ')}];`}
- this._intro = ${component.options.skipIntroByDefault ? '!!options.intro' : 'true'};
- ${templateProperties.onstate && `this._handlers.state = [%onstate];`}
- ${templateProperties.onupdate && `this._handlers.update = [%onupdate];`}
- ${(templateProperties.ondestroy || storeProps.length) && (`this._handlers.destroy = [${[templateProperties.ondestroy && `%ondestroy`, storeProps.length && `@removeFromStore`].filter(Boolean).join(', ')}];`)}
- ${renderer.slots.size && `this._slotted = options.slots || {};`}
- ${component.customElement ?
- deindent `
- this.attachShadow({ mode: 'open' });
- ${css.code && `this.shadowRoot.innerHTML = \`<style>${escape$1(css.code, { onlyEscapeAtSymbol: true }).replace(/\\/g, '\\\\')}${options.dev ? `\n/*# sourceMappingURL=${css.map.toUrl()} */` : ''}</style>\`;`}
- ` :
- (component.stylesheet.hasStyles && options.css !== false &&
- `if (!document.getElementById("${component.stylesheet.id}-style")) @add_css();`)}
- ${templateProperties.onstate && `%onstate.call(this, { changed: @assignTrue({}, this._state), current: this._state });`}
- this._fragment = @create_main_fragment(this, this._state);
- ${hasInitHooks && deindent `
- this.root._oncreate.push(() => {
- ${templateProperties.oncreate && `%oncreate.call(this);`}
- this.fire("update", { changed: @assignTrue({}, this._state), current: this._state });
- });
- `}
- ${component.customElement ? deindent `
- this._fragment.c();
- this._fragment.${block.hasIntroMethod ? 'i' : 'm'}(this.shadowRoot, null);
- if (options.target) this._mount(options.target, options.anchor);
- ` : deindent `
- if (options.target) {
- ${component.options.hydratable
- ? deindent `
- var nodes = @children(options.target);
- options.hydrate ? this._fragment.l(nodes) : this._fragment.c();
- nodes.forEach(@detachNode);` :
- deindent `
- ${options.dev &&
- `if (options.hydrate) throw new Error("options.hydrate only works if the component was compiled with the \`hydratable: true\` option");`}
- this._fragment.c();`}
- this._mount(options.target, options.anchor);
- ${(component.hasComponents || renderer.hasComplexBindings || hasInitHooks || renderer.hasIntroTransitions) &&
- `@flush(this);`}
- }
- `}
- ${component.options.skipIntroByDefault && `this._intro = true;`}
- `;
- if (component.customElement) {
- const props = component.props || Array.from(component.expectedProperties);
- builder.addBlock(deindent `
- class ${name} extends HTMLElement {
- constructor(options = {}) {
- super();
- ${constructorBody}
- }
- static get observedAttributes() {
- return ${JSON.stringify(props)};
- }
- ${props.map(prop => deindent `
- get ${prop}() {
- return this.get().${prop};
- }
- set ${prop}(value) {
- this.set({ ${prop}: value });
- }
- `).join('\n\n')}
- ${renderer.slots.size && deindent `
- connectedCallback() {
- Object.keys(this._slotted).forEach(key => {
- this.appendChild(this._slotted[key]);
- });
- }`}
- attributeChangedCallback(attr, oldValue, newValue) {
- this.set({ [attr]: newValue });
- }
- ${(component.hasComponents || renderer.hasComplexBindings || templateProperties.oncreate || renderer.hasIntroTransitions) && deindent `
- connectedCallback() {
- @flush(this);
- }
- `}
- }
- @assign(${name}.prototype, ${proto});
- ${templateProperties.methods && `@assign(${name}.prototype, %methods);`}
- @assign(${name}.prototype, {
- _mount(target, anchor) {
- target.insertBefore(this, anchor);
- }
- });
- customElements.define("${component.tag}", ${name});
- `);
- }
- else {
- builder.addBlock(deindent `
- function ${name}(options) {
- ${constructorBody}
- }
- @assign(${name}.prototype, ${proto});
- ${templateProperties.methods && `@assign(${name}.prototype, %methods);`}
- `);
- }
- const immutable = templateProperties.immutable ? templateProperties.immutable.value.value : options.immutable;
- builder.addBlock(deindent `
- ${options.dev && deindent `
- ${name}.prototype._checkReadOnly = function _checkReadOnly(newState) {
- ${Array.from(renderer.readonly).map(prop => `if ('${prop}' in newState && !this._updatingReadonlyProperty) throw new Error("${debugName}: Cannot set read-only property '${prop}'");`)}
- };
- `}
- ${computations.length ? deindent `
- ${name}.prototype._recompute = function _recompute(changed, state) {
- ${computationBuilder}
- }
- ` : (!sharedPath && `${name}.prototype._recompute = @noop;`)}
- ${templateProperties.setup && `%setup(${name});`}
- ${templateProperties.preload && `${name}.preload = %preload;`}
- ${immutable && `${name}.prototype._differs = @_differsImmutable;`}
- `);
- let result = builder.toString();
- return component.generate(result, options, {
- banner: `/* ${component.file ? `${component.file} ` : ``}generated by Svelte v${"2.15.3"} */`,
- sharedPath,
- name,
- format,
- });
- }
- function AwaitBlock (node, renderer, options) {
- const { snippet } = node.expression;
- renderer.append('${(function(__value) { if(@isPromise(__value)) return `');
- renderer.render(node.pending.children, options);
- renderer.append('`; return function(ctx) { return `');
- renderer.render(node.then.children, options);
- renderer.append(`\`;}(Object.assign({}, ctx, { ${node.value}: __value }));}(${snippet})) }`);
- }
- function Comment$1 (node, renderer, options) {
- if (options.preserveComments) {
- renderer.append(`<!--${node.data}-->`);
- }
- }
- function DebugTag (node, renderer, options) {
- if (!options.dev)
- return;
- const filename = options.file || null;
- const { line, column } = options.locate(node.start + 1);
- const obj = node.expressions.length === 0
- ? `ctx`
- : `{ ${node.expressions
- .map(e => e.node.name)
- .map(name => `${name}: ctx.${name}`)
- .join(', ')} }`;
- const str = '${@debug(' + `${filename && stringify(filename)}, ${line}, ${column}, ${obj})}`;
- renderer.append(str);
- }
- function EachBlock (node, renderer, options) {
- const { snippet } = node.expression;
- const props = node.contexts.map(prop => `${prop.key.name}: item${prop.tail}`);
- const getContext = node.index
- ? `(item, i) => Object.assign({}, ctx, { ${props.join(', ')}, ${node.index}: i })`
- : `item => Object.assign({}, ctx, { ${props.join(', ')} })`;
- const open = `\${ ${node.else ? `${snippet}.length ? ` : ''}@each(${snippet}, ${getContext}, ctx => \``;
- renderer.append(open);
- renderer.render(node.children, options);
- const close = `\`)`;
- renderer.append(close);
- if (node.else) {
- renderer.append(` : \``);
- renderer.render(node.else.children, options);
- renderer.append(`\``);
- }
- renderer.append('}');
- }
- // source: https://gist.github.com/ArjanSchouten/0b8574a6ad7f5065a5e7
- const boolean_attributes = new Set([
- 'async',
- 'autocomplete',
- 'autofocus',
- 'autoplay',
- 'border',
- 'challenge',
- 'checked',
- 'compact',
- 'contenteditable',
- 'controls',
- 'default',
- 'defer',
- 'disabled',
- 'formnovalidate',
- 'frameborder',
- 'hidden',
- 'indeterminate',
- 'ismap',
- 'loop',
- 'multiple',
- 'muted',
- 'nohref',
- 'noresize',
- 'noshade',
- 'novalidate',
- 'nowrap',
- 'open',
- 'readonly',
- 'required',
- 'reversed',
- 'scoped',
- 'scrolling',
- 'seamless',
- 'selected',
- 'sortable',
- 'spellcheck',
- 'translate'
- ]);
- function Element (node, renderer, options) {
- let openingTag = `<${node.name}`;
- let textareaContents; // awkward special case
- const slot = node.getStaticAttributeValue('slot');
- if (slot && node.hasAncestor('InlineComponent')) {
- const slot = node.attributes.find((attribute) => attribute.name === 'slot');
- const slotName = slot.chunks[0].data;
- const target = renderer.targets[renderer.targets.length - 1];
- target.slotStack.push(slotName);
- target.slots[slotName] = '';
- }
- const classExpr = node.classes.map((classDir) => {
- const { expression, name } = classDir;
- const snippet = expression ? expression.snippet : `ctx${quotePropIfNecessary(name)}`;
- return `${snippet} ? "${name}" : ""`;
- }).join(', ');
- let addClassAttribute = classExpr ? true : false;
- if (node.attributes.find(attr => attr.isSpread)) {
- // TODO dry this out
- const args = [];
- node.attributes.forEach(attribute => {
- if (attribute.isSpread) {
- args.push(attribute.expression.snippet);
- }
- else {
- if (attribute.name === 'value' && node.name === 'textarea') {
- textareaContents = stringifyAttribute(attribute);
- }
- else if (attribute.isTrue) {
- args.push(`{ ${quoteNameIfNecessary(attribute.name)}: true }`);
- }
- else if (boolean_attributes.has(attribute.name) &&
- attribute.chunks.length === 1 &&
- attribute.chunks[0].type !== 'Text') {
- // a boolean attribute with one non-Text chunk
- args.push(`{ ${quoteNameIfNecessary(attribute.name)}: ${attribute.chunks[0].snippet} }`);
- }
- else {
- args.push(`{ ${quoteNameIfNecessary(attribute.name)}: \`${stringifyAttribute(attribute)}\` }`);
- }
- }
- });
- openingTag += "${@spread([" + args.join(', ') + "])}";
- }
- else {
- node.attributes.forEach((attribute) => {
- if (attribute.type !== 'Attribute')
- return;
- if (attribute.name === 'value' && node.name === 'textarea') {
- textareaContents = stringifyAttribute(attribute);
- }
- else if (attribute.isTrue) {
- openingTag += ` ${attribute.name}`;
- }
- else if (boolean_attributes.has(attribute.name) &&
- attribute.chunks.length === 1 &&
- attribute.chunks[0].type !== 'Text') {
- // a boolean attribute with one non-Text chunk
- openingTag += '${' + attribute.chunks[0].snippet + ' ? " ' + attribute.name + '" : "" }';
- }
- else if (attribute.name === 'class' && classExpr) {
- addClassAttribute = false;
- openingTag += ` class="\${[\`${stringifyAttribute(attribute)}\`, ${classExpr}].join(' ').trim() }"`;
- }
- else if (attribute.chunks.length === 1 && attribute.chunks[0].type !== 'Text') {
- const { name } = attribute;
- const { snippet } = attribute.chunks[0];
- openingTag += '${(v => v == null ? "" : ` ' + name + '="${@escape(' + snippet + ')}"`)(' + snippet + ')}';
- }
- else {
- openingTag += ` ${attribute.name}="${stringifyAttribute(attribute)}"`;
- }
- });
- }
- node.bindings.forEach(binding => {
- const { name, value: { snippet } } = binding;
- if (name === 'group') ;
- else {
- openingTag += ' ${(v => v ? ("' + name + '" + (v === true ? "" : "=" + JSON.stringify(v))) : "")(' + snippet + ')}';
- }
- });
- if (addClassAttribute) {
- openingTag += `\${((v) => v ? ' class="' + v + '"' : '')([${classExpr}].join(' ').trim())}`;
- }
- openingTag += '>';
- renderer.append(openingTag);
- if (node.name === 'textarea' && textareaContents !== undefined) {
- renderer.append(textareaContents);
- }
- else {
- renderer.render(node.children, options);
- }
- if (!isVoidElementName(node.name)) {
- renderer.append(`</${node.name}>`);
- }
- }
- function stringifyAttribute(attribute) {
- return attribute.chunks
- .map((chunk) => {
- if (chunk.type === 'Text') {
- return escapeTemplate(escape$1(chunk.data).replace(/"/g, '"'));
- }
- return '${@escape(' + chunk.snippet + ')}';
- })
- .join('');
- }
- function Head (node, renderer, options) {
- renderer.append('${(__result.head += `');
- renderer.render(node.children, options);
- renderer.append('`, "")}');
- }
- function HtmlTag (node, renderer, options) {
- renderer.append('${' + node.expression.snippet + '}');
- }
- function IfBlock (node, renderer, options) {
- const { snippet } = node.expression;
- renderer.append('${ ' + snippet + ' ? `');
- renderer.render(node.children, options);
- renderer.append('` : `');
- if (node.else) {
- renderer.render(node.else.children, options);
- }
- renderer.append('` }');
- }
- function InlineComponent (node, renderer, options) {
- function stringifyAttribute(chunk) {
- if (chunk.type === 'Text') {
- return escapeTemplate(escape$1(chunk.data));
- }
- return '${@escape( ' + chunk.snippet + ')}';
- }
- const bindingProps = node.bindings.map(binding => {
- const { name } = getObject(binding.value.node);
- const tail = binding.value.node.type === 'MemberExpression'
- ? getTailSnippet(binding.value.node)
- : '';
- return `${quoteNameIfNecessary(binding.name)}: ctx${quotePropIfNecessary(name)}${tail}`;
- });
- function getAttributeValue(attribute) {
- if (attribute.isTrue)
- return `true`;
- if (attribute.chunks.length === 0)
- return `''`;
- if (attribute.chunks.length === 1) {
- const chunk = attribute.chunks[0];
- if (chunk.type === 'Text') {
- return stringify(chunk.data);
- }
- return chunk.snippet;
- }
- return '`' + attribute.chunks.map(stringifyAttribute).join('') + '`';
- }
- const usesSpread = node.attributes.find(attr => attr.isSpread);
- const props = usesSpread
- ? `Object.assign(${node.attributes
- .map(attribute => {
- if (attribute.isSpread) {
- return attribute.expression.snippet;
- }
- else {
- return `{ ${quoteNameIfNecessary(attribute.name)}: ${getAttributeValue(attribute)} }`;
- }
- })
- .concat(bindingProps.map(p => `{ ${p} }`))
- .join(', ')})`
- : `{ ${node.attributes
- .map(attribute => `${quoteNameIfNecessary(attribute.name)}: ${getAttributeValue(attribute)}`)
- .concat(bindingProps)
- .join(', ')} }`;
- const expression = (node.name === 'svelte:self'
- ? node.component.name
- : node.name === 'svelte:component'
- ? `((${node.expression.snippet}) || @missingComponent)`
- : `%components-${node.name}`);
- node.bindings.forEach(binding => {
- const conditions = [];
- let parent = node;
- while (parent = parent.parent) {
- if (parent.type === 'IfBlock') {
- // TODO handle contextual bindings...
- conditions.push(`(${parent.expression.snippet})`);
- }
- }
- conditions.push(`!('${binding.name}' in ctx)`, `${expression}.data`);
- const { name } = getObject(binding.value.node);
- renderer.bindings.push(deindent `
- if (${conditions.reverse().join('&&')}) {
- tmp = ${expression}.data();
- if ('${name}' in tmp) {
- ctx${quotePropIfNecessary(binding.name)} = tmp.${name};
- settled = false;
- }
- }
- `);
- });
- let open = `\${@validateSsrComponent(${expression}, '${node.name}')._render(__result, ${props}`;
- const component_options = [];
- component_options.push(`store: options.store`);
- if (node.children.length) {
- const target = {
- slots: { default: '' },
- slotStack: ['default']
- };
- renderer.targets.push(target);
- renderer.render(node.children, options);
- const slotted = Object.keys(target.slots)
- .map(name => `${quoteNameIfNecessary(name)}: () => \`${target.slots[name]}\``)
- .join(', ');
- component_options.push(`slotted: { ${slotted} }`);
- renderer.targets.pop();
- }
- if (component_options.length) {
- open += `, { ${component_options.join(', ')} }`;
- }
- renderer.append(open);
- renderer.append(')}');
- }
- function Slot (node, renderer, options) {
- const name = node.attributes.find(attribute => attribute.name === 'name');
- const slotName = name && name.chunks[0].data || 'default';
- const prop = quotePropIfNecessary(slotName);
- renderer.append(`\${options && options.slotted && options.slotted${prop} ? options.slotted${prop}() : \``);
- renderer.render(node.children, options);
- renderer.append(`\`}`);
- }
- function Tag$1 (node, renderer, options) {
- renderer.append(node.parent &&
- node.parent.type === 'Element' &&
- node.parent.name === 'style'
- ? '${' + node.expression.snippet + '}'
- : '${@escape(' + node.expression.snippet + ')}');
- }
- function Text$1 (node, renderer, options) {
- let text = node.data;
- if (!node.parent ||
- node.parent.type !== 'Element' ||
- (node.parent.name !== 'script' && node.parent.name !== 'style')) {
- // unless this Text node is inside a <script> or <style> element, escape &,<,>
- text = escapeHTML(text);
- }
- renderer.append(escape$1(escapeTemplate(text)));
- }
- function Title (node, renderer, options) {
- renderer.append(`<title>`);
- renderer.render(node.children, options);
- renderer.append(`</title>`);
- }
- function noop$2() { }
- const handlers = {
- AwaitBlock,
- Comment: Comment$1,
- DebugTag,
- Document: noop$2,
- EachBlock,
- Element,
- Head,
- IfBlock,
- InlineComponent,
- MustacheTag: Tag$1,
- RawMustacheTag: HtmlTag,
- Slot,
- Text: Text$1,
- Title,
- Window: noop$2
- };
- class Renderer$1 {
- constructor() {
- this.bindings = [];
- this.code = '';
- this.targets = [];
- }
- append(code) {
- if (this.targets.length) {
- const target = this.targets[this.targets.length - 1];
- const slotName = target.slotStack[target.slotStack.length - 1];
- target.slots[slotName] += code;
- }
- else {
- this.code += code;
- }
- }
- render(nodes, options) {
- nodes.forEach(node => {
- const handler = handlers[node.type];
- if (!handler) {
- throw new Error(`No handler for '${node.type}' nodes`);
- }
- handler(node, this, options);
- });
- }
- }
- function ssr(component, options) {
- const renderer = new Renderer$1();
- const format = options.format || 'cjs';
- const { computations, name, templateProperties } = component;
- // create main render() function
- renderer.render(trim(component.fragment.children), Object.assign({
- locate: component.locate
- }, options));
- const css = component.customElement ?
- { code: null, map: null } :
- component.stylesheet.render(options.filename, true);
- // generate initial state object
- const expectedProperties = Array.from(component.expectedProperties);
- const globals = expectedProperties.filter(prop => globalWhitelist.has(prop));
- const storeProps = expectedProperties.filter(prop => prop[0] === '$');
- const initialState = [];
- if (globals.length > 0) {
- initialState.push(`{ ${globals.map(prop => `${prop} : ${prop}`).join(', ')} }`);
- }
- if (storeProps.length > 0) {
- const initialize = `_init([${storeProps.map(prop => `"${prop.slice(1)}"`)}])`;
- initialState.push(`options.store.${initialize}`);
- }
- if (templateProperties.data) {
- initialState.push(`%data()`);
- }
- else if (globals.length === 0 && storeProps.length === 0) {
- initialState.push('{}');
- }
- initialState.push('ctx');
- let js = null;
- if (component.javascript) {
- const componentDefinition = new CodeBuilder();
- // not all properties are relevant to SSR (e.g. lifecycle hooks)
- const relevant = new Set([
- 'data',
- 'components',
- 'computed',
- 'helpers',
- 'preload',
- 'store'
- ]);
- component.declarations.forEach(declaration => {
- if (relevant.has(declaration.type)) {
- componentDefinition.addBlock(declaration.block);
- }
- });
- js = (component.javascript[0] +
- componentDefinition +
- component.javascript[1]);
- }
- const debugName = `<${component.customElement ? component.tag : name}>`;
- // TODO concatenate CSS maps
- const result = (deindent `
- ${js}
- var ${name} = {};
- ${options.filename && `${name}.filename = ${stringify(options.filename)}`};
- ${name}.data = function() {
- return ${templateProperties.data ? `%data()` : `{}`};
- };
- ${name}.render = function(state, options = {}) {
- var components = new Set();
- function addComponent(component) {
- components.add(component);
- }
- var result = { head: '', addComponent };
- var html = ${name}._render(result, state, options);
- var cssCode = Array.from(components).map(c => c.css && c.css.code).filter(Boolean).join('\\n');
- return {
- html,
- head: result.head,
- css: { code: cssCode, map: null },
- toString() {
- return html;
- }
- };
- }
- ${name}._render = function(__result, ctx, options) {
- ${templateProperties.store && `options.store = %store();`}
- __result.addComponent(${name});
- ${options.dev && storeProps.length > 0 && !templateProperties.store && deindent `
- if (!options.store) {
- throw new Error("${debugName} references store properties, but no store was provided");
- }
- `}
- ctx = Object.assign(${initialState.join(', ')});
- ${computations.map(({ key }) => `ctx.${key} = %computed-${key}(ctx);`)}
- ${renderer.bindings.length &&
- deindent `
- var settled = false;
- var tmp;
- while (!settled) {
- settled = true;
- ${renderer.bindings.join('\n\n')}
- }
- `}
- return \`${renderer.code}\`;
- };
- ${name}.css = {
- code: ${css.code ? stringify(css.code) : `''`},
- map: ${css.map ? stringify(css.map.toString()) : 'null'}
- };
- var warned = false;
- ${templateProperties.preload && `${name}.preload = %preload;`}
- `).trim();
- return component.generate(result, options, { name, format });
- }
- function trim(nodes) {
- let start = 0;
- for (; start < nodes.length; start += 1) {
- const node = nodes[start];
- if (node.type !== 'Text')
- break;
- node.data = node.data.replace(/^\s+/, '');
- if (node.data)
- break;
- }
- let end = nodes.length;
- for (; end > start; end -= 1) {
- const node = nodes[end - 1];
- if (node.type !== 'Text')
- break;
- node.data = node.data.replace(/\s+$/, '');
- if (node.data)
- break;
- }
- return nodes.slice(start, end);
- }
- var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
- function encode(decoded) {
- var sourceFileIndex = 0; // second field
- var sourceCodeLine = 0; // third field
- var sourceCodeColumn = 0; // fourth field
- var nameIndex = 0; // fifth field
- var mappings = '';
- for (var i = 0; i < decoded.length; i++) {
- var line = decoded[i];
- if (i > 0)
- mappings += ';';
- if (line.length === 0)
- continue;
- var generatedCodeColumn = 0; // first field
- var lineMappings = [];
- for (var _i = 0, line_1 = line; _i < line_1.length; _i++) {
- var segment = line_1[_i];
- var segmentMappings = encodeInteger(segment[0] - generatedCodeColumn);
- generatedCodeColumn = segment[0];
- if (segment.length > 1) {
- segmentMappings +=
- encodeInteger(segment[1] - sourceFileIndex) +
- encodeInteger(segment[2] - sourceCodeLine) +
- encodeInteger(segment[3] - sourceCodeColumn);
- sourceFileIndex = segment[1];
- sourceCodeLine = segment[2];
- sourceCodeColumn = segment[3];
- }
- if (segment.length === 5) {
- segmentMappings += encodeInteger(segment[4] - nameIndex);
- nameIndex = segment[4];
- }
- lineMappings.push(segmentMappings);
- }
- mappings += lineMappings.join(',');
- }
- return mappings;
- }
- function encodeInteger(num) {
- var result = '';
- num = num < 0 ? (-num << 1) | 1 : num << 1;
- do {
- var clamped = num & 31;
- num >>= 5;
- if (num > 0) {
- clamped |= 32;
- }
- result += chars[clamped];
- } while (num > 0);
- return result;
- }
- var Chunk = function Chunk(start, end, content) {
- this.start = start;
- this.end = end;
- this.original = content;
- this.intro = '';
- this.outro = '';
- this.content = content;
- this.storeName = false;
- this.edited = false;
- // we make these non-enumerable, for sanity while debugging
- Object.defineProperties(this, {
- previous: { writable: true, value: null },
- next: { writable: true, value: null }
- });
- };
- Chunk.prototype.appendLeft = function appendLeft (content) {
- this.outro += content;
- };
- Chunk.prototype.appendRight = function appendRight (content) {
- this.intro = this.intro + content;
- };
- Chunk.prototype.clone = function clone () {
- var chunk = new Chunk(this.start, this.end, this.original);
- chunk.intro = this.intro;
- chunk.outro = this.outro;
- chunk.content = this.content;
- chunk.storeName = this.storeName;
- chunk.edited = this.edited;
- return chunk;
- };
- Chunk.prototype.contains = function contains (index) {
- return this.start < index && index < this.end;
- };
- Chunk.prototype.eachNext = function eachNext (fn) {
- var chunk = this;
- while (chunk) {
- fn(chunk);
- chunk = chunk.next;
- }
- };
- Chunk.prototype.eachPrevious = function eachPrevious (fn) {
- var chunk = this;
- while (chunk) {
- fn(chunk);
- chunk = chunk.previous;
- }
- };
- Chunk.prototype.edit = function edit (content, storeName, contentOnly) {
- this.content = content;
- if (!contentOnly) {
- this.intro = '';
- this.outro = '';
- }
- this.storeName = storeName;
- this.edited = true;
- return this;
- };
- Chunk.prototype.prependLeft = function prependLeft (content) {
- this.outro = content + this.outro;
- };
- Chunk.prototype.prependRight = function prependRight (content) {
- this.intro = content + this.intro;
- };
- Chunk.prototype.split = function split (index) {
- var sliceIndex = index - this.start;
- var originalBefore = this.original.slice(0, sliceIndex);
- var originalAfter = this.original.slice(sliceIndex);
- this.original = originalBefore;
- var newChunk = new Chunk(index, this.end, originalAfter);
- newChunk.outro = this.outro;
- this.outro = '';
- this.end = index;
- if (this.edited) {
- // TODO is this block necessary?...
- newChunk.edit('', false);
- this.content = '';
- } else {
- this.content = originalBefore;
- }
- newChunk.next = this.next;
- if (newChunk.next) { newChunk.next.previous = newChunk; }
- newChunk.previous = this;
- this.next = newChunk;
- return newChunk;
- };
- Chunk.prototype.toString = function toString () {
- return this.intro + this.content + this.outro;
- };
- Chunk.prototype.trimEnd = function trimEnd (rx) {
- this.outro = this.outro.replace(rx, '');
- if (this.outro.length) { return true; }
- var trimmed = this.content.replace(rx, '');
- if (trimmed.length) {
- if (trimmed !== this.content) {
- this.split(this.start + trimmed.length).edit('', undefined, true);
- }
- return true;
- } else {
- this.edit('', undefined, true);
- this.intro = this.intro.replace(rx, '');
- if (this.intro.length) { return true; }
- }
- };
- Chunk.prototype.trimStart = function trimStart (rx) {
- this.intro = this.intro.replace(rx, '');
- if (this.intro.length) { return true; }
- var trimmed = this.content.replace(rx, '');
- if (trimmed.length) {
- if (trimmed !== this.content) {
- this.split(this.end - trimmed.length);
- this.edit('', undefined, true);
- }
- return true;
- } else {
- this.edit('', undefined, true);
- this.outro = this.outro.replace(rx, '');
- if (this.outro.length) { return true; }
- }
- };
- var btoa = function () {
- throw new Error('Unsupported environment: `window.btoa` or `Buffer` should be supported.');
- };
- if (typeof window !== 'undefined' && typeof window.btoa === 'function') {
- btoa = window.btoa;
- } else if (typeof Buffer === 'function') {
- btoa = function (str) { return new Buffer(str).toString('base64'); };
- }
- var SourceMap = function SourceMap(properties) {
- this.version = 3;
- this.file = properties.file;
- this.sources = properties.sources;
- this.sourcesContent = properties.sourcesContent;
- this.names = properties.names;
- this.mappings = encode(properties.mappings);
- };
- SourceMap.prototype.toString = function toString () {
- return JSON.stringify(this);
- };
- SourceMap.prototype.toUrl = function toUrl () {
- return 'data:application/json;charset=utf-8;base64,' + btoa(this.toString());
- };
- function guessIndent(code) {
- var lines = code.split('\n');
- var tabbed = lines.filter(function (line) { return /^\t+/.test(line); });
- var spaced = lines.filter(function (line) { return /^ {2,}/.test(line); });
- if (tabbed.length === 0 && spaced.length === 0) {
- return null;
- }
- // More lines tabbed than spaced? Assume tabs, and
- // default to tabs in the case of a tie (or nothing
- // to go on)
- if (tabbed.length >= spaced.length) {
- return '\t';
- }
- // Otherwise, we need to guess the multiple
- var min = spaced.reduce(function (previous, current) {
- var numSpaces = /^ +/.exec(current)[0].length;
- return Math.min(numSpaces, previous);
- }, Infinity);
- return new Array(min + 1).join(' ');
- }
- function getRelativePath(from, to) {
- var fromParts = from.split(/[/\\]/);
- var toParts = to.split(/[/\\]/);
- fromParts.pop(); // get dirname
- while (fromParts[0] === toParts[0]) {
- fromParts.shift();
- toParts.shift();
- }
- if (fromParts.length) {
- var i = fromParts.length;
- while (i--) { fromParts[i] = '..'; }
- }
- return fromParts.concat(toParts).join('/');
- }
- var toString$2 = Object.prototype.toString;
- function isObject(thing) {
- return toString$2.call(thing) === '[object Object]';
- }
- function getLocator$1(source) {
- var originalLines = source.split('\n');
- var lineOffsets = [];
- for (var i = 0, pos = 0; i < originalLines.length; i++) {
- lineOffsets.push(pos);
- pos += originalLines[i].length + 1;
- }
- return function locate(index) {
- var i = 0;
- var j = lineOffsets.length;
- while (i < j) {
- var m = (i + j) >> 1;
- if (index < lineOffsets[m]) {
- j = m;
- } else {
- i = m + 1;
- }
- }
- var line = i - 1;
- var column = index - lineOffsets[line];
- return { line: line, column: column };
- };
- }
- var Mappings = function Mappings(hires) {
- this.hires = hires;
- this.generatedCodeLine = 0;
- this.generatedCodeColumn = 0;
- this.raw = [];
- this.rawSegments = this.raw[this.generatedCodeLine] = [];
- this.pending = null;
- };
- Mappings.prototype.addEdit = function addEdit (sourceIndex, content, loc, nameIndex) {
- if (content.length) {
- var segment = [this.generatedCodeColumn, sourceIndex, loc.line, loc.column];
- if (nameIndex >= 0) {
- segment.push(nameIndex);
- }
- this.rawSegments.push(segment);
- } else if (this.pending) {
- this.rawSegments.push(this.pending);
- }
- this.advance(content);
- this.pending = null;
- };
- Mappings.prototype.addUneditedChunk = function addUneditedChunk (sourceIndex, chunk, original, loc, sourcemapLocations) {
- var this$1 = this;
- var originalCharIndex = chunk.start;
- var first = true;
- while (originalCharIndex < chunk.end) {
- if (this$1.hires || first || sourcemapLocations[originalCharIndex]) {
- this$1.rawSegments.push([this$1.generatedCodeColumn, sourceIndex, loc.line, loc.column]);
- }
- if (original[originalCharIndex] === '\n') {
- loc.line += 1;
- loc.column = 0;
- this$1.generatedCodeLine += 1;
- this$1.raw[this$1.generatedCodeLine] = this$1.rawSegments = [];
- this$1.generatedCodeColumn = 0;
- } else {
- loc.column += 1;
- this$1.generatedCodeColumn += 1;
- }
- originalCharIndex += 1;
- first = false;
- }
- this.pending = [this.generatedCodeColumn, sourceIndex, loc.line, loc.column];
- };
- Mappings.prototype.advance = function advance (str) {
- var this$1 = this;
- if (!str) { return; }
- var lines = str.split('\n');
- if (lines.length > 1) {
- for (var i = 0; i < lines.length - 1; i++) {
- this$1.generatedCodeLine++;
- this$1.raw[this$1.generatedCodeLine] = this$1.rawSegments = [];
- }
- this.generatedCodeColumn = 0;
- }
- this.generatedCodeColumn += lines[lines.length - 1].length;
- };
- var n = '\n';
- var warned = {
- insertLeft: false,
- insertRight: false,
- storeName: false
- };
- var MagicString = function MagicString(string, options) {
- if ( options === void 0 ) options = {};
- var chunk = new Chunk(0, string.length, string);
- Object.defineProperties(this, {
- original: { writable: true, value: string },
- outro: { writable: true, value: '' },
- intro: { writable: true, value: '' },
- firstChunk: { writable: true, value: chunk },
- lastChunk: { writable: true, value: chunk },
- lastSearchedChunk: { writable: true, value: chunk },
- byStart: { writable: true, value: {} },
- byEnd: { writable: true, value: {} },
- filename: { writable: true, value: options.filename },
- indentExclusionRanges: { writable: true, value: options.indentExclusionRanges },
- sourcemapLocations: { writable: true, value: {} },
- storedNames: { writable: true, value: {} },
- indentStr: { writable: true, value: guessIndent(string) }
- });
- this.byStart[0] = chunk;
- this.byEnd[string.length] = chunk;
- };
- MagicString.prototype.addSourcemapLocation = function addSourcemapLocation (char) {
- this.sourcemapLocations[char] = true;
- };
- MagicString.prototype.append = function append (content) {
- if (typeof content !== 'string') { throw new TypeError('outro content must be a string'); }
- this.outro += content;
- return this;
- };
- MagicString.prototype.appendLeft = function appendLeft (index, content) {
- if (typeof content !== 'string') { throw new TypeError('inserted content must be a string'); }
- this._split(index);
- var chunk = this.byEnd[index];
- if (chunk) {
- chunk.appendLeft(content);
- } else {
- this.intro += content;
- }
- return this;
- };
- MagicString.prototype.appendRight = function appendRight (index, content) {
- if (typeof content !== 'string') { throw new TypeError('inserted content must be a string'); }
- this._split(index);
- var chunk = this.byStart[index];
- if (chunk) {
- chunk.appendRight(content);
- } else {
- this.outro += content;
- }
- return this;
- };
- MagicString.prototype.clone = function clone () {
- var cloned = new MagicString(this.original, { filename: this.filename });
- var originalChunk = this.firstChunk;
- var clonedChunk = (cloned.firstChunk = cloned.lastSearchedChunk = originalChunk.clone());
- while (originalChunk) {
- cloned.byStart[clonedChunk.start] = clonedChunk;
- cloned.byEnd[clonedChunk.end] = clonedChunk;
- var nextOriginalChunk = originalChunk.next;
- var nextClonedChunk = nextOriginalChunk && nextOriginalChunk.clone();
- if (nextClonedChunk) {
- clonedChunk.next = nextClonedChunk;
- nextClonedChunk.previous = clonedChunk;
- clonedChunk = nextClonedChunk;
- }
- originalChunk = nextOriginalChunk;
- }
- cloned.lastChunk = clonedChunk;
- if (this.indentExclusionRanges) {
- cloned.indentExclusionRanges = this.indentExclusionRanges.slice();
- }
- Object.keys(this.sourcemapLocations).forEach(function (loc) {
- cloned.sourcemapLocations[loc] = true;
- });
- return cloned;
- };
- MagicString.prototype.generateDecodedMap = function generateDecodedMap (options) {
- var this$1 = this;
- options = options || {};
- var sourceIndex = 0;
- var names = Object.keys(this.storedNames);
- var mappings = new Mappings(options.hires);
- var locate = getLocator$1(this.original);
- if (this.intro) {
- mappings.advance(this.intro);
- }
- this.firstChunk.eachNext(function (chunk) {
- var loc = locate(chunk.start);
- if (chunk.intro.length) { mappings.advance(chunk.intro); }
- if (chunk.edited) {
- mappings.addEdit(
- sourceIndex,
- chunk.content,
- loc,
- chunk.storeName ? names.indexOf(chunk.original) : -1
- );
- } else {
- mappings.addUneditedChunk(sourceIndex, chunk, this$1.original, loc, this$1.sourcemapLocations);
- }
- if (chunk.outro.length) { mappings.advance(chunk.outro); }
- });
- return {
- file: options.file ? options.file.split(/[/\\]/).pop() : null,
- sources: [options.source ? getRelativePath(options.file || '', options.source) : null],
- sourcesContent: options.includeContent ? [this.original] : [null],
- names: names,
- mappings: mappings.raw
- };
- };
- MagicString.prototype.generateMap = function generateMap (options) {
- return new SourceMap(this.generateDecodedMap(options));
- };
- MagicString.prototype.getIndentString = function getIndentString () {
- return this.indentStr === null ? '\t' : this.indentStr;
- };
- MagicString.prototype.indent = function indent (indentStr, options) {
- var this$1 = this;
- var pattern = /^[^\r\n]/gm;
- if (isObject(indentStr)) {
- options = indentStr;
- indentStr = undefined;
- }
- indentStr = indentStr !== undefined ? indentStr : this.indentStr || '\t';
- if (indentStr === '') { return this; } // noop
- options = options || {};
- // Process exclusion ranges
- var isExcluded = {};
- if (options.exclude) {
- var exclusions =
- typeof options.exclude[0] === 'number' ? [options.exclude] : options.exclude;
- exclusions.forEach(function (exclusion) {
- for (var i = exclusion[0]; i < exclusion[1]; i += 1) {
- isExcluded[i] = true;
- }
- });
- }
- var shouldIndentNextCharacter = options.indentStart !== false;
- var replacer = function (match) {
- if (shouldIndentNextCharacter) { return ("" + indentStr + match); }
- shouldIndentNextCharacter = true;
- return match;
- };
- this.intro = this.intro.replace(pattern, replacer);
- var charIndex = 0;
- var chunk = this.firstChunk;
- while (chunk) {
- var end = chunk.end;
- if (chunk.edited) {
- if (!isExcluded[charIndex]) {
- chunk.content = chunk.content.replace(pattern, replacer);
- if (chunk.content.length) {
- shouldIndentNextCharacter = chunk.content[chunk.content.length - 1] === '\n';
- }
- }
- } else {
- charIndex = chunk.start;
- while (charIndex < end) {
- if (!isExcluded[charIndex]) {
- var char = this$1.original[charIndex];
- if (char === '\n') {
- shouldIndentNextCharacter = true;
- } else if (char !== '\r' && shouldIndentNextCharacter) {
- shouldIndentNextCharacter = false;
- if (charIndex === chunk.start) {
- chunk.prependRight(indentStr);
- } else {
- this$1._splitChunk(chunk, charIndex);
- chunk = chunk.next;
- chunk.prependRight(indentStr);
- }
- }
- }
- charIndex += 1;
- }
- }
- charIndex = chunk.end;
- chunk = chunk.next;
- }
- this.outro = this.outro.replace(pattern, replacer);
- return this;
- };
- MagicString.prototype.insert = function insert () {
- throw new Error('magicString.insert(...) is deprecated. Use prependRight(...) or appendLeft(...)');
- };
- MagicString.prototype.insertLeft = function insertLeft (index, content) {
- if (!warned.insertLeft) {
- console.warn('magicString.insertLeft(...) is deprecated. Use magicString.appendLeft(...) instead'); // eslint-disable-line no-console
- warned.insertLeft = true;
- }
- return this.appendLeft(index, content);
- };
- MagicString.prototype.insertRight = function insertRight (index, content) {
- if (!warned.insertRight) {
- console.warn('magicString.insertRight(...) is deprecated. Use magicString.prependRight(...) instead'); // eslint-disable-line no-console
- warned.insertRight = true;
- }
- return this.prependRight(index, content);
- };
- MagicString.prototype.move = function move (start, end, index) {
- if (index >= start && index <= end) { throw new Error('Cannot move a selection inside itself'); }
- this._split(start);
- this._split(end);
- this._split(index);
- var first = this.byStart[start];
- var last = this.byEnd[end];
- var oldLeft = first.previous;
- var oldRight = last.next;
- var newRight = this.byStart[index];
- if (!newRight && last === this.lastChunk) { return this; }
- var newLeft = newRight ? newRight.previous : this.lastChunk;
- if (oldLeft) { oldLeft.next = oldRight; }
- if (oldRight) { oldRight.previous = oldLeft; }
- if (newLeft) { newLeft.next = first; }
- if (newRight) { newRight.previous = last; }
- if (!first.previous) { this.firstChunk = last.next; }
- if (!last.next) {
- this.lastChunk = first.previous;
- this.lastChunk.next = null;
- }
- first.previous = newLeft;
- last.next = newRight || null;
- if (!newLeft) { this.firstChunk = first; }
- if (!newRight) { this.lastChunk = last; }
- return this;
- };
- MagicString.prototype.overwrite = function overwrite (start, end, content, options) {
- var this$1 = this;
- if (typeof content !== 'string') { throw new TypeError('replacement content must be a string'); }
- while (start < 0) { start += this$1.original.length; }
- while (end < 0) { end += this$1.original.length; }
- if (end > this.original.length) { throw new Error('end is out of bounds'); }
- if (start === end)
- { throw new Error('Cannot overwrite a zero-length range – use appendLeft or prependRight instead'); }
- this._split(start);
- this._split(end);
- if (options === true) {
- if (!warned.storeName) {
- console.warn('The final argument to magicString.overwrite(...) should be an options object. See https://github.com/rich-harris/magic-string'); // eslint-disable-line no-console
- warned.storeName = true;
- }
- options = { storeName: true };
- }
- var storeName = options !== undefined ? options.storeName : false;
- var contentOnly = options !== undefined ? options.contentOnly : false;
- if (storeName) {
- var original = this.original.slice(start, end);
- this.storedNames[original] = true;
- }
- var first = this.byStart[start];
- var last = this.byEnd[end];
- if (first) {
- if (end > first.end && first.next !== this.byStart[first.end]) {
- throw new Error('Cannot overwrite across a split point');
- }
- first.edit(content, storeName, contentOnly);
- if (first !== last) {
- var chunk = first.next;
- while (chunk !== last) {
- chunk.edit('', false);
- chunk = chunk.next;
- }
- chunk.edit('', false);
- }
- } else {
- // must be inserting at the end
- var newChunk = new Chunk(start, end, '').edit(content, storeName);
- // TODO last chunk in the array may not be the last chunk, if it's moved...
- last.next = newChunk;
- newChunk.previous = last;
- }
- return this;
- };
- MagicString.prototype.prepend = function prepend (content) {
- if (typeof content !== 'string') { throw new TypeError('outro content must be a string'); }
- this.intro = content + this.intro;
- return this;
- };
- MagicString.prototype.prependLeft = function prependLeft (index, content) {
- if (typeof content !== 'string') { throw new TypeError('inserted content must be a string'); }
- this._split(index);
- var chunk = this.byEnd[index];
- if (chunk) {
- chunk.prependLeft(content);
- } else {
- this.intro = content + this.intro;
- }
- return this;
- };
- MagicString.prototype.prependRight = function prependRight (index, content) {
- if (typeof content !== 'string') { throw new TypeError('inserted content must be a string'); }
- this._split(index);
- var chunk = this.byStart[index];
- if (chunk) {
- chunk.prependRight(content);
- } else {
- this.outro = content + this.outro;
- }
- return this;
- };
- MagicString.prototype.remove = function remove (start, end) {
- var this$1 = this;
- while (start < 0) { start += this$1.original.length; }
- while (end < 0) { end += this$1.original.length; }
- if (start === end) { return this; }
- if (start < 0 || end > this.original.length) { throw new Error('Character is out of bounds'); }
- if (start > end) { throw new Error('end must be greater than start'); }
- this._split(start);
- this._split(end);
- var chunk = this.byStart[start];
- while (chunk) {
- chunk.intro = '';
- chunk.outro = '';
- chunk.edit('');
- chunk = end > chunk.end ? this$1.byStart[chunk.end] : null;
- }
- return this;
- };
- MagicString.prototype.lastChar = function lastChar () {
- if (this.outro.length)
- { return this.outro[this.outro.length - 1]; }
- var chunk = this.lastChunk;
- do {
- if (chunk.outro.length)
- { return chunk.outro[chunk.outro.length - 1]; }
- if (chunk.content.length)
- { return chunk.content[chunk.content.length - 1]; }
- if (chunk.intro.length)
- { return chunk.intro[chunk.intro.length - 1]; }
- } while (chunk = chunk.previous);
- if (this.intro.length)
- { return this.intro[this.intro.length - 1]; }
- return '';
- };
- MagicString.prototype.lastLine = function lastLine () {
- var lineIndex = this.outro.lastIndexOf(n);
- if (lineIndex !== -1)
- { return this.outro.substr(lineIndex + 1); }
- var lineStr = this.outro;
- var chunk = this.lastChunk;
- do {
- if (chunk.outro.length > 0) {
- lineIndex = chunk.outro.lastIndexOf(n);
- if (lineIndex !== -1)
- { return chunk.outro.substr(lineIndex + 1) + lineStr; }
- lineStr = chunk.outro + lineStr;
- }
- if (chunk.content.length > 0) {
- lineIndex = chunk.content.lastIndexOf(n);
- if (lineIndex !== -1)
- { return chunk.content.substr(lineIndex + 1) + lineStr; }
- lineStr = chunk.content + lineStr;
- }
- if (chunk.intro.length > 0) {
- lineIndex = chunk.intro.lastIndexOf(n);
- if (lineIndex !== -1)
- { return chunk.intro.substr(lineIndex + 1) + lineStr; }
- lineStr = chunk.intro + lineStr;
- }
- } while (chunk = chunk.previous);
- lineIndex = this.intro.lastIndexOf(n);
- if (lineIndex !== -1)
- { return this.intro.substr(lineIndex + 1) + lineStr; }
- return this.intro + lineStr;
- };
- MagicString.prototype.slice = function slice (start, end) {
- var this$1 = this;
- if ( start === void 0 ) start = 0;
- if ( end === void 0 ) end = this.original.length;
- while (start < 0) { start += this$1.original.length; }
- while (end < 0) { end += this$1.original.length; }
- var result = '';
- // find start chunk
- var chunk = this.firstChunk;
- while (chunk && (chunk.start > start || chunk.end <= start)) {
- // found end chunk before start
- if (chunk.start < end && chunk.end >= end) {
- return result;
- }
- chunk = chunk.next;
- }
- if (chunk && chunk.edited && chunk.start !== start)
- { throw new Error(("Cannot use replaced character " + start + " as slice start anchor.")); }
- var startChunk = chunk;
- while (chunk) {
- if (chunk.intro && (startChunk !== chunk || chunk.start === start)) {
- result += chunk.intro;
- }
- var containsEnd = chunk.start < end && chunk.end >= end;
- if (containsEnd && chunk.edited && chunk.end !== end)
- { throw new Error(("Cannot use replaced character " + end + " as slice end anchor.")); }
- var sliceStart = startChunk === chunk ? start - chunk.start : 0;
- var sliceEnd = containsEnd ? chunk.content.length + end - chunk.end : chunk.content.length;
- result += chunk.content.slice(sliceStart, sliceEnd);
- if (chunk.outro && (!containsEnd || chunk.end === end)) {
- result += chunk.outro;
- }
- if (containsEnd) {
- break;
- }
- chunk = chunk.next;
- }
- return result;
- };
- // TODO deprecate this? not really very useful
- MagicString.prototype.snip = function snip (start, end) {
- var clone = this.clone();
- clone.remove(0, start);
- clone.remove(end, clone.original.length);
- return clone;
- };
- MagicString.prototype._split = function _split (index) {
- var this$1 = this;
- if (this.byStart[index] || this.byEnd[index]) { return; }
- var chunk = this.lastSearchedChunk;
- var searchForward = index > chunk.end;
- while (chunk) {
- if (chunk.contains(index)) { return this$1._splitChunk(chunk, index); }
- chunk = searchForward ? this$1.byStart[chunk.end] : this$1.byEnd[chunk.start];
- }
- };
- MagicString.prototype._splitChunk = function _splitChunk (chunk, index) {
- if (chunk.edited && chunk.content.length) {
- // zero-length edited chunks are a special case (overlapping replacements)
- var loc = getLocator$1(this.original)(index);
- throw new Error(
- ("Cannot split a chunk that has already been edited (" + (loc.line) + ":" + (loc.column) + " – \"" + (chunk.original) + "\")")
- );
- }
- var newChunk = chunk.split(index);
- this.byEnd[index] = chunk;
- this.byStart[index] = newChunk;
- this.byEnd[newChunk.end] = newChunk;
- if (chunk === this.lastChunk) { this.lastChunk = newChunk; }
- this.lastSearchedChunk = chunk;
- return true;
- };
- MagicString.prototype.toString = function toString () {
- var str = this.intro;
- var chunk = this.firstChunk;
- while (chunk) {
- str += chunk.toString();
- chunk = chunk.next;
- }
- return str + this.outro;
- };
- MagicString.prototype.isEmpty = function isEmpty () {
- var chunk = this.firstChunk;
- do {
- if (chunk.intro.length && chunk.intro.trim() ||
- chunk.content.length && chunk.content.trim() ||
- chunk.outro.length && chunk.outro.trim())
- { return false; }
- } while (chunk = chunk.next);
- return true;
- };
- MagicString.prototype.length = function length () {
- var chunk = this.firstChunk;
- var length = 0;
- do {
- length += chunk.intro.length + chunk.content.length + chunk.outro.length;
- } while (chunk = chunk.next);
- return length;
- };
- MagicString.prototype.trimLines = function trimLines () {
- return this.trim('[\\r\\n]');
- };
- MagicString.prototype.trim = function trim (charType) {
- return this.trimStart(charType).trimEnd(charType);
- };
- MagicString.prototype.trimEndAborted = function trimEndAborted (charType) {
- var this$1 = this;
- var rx = new RegExp((charType || '\\s') + '+$');
- this.outro = this.outro.replace(rx, '');
- if (this.outro.length) { return true; }
- var chunk = this.lastChunk;
- do {
- var end = chunk.end;
- var aborted = chunk.trimEnd(rx);
- // if chunk was trimmed, we have a new lastChunk
- if (chunk.end !== end) {
- if (this$1.lastChunk === chunk) {
- this$1.lastChunk = chunk.next;
- }
- this$1.byEnd[chunk.end] = chunk;
- this$1.byStart[chunk.next.start] = chunk.next;
- this$1.byEnd[chunk.next.end] = chunk.next;
- }
- if (aborted) { return true; }
- chunk = chunk.previous;
- } while (chunk);
- return false;
- };
- MagicString.prototype.trimEnd = function trimEnd (charType) {
- this.trimEndAborted(charType);
- return this;
- };
- MagicString.prototype.trimStartAborted = function trimStartAborted (charType) {
- var this$1 = this;
- var rx = new RegExp('^' + (charType || '\\s') + '+');
- this.intro = this.intro.replace(rx, '');
- if (this.intro.length) { return true; }
- var chunk = this.firstChunk;
- do {
- var end = chunk.end;
- var aborted = chunk.trimStart(rx);
- if (chunk.end !== end) {
- // special case...
- if (chunk === this$1.lastChunk) { this$1.lastChunk = chunk.next; }
- this$1.byEnd[chunk.end] = chunk;
- this$1.byStart[chunk.next.start] = chunk.next;
- this$1.byEnd[chunk.next.end] = chunk.next;
- }
- if (aborted) { return true; }
- chunk = chunk.next;
- } while (chunk);
- return false;
- };
- MagicString.prototype.trimStart = function trimStart (charType) {
- this.trimStartAborted(charType);
- return this;
- };
- var hasOwnProp = Object.prototype.hasOwnProperty;
- var Bundle = function Bundle(options) {
- if ( options === void 0 ) options = {};
- this.intro = options.intro || '';
- this.separator = options.separator !== undefined ? options.separator : '\n';
- this.sources = [];
- this.uniqueSources = [];
- this.uniqueSourceIndexByFilename = {};
- };
- Bundle.prototype.addSource = function addSource (source) {
- if (source instanceof MagicString) {
- return this.addSource({
- content: source,
- filename: source.filename,
- separator: this.separator
- });
- }
- if (!isObject(source) || !source.content) {
- throw new Error('bundle.addSource() takes an object with a `content` property, which should be an instance of MagicString, and an optional `filename`');
- }
- ['filename', 'indentExclusionRanges', 'separator'].forEach(function (option) {
- if (!hasOwnProp.call(source, option)) { source[option] = source.content[option]; }
- });
- if (source.separator === undefined) {
- // TODO there's a bunch of this sort of thing, needs cleaning up
- source.separator = this.separator;
- }
- if (source.filename) {
- if (!hasOwnProp.call(this.uniqueSourceIndexByFilename, source.filename)) {
- this.uniqueSourceIndexByFilename[source.filename] = this.uniqueSources.length;
- this.uniqueSources.push({ filename: source.filename, content: source.content.original });
- } else {
- var uniqueSource = this.uniqueSources[this.uniqueSourceIndexByFilename[source.filename]];
- if (source.content.original !== uniqueSource.content) {
- throw new Error(("Illegal source: same filename (" + (source.filename) + "), different contents"));
- }
- }
- }
- this.sources.push(source);
- return this;
- };
- Bundle.prototype.append = function append (str, options) {
- this.addSource({
- content: new MagicString(str),
- separator: (options && options.separator) || ''
- });
- return this;
- };
- Bundle.prototype.clone = function clone () {
- var bundle = new Bundle({
- intro: this.intro,
- separator: this.separator
- });
- this.sources.forEach(function (source) {
- bundle.addSource({
- filename: source.filename,
- content: source.content.clone(),
- separator: source.separator
- });
- });
- return bundle;
- };
- Bundle.prototype.generateDecodedMap = function generateDecodedMap (options) {
- var this$1 = this;
- if ( options === void 0 ) options = {};
- var names = [];
- this.sources.forEach(function (source) {
- Object.keys(source.content.storedNames).forEach(function (name) {
- if (!~names.indexOf(name)) { names.push(name); }
- });
- });
- var mappings = new Mappings(options.hires);
- if (this.intro) {
- mappings.advance(this.intro);
- }
- this.sources.forEach(function (source, i) {
- if (i > 0) {
- mappings.advance(this$1.separator);
- }
- var sourceIndex = source.filename ? this$1.uniqueSourceIndexByFilename[source.filename] : -1;
- var magicString = source.content;
- var locate = getLocator$1(magicString.original);
- if (magicString.intro) {
- mappings.advance(magicString.intro);
- }
- magicString.firstChunk.eachNext(function (chunk) {
- var loc = locate(chunk.start);
- if (chunk.intro.length) { mappings.advance(chunk.intro); }
- if (source.filename) {
- if (chunk.edited) {
- mappings.addEdit(
- sourceIndex,
- chunk.content,
- loc,
- chunk.storeName ? names.indexOf(chunk.original) : -1
- );
- } else {
- mappings.addUneditedChunk(
- sourceIndex,
- chunk,
- magicString.original,
- loc,
- magicString.sourcemapLocations
- );
- }
- } else {
- mappings.advance(chunk.content);
- }
- if (chunk.outro.length) { mappings.advance(chunk.outro); }
- });
- if (magicString.outro) {
- mappings.advance(magicString.outro);
- }
- });
- return {
- file: options.file ? options.file.split(/[/\\]/).pop() : null,
- sources: this.uniqueSources.map(function (source) {
- return options.file ? getRelativePath(options.file, source.filename) : source.filename;
- }),
- sourcesContent: this.uniqueSources.map(function (source) {
- return options.includeContent ? source.content : null;
- }),
- names: names,
- mappings: mappings.raw
- };
- };
- Bundle.prototype.generateMap = function generateMap (options) {
- return new SourceMap(this.generateDecodedMap(options));
- };
- Bundle.prototype.getIndentString = function getIndentString () {
- var indentStringCounts = {};
- this.sources.forEach(function (source) {
- var indentStr = source.content.indentStr;
- if (indentStr === null) { return; }
- if (!indentStringCounts[indentStr]) { indentStringCounts[indentStr] = 0; }
- indentStringCounts[indentStr] += 1;
- });
- return (
- Object.keys(indentStringCounts).sort(function (a, b) {
- return indentStringCounts[a] - indentStringCounts[b];
- })[0] || '\t'
- );
- };
- Bundle.prototype.indent = function indent (indentStr) {
- var this$1 = this;
- if (!arguments.length) {
- indentStr = this.getIndentString();
- }
- if (indentStr === '') { return this; } // noop
- var trailingNewline = !this.intro || this.intro.slice(-1) === '\n';
- this.sources.forEach(function (source, i) {
- var separator = source.separator !== undefined ? source.separator : this$1.separator;
- var indentStart = trailingNewline || (i > 0 && /\r?\n$/.test(separator));
- source.content.indent(indentStr, {
- exclude: source.indentExclusionRanges,
- indentStart: indentStart //: trailingNewline || /\r?\n$/.test( separator ) //true///\r?\n/.test( separator )
- });
- trailingNewline = source.content.lastChar() === '\n';
- });
- if (this.intro) {
- this.intro =
- indentStr +
- this.intro.replace(/^[^\n]/gm, function (match, index) {
- return index > 0 ? indentStr + match : match;
- });
- }
- return this;
- };
- Bundle.prototype.prepend = function prepend (str) {
- this.intro = str + this.intro;
- return this;
- };
- Bundle.prototype.toString = function toString () {
- var this$1 = this;
- var body = this.sources
- .map(function (source, i) {
- var separator = source.separator !== undefined ? source.separator : this$1.separator;
- var str = (i > 0 ? separator : '') + source.content.toString();
- return str;
- })
- .join('');
- return this.intro + body;
- };
- Bundle.prototype.isEmpty = function isEmpty () {
- if (this.intro.length && this.intro.trim())
- { return false; }
- if (this.sources.some(function (source) { return !source.content.isEmpty(); }))
- { return false; }
- return true;
- };
- Bundle.prototype.length = function length () {
- return this.sources.reduce(function (length, source) { return length + source.content.length(); }, this.intro.length);
- };
- Bundle.prototype.trimLines = function trimLines () {
- return this.trim('[\\r\\n]');
- };
- Bundle.prototype.trim = function trim (charType) {
- return this.trimStart(charType).trimEnd(charType);
- };
- Bundle.prototype.trimStart = function trimStart (charType) {
- var this$1 = this;
- var rx = new RegExp('^' + (charType || '\\s') + '+');
- this.intro = this.intro.replace(rx, '');
- if (!this.intro) {
- var source;
- var i = 0;
- do {
- source = this$1.sources[i++];
- if (!source) {
- break;
- }
- } while (!source.content.trimStartAborted(charType));
- }
- return this;
- };
- Bundle.prototype.trimEnd = function trimEnd (charType) {
- var this$1 = this;
- var rx = new RegExp((charType || '\\s') + '+$');
- var source;
- var i = this.sources.length - 1;
- do {
- source = this$1.sources[i--];
- if (!source) {
- this$1.intro = this$1.intro.replace(rx, '');
- break;
- }
- } while (!source.content.trimEndAborted(charType));
- return this;
- };
- function isReference(node, parent) {
- if (node.type === 'MemberExpression') {
- return !node.computed && isReference(node.object, node);
- }
- if (node.type === 'Identifier') {
- // the only time we could have an identifier node without a parent is
- // if it's the entire body of a function without a block statement –
- // i.e. an arrow function expression like `a => a`
- if (!parent)
- return true;
- // TODO is this right?
- if (parent.type === 'MemberExpression' || parent.type === 'MethodDefinition') {
- return parent.computed || node === parent.object;
- }
- // disregard the `bar` in `{ bar: foo }`, but keep it in `{ [bar]: foo }`
- if (parent.type === 'Property')
- return parent.computed || node === parent.value;
- // disregard the `bar` in `export { foo as bar }`
- if (parent.type === 'ExportSpecifier' && node !== parent.local)
- return false;
- return true;
- }
- return false;
- }
- function getMethodName(node) {
- if (node.type === 'Identifier')
- return node.name;
- if (node.type === 'Literal')
- return String(node.value);
- }
- const keys = {
- ObjectExpression: 'properties',
- Program: 'body',
- };
- const offsets = {
- ObjectExpression: [1, -1],
- Program: [0, 0],
- };
- function removeNode(code, parent, node) {
- const key = keys[parent.type];
- const offset = offsets[parent.type];
- if (!key || !offset)
- throw new Error(`not implemented: ${parent.type}`);
- const list = parent[key];
- const i = list.indexOf(node);
- if (i === -1)
- throw new Error('node not in list');
- let a;
- let b;
- if (list.length === 1) {
- // remove everything, leave {}
- a = parent.start + offset[0];
- b = parent.end + offset[1];
- }
- else if (i === 0) {
- // remove everything before second node, including comments
- a = parent.start + offset[0];
- while (/\s/.test(code.original[a]))
- a += 1;
- b = list[i].end;
- while (/[\s,]/.test(code.original[b]))
- b += 1;
- }
- else {
- // remove the end of the previous node to the end of this one
- a = list[i - 1].end;
- b = node.end;
- }
- code.remove(a, b);
- return;
- }
- function nodeToString(node) {
- if (node.type === 'Literal' && typeof node.value === 'string') {
- return node.value;
- }
- else if (node.type === 'TemplateLiteral'
- && node.quasis.length === 1
- && node.expressions.length === 0) {
- return node.quasis[0].value.raw;
- }
- }
- function list$1(items, conjunction = 'or') {
- if (items.length === 1)
- return items[0];
- return `${items.slice(0, -1).join(', ')} ${conjunction} ${items[items.length - 1]}`;
- }
- const wrappers$1 = { es, amd, cjs, iife, umd, eval: expr };
- function wrapModule(code, format, name, options, banner, sharedPath, helpers, imports, shorthandImports, source) {
- if (format === 'es')
- return es(code, name, options, banner, sharedPath, helpers, imports, shorthandImports, source);
- const dependencies = imports.map((declaration, i) => {
- const defaultImport = declaration.specifiers.find((x) => x.type === 'ImportDefaultSpecifier' ||
- (x.type === 'ImportSpecifier' && x.imported.name === 'default'));
- const namespaceImport = declaration.specifiers.find((x) => x.type === 'ImportNamespaceSpecifier');
- const namedImports = declaration.specifiers.filter((x) => x.type === 'ImportSpecifier' && x.imported.name !== 'default');
- const name = defaultImport || namespaceImport
- ? (defaultImport || namespaceImport).local.name
- : `__import${i}`;
- const statements = [];
- namedImports.forEach((specifier) => {
- statements.push(`var ${specifier.local.name} = ${name}.${specifier.imported.name};`);
- });
- if (defaultImport) {
- statements.push(`${name} = (${name} && ${name}.__esModule) ? ${name}["default"] : ${name};`);
- }
- return { name, statements, source: declaration.source.value };
- })
- .concat(shorthandImports.map(({ name, source }) => ({
- name,
- statements: [
- `${name} = (${name} && ${name}.__esModule) ? ${name}["default"] : ${name};`,
- ],
- source,
- })));
- if (format === 'amd')
- return amd(code, name, options, banner, dependencies);
- if (format === 'cjs')
- return cjs(code, name, options, banner, sharedPath, helpers, dependencies);
- if (format === 'iife')
- return iife(code, name, options, banner, dependencies);
- if (format === 'umd')
- return umd(code, name, options, banner, dependencies);
- if (format === 'eval')
- return expr(code, name, options, banner, dependencies);
- throw new Error(`options.format is invalid (must be ${list$1(Object.keys(wrappers$1))})`);
- }
- function es(code, name, options, banner, sharedPath, helpers, imports, shorthandImports, source) {
- const importHelpers = helpers.length > 0 && (`import { ${helpers.map(h => h.name === h.alias ? h.name : `${h.name} as ${h.alias}`).join(', ')} } from ${JSON.stringify(sharedPath)};`);
- const importBlock = imports.length > 0 && (imports
- .map((declaration) => source.slice(declaration.start, declaration.end))
- .join('\n'));
- const shorthandImportBlock = shorthandImports.length > 0 && (shorthandImports.map(({ name, source }) => `import ${name} from ${JSON.stringify(source)};`).join('\n'));
- return deindent `
- ${banner}
- ${importHelpers}
- ${importBlock}
- ${shorthandImportBlock}
- ${code}
- export default ${name};`;
- }
- function amd(code, name, options, banner, dependencies) {
- const sourceString = dependencies.length
- ? `[${dependencies.map(d => `"${removeExtension(d.source)}"`).join(', ')}], `
- : '';
- const id = options.amd && options.amd.id;
- return deindent `
- define(${id ? `"${id}", ` : ''}${sourceString}function(${paramString(dependencies)}) { "use strict";
- ${getCompatibilityStatements(dependencies)}
- ${code}
- return ${name};
- });`;
- }
- function cjs(code, name, options, banner, sharedPath, helpers, dependencies) {
- const helperDeclarations = helpers.map(h => `${h.alias === h.name ? h.name : `${h.name}: ${h.alias}`}`).join(', ');
- const helperBlock = helpers.length > 0 && (`var { ${helperDeclarations} } = require(${JSON.stringify(sharedPath)});\n`);
- const requireBlock = dependencies.length > 0 && (dependencies
- .map(d => `var ${d.name} = require("${d.source}");`)
- .join('\n\n'));
- return deindent `
- ${banner}
- "use strict";
- ${helperBlock}
- ${requireBlock}
- ${getCompatibilityStatements(dependencies)}
- ${code}
- module.exports = ${name};`;
- }
- function iife(code, name, options, banner, dependencies) {
- if (!options.name) {
- throw new Error(`Missing required 'name' option for IIFE export`);
- }
- const globals = getGlobals(dependencies, options);
- return deindent `
- ${banner}
- var ${options.name} = (function(${paramString(dependencies)}) { "use strict";
- ${getCompatibilityStatements(dependencies)}
- ${code}
- return ${name};
- }(${globals.join(', ')}));`;
- }
- function umd(code, name, options, banner, dependencies) {
- if (!options.name) {
- throw new Error(`Missing required 'name' option for UMD export`);
- }
- const amdId = options.amd && options.amd.id ? `'${options.amd.id}', ` : '';
- const amdDeps = dependencies.length
- ? `[${dependencies.map(d => `"${removeExtension(d.source)}"`).join(', ')}], `
- : '';
- const cjsDeps = dependencies
- .map(d => `require("${d.source}")`)
- .join(', ');
- const globals = getGlobals(dependencies, options);
- return deindent `
- ${banner}
- (function(global, factory) {
- typeof exports === "object" && typeof module !== "undefined" ? module.exports = factory(${cjsDeps}) :
- typeof define === "function" && define.amd ? define(${amdId}${amdDeps}factory) :
- (global.${options.name} = factory(${globals.join(', ')}));
- }(this, (function (${paramString(dependencies)}) { "use strict";
- ${getCompatibilityStatements(dependencies)}
- ${code}
- return ${name};
- })));`;
- }
- function expr(code, name, options, banner, dependencies) {
- const globals = getGlobals(dependencies, options);
- return deindent `
- (function (${paramString(dependencies)}) { "use strict";
- ${banner}
- ${getCompatibilityStatements(dependencies)}
- ${code}
- return ${name};
- }(${globals.join(', ')}))`;
- }
- function paramString(dependencies) {
- return dependencies.map(dep => dep.name).join(', ');
- }
- function removeExtension(file) {
- const index = file.lastIndexOf('.');
- return ~index ? file.slice(0, index) : file;
- }
- function getCompatibilityStatements(dependencies) {
- if (!dependencies.length)
- return null;
- const statements = [];
- dependencies.forEach(dependency => {
- statements.push(...dependency.statements);
- });
- return statements.join('\n');
- }
- function getGlobals(dependencies, options) {
- const { globals, onwarn } = options;
- const globalFn = getGlobalFn(globals);
- return dependencies.map(d => {
- let name = globalFn(d.source);
- if (!name) {
- if (d.name.startsWith('__import')) {
- throw new Error(`Could not determine name for imported module '${d.source}' – use options.globals`);
- }
- else {
- const warning = {
- code: `options-missing-globals`,
- message: `No name was supplied for imported module '${d.source}'. Guessing '${d.name}', but you should use options.globals`,
- };
- onwarn(warning);
- }
- name = d.name;
- }
- return name;
- });
- }
- function getGlobalFn(globals) {
- if (typeof globals === 'function')
- return globals;
- if (typeof globals === 'object') {
- return id => globals[id];
- }
- return () => undefined;
- }
- function createScopes(expression) {
- const map = new WeakMap();
- const globals = new Set();
- let scope = new Scope(null, false);
- walk(expression, {
- enter(node, parent) {
- if (/Function/.test(node.type)) {
- if (node.type === 'FunctionDeclaration') {
- scope.declarations.add(node.id.name);
- }
- else {
- scope = new Scope(scope, false);
- map.set(node, scope);
- if (node.id)
- scope.declarations.add(node.id.name);
- }
- node.params.forEach((param) => {
- extractNames(param).forEach(name => {
- scope.declarations.add(name);
- });
- });
- }
- else if (/For(?:In|Of)Statement/.test(node.type)) {
- scope = new Scope(scope, true);
- map.set(node, scope);
- }
- else if (node.type === 'BlockStatement') {
- scope = new Scope(scope, true);
- map.set(node, scope);
- }
- else if (/(Function|Class|Variable)Declaration/.test(node.type)) {
- scope.addDeclaration(node);
- }
- else if (isReference(node, parent)) {
- if (!scope.has(node.name)) {
- globals.add(node.name);
- }
- }
- },
- leave(node) {
- if (map.has(node)) {
- scope = scope.parent;
- }
- },
- });
- return { map, scope, globals };
- }
- // TODO remove this in favour of weakmap version
- function annotateWithScopes(expression) {
- const globals = new Set();
- let scope = new Scope(null, false);
- walk(expression, {
- enter(node, parent) {
- if (/Function/.test(node.type)) {
- if (node.type === 'FunctionDeclaration') {
- scope.declarations.add(node.id.name);
- }
- else {
- node._scope = scope = new Scope(scope, false);
- if (node.id)
- scope.declarations.add(node.id.name);
- }
- node.params.forEach((param) => {
- extractNames(param).forEach(name => {
- scope.declarations.add(name);
- });
- });
- }
- else if (/For(?:In|Of)Statement/.test(node.type)) {
- node._scope = scope = new Scope(scope, true);
- }
- else if (node.type === 'BlockStatement') {
- node._scope = scope = new Scope(scope, true);
- }
- else if (/(Function|Class|Variable)Declaration/.test(node.type)) {
- scope.addDeclaration(node);
- }
- else if (isReference(node, parent)) {
- if (!scope.has(node.name)) {
- globals.add(node.name);
- }
- }
- },
- leave(node) {
- if (node._scope) {
- scope = scope.parent;
- }
- },
- });
- return { scope, globals };
- }
- class Scope {
- constructor(parent, block) {
- this.parent = parent;
- this.block = block;
- this.declarations = new Set();
- }
- addDeclaration(node) {
- if (node.kind === 'var' && !this.block && this.parent) {
- this.parent.addDeclaration(node);
- }
- else if (node.type === 'VariableDeclaration') {
- node.declarations.forEach((declarator) => {
- extractNames(declarator.id).forEach(name => {
- this.declarations.add(name);
- });
- });
- }
- else {
- this.declarations.add(node.id.name);
- }
- }
- has(name) {
- return (this.declarations.has(name) || (this.parent && this.parent.has(name)));
- }
- }
- function extractNames(param) {
- const names = [];
- extractors[param.type](names, param);
- return names;
- }
- const extractors = {
- Identifier(names, param) {
- names.push(param.name);
- },
- ObjectPattern(names, param) {
- param.properties.forEach((prop) => {
- if (prop.type === 'RestElement') {
- names.push(prop.argument.name);
- }
- else {
- extractors[prop.value.type](names, prop.value);
- }
- });
- },
- ArrayPattern(names, param) {
- param.elements.forEach((element) => {
- if (element)
- extractors[element.type](names, element);
- });
- },
- RestElement(names, param) {
- extractors[param.argument.type](names, param.argument);
- },
- AssignmentPattern(names, param) {
- extractors[param.left.type](names, param.left);
- },
- };
- const UNKNOWN = {};
- function gatherPossibleValues(node, set) {
- if (node.type === 'Literal') {
- set.add(node.value);
- }
- else if (node.type === 'ConditionalExpression') {
- gatherPossibleValues(node.consequent, set);
- gatherPossibleValues(node.alternate, set);
- }
- else {
- set.add(UNKNOWN);
- }
- }
- class Selector$1 {
- constructor(node, stylesheet) {
- this.node = node;
- this.stylesheet = stylesheet;
- this.blocks = groupSelectors(node);
- // take trailing :global(...) selectors out of consideration
- let i = this.blocks.length;
- while (i > 0) {
- if (!this.blocks[i - 1].global)
- break;
- i -= 1;
- }
- this.localBlocks = this.blocks.slice(0, i);
- this.used = this.blocks[0].global;
- }
- apply(node, stack) {
- const toEncapsulate = [];
- applySelector(this.stylesheet, this.localBlocks.slice(), node, stack.slice(), toEncapsulate);
- if (toEncapsulate.length > 0) {
- toEncapsulate.filter((_, i) => i === 0 || i === toEncapsulate.length - 1).forEach(({ node, block }) => {
- this.stylesheet.nodesWithCssClass.add(node);
- block.shouldEncapsulate = true;
- });
- this.used = true;
- }
- }
- minify(code) {
- let c = null;
- this.blocks.forEach((block, i) => {
- if (i > 0) {
- if (block.start - c > 1) {
- code.overwrite(c, block.start, block.combinator.name || ' ');
- }
- }
- c = block.end;
- });
- }
- transform(code, attr) {
- function encapsulateBlock(block) {
- let i = block.selectors.length;
- while (i--) {
- const selector = block.selectors[i];
- if (selector.type === 'PseudoElementSelector' || selector.type === 'PseudoClassSelector')
- continue;
- if (selector.type === 'TypeSelector' && selector.name === '*') {
- code.overwrite(selector.start, selector.end, attr);
- }
- else {
- code.appendLeft(selector.end, attr);
- }
- break;
- }
- i = block.selectors.length;
- while (i--) {
- const selector = block.selectors[i];
- if (selector.type === 'RefSelector') {
- code.overwrite(selector.start, selector.end, `.svelte-ref-${selector.name}`, {
- contentOnly: true,
- storeName: false
- });
- }
- }
- }
- this.blocks.forEach((block, i) => {
- if (block.global) {
- const selector = block.selectors[0];
- const first = selector.children[0];
- const last = selector.children[selector.children.length - 1];
- code.remove(selector.start, first.start).remove(last.end, selector.end);
- }
- if (block.shouldEncapsulate)
- encapsulateBlock(block);
- });
- }
- validate(component) {
- this.blocks.forEach((block) => {
- let i = block.selectors.length;
- while (i-- > 1) {
- const selector = block.selectors[i];
- if (selector.type === 'PseudoClassSelector' && selector.name === 'global') {
- component.error(selector, {
- code: `css-invalid-global`,
- message: `:global(...) must be the first element in a compound selector`
- });
- }
- }
- });
- let start = 0;
- let end = this.blocks.length;
- for (; start < end; start += 1) {
- if (!this.blocks[start].global)
- break;
- }
- for (; end > start; end -= 1) {
- if (!this.blocks[end - 1].global)
- break;
- }
- for (let i = start; i < end; i += 1) {
- if (this.blocks[i].global) {
- component.error(this.blocks[i].selectors[0], {
- code: `css-invalid-global`,
- message: `:global(...) can be at the start or end of a selector sequence, but not in the middle`
- });
- }
- }
- }
- }
- function applySelector(stylesheet, blocks, node, stack, toEncapsulate) {
- const block = blocks.pop();
- if (!block)
- return false;
- if (!node) {
- return blocks.every(block => block.global);
- }
- let i = block.selectors.length;
- while (i--) {
- const selector = block.selectors[i];
- if (selector.type === 'PseudoClassSelector' && selector.name === 'global') {
- // TODO shouldn't see this here... maybe we should enforce that :global(...)
- // cannot be sandwiched between non-global selectors?
- return false;
- }
- if (selector.type === 'PseudoClassSelector' || selector.type === 'PseudoElementSelector') {
- continue;
- }
- if (selector.type === 'ClassSelector') {
- if (!attributeMatches(node, 'class', selector.name, '~=', false) && !classMatches(node, selector.name))
- return false;
- }
- else if (selector.type === 'IdSelector') {
- if (!attributeMatches(node, 'id', selector.name, '=', false))
- return false;
- }
- else if (selector.type === 'AttributeSelector') {
- if (!attributeMatches(node, selector.name.name, selector.value && unquote(selector.value), selector.matcher, selector.flags))
- return false;
- }
- else if (selector.type === 'TypeSelector') {
- // remove toLowerCase() in v2, when uppercase elements will be forbidden
- if (node.name.toLowerCase() !== selector.name.toLowerCase() && selector.name !== '*')
- return false;
- }
- else if (selector.type === 'RefSelector') {
- if (node.ref && node.ref.name === selector.name) {
- stylesheet.nodesWithRefCssClass.set(selector.name, node);
- toEncapsulate.push({ node, block });
- return true;
- }
- return;
- }
- else {
- // bail. TODO figure out what these could be
- toEncapsulate.push({ node, block });
- return true;
- }
- }
- if (block.combinator) {
- if (block.combinator.type === 'WhiteSpace') {
- while (stack.length) {
- if (applySelector(stylesheet, blocks.slice(), stack.pop(), stack, toEncapsulate)) {
- toEncapsulate.push({ node, block });
- return true;
- }
- }
- if (blocks.every(block => block.global)) {
- toEncapsulate.push({ node, block });
- return true;
- }
- return false;
- }
- else if (block.combinator.name === '>') {
- if (applySelector(stylesheet, blocks, stack.pop(), stack, toEncapsulate)) {
- toEncapsulate.push({ node, block });
- return true;
- }
- return false;
- }
- // TODO other combinators
- toEncapsulate.push({ node, block });
- return true;
- }
- toEncapsulate.push({ node, block });
- return true;
- }
- const operators = {
- '=': (value, flags) => new RegExp(`^${value}$`, flags),
- '~=': (value, flags) => new RegExp(`\\b${value}\\b`, flags),
- '|=': (value, flags) => new RegExp(`^${value}(-.+)?$`, flags),
- '^=': (value, flags) => new RegExp(`^${value}`, flags),
- '$=': (value, flags) => new RegExp(`${value}$`, flags),
- '*=': (value, flags) => new RegExp(value, flags)
- };
- function attributeMatches(node, name, expectedValue, operator, caseInsensitive) {
- const spread = node.attributes.find(attr => attr.type === 'Spread');
- if (spread)
- return true;
- const attr = node.attributes.find((attr) => attr.name === name);
- if (!attr)
- return false;
- if (attr.isTrue)
- return operator === null;
- if (attr.chunks.length > 1)
- return true;
- if (!expectedValue)
- return true;
- const pattern = operators[operator](expectedValue, caseInsensitive ? 'i' : '');
- const value = attr.chunks[0];
- if (!value)
- return false;
- if (value.type === 'Text')
- return pattern.test(value.data);
- const possibleValues = new Set();
- gatherPossibleValues(value.node, possibleValues);
- if (possibleValues.has(UNKNOWN))
- return true;
- for (const x of Array.from(possibleValues)) { // TypeScript for-of is slightly unlike JS
- if (pattern.test(x))
- return true;
- }
- return false;
- }
- function classMatches(node, name) {
- return node.classes.some(function (classDir) {
- return classDir.name === name;
- });
- }
- function unquote(value) {
- if (value.type === 'Identifier')
- return value.name;
- const str = value.value;
- if (str[0] === str[str.length - 1] && str[0] === "'" || str[0] === '"') {
- return str.slice(1, str.length - 1);
- }
- return str;
- }
- class Block$2 {
- constructor(combinator) {
- this.combinator = combinator;
- this.global = false;
- this.selectors = [];
- this.start = null;
- this.end = null;
- this.shouldEncapsulate = false;
- }
- add(selector) {
- if (this.selectors.length === 0) {
- this.start = selector.start;
- this.global = selector.type === 'PseudoClassSelector' && selector.name === 'global';
- }
- this.selectors.push(selector);
- this.end = selector.end;
- }
- }
- function groupSelectors(selector) {
- let block = new Block$2(null);
- const blocks = [block];
- selector.children.forEach((child, i) => {
- if (child.type === 'WhiteSpace' || child.type === 'Combinator') {
- block = new Block$2(child);
- blocks.push(block);
- }
- else {
- block.add(child);
- }
- });
- return blocks;
- }
- // https://github.com/darkskyapp/string-hash/blob/master/index.js
- function hash$1(str) {
- let hash = 5381;
- let i = str.length;
- while (i--)
- hash = ((hash << 5) - hash) ^ str.charCodeAt(i);
- return (hash >>> 0).toString(36);
- }
- function removeCSSPrefix (name) {
- return name.replace(/^-((webkit)|(moz)|(o)|(ms))-/, '');
- }
- const isKeyframesNode = (node) => removeCSSPrefix(node.name) === 'keyframes';
- class Rule$1 {
- constructor(node, stylesheet, parent) {
- this.node = node;
- this.parent = parent;
- this.selectors = node.selector.children.map((node) => new Selector$1(node, stylesheet));
- this.declarations = node.block.children.map((node) => new Declaration$1(node));
- }
- apply(node, stack) {
- this.selectors.forEach(selector => selector.apply(node, stack)); // TODO move the logic in here?
- }
- isUsed(dev) {
- if (this.parent && this.parent.node.type === 'Atrule' && isKeyframesNode(this.parent.node))
- return true;
- if (this.declarations.length === 0)
- return dev;
- return this.selectors.some(s => s.used);
- }
- minify(code, dev) {
- let c = this.node.start;
- let started = false;
- this.selectors.forEach((selector, i) => {
- if (selector.used) {
- const separator = started ? ',' : '';
- if ((selector.node.start - c) > separator.length) {
- code.overwrite(c, selector.node.start, separator);
- }
- selector.minify(code);
- c = selector.node.end;
- started = true;
- }
- });
- code.remove(c, this.node.block.start);
- c = this.node.block.start + 1;
- this.declarations.forEach((declaration, i) => {
- const separator = i > 0 ? ';' : '';
- if ((declaration.node.start - c) > separator.length) {
- code.overwrite(c, declaration.node.start, separator);
- }
- declaration.minify(code);
- c = declaration.node.end;
- });
- code.remove(c, this.node.block.end - 1);
- }
- transform(code, id, keyframes) {
- if (this.parent && this.parent.node.type === 'Atrule' && isKeyframesNode(this.parent.node))
- return true;
- const attr = `.${id}`;
- this.selectors.forEach(selector => selector.transform(code, attr));
- this.declarations.forEach(declaration => declaration.transform(code, keyframes));
- }
- validate(component) {
- this.selectors.forEach(selector => {
- selector.validate(component);
- });
- }
- warnOnUnusedSelector(handler) {
- this.selectors.forEach(selector => {
- if (!selector.used)
- handler(selector);
- });
- }
- }
- class Declaration$1 {
- constructor(node) {
- this.node = node;
- }
- transform(code, keyframes) {
- const property = this.node.property && removeCSSPrefix(this.node.property.toLowerCase());
- if (property === 'animation' || property === 'animation-name') {
- this.node.value.children.forEach((block) => {
- if (block.type === 'Identifier') {
- const name = block.name;
- if (keyframes.has(name)) {
- code.overwrite(block.start, block.end, keyframes.get(name));
- }
- }
- });
- }
- }
- minify(code) {
- if (!this.node.property)
- return; // @apply, and possibly other weird cases?
- const c = this.node.start + this.node.property.length;
- const first = this.node.value.children ?
- this.node.value.children[0] :
- this.node.value;
- let start = first.start;
- while (/\s/.test(code.original[start]))
- start += 1;
- if (start - c > 1) {
- code.overwrite(c, start, ':');
- }
- }
- }
- class Atrule$1 {
- constructor(node) {
- this.node = node;
- this.children = [];
- }
- apply(node, stack) {
- if (this.node.name === 'media' || this.node.name === 'supports') {
- this.children.forEach(child => {
- child.apply(node, stack);
- });
- }
- else if (isKeyframesNode(this.node)) {
- this.children.forEach((rule) => {
- rule.selectors.forEach(selector => {
- selector.used = true;
- });
- });
- }
- }
- isUsed(dev) {
- return true; // TODO
- }
- minify(code, dev) {
- if (this.node.name === 'media') {
- const expressionChar = code.original[this.node.expression.start];
- let c = this.node.start + (expressionChar === '(' ? 6 : 7);
- if (this.node.expression.start > c)
- code.remove(c, this.node.expression.start);
- this.node.expression.children.forEach((query) => {
- // TODO minify queries
- c = query.end;
- });
- code.remove(c, this.node.block.start);
- }
- else if (isKeyframesNode(this.node)) {
- let c = this.node.start + this.node.name.length + 1;
- if (this.node.expression.start - c > 1)
- code.overwrite(c, this.node.expression.start, ' ');
- c = this.node.expression.end;
- if (this.node.block.start - c > 0)
- code.remove(c, this.node.block.start);
- }
- else if (this.node.name === 'supports') {
- let c = this.node.start + 9;
- if (this.node.expression.start - c > 1)
- code.overwrite(c, this.node.expression.start, ' ');
- this.node.expression.children.forEach((query) => {
- // TODO minify queries
- c = query.end;
- });
- code.remove(c, this.node.block.start);
- }
- // TODO other atrules
- if (this.node.block) {
- let c = this.node.block.start + 1;
- this.children.forEach(child => {
- if (child.isUsed(dev)) {
- code.remove(c, child.node.start);
- child.minify(code, dev);
- c = child.node.end;
- }
- });
- code.remove(c, this.node.block.end - 1);
- }
- }
- transform(code, id, keyframes) {
- if (isKeyframesNode(this.node)) {
- this.node.expression.children.forEach(({ type, name, start, end }) => {
- if (type === 'Identifier') {
- if (name.startsWith('-global-')) {
- code.remove(start, start + 8);
- }
- else {
- code.overwrite(start, end, keyframes.get(name));
- }
- }
- });
- }
- this.children.forEach(child => {
- child.transform(code, id, keyframes);
- });
- }
- validate(component) {
- this.children.forEach(child => {
- child.validate(component);
- });
- }
- warnOnUnusedSelector(handler) {
- if (this.node.name !== 'media')
- return;
- this.children.forEach(child => {
- child.warnOnUnusedSelector(handler);
- });
- }
- }
- class Stylesheet {
- constructor(source, ast, filename, dev) {
- this.source = source;
- this.ast = ast;
- this.filename = filename;
- this.dev = dev;
- this.children = [];
- this.keyframes = new Map();
- this.nodesWithCssClass = new Set();
- this.nodesWithRefCssClass = new Map();
- if (ast.css && ast.css.children.length) {
- this.id = `svelte-${hash$1(ast.css.content.styles)}`;
- this.hasStyles = true;
- const stack = [];
- let currentAtrule = null;
- walk(this.ast.css, {
- enter: (node) => {
- if (node.type === 'Atrule') {
- const last = stack[stack.length - 1];
- const atrule = new Atrule$1(node);
- stack.push(atrule);
- // this is an awkward special case — @apply (and
- // possibly other future constructs)
- if (last && !(last instanceof Atrule$1))
- return;
- if (currentAtrule) {
- currentAtrule.children.push(atrule);
- }
- else {
- this.children.push(atrule);
- }
- if (isKeyframesNode(node)) {
- node.expression.children.forEach((expression) => {
- if (expression.type === 'Identifier' && !expression.name.startsWith('-global-')) {
- this.keyframes.set(expression.name, `${this.id}-${expression.name}`);
- }
- });
- }
- currentAtrule = atrule;
- }
- if (node.type === 'Rule') {
- const rule = new Rule$1(node, this, currentAtrule);
- stack.push(rule);
- if (currentAtrule) {
- currentAtrule.children.push(rule);
- }
- else {
- this.children.push(rule);
- }
- }
- },
- leave: (node) => {
- if (node.type === 'Rule' || node.type === 'Atrule')
- stack.pop();
- if (node.type === 'Atrule')
- currentAtrule = stack[stack.length - 1];
- }
- });
- }
- else {
- this.hasStyles = false;
- }
- }
- apply(node) {
- if (!this.hasStyles)
- return;
- const stack = [];
- let parent = node;
- while (parent = parent.parent) {
- if (parent.type === 'Element')
- stack.unshift(parent);
- }
- for (let i = 0; i < this.children.length; i += 1) {
- const child = this.children[i];
- child.apply(node, stack);
- }
- }
- reify() {
- this.nodesWithCssClass.forEach((node) => {
- node.addCssClass();
- });
- this.nodesWithRefCssClass.forEach((node, name) => {
- node.addCssClass(`svelte-ref-${name}`);
- });
- }
- render(cssOutputFilename, shouldTransformSelectors) {
- if (!this.hasStyles) {
- return { code: null, map: null };
- }
- const code = new MagicString(this.source);
- walk(this.ast.css, {
- enter: (node) => {
- code.addSourcemapLocation(node.start);
- code.addSourcemapLocation(node.end);
- }
- });
- if (shouldTransformSelectors) {
- this.children.forEach((child) => {
- child.transform(code, this.id, this.keyframes);
- });
- }
- let c = 0;
- this.children.forEach(child => {
- if (child.isUsed(this.dev)) {
- code.remove(c, child.node.start);
- child.minify(code, this.dev);
- c = child.node.end;
- }
- });
- code.remove(c, this.source.length);
- return {
- code: code.toString(),
- map: code.generateMap({
- includeContent: true,
- source: this.filename,
- file: cssOutputFilename
- })
- };
- }
- validate(component) {
- this.children.forEach(child => {
- child.validate(component);
- });
- }
- warnOnUnusedSelectors(onwarn) {
- let locator;
- const handler = (selector) => {
- const pos = selector.node.start;
- if (!locator)
- locator = getLocator(this.source, { offsetLine: 1 });
- const start = locator(pos);
- const end = locator(selector.node.end);
- const frame = getCodeFrame(this.source, start.line - 1, start.column);
- const message = `Unused CSS selector`;
- onwarn({
- code: `css-unused-selector`,
- message,
- frame,
- start,
- end,
- pos,
- filename: this.filename,
- toString: () => `${message} (${start.line}:${start.column})\n${frame}`,
- });
- };
- this.children.forEach(child => {
- child.warnOnUnusedSelector(handler);
- });
- }
- }
- const test = typeof process !== 'undefined' && process.env.TEST;
- class Node$1 {
- constructor(component, parent, scope, info) {
- this.start = info.start;
- this.end = info.end;
- this.type = info.type;
- // this makes properties non-enumerable, which makes logging
- // bearable. might have a performance cost. TODO remove in prod?
- Object.defineProperties(this, {
- component: {
- value: component
- },
- parent: {
- value: parent
- }
- });
- }
- cannotUseInnerHTML() {
- if (this.canUseInnerHTML !== false) {
- this.canUseInnerHTML = false;
- if (this.parent)
- this.parent.cannotUseInnerHTML();
- }
- }
- hasAncestor(type) {
- return this.parent ?
- this.parent.type === type || this.parent.hasAncestor(type) :
- false;
- }
- findNearest(selector) {
- if (selector.test(this.type))
- return this;
- if (this.parent)
- return this.parent.findNearest(selector);
- }
- remount(name) {
- return `${this.var}.m(${name}._slotted.default, null);`;
- }
- warnIfEmptyBlock() {
- if (!this.component.options.dev)
- return;
- if (!/Block$/.test(this.type) || !this.children)
- return;
- if (this.children.length > 1)
- return;
- const child = this.children[0];
- if (!child || (child.type === 'Text' && !/[^ \r\n\f\v\t]/.test(child.data))) {
- this.component.warn(this, {
- code: 'empty-block',
- message: 'Empty block'
- });
- }
- }
- }
- class PendingBlock extends Node$1 {
- constructor(component, parent, scope, info) {
- super(component, parent, scope, info);
- this.children = mapChildren(component, parent, scope, info.children);
- this.warnIfEmptyBlock();
- }
- }
- class ThenBlock extends Node$1 {
- constructor(component, parent, scope, info) {
- super(component, parent, scope, info);
- this.children = mapChildren(component, parent, scope, info.children);
- this.warnIfEmptyBlock();
- }
- }
- class CatchBlock extends Node$1 {
- constructor(component, parent, scope, info) {
- super(component, parent, scope, info);
- this.children = mapChildren(component, parent, scope, info.children);
- this.warnIfEmptyBlock();
- }
- }
- const binaryOperators = {
- '**': 15,
- '*': 14,
- '/': 14,
- '%': 14,
- '+': 13,
- '-': 13,
- '<<': 12,
- '>>': 12,
- '>>>': 12,
- '<': 11,
- '<=': 11,
- '>': 11,
- '>=': 11,
- 'in': 11,
- 'instanceof': 11,
- '==': 10,
- '!=': 10,
- '===': 10,
- '!==': 10,
- '&': 9,
- '^': 8,
- '|': 7
- };
- const logicalOperators = {
- '&&': 6,
- '||': 5
- };
- const precedence = {
- Literal: () => 21,
- Identifier: () => 21,
- ParenthesizedExpression: () => 20,
- MemberExpression: () => 19,
- NewExpression: () => 19,
- CallExpression: () => 19,
- UpdateExpression: () => 17,
- UnaryExpression: () => 16,
- BinaryExpression: (node) => binaryOperators[node.operator],
- LogicalExpression: (node) => logicalOperators[node.operator],
- ConditionalExpression: () => 4,
- AssignmentExpression: () => 3,
- YieldExpression: () => 2,
- SpreadElement: () => 1,
- SequenceExpression: () => 0
- };
- class Expression {
- constructor(component, parent, scope, info) {
- this.usesContext = false;
- this.usesEvent = false;
- // TODO revert to direct property access in prod?
- Object.defineProperties(this, {
- component: {
- value: component
- }
- });
- this.node = info;
- this.thisReferences = [];
- this.snippet = `[✂${info.start}-${info.end}✂]`;
- const dependencies = new Set();
- const { code, helpers } = component;
- let { map, scope: currentScope } = createScopes(info);
- const isEventHandler = parent.type === 'EventHandler';
- const expression = this;
- const isSynthetic = parent.isSynthetic;
- walk(info, {
- enter(node, parent, key) {
- // don't manipulate shorthand props twice
- if (key === 'value' && parent.shorthand)
- return;
- code.addSourcemapLocation(node.start);
- code.addSourcemapLocation(node.end);
- if (map.has(node)) {
- currentScope = map.get(node);
- return;
- }
- if (node.type === 'ThisExpression') {
- expression.thisReferences.push(node);
- }
- if (isReference(node, parent)) {
- const { name, nodes } = flattenReference(node);
- if (name === 'event' && isEventHandler) {
- expression.usesEvent = true;
- return;
- }
- if (currentScope.has(name))
- return;
- if (component.helpers.has(name)) {
- let object = node;
- while (object.type === 'MemberExpression')
- object = object.object;
- component.used.helpers.add(name);
- const alias = component.templateVars.get(`helpers-${name}`);
- if (alias !== name)
- code.overwrite(object.start, object.end, alias);
- return;
- }
- expression.usesContext = true;
- if (!isSynthetic) {
- // <option> value attribute could be synthetic — avoid double editing
- code.prependRight(node.start, key === 'key' && parent.shorthand
- ? `${name}: ctx.`
- : 'ctx.');
- }
- if (scope.names.has(name)) {
- scope.dependenciesForName.get(name).forEach(dependency => {
- dependencies.add(dependency);
- });
- }
- else {
- dependencies.add(name);
- component.expectedProperties.add(name);
- }
- if (node.type === 'MemberExpression') {
- nodes.forEach(node => {
- code.addSourcemapLocation(node.start);
- code.addSourcemapLocation(node.end);
- });
- }
- this.skip();
- }
- },
- leave(node, parent) {
- if (map.has(node))
- currentScope = currentScope.parent;
- }
- });
- this.dependencies = dependencies;
- }
- getPrecedence() {
- return this.node.type in precedence ? precedence[this.node.type](this.node) : 0;
- }
- overwriteThis(name) {
- this.thisReferences.forEach(ref => {
- this.component.code.overwrite(ref.start, ref.end, name, {
- storeName: true
- });
- });
- }
- }
- class AwaitBlock$1 extends Node$1 {
- constructor(component, parent, scope, info) {
- super(component, parent, scope, info);
- this.expression = new Expression(component, this, scope, info.expression);
- const deps = this.expression.dependencies;
- this.value = info.value;
- this.error = info.error;
- this.pending = new PendingBlock(component, this, scope, info.pending);
- this.then = new ThenBlock(component, this, scope.add(this.value, deps), info.then);
- this.catch = new CatchBlock(component, this, scope.add(this.error, deps), info.catch);
- }
- }
- class Comment$2 extends Node$1 {
- constructor(component, parent, scope, info) {
- super(component, parent, scope, info);
- this.data = info.data;
- }
- }
- const validCalleeObjects = new Set(['this', 'event', 'console']);
- const validBuiltins = new Set(['set', 'fire', 'destroy']);
- class EventHandler extends Node$1 {
- constructor(component, parent, scope, info) {
- super(component, parent, scope, info);
- this.name = info.name;
- this.modifiers = new Set(info.modifiers);
- component.used.events.add(this.name);
- this.dependencies = new Set();
- if (info.expression) {
- this.validateExpression(info.expression);
- this.callee = flattenReference(info.expression.callee);
- this.insertionPoint = info.expression.start;
- this.usesComponent = !validCalleeObjects.has(this.callee.name);
- this.usesContext = false;
- this.usesEventObject = this.callee.name === 'event';
- this.args = info.expression.arguments.map(param => {
- const expression = new Expression(component, this, scope, param);
- addToSet(this.dependencies, expression.dependencies);
- if (expression.usesContext)
- this.usesContext = true;
- if (expression.usesEvent)
- this.usesEventObject = true;
- return expression;
- });
- this.snippet = `[✂${info.expression.start}-${info.expression.end}✂];`;
- }
- else {
- this.callee = null;
- this.insertionPoint = null;
- this.args = null;
- this.usesComponent = true;
- this.usesContext = false;
- this.usesEventObject = true;
- this.snippet = null; // TODO handle shorthand events here?
- }
- this.isCustomEvent = component.events.has(this.name);
- this.shouldHoist = !this.isCustomEvent && parent.hasAncestor('EachBlock');
- }
- render(component, block, context, hoisted) {
- if (this.insertionPoint === null)
- return; // TODO handle shorthand events here?
- if (!validCalleeObjects.has(this.callee.name)) {
- const component_name = hoisted ? `component` : block.alias(`component`);
- // allow event.stopPropagation(), this.select() etc
- // TODO verify that it's a valid callee (i.e. built-in or declared method)
- if (this.callee.name[0] === '$' && !component.methods.has(this.callee.name)) {
- component.code.overwrite(this.insertionPoint, this.insertionPoint + 1, `${component_name}.store.`);
- }
- else {
- component.code.prependRight(this.insertionPoint, `${component_name}.`);
- }
- }
- if (this.isCustomEvent) {
- this.args.forEach(arg => {
- arg.overwriteThis(context);
- });
- if (this.callee && this.callee.name === 'this') {
- const node = this.callee.nodes[0];
- component.code.overwrite(node.start, node.end, context, {
- storeName: true,
- contentOnly: true
- });
- }
- }
- }
- validateExpression(expression) {
- const { callee, type } = expression;
- if (type !== 'CallExpression') {
- this.component.error(expression, {
- code: `invalid-event-handler`,
- message: `Expected a call expression`
- });
- }
- const { component } = this;
- const { name } = flattenReference(callee);
- if (validCalleeObjects.has(name) || name === 'options')
- return;
- if (name === 'refs') {
- this.component.refCallees.push(callee);
- return;
- }
- if ((callee.type === 'Identifier' && validBuiltins.has(name)) ||
- this.component.methods.has(name)) {
- return;
- }
- if (name[0] === '$') {
- // assume it's a store method
- return;
- }
- const validCallees = ['this.*', 'refs.*', 'event.*', 'options.*', 'console.*'].concat(Array.from(validBuiltins), Array.from(this.component.methods.keys()));
- let message = `'${component.source.slice(callee.start, callee.end)}' is an invalid callee `;
- if (name === 'store') {
- message += `(did you mean '$${component.source.slice(callee.start + 6, callee.end)}(...)'?)`;
- }
- else {
- message += `(should be one of ${list$1(validCallees)})`;
- if (callee.type === 'Identifier' && component.helpers.has(callee.name)) {
- message += `. '${callee.name}' exists on 'helpers', did you put it in the wrong place?`;
- }
- }
- component.warn(expression, {
- code: `invalid-callee`,
- message
- });
- }
- }
- class Document extends Node$1 {
- constructor(component, parent, scope, info) {
- super(component, parent, scope, info);
- this.handlers = [];
- info.attributes.forEach(node => {
- if (node.type === 'EventHandler') {
- this.handlers.push(new EventHandler(component, this, scope, node));
- }
- });
- }
- }
- class ElseBlock extends Node$1 {
- constructor(component, parent, scope, info) {
- super(component, parent, scope, info);
- this.children = mapChildren(component, this, scope, info.children);
- this.warnIfEmptyBlock();
- }
- }
- function unpackDestructuring(contexts, node, tail) {
- if (!node)
- return;
- if (node.type === 'Identifier') {
- contexts.push({
- key: node,
- tail
- });
- }
- else if (node.type === 'ArrayPattern') {
- node.elements.forEach((element, i) => {
- unpackDestructuring(contexts, element, `${tail}[${i}]`);
- });
- }
- else if (node.type === 'ObjectPattern') {
- node.properties.forEach((property) => {
- unpackDestructuring(contexts, property.value, `${tail}.${property.key.name}`);
- });
- }
- }
- class EachBlock$1 extends Node$1 {
- constructor(component, parent, scope, info) {
- super(component, parent, scope, info);
- this.expression = new Expression(component, this, scope, info.expression);
- this.context = info.context.name || 'each'; // TODO this is used to facilitate binding; currently fails with destructuring
- this.index = info.index;
- this.scope = scope.child();
- this.contexts = [];
- unpackDestructuring(this.contexts, info.context, '');
- this.contexts.forEach(context => {
- if (component.helpers.has(context.key.name)) {
- component.warn(context.key, {
- code: `each-context-clash`,
- message: `Context clashes with a helper. Rename one or the other to eliminate any ambiguity`
- });
- }
- this.scope.add(context.key.name, this.expression.dependencies);
- });
- this.key = info.key
- ? new Expression(component, this, this.scope, info.key)
- : null;
- if (this.index) {
- // index can only change if this is a keyed each block
- const dependencies = this.key ? this.expression.dependencies : [];
- this.scope.add(this.index, dependencies);
- }
- this.hasAnimation = false;
- this.children = mapChildren(component, this, this.scope, info.children);
- if (this.hasAnimation) {
- if (this.children.length !== 1) {
- const child = this.children.find(child => !!child.animation);
- component.error(child.animation, {
- code: `invalid-animation`,
- message: `An element that use the animate directive must be the sole child of a keyed each block`
- });
- }
- }
- this.warnIfEmptyBlock(); // TODO would be better if EachBlock, IfBlock etc extended an abstract Block class
- this.else = info.else
- ? new ElseBlock(component, this, this.scope, info.else)
- : null;
- }
- }
- class Attribute$1 extends Node$1 {
- constructor(component, parent, scope, info) {
- super(component, parent, scope, info);
- if (info.type === 'Spread') {
- this.name = null;
- this.isSpread = true;
- this.isTrue = false;
- this.isSynthetic = false;
- this.expression = new Expression(component, this, scope, info.expression);
- this.dependencies = this.expression.dependencies;
- this.chunks = null;
- this.isDynamic = true; // TODO not necessarily
- this.shouldCache = false; // TODO does this mean anything here?
- }
- else {
- this.name = info.name;
- this.isTrue = info.value === true;
- this.isSynthetic = info.synthetic;
- this.dependencies = new Set();
- this.chunks = this.isTrue
- ? []
- : info.value.map(node => {
- if (node.type === 'Text')
- return node;
- const expression = new Expression(component, this, scope, node.expression);
- addToSet(this.dependencies, expression.dependencies);
- return expression;
- });
- this.isDynamic = this.dependencies.size > 0;
- this.shouldCache = this.isDynamic
- ? this.chunks.length === 1
- ? this.chunks[0].node.type !== 'Identifier' || scope.names.has(this.chunks[0].node.name)
- : true
- : false;
- }
- }
- getValue() {
- if (this.isTrue)
- return true;
- if (this.chunks.length === 0)
- return `""`;
- if (this.chunks.length === 1) {
- return this.chunks[0].type === 'Text'
- ? stringify(this.chunks[0].data)
- : this.chunks[0].snippet;
- }
- return (this.chunks[0].type === 'Text' ? '' : `"" + `) +
- this.chunks
- .map(chunk => {
- if (chunk.type === 'Text') {
- return stringify(chunk.data);
- }
- else {
- return chunk.getPrecedence() <= 13 ? `(${chunk.snippet})` : chunk.snippet;
- }
- })
- .join(' + ');
- }
- getStaticValue() {
- if (this.isSpread || this.isDynamic)
- return null;
- return this.isTrue
- ? true
- : this.chunks[0]
- ? this.chunks[0].data
- : '';
- }
- }
- class Binding extends Node$1 {
- constructor(component, parent, scope, info) {
- super(component, parent, scope, info);
- this.name = info.name;
- this.value = new Expression(component, this, scope, info.value);
- let obj;
- let prop;
- const { name } = getObject(this.value.node);
- this.isContextual = scope.names.has(name);
- if (this.value.node.type === 'MemberExpression') {
- prop = `[✂${this.value.node.property.start}-${this.value.node.property.end}✂]`;
- if (!this.value.node.computed)
- prop = `'${prop}'`;
- obj = `[✂${this.value.node.object.start}-${this.value.node.object.end}✂]`;
- this.usesContext = true;
- }
- else {
- obj = 'ctx';
- prop = `'${name}'`;
- this.usesContext = scope.names.has(name);
- }
- this.obj = obj;
- this.prop = prop;
- }
- }
- class Transition extends Node$1 {
- constructor(component, parent, scope, info) {
- super(component, parent, scope, info);
- if (!component.transitions.has(info.name)) {
- component.error(info, {
- code: `missing-transition`,
- message: `Missing transition '${info.name}'`
- });
- }
- this.name = info.name;
- this.directive = info.intro && info.outro ? 'transition' : info.intro ? 'in' : 'out';
- if ((info.intro && parent.intro) || (info.outro && parent.outro)) {
- const parentTransition = (parent.intro || parent.outro);
- const message = this.directive === parentTransition.directive
- ? `An element can only have one '${this.directive}' directive`
- : `An element cannot have both ${describe(parentTransition)} directive and ${describe(this)} directive`;
- component.error(info, {
- code: `duplicate-transition`,
- message
- });
- }
- this.component.used.transitions.add(this.name);
- this.expression = info.expression
- ? new Expression(component, this, scope, info.expression)
- : null;
- }
- }
- function describe(transition) {
- return transition.directive === 'transition'
- ? `a 'transition'`
- : `an '${transition.directive}'`;
- }
- class Animation extends Node$1 {
- constructor(component, parent, scope, info) {
- super(component, parent, scope, info);
- this.name = info.name;
- component.used.animations.add(this.name);
- if (parent.animation) {
- component.error(this, {
- code: `duplicate-animation`,
- message: `An element can only have one 'animate' directive`
- });
- }
- if (!component.animations.has(this.name)) {
- component.error(this, {
- code: `missing-animation`,
- message: `Missing animation '${this.name}'`
- });
- }
- const block = parent.parent;
- if (!block || block.type !== 'EachBlock' || !block.key) {
- // TODO can we relax the 'immediate child' rule?
- component.error(this, {
- code: `invalid-animation`,
- message: `An element that use the animate directive must be the immediate child of a keyed each block`
- });
- }
- block.hasAnimation = true;
- this.expression = info.expression
- ? new Expression(component, this, scope, info.expression)
- : null;
- }
- }
- class Action extends Node$1 {
- constructor(component, parent, scope, info) {
- super(component, parent, scope, info);
- this.name = info.name;
- component.used.actions.add(this.name);
- if (!component.actions.has(this.name)) {
- component.error(this, {
- code: `missing-action`,
- message: `Missing action '${this.name}'`
- });
- }
- this.expression = info.expression
- ? new Expression(component, this, scope, info.expression)
- : null;
- }
- }
- class Class extends Node$1 {
- constructor(component, parent, scope, info) {
- super(component, parent, scope, info);
- this.name = info.name;
- this.expression = info.expression
- ? new Expression(component, this, scope, info.expression)
- : null;
- }
- }
- class Text$2 extends Node$1 {
- constructor(component, parent, scope, info) {
- super(component, parent, scope, info);
- this.data = info.data;
- }
- }
- // adapted from https://github.com/Glench/fuzzyset.js/blob/master/lib/fuzzyset.js
- // BSD Licensed
- const GRAM_SIZE_LOWER = 2;
- const GRAM_SIZE_UPPER = 3;
- // return an edit distance from 0 to 1
- function _distance(str1, str2) {
- if (str1 === null && str2 === null)
- throw 'Trying to compare two null values';
- if (str1 === null || str2 === null)
- return 0;
- str1 = String(str1);
- str2 = String(str2);
- const distance = levenshtein(str1, str2);
- if (str1.length > str2.length) {
- return 1 - distance / str1.length;
- }
- else {
- return 1 - distance / str2.length;
- }
- }
- // helper functions
- function levenshtein(str1, str2) {
- const current = [];
- let prev;
- let value;
- for (let i = 0; i <= str2.length; i++) {
- for (let j = 0; j <= str1.length; j++) {
- if (i && j) {
- if (str1.charAt(j - 1) === str2.charAt(i - 1)) {
- value = prev;
- }
- else {
- value = Math.min(current[j], current[j - 1], prev) + 1;
- }
- }
- else {
- value = i + j;
- }
- prev = current[j];
- current[j] = value;
- }
- }
- return current.pop();
- }
- const _nonWordRe = /[^\w, ]+/;
- function _iterateGrams(value, gramSize) {
- gramSize = gramSize || 2;
- const simplified = '-' + value.toLowerCase().replace(_nonWordRe, '') + '-';
- const lenDiff = gramSize - simplified.length;
- const results = [];
- if (lenDiff > 0) {
- for (let i = 0; i < lenDiff; ++i) {
- value += '-';
- }
- }
- for (let i = 0; i < simplified.length - gramSize + 1; ++i) {
- results.push(simplified.slice(i, i + gramSize));
- }
- return results;
- }
- function _gramCounter(value, gramSize) {
- // return an object where key=gram, value=number of occurrences
- gramSize = gramSize || 2;
- const result = {};
- const grams = _iterateGrams(value, gramSize);
- let i = 0;
- for (i; i < grams.length; ++i) {
- if (grams[i] in result) {
- result[grams[i]] += 1;
- }
- else {
- result[grams[i]] = 1;
- }
- }
- return result;
- }
- function sortDescending(a, b) {
- return b[0] - a[0];
- }
- class FuzzySet {
- constructor(arr) {
- // define all the object functions and attributes
- this.exactSet = {};
- this.matchDict = {};
- this.items = {};
- // initialization
- for (let i = GRAM_SIZE_LOWER; i < GRAM_SIZE_UPPER + 1; ++i) {
- this.items[i] = [];
- }
- // add all the items to the set
- for (let i = 0; i < arr.length; ++i) {
- this.add(arr[i]);
- }
- }
- add(value) {
- const normalizedValue = value.toLowerCase();
- if (normalizedValue in this.exactSet) {
- return false;
- }
- let i = GRAM_SIZE_LOWER;
- for (i; i < GRAM_SIZE_UPPER + 1; ++i) {
- this._add(value, i);
- }
- }
- _add(value, gramSize) {
- const normalizedValue = value.toLowerCase();
- const items = this.items[gramSize] || [];
- const index = items.length;
- items.push(0);
- const gramCounts = _gramCounter(normalizedValue, gramSize);
- let sumOfSquareGramCounts = 0;
- let gram;
- let gramCount;
- for (gram in gramCounts) {
- gramCount = gramCounts[gram];
- sumOfSquareGramCounts += Math.pow(gramCount, 2);
- if (gram in this.matchDict) {
- this.matchDict[gram].push([index, gramCount]);
- }
- else {
- this.matchDict[gram] = [[index, gramCount]];
- }
- }
- const vectorNormal = Math.sqrt(sumOfSquareGramCounts);
- items[index] = [vectorNormal, normalizedValue];
- this.items[gramSize] = items;
- this.exactSet[normalizedValue] = value;
- }
- ;
- get(value) {
- const normalizedValue = value.toLowerCase();
- const result = this.exactSet[normalizedValue];
- if (result) {
- return [[1, result]];
- }
- let results = [];
- // start with high gram size and if there are no results, go to lower gram sizes
- for (let gramSize = GRAM_SIZE_UPPER; gramSize >= GRAM_SIZE_LOWER; --gramSize) {
- results = this.__get(value, gramSize);
- if (results) {
- return results;
- }
- }
- return null;
- }
- __get(value, gramSize) {
- const normalizedValue = value.toLowerCase();
- const matches = {};
- const gramCounts = _gramCounter(normalizedValue, gramSize);
- const items = this.items[gramSize];
- let sumOfSquareGramCounts = 0;
- let gram;
- let gramCount;
- let i;
- let index;
- let otherGramCount;
- for (gram in gramCounts) {
- gramCount = gramCounts[gram];
- sumOfSquareGramCounts += Math.pow(gramCount, 2);
- if (gram in this.matchDict) {
- for (i = 0; i < this.matchDict[gram].length; ++i) {
- index = this.matchDict[gram][i][0];
- otherGramCount = this.matchDict[gram][i][1];
- if (index in matches) {
- matches[index] += gramCount * otherGramCount;
- }
- else {
- matches[index] = gramCount * otherGramCount;
- }
- }
- }
- }
- const vectorNormal = Math.sqrt(sumOfSquareGramCounts);
- let results = [];
- let matchScore;
- // build a results list of [score, str]
- for (const matchIndex in matches) {
- matchScore = matches[matchIndex];
- results.push([
- matchScore / (vectorNormal * items[matchIndex][0]),
- items[matchIndex][1],
- ]);
- }
- results.sort(sortDescending);
- let newResults = [];
- const endIndex = Math.min(50, results.length);
- // truncate somewhat arbitrarily to 50
- for (let i = 0; i < endIndex; ++i) {
- newResults.push([
- _distance(results[i][1], normalizedValue),
- results[i][1],
- ]);
- }
- results = newResults;
- results.sort(sortDescending);
- newResults = [];
- for (let i = 0; i < results.length; ++i) {
- if (results[i][0] == results[0][0]) {
- newResults.push([results[i][0], this.exactSet[results[i][1]]]);
- }
- }
- return newResults;
- }
- ;
- }
- function fuzzymatch(name, names) {
- const set = new FuzzySet(names);
- const matches = set.get(name);
- return matches && matches[0] && matches[0][0] > 0.7 ? matches[0][1] : null;
- }
- class Ref extends Node$1 {
- constructor(component, parent, scope, info) {
- super(component, parent, scope, info);
- if (parent.ref) {
- component.error({
- code: 'duplicate-refs',
- message: `Duplicate refs`
- });
- }
- if (!isValidIdentifier(info.name)) {
- const suggestion = info.name.replace(/[^_$a-z0-9]/ig, '_').replace(/^\d/, '_$&');
- component.error(info, {
- code: `invalid-reference-name`,
- message: `Reference name '${info.name}' is invalid — must be a valid identifier such as ${suggestion}`
- });
- }
- else {
- component.refs.add(info.name);
- }
- this.name = info.name;
- }
- }
- const svg$1 = /^(?:altGlyph|altGlyphDef|altGlyphItem|animate|animateColor|animateMotion|animateTransform|circle|clipPath|color-profile|cursor|defs|desc|discard|ellipse|feBlend|feColorMatrix|feComponentTransfer|feComposite|feConvolveMatrix|feDiffuseLighting|feDisplacementMap|feDistantLight|feDropShadow|feFlood|feFuncA|feFuncB|feFuncG|feFuncR|feGaussianBlur|feImage|feMerge|feMergeNode|feMorphology|feOffset|fePointLight|feSpecularLighting|feSpotLight|feTile|feTurbulence|filter|font|font-face|font-face-format|font-face-name|font-face-src|font-face-uri|foreignObject|g|glyph|glyphRef|hatch|hatchpath|hkern|image|line|linearGradient|marker|mask|mesh|meshgradient|meshpatch|meshrow|metadata|missing-glyph|mpath|path|pattern|polygon|polyline|radialGradient|rect|set|solidcolor|stop|switch|symbol|text|textPath|tref|tspan|unknown|use|view|vkern)$/;
- const ariaAttributes = 'activedescendant atomic autocomplete busy checked controls current describedby details disabled dropeffect errormessage expanded flowto grabbed haspopup hidden invalid keyshortcuts label labelledby level live modal multiline multiselectable orientation owns placeholder posinset pressed readonly relevant required roledescription selected setsize sort valuemax valuemin valuenow valuetext'.split(' ');
- const ariaAttributeSet = new Set(ariaAttributes);
- const ariaRoles = 'alert alertdialog application article banner button cell checkbox columnheader combobox command complementary composite contentinfo definition dialog directory document feed figure form grid gridcell group heading img input landmark link list listbox listitem log main marquee math menu menubar menuitem menuitemcheckbox menuitemradio navigation none note option presentation progressbar radio radiogroup range region roletype row rowgroup rowheader scrollbar search searchbox section sectionhead select separator slider spinbutton status structure switch tab table tablist tabpanel term textbox timer toolbar tooltip tree treegrid treeitem widget window'.split(' ');
- const ariaRoleSet = new Set(ariaRoles);
- const a11yRequiredAttributes = {
- a: ['href'],
- area: ['alt', 'aria-label', 'aria-labelledby'],
- // html-has-lang
- html: ['lang'],
- // iframe-has-title
- iframe: ['title'],
- img: ['alt'],
- object: ['title', 'aria-label', 'aria-labelledby']
- };
- const a11yDistractingElements = new Set([
- 'blink',
- 'marquee'
- ]);
- const a11yRequiredContent = new Set([
- // anchor-has-content
- 'a',
- // heading-has-content
- 'h1',
- 'h2',
- 'h3',
- 'h4',
- 'h5',
- 'h6'
- ]);
- const invisibleElements = new Set(['meta', 'html', 'script', 'style']);
- const validModifiers = new Set([
- 'preventDefault',
- 'stopPropagation',
- 'capture',
- 'once',
- 'passive'
- ]);
- const passiveEvents = new Set([
- 'wheel',
- 'touchstart',
- 'touchmove',
- 'touchend',
- 'touchcancel'
- ]);
- class Element$1 extends Node$1 {
- constructor(component, parent, scope, info) {
- super(component, parent, scope, info);
- this.name = info.name;
- this.scope = scope;
- const parentElement = parent.findNearest(/^Element/);
- this.namespace = this.name === 'svg' ?
- svg :
- parentElement ? parentElement.namespace : this.component.namespace;
- if (!this.namespace && svg$1.test(this.name)) {
- this.component.warn(this, {
- code: `missing-namespace`,
- message: `<${this.name}> is an SVG element – did you forget to add { namespace: 'svg' } ?`
- });
- }
- this.attributes = [];
- this.actions = [];
- this.bindings = [];
- this.classes = [];
- this.handlers = [];
- this.intro = null;
- this.outro = null;
- this.animation = null;
- if (this.name === 'textarea') {
- if (info.children.length > 0) {
- const valueAttribute = info.attributes.find(node => node.name === 'value');
- if (valueAttribute) {
- component.error(valueAttribute, {
- code: `textarea-duplicate-value`,
- message: `A <textarea> can have either a value attribute or (equivalently) child content, but not both`
- });
- }
- // this is an egregious hack, but it's the easiest way to get <textarea>
- // children treated the same way as a value attribute
- info.attributes.push({
- type: 'Attribute',
- name: 'value',
- value: info.children
- });
- info.children = [];
- }
- }
- if (this.name === 'option') {
- // Special case — treat these the same way:
- // <option>{foo}</option>
- // <option value={foo}>{foo}</option>
- const valueAttribute = info.attributes.find((attribute) => attribute.name === 'value');
- if (!valueAttribute) {
- info.attributes.push({
- type: 'Attribute',
- name: 'value',
- value: info.children,
- synthetic: true
- });
- }
- }
- info.attributes.forEach(node => {
- switch (node.type) {
- case 'Action':
- this.actions.push(new Action(component, this, scope, node));
- break;
- case 'Attribute':
- case 'Spread':
- // special case
- if (node.name === 'xmlns')
- this.namespace = node.value[0].data;
- this.attributes.push(new Attribute$1(component, this, scope, node));
- break;
- case 'Binding':
- this.bindings.push(new Binding(component, this, scope, node));
- break;
- case 'Class':
- this.classes.push(new Class(component, this, scope, node));
- break;
- case 'EventHandler':
- this.handlers.push(new EventHandler(component, this, scope, node));
- break;
- case 'Transition':
- const transition = new Transition(component, this, scope, node);
- if (node.intro)
- this.intro = transition;
- if (node.outro)
- this.outro = transition;
- break;
- case 'Animation':
- this.animation = new Animation(component, this, scope, node);
- break;
- case 'Ref':
- this.ref = new Ref(component, this, scope, node);
- break;
- default:
- throw new Error(`Not implemented: ${node.type}`);
- }
- });
- this.children = mapChildren(component, this, scope, info.children);
- this.validate();
- component.stylesheet.apply(this);
- }
- validate() {
- if (a11yDistractingElements.has(this.name)) {
- // no-distracting-elements
- this.component.warn(this, {
- code: `a11y-distracting-elements`,
- message: `A11y: Avoid <${this.name}> elements`
- });
- }
- if (this.name === 'figcaption') {
- if (this.parent.name !== 'figure') {
- this.component.warn(this, {
- code: `a11y-structure`,
- message: `A11y: <figcaption> must be an immediate child of <figure>`
- });
- }
- }
- if (this.name === 'figure') {
- const children = this.children.filter(node => {
- if (node.type === 'Comment')
- return false;
- if (node.type === 'Text')
- return /\S/.test(node.data);
- return true;
- });
- const index = children.findIndex(child => child.name === 'figcaption');
- if (index !== -1 && (index !== 0 && index !== children.length - 1)) {
- this.component.warn(children[index], {
- code: `a11y-structure`,
- message: `A11y: <figcaption> must be first or last child of <figure>`
- });
- }
- }
- this.validateAttributes();
- this.validateBindings();
- this.validateContent();
- this.validateEventHandlers();
- }
- validateAttributes() {
- const { component } = this;
- const attributeMap = new Map();
- this.attributes.forEach(attribute => {
- if (attribute.isSpread)
- return;
- const name = attribute.name.toLowerCase();
- // aria-props
- if (name.startsWith('aria-')) {
- if (invisibleElements.has(this.name)) {
- // aria-unsupported-elements
- component.warn(attribute, {
- code: `a11y-aria-attributes`,
- message: `A11y: <${this.name}> should not have aria-* attributes`
- });
- }
- const type = name.slice(5);
- if (!ariaAttributeSet.has(type)) {
- const match = fuzzymatch(type, ariaAttributes);
- let message = `A11y: Unknown aria attribute 'aria-${type}'`;
- if (match)
- message += ` (did you mean '${match}'?)`;
- component.warn(attribute, {
- code: `a11y-unknown-aria-attribute`,
- message
- });
- }
- if (name === 'aria-hidden' && /^h[1-6]$/.test(this.name)) {
- component.warn(attribute, {
- code: `a11y-hidden`,
- message: `A11y: <${this.name}> element should not be hidden`
- });
- }
- }
- // aria-role
- if (name === 'role') {
- if (invisibleElements.has(this.name)) {
- // aria-unsupported-elements
- component.warn(attribute, {
- code: `a11y-misplaced-role`,
- message: `A11y: <${this.name}> should not have role attribute`
- });
- }
- const value = attribute.getStaticValue();
- if (value && !ariaRoleSet.has(value)) {
- const match = fuzzymatch(value, ariaRoles);
- let message = `A11y: Unknown role '${value}'`;
- if (match)
- message += ` (did you mean '${match}'?)`;
- component.warn(attribute, {
- code: `a11y-unknown-role`,
- message
- });
- }
- }
- // no-access-key
- if (name === 'accesskey') {
- component.warn(attribute, {
- code: `a11y-accesskey`,
- message: `A11y: Avoid using accesskey`
- });
- }
- // no-autofocus
- if (name === 'autofocus') {
- component.warn(attribute, {
- code: `a11y-autofocus`,
- message: `A11y: Avoid using autofocus`
- });
- }
- // scope
- if (name === 'scope' && this.name !== 'th') {
- component.warn(attribute, {
- code: `a11y-misplaced-scope`,
- message: `A11y: The scope attribute should only be used with <th> elements`
- });
- }
- // tabindex-no-positive
- if (name === 'tabindex') {
- const value = attribute.getStaticValue();
- if (!isNaN(value) && +value > 0) {
- component.warn(attribute, {
- code: `a11y-positive-tabindex`,
- message: `A11y: avoid tabindex values above zero`
- });
- }
- }
- if (name === 'slot') {
- if (attribute.isDynamic) {
- component.error(attribute, {
- code: `invalid-slot-attribute`,
- message: `slot attribute cannot have a dynamic value`
- });
- }
- let ancestor = this.parent;
- do {
- if (ancestor.type === 'InlineComponent')
- break;
- if (ancestor.type === 'Element' && /-/.test(ancestor.name))
- break;
- if (ancestor.type === 'IfBlock' || ancestor.type === 'EachBlock') {
- const type = ancestor.type === 'IfBlock' ? 'if' : 'each';
- const message = `Cannot place slotted elements inside an ${type}-block`;
- component.error(attribute, {
- code: `invalid-slotted-content`,
- message
- });
- }
- } while (ancestor = ancestor.parent);
- if (!ancestor) {
- component.error(attribute, {
- code: `invalid-slotted-content`,
- message: `Element with a slot='...' attribute must be a descendant of a component or custom element`
- });
- }
- }
- attributeMap.set(attribute.name, attribute);
- });
- // handle special cases
- if (this.name === 'a') {
- const attribute = attributeMap.get('href') || attributeMap.get('xlink:href');
- if (attribute) {
- const value = attribute.getStaticValue();
- if (value === '' || value === '#') {
- component.warn(attribute, {
- code: `a11y-invalid-attribute`,
- message: `A11y: '${value}' is not a valid ${attribute.name} attribute`
- });
- }
- }
- else {
- component.warn(this, {
- code: `a11y-missing-attribute`,
- message: `A11y: <a> element should have an href attribute`
- });
- }
- }
- else {
- const requiredAttributes = a11yRequiredAttributes[this.name];
- if (requiredAttributes) {
- const hasAttribute = requiredAttributes.some(name => attributeMap.has(name));
- if (!hasAttribute) {
- shouldHaveAttribute(this, requiredAttributes);
- }
- }
- if (this.name === 'input') {
- const type = attributeMap.get('type');
- if (type && type.getStaticValue() === 'image') {
- shouldHaveAttribute(this, ['alt', 'aria-label', 'aria-labelledby'], 'input type="image"');
- }
- }
- }
- }
- validateBindings() {
- const { component } = this;
- const checkTypeAttribute = () => {
- const attribute = this.attributes.find((attribute) => attribute.name === 'type');
- if (!attribute)
- return null;
- if (attribute.isDynamic) {
- component.error(attribute, {
- code: `invalid-type`,
- message: `'type' attribute cannot be dynamic if input uses two-way binding`
- });
- }
- const value = attribute.getStaticValue();
- if (value === true) {
- component.error(attribute, {
- code: `missing-type`,
- message: `'type' attribute must be specified`
- });
- }
- return value;
- };
- this.bindings.forEach(binding => {
- const { name } = binding;
- if (name === 'value') {
- if (this.name !== 'input' &&
- this.name !== 'textarea' &&
- this.name !== 'select') {
- component.error(binding, {
- code: `invalid-binding`,
- message: `'value' is not a valid binding on <${this.name}> elements`
- });
- }
- if (this.name === 'select') {
- const attribute = this.attributes.find((attribute) => attribute.name === 'multiple');
- if (attribute && attribute.isDynamic) {
- component.error(attribute, {
- code: `dynamic-multiple-attribute`,
- message: `'multiple' attribute cannot be dynamic if select uses two-way binding`
- });
- }
- }
- else {
- checkTypeAttribute();
- }
- }
- else if (name === 'checked' || name === 'indeterminate') {
- if (this.name !== 'input') {
- component.error(binding, {
- code: `invalid-binding`,
- message: `'${name}' is not a valid binding on <${this.name}> elements`
- });
- }
- if (checkTypeAttribute() !== 'checkbox') {
- component.error(binding, {
- code: `invalid-binding`,
- message: `'${name}' binding can only be used with <input type="checkbox">`
- });
- }
- }
- else if (name === 'group') {
- if (this.name !== 'input') {
- component.error(binding, {
- code: `invalid-binding`,
- message: `'group' is not a valid binding on <${this.name}> elements`
- });
- }
- const type = checkTypeAttribute();
- if (type !== 'checkbox' && type !== 'radio') {
- component.error(binding, {
- code: `invalid-binding`,
- message: `'checked' binding can only be used with <input type="checkbox"> or <input type="radio">`
- });
- }
- }
- else if (name == 'files') {
- if (this.name !== 'input') {
- component.error(binding, {
- code: `invalid-binding`,
- message: `'files' binding acn only be used with <input type="file">`
- });
- }
- const type = checkTypeAttribute();
- if (type !== 'file') {
- component.error(binding, {
- code: `invalid-binding`,
- message: `'files' binding can only be used with <input type="file">`
- });
- }
- }
- else if (name === 'currentTime' ||
- name === 'duration' ||
- name === 'paused' ||
- name === 'buffered' ||
- name === 'seekable' ||
- name === 'played' ||
- name === 'volume') {
- if (this.name !== 'audio' && this.name !== 'video') {
- component.error(binding, {
- code: `invalid-binding`,
- message: `'${name}' binding can only be used with <audio> or <video>`
- });
- }
- }
- else if (dimensions.test(name)) {
- if (this.name === 'svg' && (name === 'offsetWidth' || name === 'offsetHeight')) {
- component.error(binding, {
- code: 'invalid-binding',
- message: `'${binding.name}' is not a valid binding on <svg>. Use '${name.replace('offset', 'client')}' instead`
- });
- }
- else if (svg$1.test(this.name)) {
- component.error(binding, {
- code: 'invalid-binding',
- message: `'${binding.name}' is not a valid binding on SVG elements`
- });
- }
- else if (isVoidElementName(this.name)) {
- component.error(binding, {
- code: 'invalid-binding',
- message: `'${binding.name}' is not a valid binding on void elements like <${this.name}>. Use a wrapper element instead`
- });
- }
- }
- else {
- component.error(binding, {
- code: `invalid-binding`,
- message: `'${binding.name}' is not a valid binding`
- });
- }
- });
- }
- validateContent() {
- if (!a11yRequiredContent.has(this.name))
- return;
- if (this.children.length === 0) {
- this.component.warn(this, {
- code: `a11y-missing-content`,
- message: `A11y: <${this.name}> element should have child content`
- });
- }
- }
- validateEventHandlers() {
- const { component } = this;
- this.handlers.forEach(handler => {
- if (handler.modifiers.has('passive') && handler.modifiers.has('preventDefault')) {
- component.error(handler, {
- code: 'invalid-event-modifier',
- message: `The 'passive' and 'preventDefault' modifiers cannot be used together`
- });
- }
- handler.modifiers.forEach(modifier => {
- if (!validModifiers.has(modifier)) {
- component.error(handler, {
- code: 'invalid-event-modifier',
- message: `Valid event modifiers are ${list$1([...validModifiers])}`
- });
- }
- if (modifier === 'passive') {
- if (passiveEvents.has(handler.name)) {
- if (!handler.usesEventObject) {
- component.warn(handler, {
- code: 'redundant-event-modifier',
- message: `Touch event handlers that don't use the 'event' object are passive by default`
- });
- }
- }
- else {
- component.warn(handler, {
- code: 'redundant-event-modifier',
- message: `The passive modifier only works with wheel and touch events`
- });
- }
- }
- if (component.options.legacy && (modifier === 'once' || modifier === 'passive')) {
- // TODO this could be supported, but it would need a few changes to
- // how event listeners work
- component.error(handler, {
- code: 'invalid-event-modifier',
- message: `The '${modifier}' modifier cannot be used in legacy mode`
- });
- }
- });
- if (passiveEvents.has(handler.name) && !handler.usesEventObject && !handler.modifiers.has('preventDefault')) {
- // touch/wheel events should be passive by default
- handler.modifiers.add('passive');
- }
- });
- }
- getStaticAttributeValue(name) {
- const attribute = this.attributes.find((attr) => attr.type === 'Attribute' && attr.name.toLowerCase() === name);
- if (!attribute)
- return null;
- if (attribute.isTrue)
- return true;
- if (attribute.chunks.length === 0)
- return '';
- if (attribute.chunks.length === 1 && attribute.chunks[0].type === 'Text') {
- return attribute.chunks[0].data;
- }
- return null;
- }
- isMediaNode() {
- return this.name === 'audio' || this.name === 'video';
- }
- remount(name) {
- const slot = this.attributes.find(attribute => attribute.name === 'slot');
- if (slot) {
- const prop = quotePropIfNecessary(slot.chunks[0].data);
- return `@append(${name}._slotted${prop}, ${this.var});`;
- }
- return `@append(${name}._slotted.default, ${this.var});`;
- }
- addCssClass(className = this.component.stylesheet.id) {
- const classAttribute = this.attributes.find(a => a.name === 'class');
- if (classAttribute && !classAttribute.isTrue) {
- if (classAttribute.chunks.length === 1 && classAttribute.chunks[0].type === 'Text') {
- classAttribute.chunks[0].data += ` ${className}`;
- }
- else {
- classAttribute.chunks.push(new Text$2(this.component, this, this.scope, {
- type: 'Text',
- data: ` ${className}`
- }));
- }
- }
- else {
- this.attributes.push(new Attribute$1(this.component, this, this.scope, {
- type: 'Attribute',
- name: 'class',
- value: [{ type: 'Text', data: className }]
- }));
- }
- }
- }
- function shouldHaveAttribute(node, attributes, name = node.name) {
- const article = /^[aeiou]/.test(attributes[0]) ? 'an' : 'a';
- const sequence = attributes.length > 1 ?
- attributes.slice(0, -1).join(', ') + ` or ${attributes[attributes.length - 1]}` :
- attributes[0];
- node.component.warn(node, {
- code: `a11y-missing-attribute`,
- message: `A11y: <${name}> element should have ${article} ${sequence} attribute`
- });
- }
- class Head$1 extends Node$1 {
- constructor(component, parent, scope, info) {
- super(component, parent, scope, info);
- if (info.attributes.length) {
- component.error(info.attributes[0], {
- code: `invalid-attribute`,
- message: `<svelte:head> should not have any attributes or directives`
- });
- }
- this.children = mapChildren(component, parent, scope, info.children.filter(child => {
- return (child.type !== 'Text' || /\S/.test(child.data));
- }));
- }
- }
- class IfBlock$1 extends Node$1 {
- constructor(component, parent, scope, info) {
- super(component, parent, scope, info);
- this.expression = new Expression(component, this, scope, info.expression);
- this.children = mapChildren(component, this, scope, info.children);
- this.else = info.else
- ? new ElseBlock(component, this, scope, info.else)
- : null;
- this.warnIfEmptyBlock();
- }
- }
- class InlineComponent$1 extends Node$1 {
- constructor(component, parent, scope, info) {
- super(component, parent, scope, info);
- component.hasComponents = true;
- this.name = info.name;
- if (this.name !== 'svelte:self' && this.name !== 'svelte:component') {
- if (!component.components.has(this.name)) {
- component.error(this, {
- code: `missing-component`,
- message: `${this.name} component is not defined`
- });
- }
- component.used.components.add(this.name);
- }
- this.expression = this.name === 'svelte:component'
- ? new Expression(component, this, scope, info.expression)
- : null;
- this.attributes = [];
- this.bindings = [];
- this.handlers = [];
- info.attributes.forEach(node => {
- switch (node.type) {
- case 'Action':
- component.error(node, {
- code: `invalid-action`,
- message: `Actions can only be applied to DOM elements, not components`
- });
- case 'Attribute':
- case 'Spread':
- this.attributes.push(new Attribute$1(component, this, scope, node));
- break;
- case 'Binding':
- this.bindings.push(new Binding(component, this, scope, node));
- break;
- case 'Class':
- component.error(node, {
- code: `invalid-class`,
- message: `Classes can only be applied to DOM elements, not components`
- });
- case 'EventHandler':
- this.handlers.push(new EventHandler(component, this, scope, node));
- break;
- case 'Ref':
- this.ref = new Ref(component, this, scope, node);
- break;
- case 'Transition':
- component.error(node, {
- code: `invalid-transition`,
- message: `Transitions can only be applied to DOM elements, not components`
- });
- default:
- throw new Error(`Not implemented: ${node.type}`);
- }
- });
- this.children = mapChildren(component, this, scope, info.children);
- }
- }
- class Tag$2 extends Node$1 {
- constructor(component, parent, scope, info) {
- super(component, parent, scope, info);
- this.expression = new Expression(component, this, scope, info.expression);
- this.shouldCache = (info.expression.type !== 'Identifier' ||
- (this.expression.dependencies.size && scope.names.has(info.expression.name)));
- }
- }
- class MustacheTag extends Tag$2 {
- }
- class RawMustacheTag extends Tag$2 {
- }
- class DebugTag$1 extends Node$1 {
- constructor(component, parent, scope, info) {
- super(component, parent, scope, info);
- this.expressions = info.identifiers.map(node => {
- return new Expression(component, parent, scope, node);
- });
- }
- }
- class Slot$1 extends Element$1 {
- constructor(component, parent, scope, info) {
- super(component, parent, scope, info);
- info.attributes.forEach(attr => {
- if (attr.type !== 'Attribute') {
- component.error(attr, {
- code: `invalid-slot-directive`,
- message: `<slot> cannot have directives`
- });
- }
- if (attr.name !== 'name') {
- component.error(attr, {
- code: `invalid-slot-attribute`,
- message: `"name" is the only attribute permitted on <slot> elements`
- });
- }
- if (attr.value.length !== 1 || attr.value[0].type !== 'Text') {
- component.error(attr, {
- code: `dynamic-slot-name`,
- message: `<slot> name cannot be dynamic`
- });
- }
- const slotName = attr.value[0].data;
- if (slotName === 'default') {
- component.error(attr, {
- code: `invalid-slot-name`,
- message: `default is a reserved word — it cannot be used as a slot name`
- });
- }
- // TODO should duplicate slots be disallowed? Feels like it's more likely to be a
- // bug than anything. Perhaps it should be a warning
- // if (validator.slots.has(slotName)) {
- // validator.error(`duplicate '${slotName}' <slot> element`, nameAttribute.start);
- // }
- // validator.slots.add(slotName);
- });
- // if (node.attributes.length === 0) && validator.slots.has('default')) {
- // validator.error(node, {
- // code: `duplicate-slot`,
- // message: `duplicate default <slot> element`
- // });
- // }
- }
- getStaticAttributeValue(name) {
- const attribute = this.attributes.find(attr => attr.name.toLowerCase() === name);
- if (!attribute)
- return null;
- if (attribute.isTrue)
- return true;
- if (attribute.chunks.length === 0)
- return '';
- if (attribute.chunks.length === 1 && attribute.chunks[0].type === 'Text') {
- return attribute.chunks[0].data;
- }
- return null;
- }
- }
- class Title$1 extends Node$1 {
- constructor(component, parent, scope, info) {
- super(component, parent, scope, info);
- this.children = mapChildren(component, parent, scope, info.children);
- if (info.attributes.length > 0) {
- component.error(info.attributes[0], {
- code: `illegal-attribute`,
- message: `<title> cannot have attributes`
- });
- }
- info.children.forEach(child => {
- if (child.type !== 'Text' && child.type !== 'MustacheTag') {
- component.error(child, {
- code: 'illegal-structure',
- message: `<title> can only contain text and {tags}`
- });
- }
- });
- this.shouldCache = info.children.length === 1
- ? (info.children[0].type !== 'Identifier' ||
- scope.names.has(info.children[0].name))
- : true;
- }
- }
- const validBindings = [
- 'innerWidth',
- 'innerHeight',
- 'outerWidth',
- 'outerHeight',
- 'scrollX',
- 'scrollY',
- 'online'
- ];
- class Window extends Node$1 {
- constructor(component, parent, scope, info) {
- super(component, parent, scope, info);
- this.handlers = [];
- this.bindings = [];
- info.attributes.forEach(node => {
- if (node.type === 'EventHandler') {
- this.handlers.push(new EventHandler(component, this, scope, node));
- }
- else if (node.type === 'Binding') {
- if (node.value.type !== 'Identifier') {
- const { parts } = flattenReference(node.value);
- component.error(node.value, {
- code: `invalid-binding`,
- message: `Bindings on <svelte:window> must be to top-level properties, e.g. '${parts[parts.length - 1]}' rather than '${parts.join('.')}'`
- });
- }
- if (!~validBindings.indexOf(node.name)) {
- const match = node.name === 'width'
- ? 'innerWidth'
- : node.name === 'height'
- ? 'innerHeight'
- : fuzzymatch(node.name, validBindings);
- const message = `'${node.name}' is not a valid binding on <svelte:window>`;
- if (match) {
- component.error(node, {
- code: `invalid-binding`,
- message: `${message} (did you mean '${match}'?)`
- });
- }
- else {
- component.error(node, {
- code: `invalid-binding`,
- message: `${message} — valid bindings are ${list$1(validBindings)}`
- });
- }
- }
- this.bindings.push(new Binding(component, this, scope, node));
- }
- });
- }
- }
- function getConstructor(type) {
- switch (type) {
- case 'AwaitBlock': return AwaitBlock$1;
- case 'Comment': return Comment$2;
- case 'Document': return Document;
- case 'EachBlock': return EachBlock$1;
- case 'Element': return Element$1;
- case 'Head': return Head$1;
- case 'IfBlock': return IfBlock$1;
- case 'InlineComponent': return InlineComponent$1;
- case 'MustacheTag': return MustacheTag;
- case 'RawMustacheTag': return RawMustacheTag;
- case 'DebugTag': return DebugTag$1;
- case 'Slot': return Slot$1;
- case 'Text': return Text$2;
- case 'Title': return Title$1;
- case 'Window': return Window;
- default: throw new Error(`Not implemented: ${type}`);
- }
- }
- function mapChildren(component, parent, scope, children) {
- let last = null;
- return children.map(child => {
- const constructor = getConstructor(child.type);
- const node = new constructor(component, parent, scope, child);
- if (last)
- last.next = node;
- node.prev = last;
- last = node;
- return node;
- });
- }
- class TemplateScope {
- constructor(parent) {
- this.names = new Set(parent ? parent.names : []);
- this.dependenciesForName = new Map(parent ? parent.dependenciesForName : []);
- }
- add(name, dependencies) {
- this.names.add(name);
- this.dependenciesForName.set(name, dependencies);
- return this;
- }
- child() {
- return new TemplateScope(this);
- }
- }
- class Fragment extends Node$1 {
- constructor(component, info) {
- const scope = new TemplateScope();
- super(component, null, scope, info);
- this.scope = scope;
- this.children = mapChildren(component, this, scope, info.children);
- }
- }
- // this file is auto-generated, do not edit it
- const shared = {
- "wrapAnimation": "function wrapAnimation(node, from, fn, params) {\n\tif (!from) return;\n\n\tconst to = node.getBoundingClientRect();\n\tif (from.left === to.left && from.right === to.right && from.top === to.top && from.bottom === to.bottom) return;\n\n\tconst info = fn(node, { from, to }, params);\n\n\tconst duration = 'duration' in info ? info.duration : 300;\n\tconst delay = 'delay' in info ? info.delay : 0;\n\tconst ease = info.easing || linear;\n\tconst start = window.performance.now() + delay;\n\tconst end = start + duration;\n\n\tconst program = {\n\t\ta: 0,\n\t\tt: 0,\n\t\tb: 1,\n\t\tdelta: 1,\n\t\tduration,\n\t\tstart,\n\t\tend\n\t};\n\n\tconst cssText = node.style.cssText;\n\n\tconst animation = {\n\t\tpending: delay ? program : null,\n\t\tprogram: delay ? null : program,\n\t\trunning: true,\n\n\t\tstart() {\n\t\t\tif (info.css) {\n\t\t\t\tif (delay) node.style.cssText = cssText;\n\n\t\t\t\tconst rule = generateRule(program, ease, info.css);\n\t\t\t\tprogram.name = `__svelte_${hash(rule)}`;\n\n\t\t\t\ttransitionManager.addRule(rule, program.name);\n\n\t\t\t\tnode.style.animation = (node.style.animation || '')\n\t\t\t\t\t.split(', ')\n\t\t\t\t\t.filter(anim => anim && (program.delta < 0 || !/__svelte/.test(anim)))\n\t\t\t\t\t.concat(`${program.name} ${program.duration}ms linear 1 forwards`)\n\t\t\t\t\t.join(', ');\n\t\t\t}\n\n\t\t\tanimation.program = program;\n\t\t\tanimation.pending = null;\n\t\t},\n\n\t\tupdate: now => {\n\t\t\tconst p = now - program.start;\n\t\t\tconst t = program.a + program.delta * ease(p / program.duration);\n\t\t\tif (info.tick) info.tick(t, 1 - t);\n\t\t},\n\n\t\tdone() {\n\t\t\tif (info.tick) info.tick(1, 0);\n\t\t\tanimation.stop();\n\t\t},\n\n\t\tstop() {\n\t\t\tif (info.css) transitionManager.deleteRule(node, program.name);\n\t\t\tanimation.running = false;\n\t\t}\n\t};\n\n\ttransitionManager.add(animation);\n\n\tif (info.tick) info.tick(0, 1);\n\n\tif (delay) {\n\t\tif (info.css) node.style.cssText += info.css(0, 1);\n\t} else {\n\t\tanimation.start();\n\t}\n\n\treturn animation;\n}",
- "fixPosition": "function fixPosition(node) {\n\tconst style = getComputedStyle(node);\n\n\tif (style.position !== 'absolute' && style.position !== 'fixed') {\n\t\tconst { width, height } = style;\n\t\tconst a = node.getBoundingClientRect();\n\t\tnode.style.position = 'absolute';\n\t\tnode.style.width = width;\n\t\tnode.style.height = height;\n\t\tconst b = node.getBoundingClientRect();\n\n\t\tif (a.left !== b.left || a.top !== b.top) {\n\t\t\tconst style = getComputedStyle(node);\n\t\t\tconst transform = style.transform === 'none' ? '' : style.transform;\n\n\t\t\tnode.style.transform = `${transform} translate(${a.left - b.left}px, ${a.top - b.top}px)`;\n\t\t}\n\t}\n}",
- "handlePromise": "function handlePromise(promise, info) {\n\tvar token = info.token = {};\n\n\tfunction update(type, index, key, value) {\n\t\tif (info.token !== token) return;\n\n\t\tinfo.resolved = key && { [key]: value };\n\n\t\tconst child_ctx = assign(assign({}, info.ctx), info.resolved);\n\t\tconst block = type && (info.current = type)(info.component, child_ctx);\n\n\t\tif (info.block) {\n\t\t\tif (info.blocks) {\n\t\t\t\tinfo.blocks.forEach((block, i) => {\n\t\t\t\t\tif (i !== index && block) {\n\t\t\t\t\t\tgroupOutros();\n\t\t\t\t\t\tblock.o(() => {\n\t\t\t\t\t\t\tblock.d(1);\n\t\t\t\t\t\t\tinfo.blocks[i] = null;\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tinfo.block.d(1);\n\t\t\t}\n\n\t\t\tblock.c();\n\t\t\tblock[block.i ? 'i' : 'm'](info.mount(), info.anchor);\n\n\t\t\tinfo.component.root.set({}); // flush any handlers that were created\n\t\t}\n\n\t\tinfo.block = block;\n\t\tif (info.blocks) info.blocks[index] = block;\n\t}\n\n\tif (isPromise(promise)) {\n\t\tpromise.then(value => {\n\t\t\tupdate(info.then, 1, info.value, value);\n\t\t}, error => {\n\t\t\tupdate(info.catch, 2, info.error, error);\n\t\t});\n\n\t\t// if we previously had a then/catch block, destroy it\n\t\tif (info.current !== info.pending) {\n\t\t\tupdate(info.pending, 0);\n\t\t\treturn true;\n\t\t}\n\t} else {\n\t\tif (info.current !== info.then) {\n\t\t\tupdate(info.then, 1, info.value, promise);\n\t\t\treturn true;\n\t\t}\n\n\t\tinfo.resolved = { [info.value]: promise };\n\t}\n}",
- "append": "function append(target, node) {\n\ttarget.appendChild(node);\n}",
- "insert": "function insert(target, node, anchor) {\n\ttarget.insertBefore(node, anchor);\n}",
- "detachNode": "function detachNode(node) {\n\tnode.parentNode.removeChild(node);\n}",
- "detachBetween": "function detachBetween(before, after) {\n\twhile (before.nextSibling && before.nextSibling !== after) {\n\t\tbefore.parentNode.removeChild(before.nextSibling);\n\t}\n}",
- "detachBefore": "function detachBefore(after) {\n\twhile (after.previousSibling) {\n\t\tafter.parentNode.removeChild(after.previousSibling);\n\t}\n}",
- "detachAfter": "function detachAfter(before) {\n\twhile (before.nextSibling) {\n\t\tbefore.parentNode.removeChild(before.nextSibling);\n\t}\n}",
- "reinsertBetween": "function reinsertBetween(before, after, target) {\n\twhile (before.nextSibling && before.nextSibling !== after) {\n\t\ttarget.appendChild(before.parentNode.removeChild(before.nextSibling));\n\t}\n}",
- "reinsertChildren": "function reinsertChildren(parent, target) {\n\twhile (parent.firstChild) target.appendChild(parent.firstChild);\n}",
- "reinsertAfter": "function reinsertAfter(before, target) {\n\twhile (before.nextSibling) target.appendChild(before.nextSibling);\n}",
- "reinsertBefore": "function reinsertBefore(after, target) {\n\tvar parent = after.parentNode;\n\twhile (parent.firstChild !== after) target.appendChild(parent.firstChild);\n}",
- "destroyEach": "function destroyEach(iterations, detach) {\n\tfor (var i = 0; i < iterations.length; i += 1) {\n\t\tif (iterations[i]) iterations[i].d(detach);\n\t}\n}",
- "createFragment": "function createFragment() {\n\treturn document.createDocumentFragment();\n}",
- "createElement": "function createElement(name) {\n\treturn document.createElement(name);\n}",
- "createSvgElement": "function createSvgElement(name) {\n\treturn document.createElementNS('http://www.w3.org/2000/svg', name);\n}",
- "createText": "function createText(data) {\n\treturn document.createTextNode(data);\n}",
- "createComment": "function createComment() {\n\treturn document.createComment('');\n}",
- "addListener": "function addListener(node, event, handler, options) {\n\tnode.addEventListener(event, handler, options);\n}",
- "removeListener": "function removeListener(node, event, handler, options) {\n\tnode.removeEventListener(event, handler, options);\n}",
- "setAttribute": "function setAttribute(node, attribute, value) {\n\tif (value == null) node.removeAttribute(attribute);\n\telse node.setAttribute(attribute, value);\n}",
- "setAttributes": "function setAttributes(node, attributes) {\n\tfor (var key in attributes) {\n\t\tif (key === 'style') {\n\t\t\tnode.style.cssText = attributes[key];\n\t\t} else if (key in node) {\n\t\t\tnode[key] = attributes[key];\n\t\t} else {\n\t\t\tsetAttribute(node, key, attributes[key]);\n\t\t}\n\t}\n}",
- "setCustomElementData": "function setCustomElementData(node, prop, value) {\n\tif (prop in node) {\n\t\tnode[prop] = value;\n\t} else if (value) {\n\t\tsetAttribute(node, prop, value);\n\t} else {\n\t\tnode.removeAttribute(prop);\n\t}\n}",
- "setXlinkAttribute": "function setXlinkAttribute(node, attribute, value) {\n\tnode.setAttributeNS('http://www.w3.org/1999/xlink', attribute, value);\n}",
- "getBindingGroupValue": "function getBindingGroupValue(group) {\n\tvar value = [];\n\tfor (var i = 0; i < group.length; i += 1) {\n\t\tif (group[i].checked) value.push(group[i].__value);\n\t}\n\treturn value;\n}",
- "toNumber": "function toNumber(value) {\n\treturn value === '' ? undefined : +value;\n}",
- "timeRangesToArray": "function timeRangesToArray(ranges) {\n\tvar array = [];\n\tfor (var i = 0; i < ranges.length; i += 1) {\n\t\tarray.push({ start: ranges.start(i), end: ranges.end(i) });\n\t}\n\treturn array;\n}",
- "children": "function children (element) {\n\treturn Array.from(element.childNodes);\n}",
- "claimElement": "function claimElement (nodes, name, attributes, svg) {\n\tfor (var i = 0; i < nodes.length; i += 1) {\n\t\tvar node = nodes[i];\n\t\tif (node.nodeName === name) {\n\t\t\tfor (var j = 0; j < node.attributes.length; j += 1) {\n\t\t\t\tvar attribute = node.attributes[j];\n\t\t\t\tif (!attributes[attribute.name]) node.removeAttribute(attribute.name);\n\t\t\t}\n\t\t\treturn nodes.splice(i, 1)[0]; // TODO strip unwanted attributes\n\t\t}\n\t}\n\n\treturn svg ? createSvgElement(name) : createElement(name);\n}",
- "claimText": "function claimText (nodes, data) {\n\tfor (var i = 0; i < nodes.length; i += 1) {\n\t\tvar node = nodes[i];\n\t\tif (node.nodeType === 3) {\n\t\t\tnode.data = data;\n\t\t\treturn nodes.splice(i, 1)[0];\n\t\t}\n\t}\n\n\treturn createText(data);\n}",
- "setData": "function setData(text, data) {\n\ttext.data = '' + data;\n}",
- "setInputType": "function setInputType(input, type) {\n\ttry {\n\t\tinput.type = type;\n\t} catch (e) {}\n}",
- "setStyle": "function setStyle(node, key, value) {\n\tnode.style.setProperty(key, value);\n}",
- "selectOption": "function selectOption(select, value) {\n\tfor (var i = 0; i < select.options.length; i += 1) {\n\t\tvar option = select.options[i];\n\n\t\tif (option.__value === value) {\n\t\t\toption.selected = true;\n\t\t\treturn;\n\t\t}\n\t}\n}",
- "selectOptions": "function selectOptions(select, value) {\n\tfor (var i = 0; i < select.options.length; i += 1) {\n\t\tvar option = select.options[i];\n\t\toption.selected = ~value.indexOf(option.__value);\n\t}\n}",
- "selectValue": "function selectValue(select) {\n\tvar selectedOption = select.querySelector(':checked') || select.options[0];\n\treturn selectedOption && selectedOption.__value;\n}",
- "selectMultipleValue": "function selectMultipleValue(select) {\n\treturn [].map.call(select.querySelectorAll(':checked'), function(option) {\n\t\treturn option.__value;\n\t});\n}",
- "addResizeListener": "function addResizeListener(element, fn) {\n\tif (getComputedStyle(element).position === 'static') {\n\t\telement.style.position = 'relative';\n\t}\n\n\tconst object = document.createElement('object');\n\tobject.setAttribute('style', 'display: block; position: absolute; top: 0; left: 0; height: 100%; width: 100%; overflow: hidden; pointer-events: none; z-index: -1;');\n\tobject.type = 'text/html';\n\n\tlet win;\n\n\tobject.onload = () => {\n\t\twin = object.contentDocument.defaultView;\n\t\twin.addEventListener('resize', fn);\n\t};\n\n\tif (/Trident/.test(navigator.userAgent)) {\n\t\telement.appendChild(object);\n\t\tobject.data = 'about:blank';\n\t} else {\n\t\tobject.data = 'about:blank';\n\t\telement.appendChild(object);\n\t}\n\n\treturn {\n\t\tcancel: () => {\n\t\t\twin && win.removeEventListener && win.removeEventListener('resize', fn);\n\t\t\telement.removeChild(object);\n\t\t}\n\t};\n}",
- "toggleClass": "function toggleClass(element, name, toggle) {\n\telement.classList.toggle(name, !!toggle);\n}",
- "blankObject": "function blankObject() {\n\treturn Object.create(null);\n}",
- "destroy": "function destroy(detach) {\n\tthis.destroy = noop;\n\tthis.fire('destroy');\n\tthis.set = noop;\n\n\tthis._fragment.d(detach !== false);\n\tthis._fragment = null;\n\tthis._state = {};\n}",
- "destroyDev": "function destroyDev(detach) {\n\tdestroy.call(this, detach);\n\tthis.destroy = function() {\n\t\tconsole.warn('Component was already destroyed');\n\t};\n}",
- "_differs": "function _differs(a, b) {\n\treturn a != a ? b == b : a !== b || ((a && typeof a === 'object') || typeof a === 'function');\n}",
- "_differsImmutable": "function _differsImmutable(a, b) {\n\treturn a != a ? b == b : a !== b;\n}",
- "fire": "function fire(eventName, data) {\n\tvar handlers =\n\t\teventName in this._handlers && this._handlers[eventName].slice();\n\tif (!handlers) return;\n\n\tfor (var i = 0; i < handlers.length; i += 1) {\n\t\tvar handler = handlers[i];\n\n\t\tif (!handler.__calling) {\n\t\t\ttry {\n\t\t\t\thandler.__calling = true;\n\t\t\t\thandler.call(this, data);\n\t\t\t} finally {\n\t\t\t\thandler.__calling = false;\n\t\t\t}\n\t\t}\n\t}\n}",
- "flush": "function flush(component) {\n\tcomponent._lock = true;\n\tcallAll(component._beforecreate);\n\tcallAll(component._oncreate);\n\tcallAll(component._aftercreate);\n\tcomponent._lock = false;\n}",
- "get": "function get() {\n\treturn this._state;\n}",
- "init": "function init(component, options) {\n\tcomponent._handlers = blankObject();\n\tcomponent._slots = blankObject();\n\tcomponent._bind = options._bind;\n\tcomponent._staged = {};\n\n\tcomponent.options = options;\n\tcomponent.root = options.root || component;\n\tcomponent.store = options.store || component.root.store;\n\n\tif (!options.root) {\n\t\tcomponent._beforecreate = [];\n\t\tcomponent._oncreate = [];\n\t\tcomponent._aftercreate = [];\n\t}\n}",
- "on": "function on(eventName, handler) {\n\tvar handlers = this._handlers[eventName] || (this._handlers[eventName] = []);\n\thandlers.push(handler);\n\n\treturn {\n\t\tcancel: function() {\n\t\t\tvar index = handlers.indexOf(handler);\n\t\t\tif (~index) handlers.splice(index, 1);\n\t\t}\n\t};\n}",
- "set": "function set(newState) {\n\tthis._set(assign({}, newState));\n\tif (this.root._lock) return;\n\tflush(this.root);\n}",
- "_set": "function _set(newState) {\n\tvar oldState = this._state,\n\t\tchanged = {},\n\t\tdirty = false;\n\n\tnewState = assign(this._staged, newState);\n\tthis._staged = {};\n\n\tfor (var key in newState) {\n\t\tif (this._differs(newState[key], oldState[key])) changed[key] = dirty = true;\n\t}\n\tif (!dirty) return;\n\n\tthis._state = assign(assign({}, oldState), newState);\n\tthis._recompute(changed, this._state);\n\tif (this._bind) this._bind(changed, this._state);\n\n\tif (this._fragment) {\n\t\tthis.fire(\"state\", { changed: changed, current: this._state, previous: oldState });\n\t\tthis._fragment.p(changed, this._state);\n\t\tthis.fire(\"update\", { changed: changed, current: this._state, previous: oldState });\n\t}\n}",
- "_stage": "function _stage(newState) {\n\tassign(this._staged, newState);\n}",
- "setDev": "function setDev(newState) {\n\tif (typeof newState !== 'object') {\n\t\tthrow new Error(\n\t\t\tthis._debugName + '.set was called without an object of data key-values to update.'\n\t\t);\n\t}\n\n\tthis._checkReadOnly(newState);\n\tset.call(this, newState);\n}",
- "callAll": "function callAll(fns) {\n\twhile (fns && fns.length) fns.shift()();\n}",
- "_mount": "function _mount(target, anchor) {\n\tthis._fragment[this._fragment.i ? 'i' : 'm'](target, anchor || null);\n}",
- "PENDING": "{}",
- "SUCCESS": "{}",
- "FAILURE": "{}",
- "removeFromStore": "function removeFromStore() {\n\tthis.store._remove(this);\n}",
- "proto": "{\n\tdestroy,\n\tget,\n\tfire,\n\ton,\n\tset,\n\t_recompute: noop,\n\t_set,\n\t_stage,\n\t_mount,\n\t_differs\n}",
- "protoDev": "{\n\tdestroy: destroyDev,\n\tget,\n\tfire,\n\ton,\n\tset: setDev,\n\t_recompute: noop,\n\t_set,\n\t_stage,\n\t_mount,\n\t_differs\n}",
- "destroyBlock": "function destroyBlock(block, lookup) {\n\tblock.d(1);\n\tlookup[block.key] = null;\n}",
- "outroAndDestroyBlock": "function outroAndDestroyBlock(block, lookup) {\n\tblock.o(function() {\n\t\tdestroyBlock(block, lookup);\n\t});\n}",
- "fixAndOutroAndDestroyBlock": "function fixAndOutroAndDestroyBlock(block, lookup) {\n\tblock.f();\n\toutroAndDestroyBlock(block, lookup);\n}",
- "updateKeyedEach": "function updateKeyedEach(old_blocks, component, changed, get_key, dynamic, ctx, list, lookup, node, destroy, create_each_block, intro_method, next, get_context) {\n\tvar o = old_blocks.length;\n\tvar n = list.length;\n\n\tvar i = o;\n\tvar old_indexes = {};\n\twhile (i--) old_indexes[old_blocks[i].key] = i;\n\n\tvar new_blocks = [];\n\tvar new_lookup = {};\n\tvar deltas = {};\n\n\tvar i = n;\n\twhile (i--) {\n\t\tvar child_ctx = get_context(ctx, list, i);\n\t\tvar key = get_key(child_ctx);\n\t\tvar block = lookup[key];\n\n\t\tif (!block) {\n\t\t\tblock = create_each_block(component, key, child_ctx);\n\t\t\tblock.c();\n\t\t} else if (dynamic) {\n\t\t\tblock.p(changed, child_ctx);\n\t\t}\n\n\t\tnew_blocks[i] = new_lookup[key] = block;\n\n\t\tif (key in old_indexes) deltas[key] = Math.abs(i - old_indexes[key]);\n\t}\n\n\tvar will_move = {};\n\tvar did_move = {};\n\n\tfunction insert(block) {\n\t\tblock[intro_method](node, next);\n\t\tlookup[block.key] = block;\n\t\tnext = block.first;\n\t\tn--;\n\t}\n\n\twhile (o && n) {\n\t\tvar new_block = new_blocks[n - 1];\n\t\tvar old_block = old_blocks[o - 1];\n\t\tvar new_key = new_block.key;\n\t\tvar old_key = old_block.key;\n\n\t\tif (new_block === old_block) {\n\t\t\t// do nothing\n\t\t\tnext = new_block.first;\n\t\t\to--;\n\t\t\tn--;\n\t\t}\n\n\t\telse if (!new_lookup[old_key]) {\n\t\t\t// remove old block\n\t\t\tdestroy(old_block, lookup);\n\t\t\to--;\n\t\t}\n\n\t\telse if (!lookup[new_key] || will_move[new_key]) {\n\t\t\tinsert(new_block);\n\t\t}\n\n\t\telse if (did_move[old_key]) {\n\t\t\to--;\n\n\t\t} else if (deltas[new_key] > deltas[old_key]) {\n\t\t\tdid_move[new_key] = true;\n\t\t\tinsert(new_block);\n\n\t\t} else {\n\t\t\twill_move[old_key] = true;\n\t\t\to--;\n\t\t}\n\t}\n\n\twhile (o--) {\n\t\tvar old_block = old_blocks[o];\n\t\tif (!new_lookup[old_block.key]) destroy(old_block, lookup);\n\t}\n\n\twhile (n) insert(new_blocks[n - 1]);\n\n\treturn new_blocks;\n}",
- "measure": "function measure(blocks) {\n\tconst rects = {};\n\tlet i = blocks.length;\n\twhile (i--) rects[blocks[i].key] = blocks[i].node.getBoundingClientRect();\n\treturn rects;\n}",
- "animate": "function animate(blocks, rects, fn, params) {\n\tlet i = blocks.length;\n\twhile (i--) {\n\t\tconst block = blocks[i];\n\t\tconst from = rects[block.key];\n\n\t\tif (!from) continue;\n\t\tconst to = block.node.getBoundingClientRect();\n\n\t\tif (from.left === to.left && from.right === to.right && from.top === to.top && from.bottom === to.bottom) continue;\n\n\n\t}\n}",
- "getSpreadUpdate": "function getSpreadUpdate(levels, updates) {\n\tvar update = {};\n\n\tvar to_null_out = {};\n\tvar accounted_for = {};\n\n\tvar i = levels.length;\n\twhile (i--) {\n\t\tvar o = levels[i];\n\t\tvar n = updates[i];\n\n\t\tif (n) {\n\t\t\tfor (var key in o) {\n\t\t\t\tif (!(key in n)) to_null_out[key] = 1;\n\t\t\t}\n\n\t\t\tfor (var key in n) {\n\t\t\t\tif (!accounted_for[key]) {\n\t\t\t\t\tupdate[key] = n[key];\n\t\t\t\t\taccounted_for[key] = 1;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tlevels[i] = n;\n\t\t} else {\n\t\t\tfor (var key in o) {\n\t\t\t\taccounted_for[key] = 1;\n\t\t\t}\n\t\t}\n\t}\n\n\tfor (var key in to_null_out) {\n\t\tif (!(key in update)) update[key] = undefined;\n\t}\n\n\treturn update;\n}",
- "invalidAttributeNameCharacter": "/[\\s'\">\\/=\\u{FDD0}-\\u{FDEF}\\u{FFFE}\\u{FFFF}\\u{1FFFE}\\u{1FFFF}\\u{2FFFE}\\u{2FFFF}\\u{3FFFE}\\u{3FFFF}\\u{4FFFE}\\u{4FFFF}\\u{5FFFE}\\u{5FFFF}\\u{6FFFE}\\u{6FFFF}\\u{7FFFE}\\u{7FFFF}\\u{8FFFE}\\u{8FFFF}\\u{9FFFE}\\u{9FFFF}\\u{AFFFE}\\u{AFFFF}\\u{BFFFE}\\u{BFFFF}\\u{CFFFE}\\u{CFFFF}\\u{DFFFE}\\u{DFFFF}\\u{EFFFE}\\u{EFFFF}\\u{FFFFE}\\u{FFFFF}\\u{10FFFE}\\u{10FFFF}]/u",
- "spread": "function spread(args) {\n\tconst attributes = Object.assign({}, ...args);\n\tlet str = '';\n\n\tObject.keys(attributes).forEach(name => {\n\t\tif (invalidAttributeNameCharacter.test(name)) return;\n\n\t\tconst value = attributes[name];\n\t\tif (value === undefined) return;\n\t\tif (value === true) str += \" \" + name;\n\n\t\tconst escaped = String(value)\n\t\t\t.replace(/\"/g, '"')\n\t\t\t.replace(/'/g, ''');\n\n\t\tstr += \" \" + name + \"=\" + JSON.stringify(escaped);\n\t});\n\n\treturn str;\n}",
- "escaped": "{\n\t'\"': '"',\n\t\"'\": ''',\n\t'&': '&',\n\t'<': '<',\n\t'>': '>'\n}",
- "escape": "function escape(html) {\n\treturn String(html).replace(/[\"'&<>]/g, match => escaped[match]);\n}",
- "each": "function each(items, assign, fn) {\n\tlet str = '';\n\tfor (let i = 0; i < items.length; i += 1) {\n\t\tstr += fn(assign(items[i], i));\n\t}\n\treturn str;\n}",
- "missingComponent": "{\n\t_render: () => ''\n}",
- "validateSsrComponent": "function validateSsrComponent(component, name) {\n\tif (!component || !component._render) {\n\t\tif (name === 'svelte:component') name += ' this={...}';\n\t\tthrow new Error(`<${name}> is not a valid SSR component. You may need to review your build config to ensure that dependencies are compiled, rather than imported as pre-compiled modules`);\n\t}\n\n\treturn component;\n}",
- "debug": "function debug(file, line, column, values) {\n\tconsole.log(`{@debug} ${file ? file + ' ' : ''}(${line}:${column})`);\n\tconsole.log(values);\n\treturn '';\n}",
- "linear": "function linear(t) {\n\treturn t;\n}",
- "generateRule": "function generateRule({ a, b, delta, duration }, ease, fn) {\n\tconst step = 16.666 / duration;\n\tlet keyframes = '{\\n';\n\n\tfor (let p = 0; p <= 1; p += step) {\n\t\tconst t = a + delta * ease(p);\n\t\tkeyframes += p * 100 + `%{${fn(t, 1 - t)}}\\n`;\n\t}\n\n\treturn keyframes + `100% {${fn(b, 1 - b)}}\\n}`;\n}",
- "hash": "function hash(str) {\n\tlet hash = 5381;\n\tlet i = str.length;\n\n\twhile (i--) hash = ((hash << 5) - hash) ^ str.charCodeAt(i);\n\treturn hash >>> 0;\n}",
- "wrapTransition": "function wrapTransition(component, node, fn, params, intro) {\n\tlet obj = fn.call(component, node, params);\n\tlet duration;\n\tlet ease;\n\tlet cssText;\n\n\tlet initialised = false;\n\n\treturn {\n\t\tt: intro ? 0 : 1,\n\t\trunning: false,\n\t\tprogram: null,\n\t\tpending: null,\n\n\t\trun(b, callback) {\n\t\t\tif (typeof obj === 'function') {\n\t\t\t\ttransitionManager.wait().then(() => {\n\t\t\t\t\tobj = obj();\n\t\t\t\t\tthis._run(b, callback);\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tthis._run(b, callback);\n\t\t\t}\n\t\t},\n\n\t\t_run(b, callback) {\n\t\t\tduration = obj.duration || 300;\n\t\t\tease = obj.easing || linear;\n\n\t\t\tconst program = {\n\t\t\t\tstart: window.performance.now() + (obj.delay || 0),\n\t\t\t\tb,\n\t\t\t\tcallback: callback || noop\n\t\t\t};\n\n\t\t\tif (intro && !initialised) {\n\t\t\t\tif (obj.css && obj.delay) {\n\t\t\t\t\tcssText = node.style.cssText;\n\t\t\t\t\tnode.style.cssText += obj.css(0, 1);\n\t\t\t\t}\n\n\t\t\t\tif (obj.tick) obj.tick(0, 1);\n\t\t\t\tinitialised = true;\n\t\t\t}\n\n\t\t\tif (!b) {\n\t\t\t\tprogram.group = outros.current;\n\t\t\t\toutros.current.remaining += 1;\n\t\t\t}\n\n\t\t\tif (obj.delay) {\n\t\t\t\tthis.pending = program;\n\t\t\t} else {\n\t\t\t\tthis.start(program);\n\t\t\t}\n\n\t\t\tif (!this.running) {\n\t\t\t\tthis.running = true;\n\t\t\t\ttransitionManager.add(this);\n\t\t\t}\n\t\t},\n\n\t\tstart(program) {\n\t\t\tcomponent.fire(`${program.b ? 'intro' : 'outro'}.start`, { node });\n\n\t\t\tprogram.a = this.t;\n\t\t\tprogram.delta = program.b - program.a;\n\t\t\tprogram.duration = duration * Math.abs(program.b - program.a);\n\t\t\tprogram.end = program.start + program.duration;\n\n\t\t\tif (obj.css) {\n\t\t\t\tif (obj.delay) node.style.cssText = cssText;\n\n\t\t\t\tconst rule = generateRule(program, ease, obj.css);\n\t\t\t\ttransitionManager.addRule(rule, program.name = '__svelte_' + hash(rule));\n\n\t\t\t\tnode.style.animation = (node.style.animation || '')\n\t\t\t\t\t.split(', ')\n\t\t\t\t\t.filter(anim => anim && (program.delta < 0 || !/__svelte/.test(anim)))\n\t\t\t\t\t.concat(`${program.name} ${program.duration}ms linear 1 forwards`)\n\t\t\t\t\t.join(', ');\n\t\t\t}\n\n\t\t\tthis.program = program;\n\t\t\tthis.pending = null;\n\t\t},\n\n\t\tupdate(now) {\n\t\t\tconst program = this.program;\n\t\t\tif (!program) return;\n\n\t\t\tconst p = now - program.start;\n\t\t\tthis.t = program.a + program.delta * ease(p / program.duration);\n\t\t\tif (obj.tick) obj.tick(this.t, 1 - this.t);\n\t\t},\n\n\t\tdone() {\n\t\t\tconst program = this.program;\n\t\t\tthis.t = program.b;\n\n\t\t\tif (obj.tick) obj.tick(this.t, 1 - this.t);\n\n\t\t\tcomponent.fire(`${program.b ? 'intro' : 'outro'}.end`, { node });\n\n\t\t\tif (!program.b && !program.invalidated) {\n\t\t\t\tprogram.group.callbacks.push(() => {\n\t\t\t\t\tprogram.callback();\n\t\t\t\t\tif (obj.css) transitionManager.deleteRule(node, program.name);\n\t\t\t\t});\n\n\t\t\t\tif (--program.group.remaining === 0) {\n\t\t\t\t\tprogram.group.callbacks.forEach(run);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif (obj.css) transitionManager.deleteRule(node, program.name);\n\t\t\t}\n\n\t\t\tthis.running = !!this.pending;\n\t\t},\n\n\t\tabort(reset) {\n\t\t\tif (this.program) {\n\t\t\t\tif (reset && obj.tick) obj.tick(1, 0);\n\t\t\t\tif (obj.css) transitionManager.deleteRule(node, this.program.name);\n\t\t\t\tthis.program = this.pending = null;\n\t\t\t\tthis.running = false;\n\t\t\t}\n\t\t},\n\n\t\tinvalidate() {\n\t\t\tif (this.program) {\n\t\t\t\tthis.program.invalidated = true;\n\t\t\t}\n\t\t}\n\t};\n}",
- "outros": "{}",
- "groupOutros": "function groupOutros() {\n\toutros.current = {\n\t\tremaining: 0,\n\t\tcallbacks: []\n\t};\n}",
- "transitionManager": "{\n\trunning: false,\n\ttransitions: [],\n\tbound: null,\n\tstylesheet: null,\n\tactiveRules: {},\n\tpromise: null,\n\n\tadd(transition) {\n\t\tthis.transitions.push(transition);\n\n\t\tif (!this.running) {\n\t\t\tthis.running = true;\n\t\t\trequestAnimationFrame(this.bound || (this.bound = this.next.bind(this)));\n\t\t}\n\t},\n\n\taddRule(rule, name) {\n\t\tif (!this.stylesheet) {\n\t\t\tconst style = createElement('style');\n\t\t\tdocument.head.appendChild(style);\n\t\t\ttransitionManager.stylesheet = style.sheet;\n\t\t}\n\n\t\tif (!this.activeRules[name]) {\n\t\t\tthis.activeRules[name] = true;\n\t\t\tthis.stylesheet.insertRule(`@keyframes ${name} ${rule}`, this.stylesheet.cssRules.length);\n\t\t}\n\t},\n\n\tnext() {\n\t\tthis.running = false;\n\n\t\tconst now = window.performance.now();\n\t\tlet i = this.transitions.length;\n\n\t\twhile (i--) {\n\t\t\tconst transition = this.transitions[i];\n\n\t\t\tif (transition.program && now >= transition.program.end) {\n\t\t\t\ttransition.done();\n\t\t\t}\n\n\t\t\tif (transition.pending && now >= transition.pending.start) {\n\t\t\t\ttransition.start(transition.pending);\n\t\t\t}\n\n\t\t\tif (transition.running) {\n\t\t\t\ttransition.update(now);\n\t\t\t\tthis.running = true;\n\t\t\t} else if (!transition.pending) {\n\t\t\t\tthis.transitions.splice(i, 1);\n\t\t\t}\n\t\t}\n\n\t\tif (this.running) {\n\t\t\trequestAnimationFrame(this.bound);\n\t\t} else if (this.stylesheet) {\n\t\t\tlet i = this.stylesheet.cssRules.length;\n\t\t\twhile (i--) this.stylesheet.deleteRule(i);\n\t\t\tthis.activeRules = {};\n\t\t}\n\t},\n\n\tdeleteRule(node, name) {\n\t\tnode.style.animation = node.style.animation\n\t\t\t.split(', ')\n\t\t\t.filter(anim => anim && anim.indexOf(name) === -1)\n\t\t\t.join(', ');\n\t},\n\n\twait() {\n\t\tif (!transitionManager.promise) {\n\t\t\ttransitionManager.promise = Promise.resolve();\n\t\t\ttransitionManager.promise.then(() => {\n\t\t\t\ttransitionManager.promise = null;\n\t\t\t});\n\t\t}\n\n\t\treturn transitionManager.promise;\n\t}\n}",
- "noop": "function noop() {}",
- "assign": "function assign(tar, src) {\n\tfor (var k in src) tar[k] = src[k];\n\treturn tar;\n}",
- "assignTrue": "function assignTrue(tar, src) {\n\tfor (var k in src) tar[k] = 1;\n\treturn tar;\n}",
- "isPromise": "function isPromise(value) {\n\treturn value && typeof value.then === 'function';\n}",
- "callAfter": "function callAfter(fn, i) {\n\tif (i === 0) fn();\n\treturn () => {\n\t\tif (!--i) fn();\n\t};\n}",
- "addLoc": "function addLoc(element, file, line, column, char) {\n\telement.__svelte_meta = {\n\t\tloc: { file, line, column, char }\n\t};\n}",
- "exclude": "function exclude(src, prop) {\n\tconst tar = {};\n\tfor (const k in src) k === prop || (tar[k] = src[k]);\n\treturn tar;\n}",
- "run": "function run(fn) {\n\tfn();\n}"
- };
- function checkForComputedKeys(component, properties) {
- properties.forEach(prop => {
- if (prop.key.computed) {
- component.error(prop, {
- code: `computed-key`,
- message: `Cannot use computed keys`
- });
- }
- });
- }
- function checkForDupes(component, properties) {
- const seen = new Set();
- properties.forEach(prop => {
- const name = getMethodName(prop.key);
- if (seen.has(name)) {
- component.error(prop, {
- code: `duplicate-property`,
- message: `Duplicate property '${name}'`
- });
- }
- seen.add(name);
- });
- }
- const disallowed = new Set(['Literal', 'ObjectExpression', 'ArrayExpression']);
- function data$1(component, prop) {
- while (prop.type === 'ParenthesizedExpression')
- prop = prop.expression;
- if (disallowed.has(prop.value.type)) {
- component.error(prop.value, {
- code: `invalid-data-property`,
- message: `'data' must be a function`
- });
- }
- }
- function actions(component, prop) {
- if (prop.value.type !== 'ObjectExpression') {
- component.error(prop, {
- code: `invalid-actions`,
- message: `The 'actions' property must be an object literal`
- });
- }
- checkForDupes(component, prop.value.properties);
- checkForComputedKeys(component, prop.value.properties);
- }
- function transitions(component, prop) {
- if (prop.value.type !== 'ObjectExpression') {
- component.error(prop, {
- code: `invalid-transitions-property`,
- message: `The 'transitions' property must be an object literal`
- });
- }
- checkForDupes(component, prop.value.properties);
- checkForComputedKeys(component, prop.value.properties);
- prop.value.properties.forEach(() => {
- // TODO probably some validation that can happen here...
- // checking for use of `this` etc?
- });
- }
- function walkThroughTopFunctionScope(body, callback) {
- let lexicalDepth = 0;
- walk(body, {
- enter(node) {
- if (/^Function/.test(node.type)) {
- lexicalDepth += 1;
- }
- else if (lexicalDepth === 0) {
- callback(node);
- }
- },
- leave(node) {
- if (/^Function/.test(node.type)) {
- lexicalDepth -= 1;
- }
- },
- });
- }
- function isThisGetCallExpression(node) {
- return node.type === 'CallExpression' &&
- node.callee.type === 'MemberExpression' &&
- node.callee.object.type === 'ThisExpression' &&
- node.callee.property.name === 'get';
- }
- const isFunctionExpression = new Set([
- 'FunctionExpression',
- 'ArrowFunctionExpression',
- ]);
- function computed(component, prop) {
- if (prop.value.type !== 'ObjectExpression') {
- component.error(prop, {
- code: `invalid-computed-property`,
- message: `The 'computed' property must be an object literal`
- });
- }
- checkForDupes(component, prop.value.properties);
- checkForComputedKeys(component, prop.value.properties);
- prop.value.properties.forEach((computation) => {
- const name = getMethodName(computation.key);
- if (!isValidIdentifier(name)) {
- const suggestion = name.replace(/[^_$a-z0-9]/ig, '_').replace(/^\d/, '_$&');
- component.error(computation.key, {
- code: `invalid-computed-name`,
- message: `Computed property name '${name}' is invalid — must be a valid identifier such as ${suggestion}`
- });
- }
- if (reservedNames.has(name)) {
- component.error(computation.key, {
- code: `invalid-computed-name`,
- message: `Computed property name '${name}' is invalid — cannot be a JavaScript reserved word`
- });
- }
- if (!isFunctionExpression.has(computation.value.type)) {
- component.error(computation.value, {
- code: `invalid-computed-value`,
- message: `Computed properties can be function expressions or arrow function expressions`
- });
- }
- const { body, params } = computation.value;
- walkThroughTopFunctionScope(body, (node) => {
- if (isThisGetCallExpression(node) && !node.callee.property.computed) {
- component.error(node, {
- code: `impure-computed`,
- message: `Cannot use this.get(...) — values must be passed into the function as arguments`
- });
- }
- if (node.type === 'ThisExpression') {
- component.error(node, {
- code: `impure-computed`,
- message: `Computed properties should be pure functions — they do not have access to the component instance and cannot use 'this'. Did you mean to put this in 'methods'?`
- });
- }
- });
- if (params.length === 0) {
- component.error(computation.value, {
- code: `impure-computed`,
- message: `A computed value must depend on at least one property`
- });
- }
- if (params.length > 1) {
- component.error(computation.value, {
- code: `invalid-computed-arguments`,
- message: `Computed properties must take a single argument`
- });
- }
- });
- }
- function usesThisOrArguments(node) {
- let result = false;
- walk(node, {
- enter(node, parent) {
- if (result ||
- node.type === 'FunctionExpression' ||
- node.type === 'FunctionDeclaration') {
- return this.skip();
- }
- if (node.type === 'ThisExpression') {
- result = true;
- }
- if (node.type === 'Identifier' &&
- isReference(node, parent) &&
- node.name === 'arguments') {
- result = true;
- }
- },
- });
- return result;
- }
- function oncreate(component, prop) {
- if (prop.value.type === 'ArrowFunctionExpression') {
- if (usesThisOrArguments(prop.value.body)) {
- component.error(prop, {
- code: `invalid-oncreate-property`,
- message: `'oncreate' should be a function expression, not an arrow function expression`
- });
- }
- }
- }
- function ondestroy(component, prop) {
- if (prop.value.type === 'ArrowFunctionExpression') {
- if (usesThisOrArguments(prop.value.body)) {
- component.error(prop, {
- code: `invalid-ondestroy-property`,
- message: `'ondestroy' should be a function expression, not an arrow function expression`
- });
- }
- }
- }
- function onstate(component, prop) {
- if (prop.value.type === 'ArrowFunctionExpression') {
- if (usesThisOrArguments(prop.value.body)) {
- component.error(prop, {
- code: `invalid-onstate-property`,
- message: `'onstate' should be a function expression, not an arrow function expression`
- });
- }
- }
- }
- function onupdate(component, prop) {
- if (prop.value.type === 'ArrowFunctionExpression') {
- if (usesThisOrArguments(prop.value.body)) {
- component.error(prop, {
- code: `invalid-onupdate-property`,
- message: `'onupdate' should be a function expression, not an arrow function expression`
- });
- }
- }
- }
- function onrender(component, prop) {
- component.warn(prop, {
- code: `deprecated-onrender`,
- message: `'onrender' has been deprecated in favour of 'oncreate', and will cause an error in Svelte 2.x`
- });
- oncreate(component, prop);
- }
- function onteardown(component, prop) {
- component.warn(prop, {
- code: `deprecated-onteardown`,
- message: `'onteardown' has been deprecated in favour of 'ondestroy', and will cause an error in Svelte 2.x`
- });
- ondestroy(component, prop);
- }
- function helpers(component, prop) {
- if (prop.value.type !== 'ObjectExpression') {
- component.error(prop, {
- code: `invalid-helpers-property`,
- message: `The 'helpers' property must be an object literal`
- });
- }
- checkForDupes(component, prop.value.properties);
- checkForComputedKeys(component, prop.value.properties);
- prop.value.properties.forEach((prop) => {
- if (!/FunctionExpression/.test(prop.value.type))
- return;
- let usesArguments = false;
- walkThroughTopFunctionScope(prop.value.body, (node) => {
- if (isThisGetCallExpression(node) && !node.callee.property.computed) {
- component.error(node, {
- code: `impure-helper`,
- message: `Cannot use this.get(...) — values must be passed into the helper function as arguments`
- });
- }
- if (node.type === 'ThisExpression') {
- component.error(node, {
- code: `impure-helper`,
- message: `Helpers should be pure functions — they do not have access to the component instance and cannot use 'this'. Did you mean to put this in 'methods'?`
- });
- }
- else if (node.type === 'Identifier' && node.name === 'arguments') {
- usesArguments = true;
- }
- });
- if (prop.value.params.length === 0 && !usesArguments) {
- component.warn(prop, {
- code: `impure-helper`,
- message: `Helpers should be pure functions, with at least one argument`
- });
- }
- });
- }
- function checkForAccessors(component, properties, label) {
- properties.forEach(prop => {
- if (prop.kind !== 'init') {
- component.error(prop, {
- code: `illegal-accessor`,
- message: `${label} cannot use getters and setters`
- });
- }
- });
- }
- const builtin = new Set(['set', 'get', 'on', 'fire', 'destroy']);
- function methods(component, prop) {
- if (prop.value.type !== 'ObjectExpression') {
- component.error(prop, {
- code: `invalid-methods-property`,
- message: `The 'methods' property must be an object literal`
- });
- }
- checkForAccessors(component, prop.value.properties, 'Methods');
- checkForDupes(component, prop.value.properties);
- checkForComputedKeys(component, prop.value.properties);
- prop.value.properties.forEach((prop) => {
- const name = getMethodName(prop.key);
- if (builtin.has(name)) {
- component.error(prop, {
- code: `invalid-method-name`,
- message: `Cannot overwrite built-in method '${name}'`
- });
- }
- if (prop.value.type === 'ArrowFunctionExpression') {
- if (usesThisOrArguments(prop.value.body)) {
- component.error(prop, {
- code: `invalid-method-value`,
- message: `Method '${prop.key.name}' should be a function expression, not an arrow function expression`
- });
- }
- }
- });
- }
- function components(component, prop) {
- if (prop.value.type !== 'ObjectExpression') {
- component.error(prop, {
- code: `invalid-components-property`,
- message: `The 'components' property must be an object literal`
- });
- }
- checkForDupes(component, prop.value.properties);
- checkForComputedKeys(component, prop.value.properties);
- prop.value.properties.forEach((node) => {
- const name = getMethodName(node.key);
- if (name === 'state') {
- // TODO is this still true?
- component.error(node, {
- code: `invalid-name`,
- message: `Component constructors cannot be called 'state' due to technical limitations`
- });
- }
- if (!/^[A-Z]/.test(name)) {
- component.error(node, {
- code: `component-lowercase`,
- message: `Component names must be capitalised`
- });
- }
- });
- }
- function events$1(component, prop) {
- if (prop.value.type !== 'ObjectExpression') {
- component.error(prop, {
- code: `invalid-events-property`,
- message: `The 'events' property must be an object literal`
- });
- }
- checkForDupes(component, prop.value.properties);
- checkForComputedKeys(component, prop.value.properties);
- }
- const valid = new Set(validNamespaces);
- function namespace(component, prop) {
- const ns = nodeToString(prop.value);
- if (typeof ns !== 'string') {
- component.error(prop, {
- code: `invalid-namespace-property`,
- message: `The 'namespace' property must be a string literal representing a valid namespace`
- });
- }
- if (!valid.has(ns)) {
- const match = fuzzymatch(ns, validNamespaces);
- if (match) {
- component.error(prop, {
- code: `invalid-namespace-property`,
- message: `Invalid namespace '${ns}' (did you mean '${match}'?)`
- });
- }
- else {
- component.error(prop, {
- code: `invalid-namespace-property`,
- message: `Invalid namespace '${ns}'`
- });
- }
- }
- }
- function preload(component, prop) {
- // not sure there's anything we need to check here...
- }
- function props(component, prop) {
- if (prop.value.type !== 'ArrayExpression') {
- component.error(prop.value, {
- code: `invalid-props-property`,
- message: `'props' must be an array expression, if specified`
- });
- }
- prop.value.elements.forEach((element) => {
- if (typeof nodeToString(element) !== 'string') {
- component.error(element, {
- code: `invalid-props-property`,
- message: `'props' must be an array of string literals`
- });
- }
- });
- }
- function tag$1(component, prop) {
- const tag = nodeToString(prop.value);
- if (typeof tag !== 'string') {
- component.error(prop.value, {
- code: `invalid-tag-property`,
- message: `'tag' must be a string literal`
- });
- }
- if (!/^[a-zA-Z][a-zA-Z0-9]*-[a-zA-Z0-9-]+$/.test(tag)) {
- component.error(prop.value, {
- code: `invalid-tag-property`,
- message: `tag name must be two or more words joined by the '-' character`
- });
- }
- }
- function transitions$1(component, prop) {
- if (prop.value.type !== 'ObjectExpression') {
- component.error(prop, {
- code: `invalid-transitions-property`,
- message: `The 'transitions' property must be an object literal`
- });
- }
- checkForDupes(component, prop.value.properties);
- checkForComputedKeys(component, prop.value.properties);
- prop.value.properties.forEach(() => {
- // TODO probably some validation that can happen here...
- // checking for use of `this` etc?
- });
- }
- const disallowed$1 = new Set(['Literal', 'ObjectExpression', 'ArrayExpression']);
- function setup(component, prop) {
- while (prop.type === 'ParenthesizedExpression')
- prop = prop.expression;
- if (disallowed$1.has(prop.value.type)) {
- component.error(prop.value, {
- code: `invalid-setup-property`,
- message: `'setup' must be a function`
- });
- }
- }
- function store(component, prop) {
- // not sure there's anything we need to check here...
- }
- function immutable(component, prop) {
- if (prop.value.type !== 'Literal' || typeof prop.value.value !== 'boolean') {
- component.error(prop.value, {
- code: `invalid-immutable-property`,
- message: `'immutable' must be a boolean literal`
- });
- }
- }
- var propValidators = {
- data: data$1,
- actions,
- animations: transitions,
- computed,
- oncreate,
- ondestroy,
- onstate,
- onupdate,
- onrender,
- onteardown,
- helpers,
- methods,
- components,
- events: events$1,
- namespace,
- preload,
- props,
- tag: tag$1,
- transitions: transitions$1,
- setup,
- store,
- immutable,
- };
- function getIndentationLevel(str, b) {
- let a = b;
- while (a > 0 && str[a - 1] !== '\n')
- a -= 1;
- return /^\s*/.exec(str.slice(a, b))[0];
- }
- function getIndentExclusionRanges(node) {
- // TODO can we fold this into a different pass?
- const ranges = [];
- walk(node, {
- enter(node) {
- if (node.type === 'TemplateElement')
- ranges.push(node);
- }
- });
- return ranges;
- }
- function removeIndentation(code, start, end, indentationLevel, ranges) {
- const str = code.original.slice(start, end);
- const pattern = new RegExp(`^${indentationLevel}`, 'gm');
- let match;
- while (match = pattern.exec(str)) {
- // TODO bail if we're inside an exclusion range
- code.remove(start + match.index, start + match.index + indentationLevel.length);
- }
- }
- // We need to tell estree-walker that it should always
- // look for an `else` block, otherwise it might get
- // the wrong idea about the shape of each/if blocks
- childKeys.EachBlock = childKeys.IfBlock = ['children', 'else'];
- childKeys.Attribute = ['value'];
- class Component {
- constructor(ast, source, name, options, stats) {
- this.stats = stats;
- this.ast = ast;
- this.source = source;
- this.options = options;
- this.imports = [];
- this.shorthandImports = [];
- this.helpers = new Set();
- this.components = new Set();
- this.events = new Set();
- this.methods = new Set();
- this.animations = new Set();
- this.transitions = new Set();
- this.actions = new Set();
- this.importedComponents = new Map();
- this.used = {
- components: new Set(),
- helpers: new Set(),
- events: new Set(),
- animations: new Set(),
- transitions: new Set(),
- actions: new Set(),
- };
- this.declarations = [];
- this.refs = new Set();
- this.refCallees = [];
- this.indirectDependencies = new Map();
- this.file = options.filename && (typeof process !== 'undefined' ? options.filename.replace(process.cwd(), '').replace(/^[\/\\]/, '') : options.filename);
- this.locate = getLocator(this.source);
- // track which properties are needed, so we can provide useful info
- // in dev mode
- this.expectedProperties = new Set();
- this.code = new MagicString(source);
- // styles
- this.stylesheet = new Stylesheet(source, ast, options.filename, options.dev);
- this.stylesheet.validate(this);
- // allow compiler to deconflict user's `import { get } from 'whatever'` and
- // Svelte's builtin `import { get, ... } from 'svelte/shared.ts'`;
- this.userVars = new Set();
- this.templateVars = new Map();
- this.aliases = new Map();
- this.usedNames = new Set();
- this.computations = [];
- this.templateProperties = {};
- this.properties = new Map();
- this.walkJs();
- this.name = this.alias(name);
- if (options.customElement === true) {
- this.customElement = {
- tag: this.tag,
- props: this.props
- };
- }
- else {
- this.customElement = options.customElement;
- }
- if (this.customElement && !this.customElement.tag) {
- throw new Error(`No tag name specified`); // TODO better error
- }
- this.fragment = new Fragment(this, ast.html);
- // this.walkTemplate();
- if (!this.customElement)
- this.stylesheet.reify();
- this.stylesheet.warnOnUnusedSelectors(options.onwarn);
- if (this.defaultExport) {
- const categories = {
- components: 'component',
- helpers: 'helper',
- events: 'event definition',
- transitions: 'transition',
- actions: 'actions',
- };
- Object.keys(categories).forEach(category => {
- const definitions = this.defaultExport.declaration.properties.find(prop => prop.key.name === category);
- if (definitions) {
- definitions.value.properties.forEach(prop => {
- const { name } = prop.key;
- if (!this.used[category].has(name)) {
- this.warn(prop, {
- code: `unused-${category.slice(0, -1)}`,
- message: `The '${name}' ${categories[category]} is unused`
- });
- }
- });
- }
- });
- }
- this.refCallees.forEach(callee => {
- const { parts } = flattenReference(callee);
- const ref = parts[1];
- if (this.refs.has(ref)) ;
- else {
- const match = fuzzymatch(ref, Array.from(this.refs.keys()));
- let message = `'refs.${ref}' does not exist`;
- if (match)
- message += ` (did you mean 'refs.${match}'?)`;
- this.error(callee, {
- code: `missing-ref`,
- message
- });
- }
- });
- }
- addSourcemapLocations(node) {
- walk(node, {
- enter: (node) => {
- this.code.addSourcemapLocation(node.start);
- this.code.addSourcemapLocation(node.end);
- },
- });
- }
- alias(name) {
- if (!this.aliases.has(name)) {
- this.aliases.set(name, this.getUniqueName(name));
- }
- return this.aliases.get(name);
- }
- generate(result, options, { banner = '', name, format }) {
- const pattern = /\[✂(\d+)-(\d+)$/;
- const helpers = new Set();
- // TODO use same regex for both
- result = result.replace(options.generate === 'ssr' ? /(@+|#+|%+)(\w*(?:-\w*)?)/g : /(%+|@+)(\w*(?:-\w*)?)/g, (match, sigil, name) => {
- if (sigil === '@') {
- if (name in shared) {
- if (options.dev && `${name}Dev` in shared)
- name = `${name}Dev`;
- helpers.add(name);
- }
- return this.alias(name);
- }
- if (sigil === '%') {
- return this.templateVars.get(name);
- }
- return sigil.slice(1) + name;
- });
- let importedHelpers;
- if (options.shared) {
- if (format !== 'es' && format !== 'cjs') {
- throw new Error(`Components with shared helpers must be compiled with \`format: 'es'\` or \`format: 'cjs'\``);
- }
- importedHelpers = Array.from(helpers).sort().map(name => {
- const alias = this.alias(name);
- return { name, alias };
- });
- }
- else {
- let inlineHelpers = '';
- const component = this;
- importedHelpers = [];
- helpers.forEach(name => {
- const str = shared[name];
- const code = new MagicString(str);
- const expression = parseExpressionAt(str, 0);
- let { scope } = annotateWithScopes(expression);
- walk(expression, {
- enter(node, parent) {
- if (node._scope)
- scope = node._scope;
- if (node.type === 'Identifier' &&
- isReference(node, parent) &&
- !scope.has(node.name)) {
- if (node.name in shared) {
- // this helper function depends on another one
- const dependency = node.name;
- helpers.add(dependency);
- const alias = component.alias(dependency);
- if (alias !== node.name) {
- code.overwrite(node.start, node.end, alias);
- }
- }
- }
- },
- leave(node) {
- if (node._scope)
- scope = scope.parent;
- },
- });
- if (name === 'transitionManager' || name === 'outros') {
- // special case
- const global = name === 'outros'
- ? `_svelteOutros`
- : `_svelteTransitionManager`;
- inlineHelpers += `\n\nvar ${this.alias(name)} = window.${global} || (window.${global} = ${code});\n\n`;
- }
- else if (name === 'escaped' || name === 'missingComponent' || name === 'invalidAttributeNameCharacter') {
- // vars are an awkward special case... would be nice to avoid this
- const alias = this.alias(name);
- inlineHelpers += `\n\nconst ${alias} = ${code};`;
- }
- else {
- const alias = this.alias(expression.id.name);
- if (alias !== expression.id.name) {
- code.overwrite(expression.id.start, expression.id.end, alias);
- }
- inlineHelpers += `\n\n${code}`;
- }
- });
- result += inlineHelpers;
- }
- const sharedPath = options.shared === true
- ? 'svelte/shared.js'
- : options.shared || '';
- const module = wrapModule(result, format, name, options, banner, sharedPath, importedHelpers, this.imports, this.shorthandImports, this.source);
- const parts = module.split('✂]');
- const finalChunk = parts.pop();
- const compiled = new Bundle({ separator: '' });
- function addString(str) {
- compiled.addSource({
- content: new MagicString(str),
- });
- }
- const { filename } = options;
- // special case — the source file doesn't actually get used anywhere. we need
- // to add an empty file to populate map.sources and map.sourcesContent
- if (!parts.length) {
- compiled.addSource({
- filename,
- content: new MagicString(this.source).remove(0, this.source.length),
- });
- }
- parts.forEach((str) => {
- const chunk = str.replace(pattern, '');
- if (chunk)
- addString(chunk);
- const match = pattern.exec(str);
- const snippet = this.code.snip(+match[1], +match[2]);
- compiled.addSource({
- filename,
- content: snippet,
- });
- });
- addString(finalChunk);
- const css = this.customElement ?
- { code: null, map: null } :
- this.stylesheet.render(options.cssOutputFilename, true);
- const js = {
- code: compiled.toString(),
- map: compiled.generateMap({
- includeContent: true,
- file: options.outputFilename,
- })
- };
- return {
- ast: this.ast,
- js,
- css,
- stats: this.stats.render(this)
- };
- }
- getUniqueName(name) {
- if (test)
- name = `${name}$`;
- let alias = name;
- for (let i = 1; reservedNames.has(alias) ||
- this.userVars.has(alias) ||
- this.usedNames.has(alias); alias = `${name}_${i++}`)
- ;
- this.usedNames.add(alias);
- return alias;
- }
- getUniqueNameMaker() {
- const localUsedNames = new Set();
- function add(name) {
- localUsedNames.add(name);
- }
- reservedNames.forEach(add);
- this.userVars.forEach(add);
- return (name) => {
- if (test)
- name = `${name}$`;
- let alias = name;
- for (let i = 1; this.usedNames.has(alias) ||
- localUsedNames.has(alias); alias = `${name}_${i++}`)
- ;
- localUsedNames.add(alias);
- return alias;
- };
- }
- error(pos, e) {
- error$1(e.message, {
- name: 'ValidationError',
- code: e.code,
- source: this.source,
- start: pos.start,
- end: pos.end,
- filename: this.options.filename
- });
- }
- warn(pos, warning) {
- if (!this.locator) {
- this.locator = getLocator(this.source, { offsetLine: 1 });
- }
- const start = this.locator(pos.start);
- const end = this.locator(pos.end);
- const frame = getCodeFrame(this.source, start.line - 1, start.column);
- this.stats.warn({
- code: warning.code,
- message: warning.message,
- frame,
- start,
- end,
- pos: pos.start,
- filename: this.options.filename,
- toString: () => `${warning.message} (${start.line + 1}:${start.column})\n${frame}`,
- });
- }
- processDefaultExport(node, indentExclusionRanges) {
- const { templateProperties, source, code } = this;
- if (node.declaration.type !== 'ObjectExpression') {
- this.error(node.declaration, {
- code: `invalid-default-export`,
- message: `Default export must be an object literal`
- });
- }
- checkForComputedKeys(this, node.declaration.properties);
- checkForDupes(this, node.declaration.properties);
- const props = this.properties;
- node.declaration.properties.forEach((prop) => {
- props.set(getMethodName(prop.key), prop);
- });
- const validPropList = Object.keys(propValidators);
- // ensure all exported props are valid
- node.declaration.properties.forEach((prop) => {
- const name = getMethodName(prop.key);
- const propValidator = propValidators[name];
- if (propValidator) {
- propValidator(this, prop);
- }
- else {
- const match = fuzzymatch(name, validPropList);
- if (match) {
- this.error(prop, {
- code: `unexpected-property`,
- message: `Unexpected property '${name}' (did you mean '${match}'?)`
- });
- }
- else if (/FunctionExpression/.test(prop.value.type)) {
- this.error(prop, {
- code: `unexpected-property`,
- message: `Unexpected property '${name}' (did you mean to include it in 'methods'?)`
- });
- }
- else {
- this.error(prop, {
- code: `unexpected-property`,
- message: `Unexpected property '${name}'`
- });
- }
- }
- });
- if (props.has('namespace')) {
- const ns = nodeToString(props.get('namespace').value);
- this.namespace = namespaces[ns] || ns;
- }
- node.declaration.properties.forEach((prop) => {
- templateProperties[getMethodName(prop.key)] = prop;
- });
- ['helpers', 'events', 'components', 'transitions', 'actions', 'animations'].forEach(key => {
- if (templateProperties[key]) {
- templateProperties[key].value.properties.forEach((prop) => {
- this[key].add(getMethodName(prop.key));
- });
- }
- });
- const addArrowFunctionExpression = (type, name, node) => {
- const { body, params, async } = node;
- const fnKeyword = async ? 'async function' : 'function';
- const paramString = params.length ?
- `[✂${params[0].start}-${params[params.length - 1].end}✂]` :
- ``;
- const block = body.type === 'BlockStatement'
- ? deindent `
- ${fnKeyword} ${name}(${paramString}) [✂${body.start}-${body.end}✂]
- `
- : deindent `
- ${fnKeyword} ${name}(${paramString}) {
- return [✂${body.start}-${body.end}✂];
- }
- `;
- this.declarations.push({ type, name, block, node });
- };
- const addFunctionExpression = (type, name, node) => {
- const { async } = node;
- const fnKeyword = async ? 'async function' : 'function';
- let c = node.start;
- while (this.source[c] !== '(')
- c += 1;
- const block = deindent `
- ${fnKeyword} ${name}[✂${c}-${node.end}✂];
- `;
- this.declarations.push({ type, name, block, node });
- };
- const addValue = (type, name, node) => {
- const block = deindent `
- var ${name} = [✂${node.start}-${node.end}✂];
- `;
- this.declarations.push({ type, name, block, node });
- };
- const addDeclaration = (type, key, node, allowShorthandImport, disambiguator, conflicts) => {
- const qualified = disambiguator ? `${disambiguator}-${key}` : key;
- if (node.type === 'Identifier' && node.name === key) {
- this.templateVars.set(qualified, key);
- return;
- }
- let deconflicted = key;
- if (conflicts)
- while (deconflicted in conflicts)
- deconflicted += '_';
- let name = this.getUniqueName(deconflicted);
- this.templateVars.set(qualified, name);
- if (allowShorthandImport && node.type === 'Literal' && typeof node.value === 'string') {
- this.shorthandImports.push({ name, source: node.value });
- return;
- }
- // deindent
- const indentationLevel = getIndentationLevel(source, node.start);
- if (indentationLevel) {
- removeIndentation(code, node.start, node.end, indentationLevel, indentExclusionRanges);
- }
- if (node.type === 'ArrowFunctionExpression') {
- addArrowFunctionExpression(type, name, node);
- }
- else if (node.type === 'FunctionExpression') {
- addFunctionExpression(type, name, node);
- }
- else {
- addValue(type, name, node);
- }
- };
- if (templateProperties.components) {
- templateProperties.components.value.properties.forEach((property) => {
- addDeclaration('components', getMethodName(property.key), property.value, true, 'components');
- });
- }
- if (templateProperties.computed) {
- const dependencies = new Map();
- const fullStateComputations = [];
- templateProperties.computed.value.properties.forEach((prop) => {
- const key = getMethodName(prop.key);
- const value = prop.value;
- addDeclaration('computed', key, value, false, 'computed', {
- state: true,
- changed: true
- });
- const param = value.params[0];
- const hasRestParam = (param.properties &&
- param.properties.some(prop => prop.type === 'RestElement'));
- if (param.type !== 'ObjectPattern' || hasRestParam) {
- fullStateComputations.push({ key, deps: null, hasRestParam });
- }
- else {
- const deps = param.properties.map(prop => prop.key.name);
- deps.forEach(dep => {
- this.expectedProperties.add(dep);
- });
- dependencies.set(key, deps);
- }
- });
- const visited = new Set();
- const visit = (key) => {
- if (!dependencies.has(key))
- return; // not a computation
- if (visited.has(key))
- return;
- visited.add(key);
- const deps = dependencies.get(key);
- deps.forEach(visit);
- this.computations.push({ key, deps, hasRestParam: false });
- const prop = templateProperties.computed.value.properties.find((prop) => getMethodName(prop.key) === key);
- };
- templateProperties.computed.value.properties.forEach((prop) => visit(getMethodName(prop.key)));
- if (fullStateComputations.length > 0) {
- this.computations.push(...fullStateComputations);
- }
- }
- if (templateProperties.data) {
- addDeclaration('data', 'data', templateProperties.data.value);
- }
- if (templateProperties.events) {
- templateProperties.events.value.properties.forEach((property) => {
- addDeclaration('events', getMethodName(property.key), property.value, false, 'events');
- });
- }
- if (templateProperties.helpers) {
- templateProperties.helpers.value.properties.forEach((property) => {
- addDeclaration('helpers', getMethodName(property.key), property.value, false, 'helpers');
- });
- }
- if (templateProperties.methods) {
- addDeclaration('methods', 'methods', templateProperties.methods.value);
- templateProperties.methods.value.properties.forEach(property => {
- this.methods.add(getMethodName(property.key));
- });
- }
- if (templateProperties.namespace) {
- const ns = nodeToString(templateProperties.namespace.value);
- this.namespace = namespaces[ns] || ns;
- }
- if (templateProperties.oncreate) {
- addDeclaration('oncreate', 'oncreate', templateProperties.oncreate.value);
- }
- if (templateProperties.ondestroy) {
- addDeclaration('ondestroy', 'ondestroy', templateProperties.ondestroy.value);
- }
- if (templateProperties.onstate) {
- addDeclaration('onstate', 'onstate', templateProperties.onstate.value);
- }
- if (templateProperties.onupdate) {
- addDeclaration('onupdate', 'onupdate', templateProperties.onupdate.value);
- }
- if (templateProperties.preload) {
- addDeclaration('preload', 'preload', templateProperties.preload.value);
- }
- if (templateProperties.props) {
- this.props = templateProperties.props.value.elements.map((element) => nodeToString(element));
- }
- if (templateProperties.setup) {
- addDeclaration('setup', 'setup', templateProperties.setup.value);
- }
- if (templateProperties.store) {
- addDeclaration('store', 'store', templateProperties.store.value);
- }
- if (templateProperties.tag) {
- this.tag = nodeToString(templateProperties.tag.value);
- }
- if (templateProperties.transitions) {
- templateProperties.transitions.value.properties.forEach((property) => {
- addDeclaration('transitions', getMethodName(property.key), property.value, false, 'transitions');
- });
- }
- if (templateProperties.animations) {
- templateProperties.animations.value.properties.forEach((property) => {
- addDeclaration('animations', getMethodName(property.key), property.value, false, 'animations');
- });
- }
- if (templateProperties.actions) {
- templateProperties.actions.value.properties.forEach((property) => {
- addDeclaration('actions', getMethodName(property.key), property.value, false, 'actions');
- });
- }
- this.defaultExport = node;
- }
- walkJs() {
- const { js } = this.ast;
- if (!js)
- return;
- this.addSourcemapLocations(js.content);
- const { code, source, imports } = this;
- const indentationLevel = getIndentationLevel(source, js.content.body[0].start);
- const indentExclusionRanges = getIndentExclusionRanges(js.content);
- const { scope, globals } = annotateWithScopes(js.content);
- scope.declarations.forEach(name => {
- this.userVars.add(name);
- });
- globals.forEach(name => {
- this.userVars.add(name);
- });
- const body = js.content.body.slice(); // slice, because we're going to be mutating the original
- body.forEach(node => {
- // check there are no named exports
- if (node.type === 'ExportNamedDeclaration') {
- this.error(node, {
- code: `named-export`,
- message: `A component can only have a default export`
- });
- }
- if (node.type === 'ExportDefaultDeclaration') {
- this.processDefaultExport(node, indentExclusionRanges);
- }
- // imports need to be hoisted out of the IIFE
- else if (node.type === 'ImportDeclaration') {
- removeNode(code, js.content, node);
- imports.push(node);
- node.specifiers.forEach((specifier) => {
- this.userVars.add(specifier.local.name);
- });
- }
- });
- if (indentationLevel) {
- if (this.defaultExport) {
- removeIndentation(code, js.content.start, this.defaultExport.start, indentationLevel, indentExclusionRanges);
- removeIndentation(code, this.defaultExport.end, js.content.end, indentationLevel, indentExclusionRanges);
- }
- else {
- removeIndentation(code, js.content.start, js.content.end, indentationLevel, indentExclusionRanges);
- }
- }
- let a = js.content.start;
- while (/\s/.test(source[a]))
- a += 1;
- let b = js.content.end;
- while (/\s/.test(source[b - 1]))
- b -= 1;
- this.javascript = this.defaultExport
- ? [
- a !== this.defaultExport.start ? `[✂${a}-${this.defaultExport.start}✂]` : '',
- b !== this.defaultExport.end ? `[✂${this.defaultExport.end}-${b}✂]` : ''
- ]
- : [
- a !== b ? `[✂${a}-${b}✂]` : '',
- ''
- ];
- }
- }
- const seen = new Set();
- function deprecate(message, code = message) {
- if (seen.has(code))
- return;
- seen.add(code);
- console.warn(`[svelte] DEPRECATION: ${message}`);
- }
- function normalize_options(options) {
- let normalized = assign({ generate: 'dom', dev: false }, options);
- const { onwarn } = normalized;
- normalized.onwarn = onwarn
- ? (warning) => onwarn(warning, default_onwarn)
- : default_onwarn;
- return normalized;
- }
- function default_onwarn({ start, message }) {
- if (start) {
- console.warn(`(${start.line}:${start.column}) – ${message}`);
- }
- else {
- console.warn(message);
- }
- }
- function validate_options(options, stats) {
- const { name, filename } = options;
- if (name && !/^[a-zA-Z_$][a-zA-Z_$0-9]*$/.test(name)) {
- const error = new Error(`options.name must be a valid identifier (got '${name}')`);
- throw error;
- }
- if (name && /^[a-z]/.test(name)) {
- const message = `options.name should be capitalised`;
- stats.warn({
- code: `options-lowercase-name`,
- message,
- filename,
- toString: () => message,
- });
- }
- }
- function compile(source, options = {}) {
- const onerror = options.onerror || (err => {
- throw err;
- });
- if (options.onerror) {
- // TODO remove in v3
- deprecate(`Instead of using options.onerror, wrap svelte.compile in a try-catch block`);
- delete options.onerror;
- }
- options = normalize_options(options);
- const stats = new Stats({
- onwarn: options.onwarn
- });
- let ast;
- try {
- validate_options(options, stats);
- stats.start('parse');
- ast = parse$1(source, options);
- stats.stop('parse');
- stats.start('create component');
- const component = new Component(ast, source, options.name || 'SvelteComponent', options, stats);
- stats.stop('create component');
- if (options.generate === false) {
- return { ast, stats: stats.render(component), js: null, css: null };
- }
- if (options.generate === 'ssr') {
- return ssr(component, options);
- }
- return dom(component, options);
- }
- catch (err) {
- onerror(err);
- }
- }
- /*! *****************************************************************************
- Copyright (c) Microsoft Corporation. All rights reserved.
- Licensed under the Apache License, Version 2.0 (the "License"); you may not use
- this file except in compliance with the License. You may obtain a copy of the
- License at http://www.apache.org/licenses/LICENSE-2.0
- THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
- WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
- MERCHANTABLITY OR NON-INFRINGEMENT.
- See the Apache Version 2.0 License for specific language governing permissions
- and limitations under the License.
- ***************************************************************************** */
- function __awaiter$1(thisArg, _arguments, P, generator) {
- return new (P || (P = Promise))(function (resolve, reject) {
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
- function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
- step((generator = generator.apply(thisArg, _arguments || [])).next());
- });
- }
- function parseAttributeValue(value) {
- return /^['"]/.test(value) ?
- value.slice(1, -1) :
- value;
- }
- function parseAttributes(str) {
- const attrs = {};
- str.split(/\s+/).filter(Boolean).forEach(attr => {
- const [name, value] = attr.split('=');
- attrs[name] = value ? parseAttributeValue(value) : true;
- });
- return attrs;
- }
- function replaceTagContents(source, type, preprocessor, options) {
- return __awaiter$1(this, void 0, void 0, function* () {
- const exp = new RegExp(`<${type}([\\S\\s]*?)>([\\S\\s]*?)<\\/${type}>`, 'ig');
- const match = exp.exec(source);
- if (match) {
- const attributes = parseAttributes(match[1]);
- const content = match[2];
- const processed = yield preprocessor({
- content,
- attributes,
- filename: options.filename
- });
- if (processed && processed.code) {
- return (source.slice(0, match.index) +
- `<${type}>${processed.code}</${type}>` +
- source.slice(match.index + match[0].length));
- }
- }
- return source;
- });
- }
- function preprocess(source, options) {
- return __awaiter$1(this, void 0, void 0, function* () {
- const { markup, style, script } = options;
- if (!!markup) {
- const processed = yield markup({
- content: source,
- filename: options.filename
- });
- source = processed.code;
- }
- if (!!style) {
- source = yield replaceTagContents(source, 'style', style, options);
- }
- if (!!script) {
- source = yield replaceTagContents(source, 'script', script, options);
- }
- return {
- // TODO return separated output, in future version where svelte.compile supports it:
- // style: { code: styleCode, map: styleMap },
- // script { code: scriptCode, map: scriptMap },
- // markup { code: markupCode, map: markupMap },
- toString() {
- return source;
- }
- };
- });
- }
- function create$1(source, options = {}) {
- const onerror = options.onerror || (err => {
- throw err;
- });
- if (options.onerror) {
- // TODO remove in v3
- deprecate(`Instead of using options.onerror, wrap svelte.create in a try-catch block`);
- delete options.onerror;
- }
- options.format = 'eval';
- try {
- const compiled = compile(source, options);
- if (!compiled || !compiled.js.code) {
- return;
- }
- return (new Function(`return ${compiled.js.code}`))();
- }
- catch (err) {
- onerror(err);
- }
- }
- const VERSION = '2.15.3';
- exports.create = create$1;
- exports.VERSION = VERSION;
- exports.compile = compile;
- exports.parse = parse$1;
- exports.preprocess = preprocess;
- Object.defineProperty(exports, '__esModule', { value: true });
- })));
- //# sourceMappingURL=svelte.js.map
|