1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276427742784279428042814282428342844285428642874288428942904291429242934294429542964297429842994300430143024303430443054306430743084309431043114312431343144315431643174318431943204321432243234324432543264327432843294330433143324333433443354336433743384339434043414342434343444345434643474348434943504351435243534354435543564357435843594360436143624363436443654366436743684369437043714372437343744375437643774378437943804381438243834384438543864387438843894390439143924393439443954396439743984399440044014402440344044405440644074408440944104411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480448144824483448444854486448744884489449044914492449344944495449644974498449945004501450245034504450545064507450845094510451145124513451445154516451745184519452045214522452345244525452645274528452945304531453245334534453545364537453845394540454145424543454445454546454745484549455045514552455345544555455645574558455945604561456245634564456545664567456845694570457145724573457445754576457745784579458045814582458345844585458645874588458945904591459245934594459545964597459845994600460146024603460446054606460746084609461046114612461346144615461646174618461946204621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690469146924693469446954696469746984699470047014702470347044705470647074708470947104711471247134714471547164717471847194720472147224723472447254726472747284729473047314732473347344735473647374738473947404741474247434744474547464747474847494750475147524753475447554756475747584759476047614762476347644765476647674768476947704771477247734774477547764777477847794780478147824783478447854786478747884789479047914792479347944795479647974798479948004801480248034804480548064807480848094810481148124813481448154816481748184819482048214822482348244825482648274828482948304831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900490149024903490449054906490749084909491049114912491349144915491649174918491949204921492249234924492549264927492849294930493149324933493449354936493749384939494049414942494349444945494649474948494949504951495249534954495549564957495849594960496149624963496449654966496749684969497049714972497349744975497649774978497949804981498249834984498549864987498849894990499149924993499449954996499749984999500050015002500350045005500650075008500950105011501250135014501550165017501850195020502150225023502450255026502750285029503050315032503350345035503650375038503950405041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110511151125113511451155116511751185119512051215122512351245125512651275128512951305131513251335134513551365137513851395140514151425143514451455146514751485149515051515152515351545155515651575158515951605161516251635164516551665167516851695170517151725173517451755176517751785179518051815182518351845185518651875188518951905191519251935194519551965197519851995200520152025203520452055206520752085209521052115212521352145215521652175218521952205221522252235224522552265227522852295230523152325233523452355236523752385239524052415242524352445245524652475248524952505251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320532153225323532453255326532753285329533053315332533353345335533653375338533953405341534253435344534553465347534853495350535153525353535453555356535753585359536053615362536353645365536653675368536953705371537253735374537553765377537853795380538153825383538453855386538753885389539053915392539353945395539653975398539954005401540254035404540554065407540854095410541154125413541454155416541754185419542054215422542354245425542654275428542954305431543254335434543554365437543854395440544154425443544454455446544754485449545054515452545354545455545654575458545954605461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530553155325533553455355536553755385539554055415542554355445545554655475548554955505551555255535554555555565557555855595560556155625563556455655566556755685569557055715572557355745575557655775578557955805581558255835584558555865587558855895590559155925593559455955596559755985599560056015602560356045605560656075608560956105611561256135614561556165617561856195620562156225623562456255626562756285629563056315632563356345635563656375638563956405641564256435644564556465647564856495650565156525653565456555656565756585659566056615662566356645665566656675668566956705671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740574157425743574457455746574757485749575057515752575357545755575657575758575957605761576257635764576557665767576857695770577157725773577457755776577757785779578057815782578357845785578657875788578957905791579257935794579557965797579857995800580158025803580458055806580758085809581058115812581358145815581658175818581958205821582258235824582558265827582858295830583158325833583458355836583758385839584058415842584358445845584658475848584958505851585258535854585558565857585858595860586158625863586458655866586758685869587058715872587358745875587658775878587958805881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950595159525953595459555956595759585959596059615962596359645965596659675968596959705971597259735974597559765977597859795980598159825983598459855986598759885989599059915992599359945995599659975998599960006001600260036004600560066007600860096010601160126013601460156016601760186019602060216022602360246025602660276028602960306031603260336034603560366037603860396040604160426043604460456046604760486049605060516052605360546055605660576058605960606061606260636064606560666067606860696070607160726073607460756076607760786079608060816082608360846085608660876088608960906091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160616161626163616461656166616761686169617061716172617361746175617661776178617961806181618261836184618561866187618861896190619161926193619461956196619761986199620062016202620362046205620662076208620962106211621262136214621562166217621862196220622162226223622462256226622762286229623062316232623362346235623662376238623962406241624262436244624562466247624862496250625162526253625462556256625762586259626062616262626362646265626662676268626962706271627262736274627562766277627862796280628162826283628462856286628762886289629062916292629362946295629662976298629963006301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370637163726373637463756376637763786379638063816382638363846385638663876388638963906391639263936394639563966397639863996400640164026403640464056406640764086409641064116412641364146415641664176418641964206421642264236424642564266427642864296430643164326433643464356436643764386439644064416442644364446445644664476448644964506451645264536454645564566457645864596460646164626463646464656466646764686469647064716472647364746475647664776478647964806481648264836484648564866487648864896490649164926493649464956496649764986499650065016502650365046505650665076508650965106511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580658165826583658465856586658765886589659065916592659365946595659665976598659966006601660266036604660566066607660866096610661166126613661466156616661766186619662066216622662366246625662666276628662966306631663266336634663566366637663866396640664166426643664466456646664766486649665066516652665366546655665666576658665966606661666266636664666566666667666866696670667166726673667466756676667766786679668066816682668366846685668666876688668966906691669266936694669566966697669866996700670167026703670467056706670767086709671067116712671367146715671667176718671967206721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790679167926793679467956796679767986799680068016802680368046805680668076808680968106811681268136814681568166817681868196820682168226823682468256826682768286829683068316832683368346835683668376838683968406841684268436844684568466847684868496850685168526853685468556856685768586859686068616862686368646865686668676868686968706871687268736874687568766877687868796880688168826883688468856886688768886889689068916892689368946895689668976898689969006901690269036904690569066907690869096910691169126913691469156916691769186919692069216922692369246925692669276928692969306931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000700170027003700470057006700770087009701070117012701370147015701670177018701970207021702270237024702570267027702870297030703170327033703470357036703770387039704070417042704370447045704670477048704970507051705270537054705570567057705870597060706170627063706470657066706770687069707070717072707370747075707670777078707970807081708270837084708570867087708870897090709170927093709470957096709770987099710071017102710371047105710671077108710971107111711271137114711571167117711871197120712171227123712471257126712771287129713071317132713371347135713671377138713971407141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210721172127213721472157216721772187219722072217222722372247225722672277228722972307231723272337234723572367237723872397240724172427243724472457246724772487249725072517252725372547255725672577258725972607261726272637264726572667267726872697270727172727273727472757276727772787279728072817282728372847285728672877288728972907291729272937294729572967297729872997300730173027303730473057306730773087309731073117312731373147315731673177318731973207321732273237324732573267327732873297330733173327333733473357336733773387339734073417342734373447345734673477348734973507351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420742174227423742474257426742774287429743074317432743374347435743674377438743974407441744274437444744574467447744874497450745174527453745474557456745774587459746074617462746374647465746674677468746974707471747274737474747574767477747874797480748174827483748474857486748774887489749074917492749374947495749674977498749975007501750275037504750575067507750875097510751175127513751475157516751775187519752075217522752375247525752675277528752975307531753275337534753575367537753875397540754175427543754475457546754775487549755075517552755375547555755675577558755975607561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621762276237624762576267627762876297630763176327633763476357636763776387639764076417642764376447645764676477648764976507651765276537654765576567657765876597660766176627663766476657666766776687669767076717672767376747675767676777678767976807681768276837684768576867687768876897690769176927693769476957696769776987699770077017702770377047705770677077708770977107711771277137714771577167717771877197720772177227723772477257726772777287729773077317732773377347735773677377738773977407741774277437744774577467747774877497750775177527753775477557756775777587759776077617762776377647765776677677768776977707771777277737774777577767777777877797780778177827783778477857786778777887789779077917792779377947795779677977798779978007801780278037804780578067807780878097810781178127813781478157816781778187819782078217822782378247825782678277828782978307831783278337834783578367837783878397840784178427843784478457846784778487849785078517852785378547855785678577858785978607861786278637864786578667867786878697870787178727873787478757876787778787879788078817882788378847885788678877888788978907891789278937894789578967897789878997900790179027903790479057906790779087909791079117912791379147915791679177918791979207921792279237924792579267927792879297930793179327933793479357936793779387939794079417942794379447945794679477948794979507951795279537954795579567957795879597960796179627963796479657966796779687969797079717972797379747975797679777978797979807981798279837984798579867987798879897990799179927993799479957996799779987999800080018002800380048005800680078008800980108011801280138014801580168017801880198020802180228023802480258026802780288029803080318032803380348035803680378038803980408041804280438044804580468047804880498050805180528053805480558056805780588059806080618062806380648065806680678068806980708071807280738074807580768077807880798080808180828083808480858086808780888089809080918092809380948095809680978098809981008101810281038104810581068107810881098110811181128113811481158116811781188119812081218122812381248125812681278128812981308131813281338134813581368137813881398140814181428143814481458146814781488149815081518152815381548155815681578158815981608161816281638164816581668167816881698170817181728173817481758176817781788179818081818182818381848185818681878188818981908191819281938194819581968197819881998200820182028203820482058206820782088209821082118212821382148215821682178218821982208221822282238224822582268227822882298230823182328233823482358236823782388239824082418242824382448245824682478248824982508251825282538254825582568257825882598260826182628263826482658266826782688269827082718272827382748275827682778278827982808281828282838284828582868287828882898290829182928293829482958296829782988299830083018302830383048305830683078308830983108311831283138314831583168317831883198320832183228323832483258326832783288329833083318332833383348335833683378338833983408341834283438344834583468347834883498350835183528353835483558356835783588359836083618362836383648365836683678368836983708371837283738374837583768377837883798380838183828383838483858386838783888389839083918392839383948395839683978398839984008401840284038404840584068407840884098410841184128413841484158416841784188419842084218422842384248425842684278428842984308431843284338434843584368437843884398440844184428443844484458446844784488449845084518452845384548455845684578458845984608461846284638464846584668467846884698470847184728473847484758476847784788479848084818482848384848485848684878488848984908491849284938494849584968497849884998500850185028503850485058506850785088509851085118512851385148515851685178518851985208521852285238524852585268527852885298530853185328533853485358536853785388539854085418542854385448545854685478548854985508551855285538554855585568557855885598560856185628563856485658566856785688569857085718572857385748575857685778578857985808581858285838584858585868587858885898590859185928593859485958596859785988599860086018602860386048605860686078608860986108611861286138614861586168617861886198620862186228623862486258626862786288629863086318632863386348635863686378638863986408641864286438644864586468647864886498650865186528653865486558656865786588659866086618662866386648665866686678668866986708671867286738674867586768677867886798680868186828683868486858686868786888689869086918692869386948695869686978698869987008701870287038704870587068707870887098710871187128713871487158716871787188719872087218722872387248725872687278728872987308731873287338734873587368737873887398740874187428743874487458746874787488749875087518752875387548755875687578758875987608761876287638764876587668767876887698770877187728773877487758776877787788779878087818782878387848785878687878788878987908791879287938794879587968797879887998800880188028803880488058806880788088809881088118812881388148815881688178818881988208821882288238824882588268827882888298830883188328833883488358836883788388839884088418842884388448845884688478848884988508851885288538854885588568857885888598860886188628863886488658866886788688869887088718872887388748875887688778878887988808881888288838884888588868887888888898890889188928893889488958896889788988899890089018902890389048905890689078908890989108911891289138914891589168917891889198920892189228923892489258926892789288929893089318932893389348935893689378938893989408941894289438944894589468947894889498950895189528953895489558956895789588959896089618962896389648965896689678968896989708971897289738974897589768977897889798980898189828983898489858986898789888989899089918992899389948995899689978998899990009001900290039004900590069007900890099010901190129013901490159016901790189019902090219022902390249025902690279028902990309031903290339034903590369037903890399040904190429043904490459046904790489049905090519052905390549055905690579058905990609061906290639064906590669067906890699070907190729073907490759076907790789079908090819082908390849085908690879088908990909091909290939094909590969097909890999100910191029103910491059106910791089109911091119112911391149115911691179118911991209121912291239124912591269127912891299130913191329133913491359136913791389139914091419142914391449145914691479148914991509151915291539154915591569157915891599160916191629163916491659166916791689169917091719172917391749175917691779178917991809181918291839184918591869187918891899190919191929193919491959196 |
- (function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.jade = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
- (function (process){
- 'use strict';
- /*!
- * Jade
- * Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>
- * MIT Licensed
- */
- /**
- * Module dependencies.
- */
- var Parser = require('./parser')
- , Lexer = require('./lexer')
- , Compiler = require('./compiler')
- , runtime = require('./runtime')
- , addWith = require('with')
- , fs = require('fs')
- , utils = require('./utils');
- /**
- * Expose self closing tags.
- */
- // FIXME: either stop exporting selfClosing in v2 or export the new object
- // form
- exports.selfClosing = Object.keys(require('void-elements'));
- /**
- * Default supported doctypes.
- */
- exports.doctypes = require('./doctypes');
- /**
- * Text filters.
- */
- exports.filters = require('./filters');
- /**
- * Utilities.
- */
- exports.utils = utils;
- /**
- * Expose `Compiler`.
- */
- exports.Compiler = Compiler;
- /**
- * Expose `Parser`.
- */
- exports.Parser = Parser;
- /**
- * Expose `Lexer`.
- */
- exports.Lexer = Lexer;
- /**
- * Nodes.
- */
- exports.nodes = require('./nodes');
- /**
- * Jade runtime helpers.
- */
- exports.runtime = runtime;
- /**
- * Template function cache.
- */
- exports.cache = {};
- /**
- * Parse the given `str` of jade and return a function body.
- *
- * @param {String} str
- * @param {Object} options
- * @return {Object}
- * @api private
- */
- function parse(str, options){
- if (options.lexer) {
- console.warn('Using `lexer` as a local in render() is deprecated and '
- + 'will be interpreted as an option in Jade 2.0.0');
- }
- // Parse
- var parser = new (options.parser || Parser)(str, options.filename, options);
- var tokens;
- try {
- // Parse
- tokens = parser.parse();
- } catch (err) {
- parser = parser.context();
- runtime.rethrow(err, parser.filename, parser.lexer.lineno, parser.input);
- }
- // Compile
- var compiler = new (options.compiler || Compiler)(tokens, options);
- var js;
- try {
- js = compiler.compile();
- } catch (err) {
- if (err.line && (err.filename || !options.filename)) {
- runtime.rethrow(err, err.filename, err.line, parser.input);
- } else {
- if (err instanceof Error) {
- err.message += '\n\nPlease report this entire error and stack trace to https://github.com/jadejs/jade/issues';
- }
- throw err;
- }
- }
- // Debug compiler
- if (options.debug) {
- console.error('\nCompiled Function:\n\n\u001b[90m%s\u001b[0m', js.replace(/^/gm, ' '));
- }
- var globals = [];
- if (options.globals) {
- globals = options.globals.slice();
- }
- globals.push('jade');
- globals.push('jade_mixins');
- globals.push('jade_interp');
- globals.push('jade_debug');
- globals.push('buf');
- var body = ''
- + 'var buf = [];\n'
- + 'var jade_mixins = {};\n'
- + 'var jade_interp;\n'
- + (options.self
- ? 'var self = locals || {};\n' + js
- : addWith('locals || {}', '\n' + js, globals)) + ';'
- + 'return buf.join("");';
- return {body: body, dependencies: parser.dependencies};
- }
- /**
- * Get the template from a string or a file, either compiled on-the-fly or
- * read from cache (if enabled), and cache the template if needed.
- *
- * If `str` is not set, the file specified in `options.filename` will be read.
- *
- * If `options.cache` is true, this function reads the file from
- * `options.filename` so it must be set prior to calling this function.
- *
- * @param {Object} options
- * @param {String=} str
- * @return {Function}
- * @api private
- */
- function handleTemplateCache (options, str) {
- var key = options.filename;
- if (options.cache && exports.cache[key]) {
- return exports.cache[key];
- } else {
- if (str === undefined) str = fs.readFileSync(options.filename, 'utf8');
- var templ = exports.compile(str, options);
- if (options.cache) exports.cache[key] = templ;
- return templ;
- }
- }
- /**
- * Compile a `Function` representation of the given jade `str`.
- *
- * Options:
- *
- * - `compileDebug` when `false` debugging code is stripped from the compiled
- template, when it is explicitly `true`, the source code is included in
- the compiled template for better accuracy.
- * - `filename` used to improve errors when `compileDebug` is not `false` and to resolve imports/extends
- *
- * @param {String} str
- * @param {Options} options
- * @return {Function}
- * @api public
- */
- exports.compile = function(str, options){
- var options = options || {}
- , filename = options.filename
- ? utils.stringify(options.filename)
- : 'undefined'
- , fn;
- str = String(str);
- var parsed = parse(str, options);
- if (options.compileDebug !== false) {
- fn = [
- 'var jade_debug = [ new jade.DebugItem( 1, ' + filename + ' ) ];'
- , 'try {'
- , parsed.body
- , '} catch (err) {'
- , ' jade.rethrow(err, jade_debug[0].filename, jade_debug[0].lineno' + (options.compileDebug === true ? ',' + utils.stringify(str) : '') + ');'
- , '}'
- ].join('\n');
- } else {
- fn = parsed.body;
- }
- fn = new Function('locals, jade', fn)
- var res = function(locals){ return fn(locals, Object.create(runtime)) };
- if (options.client) {
- res.toString = function () {
- var err = new Error('The `client` option is deprecated, use the `jade.compileClient` method instead');
- err.name = 'Warning';
- console.error(err.stack || /* istanbul ignore next */ err.message);
- return exports.compileClient(str, options);
- };
- }
- res.dependencies = parsed.dependencies;
- return res;
- };
- /**
- * Compile a JavaScript source representation of the given jade `str`.
- *
- * Options:
- *
- * - `compileDebug` When it is `true`, the source code is included in
- * the compiled template for better error messages.
- * - `filename` used to improve errors when `compileDebug` is not `true` and to resolve imports/extends
- * - `name` the name of the resulting function (defaults to "template")
- *
- * @param {String} str
- * @param {Options} options
- * @return {Object}
- * @api public
- */
- exports.compileClientWithDependenciesTracked = function(str, options){
- var options = options || {};
- var name = options.name || 'template';
- var filename = options.filename ? utils.stringify(options.filename) : 'undefined';
- var fn;
- str = String(str);
- options.compileDebug = options.compileDebug ? true : false;
- var parsed = parse(str, options);
- if (options.compileDebug) {
- fn = [
- 'var jade_debug = [ new jade.DebugItem( 1, ' + filename + ' ) ];'
- , 'try {'
- , parsed.body
- , '} catch (err) {'
- , ' jade.rethrow(err, jade_debug[0].filename, jade_debug[0].lineno, ' + utils.stringify(str) + ');'
- , '}'
- ].join('\n');
- } else {
- fn = parsed.body;
- }
- return {body: 'function ' + name + '(locals) {\n' + fn + '\n}', dependencies: parsed.dependencies};
- };
- /**
- * Compile a JavaScript source representation of the given jade `str`.
- *
- * Options:
- *
- * - `compileDebug` When it is `true`, the source code is included in
- * the compiled template for better error messages.
- * - `filename` used to improve errors when `compileDebug` is not `true` and to resolve imports/extends
- * - `name` the name of the resulting function (defaults to "template")
- *
- * @param {String} str
- * @param {Options} options
- * @return {String}
- * @api public
- */
- exports.compileClient = function (str, options) {
- return exports.compileClientWithDependenciesTracked(str, options).body;
- };
- /**
- * Compile a `Function` representation of the given jade file.
- *
- * Options:
- *
- * - `compileDebug` when `false` debugging code is stripped from the compiled
- template, when it is explicitly `true`, the source code is included in
- the compiled template for better accuracy.
- *
- * @param {String} path
- * @param {Options} options
- * @return {Function}
- * @api public
- */
- exports.compileFile = function (path, options) {
- options = options || {};
- options.filename = path;
- return handleTemplateCache(options);
- };
- /**
- * Render the given `str` of jade.
- *
- * Options:
- *
- * - `cache` enable template caching
- * - `filename` filename required for `include` / `extends` and caching
- *
- * @param {String} str
- * @param {Object|Function} options or fn
- * @param {Function|undefined} fn
- * @returns {String}
- * @api public
- */
- exports.render = function(str, options, fn){
- // support callback API
- if ('function' == typeof options) {
- fn = options, options = undefined;
- }
- if (typeof fn === 'function') {
- var res
- try {
- res = exports.render(str, options);
- } catch (ex) {
- return fn(ex);
- }
- return fn(null, res);
- }
- options = options || {};
- // cache requires .filename
- if (options.cache && !options.filename) {
- throw new Error('the "filename" option is required for caching');
- }
- return handleTemplateCache(options, str)(options);
- };
- /**
- * Render a Jade file at the given `path`.
- *
- * @param {String} path
- * @param {Object|Function} options or callback
- * @param {Function|undefined} fn
- * @returns {String}
- * @api public
- */
- exports.renderFile = function(path, options, fn){
- // support callback API
- if ('function' == typeof options) {
- fn = options, options = undefined;
- }
- if (typeof fn === 'function') {
- var res
- try {
- res = exports.renderFile(path, options);
- } catch (ex) {
- return fn(ex);
- }
- return fn(null, res);
- }
- options = options || {};
- options.filename = path;
- return handleTemplateCache(options)(options);
- };
- /**
- * Compile a Jade file at the given `path` for use on the client.
- *
- * @param {String} path
- * @param {Object} options
- * @returns {String}
- * @api public
- */
- exports.compileFileClient = function(path, options){
- var key = path + ':client';
- options = options || {};
- options.filename = path;
- if (options.cache && exports.cache[key]) {
- return exports.cache[key];
- }
- var str = fs.readFileSync(options.filename, 'utf8');
- var out = exports.compileClient(str, options);
- if (options.cache) exports.cache[key] = out;
- return out;
- };
- /**
- * Express support.
- */
- exports.__express = function(path, options, fn) {
- if(options.compileDebug == undefined && process.env.NODE_ENV === 'production') {
- options.compileDebug = false;
- }
- exports.renderFile(path, options, fn);
- }
- }).call(this,require('_process'))
- },{"./compiler":2,"./doctypes":3,"./filters":4,"./lexer":6,"./nodes":16,"./parser":23,"./runtime":24,"./utils":25,"_process":28,"fs":26,"void-elements":34,"with":35}],2:[function(require,module,exports){
- 'use strict';
- var nodes = require('./nodes');
- var filters = require('./filters');
- var doctypes = require('./doctypes');
- var runtime = require('./runtime');
- var utils = require('./utils');
- var selfClosing = require('void-elements');
- var parseJSExpression = require('character-parser').parseMax;
- var constantinople = require('constantinople');
- function isConstant(src) {
- return constantinople(src, {jade: runtime, 'jade_interp': undefined});
- }
- function toConstant(src) {
- return constantinople.toConstant(src, {jade: runtime, 'jade_interp': undefined});
- }
- function errorAtNode(node, error) {
- error.line = node.line;
- error.filename = node.filename;
- return error;
- }
- /**
- * Initialize `Compiler` with the given `node`.
- *
- * @param {Node} node
- * @param {Object} options
- * @api public
- */
- var Compiler = module.exports = function Compiler(node, options) {
- this.options = options = options || {};
- this.node = node;
- this.hasCompiledDoctype = false;
- this.hasCompiledTag = false;
- this.pp = options.pretty || false;
- if (this.pp && typeof this.pp !== 'string') {
- this.pp = ' ';
- }
- this.debug = false !== options.compileDebug;
- this.indents = 0;
- this.parentIndents = 0;
- this.terse = false;
- this.mixins = {};
- this.dynamicMixins = false;
- if (options.doctype) this.setDoctype(options.doctype);
- };
- /**
- * Compiler prototype.
- */
- Compiler.prototype = {
- /**
- * Compile parse tree to JavaScript.
- *
- * @api public
- */
- compile: function(){
- this.buf = [];
- if (this.pp) this.buf.push("var jade_indent = [];");
- this.lastBufferedIdx = -1;
- this.visit(this.node);
- if (!this.dynamicMixins) {
- // if there are no dynamic mixins we can remove any un-used mixins
- var mixinNames = Object.keys(this.mixins);
- for (var i = 0; i < mixinNames.length; i++) {
- var mixin = this.mixins[mixinNames[i]];
- if (!mixin.used) {
- for (var x = 0; x < mixin.instances.length; x++) {
- for (var y = mixin.instances[x].start; y < mixin.instances[x].end; y++) {
- this.buf[y] = '';
- }
- }
- }
- }
- }
- return this.buf.join('\n');
- },
- /**
- * Sets the default doctype `name`. Sets terse mode to `true` when
- * html 5 is used, causing self-closing tags to end with ">" vs "/>",
- * and boolean attributes are not mirrored.
- *
- * @param {string} name
- * @api public
- */
- setDoctype: function(name){
- this.doctype = doctypes[name.toLowerCase()] || '<!DOCTYPE ' + name + '>';
- this.terse = this.doctype.toLowerCase() == '<!doctype html>';
- this.xml = 0 == this.doctype.indexOf('<?xml');
- },
- /**
- * Buffer the given `str` exactly as is or with interpolation
- *
- * @param {String} str
- * @param {Boolean} interpolate
- * @api public
- */
- buffer: function (str, interpolate) {
- var self = this;
- if (interpolate) {
- var match = /(\\)?([#!]){((?:.|\n)*)$/.exec(str);
- if (match) {
- this.buffer(str.substr(0, match.index), false);
- if (match[1]) { // escape
- this.buffer(match[2] + '{', false);
- this.buffer(match[3], true);
- return;
- } else {
- var rest = match[3];
- var range = parseJSExpression(rest);
- var code = ('!' == match[2] ? '' : 'jade.escape') + "((jade_interp = " + range.src + ") == null ? '' : jade_interp)";
- this.bufferExpression(code);
- this.buffer(rest.substr(range.end + 1), true);
- return;
- }
- }
- }
- str = utils.stringify(str);
- str = str.substr(1, str.length - 2);
- if (this.lastBufferedIdx == this.buf.length) {
- if (this.lastBufferedType === 'code') this.lastBuffered += ' + "';
- this.lastBufferedType = 'text';
- this.lastBuffered += str;
- this.buf[this.lastBufferedIdx - 1] = 'buf.push(' + this.bufferStartChar + this.lastBuffered + '");'
- } else {
- this.buf.push('buf.push("' + str + '");');
- this.lastBufferedType = 'text';
- this.bufferStartChar = '"';
- this.lastBuffered = str;
- this.lastBufferedIdx = this.buf.length;
- }
- },
- /**
- * Buffer the given `src` so it is evaluated at run time
- *
- * @param {String} src
- * @api public
- */
- bufferExpression: function (src) {
- if (isConstant(src)) {
- return this.buffer(toConstant(src) + '', false)
- }
- if (this.lastBufferedIdx == this.buf.length) {
- if (this.lastBufferedType === 'text') this.lastBuffered += '"';
- this.lastBufferedType = 'code';
- this.lastBuffered += ' + (' + src + ')';
- this.buf[this.lastBufferedIdx - 1] = 'buf.push(' + this.bufferStartChar + this.lastBuffered + ');'
- } else {
- this.buf.push('buf.push(' + src + ');');
- this.lastBufferedType = 'code';
- this.bufferStartChar = '';
- this.lastBuffered = '(' + src + ')';
- this.lastBufferedIdx = this.buf.length;
- }
- },
- /**
- * Buffer an indent based on the current `indent`
- * property and an additional `offset`.
- *
- * @param {Number} offset
- * @param {Boolean} newline
- * @api public
- */
- prettyIndent: function(offset, newline){
- offset = offset || 0;
- newline = newline ? '\n' : '';
- this.buffer(newline + Array(this.indents + offset).join(this.pp));
- if (this.parentIndents)
- this.buf.push("buf.push.apply(buf, jade_indent);");
- },
- /**
- * Visit `node`.
- *
- * @param {Node} node
- * @api public
- */
- visit: function(node){
- var debug = this.debug;
- if (debug) {
- this.buf.push('jade_debug.unshift(new jade.DebugItem( ' + node.line
- + ', ' + (node.filename
- ? utils.stringify(node.filename)
- : 'jade_debug[0].filename')
- + ' ));');
- }
- // Massive hack to fix our context
- // stack for - else[ if] etc
- if (false === node.debug && this.debug) {
- this.buf.pop();
- this.buf.pop();
- }
- this.visitNode(node);
- if (debug) this.buf.push('jade_debug.shift();');
- },
- /**
- * Visit `node`.
- *
- * @param {Node} node
- * @api public
- */
- visitNode: function(node){
- return this['visit' + node.type](node);
- },
- /**
- * Visit case `node`.
- *
- * @param {Literal} node
- * @api public
- */
- visitCase: function(node){
- var _ = this.withinCase;
- this.withinCase = true;
- this.buf.push('switch (' + node.expr + '){');
- this.visit(node.block);
- this.buf.push('}');
- this.withinCase = _;
- },
- /**
- * Visit when `node`.
- *
- * @param {Literal} node
- * @api public
- */
- visitWhen: function(node){
- if ('default' == node.expr) {
- this.buf.push('default:');
- } else {
- this.buf.push('case ' + node.expr + ':');
- }
- if (node.block) {
- this.visit(node.block);
- this.buf.push(' break;');
- }
- },
- /**
- * Visit literal `node`.
- *
- * @param {Literal} node
- * @api public
- */
- visitLiteral: function(node){
- this.buffer(node.str);
- },
- /**
- * Visit all nodes in `block`.
- *
- * @param {Block} block
- * @api public
- */
- visitBlock: function(block){
- var len = block.nodes.length
- , escape = this.escape
- , pp = this.pp
- // Pretty print multi-line text
- if (pp && len > 1 && !escape && block.nodes[0].isText && block.nodes[1].isText)
- this.prettyIndent(1, true);
- for (var i = 0; i < len; ++i) {
- // Pretty print text
- if (pp && i > 0 && !escape && block.nodes[i].isText && block.nodes[i-1].isText)
- this.prettyIndent(1, false);
- this.visit(block.nodes[i]);
- // Multiple text nodes are separated by newlines
- if (block.nodes[i+1] && block.nodes[i].isText && block.nodes[i+1].isText)
- this.buffer('\n');
- }
- },
- /**
- * Visit a mixin's `block` keyword.
- *
- * @param {MixinBlock} block
- * @api public
- */
- visitMixinBlock: function(block){
- if (this.pp) this.buf.push("jade_indent.push('" + Array(this.indents + 1).join(this.pp) + "');");
- this.buf.push('block && block();');
- if (this.pp) this.buf.push("jade_indent.pop();");
- },
- /**
- * Visit `doctype`. Sets terse mode to `true` when html 5
- * is used, causing self-closing tags to end with ">" vs "/>",
- * and boolean attributes are not mirrored.
- *
- * @param {Doctype} doctype
- * @api public
- */
- visitDoctype: function(doctype){
- if (doctype && (doctype.val || !this.doctype)) {
- this.setDoctype(doctype.val || 'default');
- }
- if (this.doctype) this.buffer(this.doctype);
- this.hasCompiledDoctype = true;
- },
- /**
- * Visit `mixin`, generating a function that
- * may be called within the template.
- *
- * @param {Mixin} mixin
- * @api public
- */
- visitMixin: function(mixin){
- var name = 'jade_mixins[';
- var args = mixin.args || '';
- var block = mixin.block;
- var attrs = mixin.attrs;
- var attrsBlocks = mixin.attributeBlocks.slice();
- var pp = this.pp;
- var dynamic = mixin.name[0]==='#';
- var key = mixin.name;
- if (dynamic) this.dynamicMixins = true;
- name += (dynamic ? mixin.name.substr(2,mixin.name.length-3):'"'+mixin.name+'"')+']';
- this.mixins[key] = this.mixins[key] || {used: false, instances: []};
- if (mixin.call) {
- this.mixins[key].used = true;
- if (pp) this.buf.push("jade_indent.push('" + Array(this.indents + 1).join(pp) + "');")
- if (block || attrs.length || attrsBlocks.length) {
- this.buf.push(name + '.call({');
- if (block) {
- this.buf.push('block: function(){');
- // Render block with no indents, dynamically added when rendered
- this.parentIndents++;
- var _indents = this.indents;
- this.indents = 0;
- this.visit(mixin.block);
- this.indents = _indents;
- this.parentIndents--;
- if (attrs.length || attrsBlocks.length) {
- this.buf.push('},');
- } else {
- this.buf.push('}');
- }
- }
- if (attrsBlocks.length) {
- if (attrs.length) {
- var val = this.attrs(attrs);
- attrsBlocks.unshift(val);
- }
- this.buf.push('attributes: jade.merge([' + attrsBlocks.join(',') + '])');
- } else if (attrs.length) {
- var val = this.attrs(attrs);
- this.buf.push('attributes: ' + val);
- }
- if (args) {
- this.buf.push('}, ' + args + ');');
- } else {
- this.buf.push('});');
- }
- } else {
- this.buf.push(name + '(' + args + ');');
- }
- if (pp) this.buf.push("jade_indent.pop();")
- } else {
- var mixin_start = this.buf.length;
- args = args ? args.split(',') : [];
- var rest;
- if (args.length && /^\.\.\./.test(args[args.length - 1].trim())) {
- rest = args.pop().trim().replace(/^\.\.\./, '');
- }
- // we need use jade_interp here for v8: https://code.google.com/p/v8/issues/detail?id=4165
- // once fixed, use this: this.buf.push(name + ' = function(' + args.join(',') + '){');
- this.buf.push(name + ' = jade_interp = function(' + args.join(',') + '){');
- this.buf.push('var block = (this && this.block), attributes = (this && this.attributes) || {};');
- if (rest) {
- this.buf.push('var ' + rest + ' = [];');
- this.buf.push('for (jade_interp = ' + args.length + '; jade_interp < arguments.length; jade_interp++) {');
- this.buf.push(' ' + rest + '.push(arguments[jade_interp]);');
- this.buf.push('}');
- }
- this.parentIndents++;
- this.visit(block);
- this.parentIndents--;
- this.buf.push('};');
- var mixin_end = this.buf.length;
- this.mixins[key].instances.push({start: mixin_start, end: mixin_end});
- }
- },
- /**
- * Visit `tag` buffering tag markup, generating
- * attributes, visiting the `tag`'s code and block.
- *
- * @param {Tag} tag
- * @api public
- */
- visitTag: function(tag){
- this.indents++;
- var name = tag.name
- , pp = this.pp
- , self = this;
- function bufferName() {
- if (tag.buffer) self.bufferExpression(name);
- else self.buffer(name);
- }
- if ('pre' == tag.name) this.escape = true;
- if (!this.hasCompiledTag) {
- if (!this.hasCompiledDoctype && 'html' == name) {
- this.visitDoctype();
- }
- this.hasCompiledTag = true;
- }
- // pretty print
- if (pp && !tag.isInline())
- this.prettyIndent(0, true);
- if (tag.selfClosing || (!this.xml && selfClosing[tag.name])) {
- this.buffer('<');
- bufferName();
- this.visitAttributes(tag.attrs, tag.attributeBlocks.slice());
- this.terse
- ? this.buffer('>')
- : this.buffer('/>');
- // if it is non-empty throw an error
- if (tag.block &&
- !(tag.block.type === 'Block' && tag.block.nodes.length === 0) &&
- tag.block.nodes.some(function (tag) {
- return tag.type !== 'Text' || !/^\s*$/.test(tag.val)
- })) {
- throw errorAtNode(tag, new Error(name + ' is self closing and should not have content.'));
- }
- } else {
- // Optimize attributes buffering
- this.buffer('<');
- bufferName();
- this.visitAttributes(tag.attrs, tag.attributeBlocks.slice());
- this.buffer('>');
- if (tag.code) this.visitCode(tag.code);
- this.visit(tag.block);
- // pretty print
- if (pp && !tag.isInline() && 'pre' != tag.name && !tag.canInline())
- this.prettyIndent(0, true);
- this.buffer('</');
- bufferName();
- this.buffer('>');
- }
- if ('pre' == tag.name) this.escape = false;
- this.indents--;
- },
- /**
- * Visit `filter`, throwing when the filter does not exist.
- *
- * @param {Filter} filter
- * @api public
- */
- visitFilter: function(filter){
- var text = filter.block.nodes.map(
- function(node){ return node.val; }
- ).join('\n');
- filter.attrs.filename = this.options.filename;
- try {
- this.buffer(filters(filter.name, text, filter.attrs), true);
- } catch (err) {
- throw errorAtNode(filter, err);
- }
- },
- /**
- * Visit `text` node.
- *
- * @param {Text} text
- * @api public
- */
- visitText: function(text){
- this.buffer(text.val, true);
- },
- /**
- * Visit a `comment`, only buffering when the buffer flag is set.
- *
- * @param {Comment} comment
- * @api public
- */
- visitComment: function(comment){
- if (!comment.buffer) return;
- if (this.pp) this.prettyIndent(1, true);
- this.buffer('<!--' + comment.val + '-->');
- },
- /**
- * Visit a `BlockComment`.
- *
- * @param {Comment} comment
- * @api public
- */
- visitBlockComment: function(comment){
- if (!comment.buffer) return;
- if (this.pp) this.prettyIndent(1, true);
- this.buffer('<!--' + comment.val);
- this.visit(comment.block);
- if (this.pp) this.prettyIndent(1, true);
- this.buffer('-->');
- },
- /**
- * Visit `code`, respecting buffer / escape flags.
- * If the code is followed by a block, wrap it in
- * a self-calling function.
- *
- * @param {Code} code
- * @api public
- */
- visitCode: function(code){
- // Wrap code blocks with {}.
- // we only wrap unbuffered code blocks ATM
- // since they are usually flow control
- // Buffer code
- if (code.buffer) {
- var val = code.val.trim();
- val = 'null == (jade_interp = '+val+') ? "" : jade_interp';
- if (code.escape) val = 'jade.escape(' + val + ')';
- this.bufferExpression(val);
- } else {
- this.buf.push(code.val);
- }
- // Block support
- if (code.block) {
- if (!code.buffer) this.buf.push('{');
- this.visit(code.block);
- if (!code.buffer) this.buf.push('}');
- }
- },
- /**
- * Visit `each` block.
- *
- * @param {Each} each
- * @api public
- */
- visitEach: function(each){
- this.buf.push(''
- + '// iterate ' + each.obj + '\n'
- + ';(function(){\n'
- + ' var $$obj = ' + each.obj + ';\n'
- + ' if (\'number\' == typeof $$obj.length) {\n');
- if (each.alternative) {
- this.buf.push(' if ($$obj.length) {');
- }
- this.buf.push(''
- + ' for (var ' + each.key + ' = 0, $$l = $$obj.length; ' + each.key + ' < $$l; ' + each.key + '++) {\n'
- + ' var ' + each.val + ' = $$obj[' + each.key + '];\n');
- this.visit(each.block);
- this.buf.push(' }\n');
- if (each.alternative) {
- this.buf.push(' } else {');
- this.visit(each.alternative);
- this.buf.push(' }');
- }
- this.buf.push(''
- + ' } else {\n'
- + ' var $$l = 0;\n'
- + ' for (var ' + each.key + ' in $$obj) {\n'
- + ' $$l++;'
- + ' var ' + each.val + ' = $$obj[' + each.key + '];\n');
- this.visit(each.block);
- this.buf.push(' }\n');
- if (each.alternative) {
- this.buf.push(' if ($$l === 0) {');
- this.visit(each.alternative);
- this.buf.push(' }');
- }
- this.buf.push(' }\n}).call(this);\n');
- },
- /**
- * Visit `attrs`.
- *
- * @param {Array} attrs
- * @api public
- */
- visitAttributes: function(attrs, attributeBlocks){
- if (attributeBlocks.length) {
- if (attrs.length) {
- var val = this.attrs(attrs);
- attributeBlocks.unshift(val);
- }
- this.bufferExpression('jade.attrs(jade.merge([' + attributeBlocks.join(',') + ']), ' + utils.stringify(this.terse) + ')');
- } else if (attrs.length) {
- this.attrs(attrs, true);
- }
- },
- /**
- * Compile attributes.
- */
- attrs: function(attrs, buffer){
- var buf = [];
- var classes = [];
- var classEscaping = [];
- attrs.forEach(function(attr){
- var key = attr.name;
- var escaped = attr.escaped;
- if (key === 'class') {
- classes.push(attr.val);
- classEscaping.push(attr.escaped);
- } else if (isConstant(attr.val)) {
- if (buffer) {
- this.buffer(runtime.attr(key, toConstant(attr.val), escaped, this.terse));
- } else {
- var val = toConstant(attr.val);
- if (key === 'style') val = runtime.style(val);
- if (escaped && !(key.indexOf('data') === 0 && typeof val !== 'string')) {
- val = runtime.escape(val);
- }
- buf.push(utils.stringify(key) + ': ' + utils.stringify(val));
- }
- } else {
- if (buffer) {
- this.bufferExpression('jade.attr("' + key + '", ' + attr.val + ', ' + utils.stringify(escaped) + ', ' + utils.stringify(this.terse) + ')');
- } else {
- var val = attr.val;
- if (key === 'style') {
- val = 'jade.style(' + val + ')';
- }
- if (escaped && !(key.indexOf('data') === 0)) {
- val = 'jade.escape(' + val + ')';
- } else if (escaped) {
- val = '(typeof (jade_interp = ' + val + ') == "string" ? jade.escape(jade_interp) : jade_interp)';
- }
- buf.push(utils.stringify(key) + ': ' + val);
- }
- }
- }.bind(this));
- if (buffer) {
- if (classes.every(isConstant)) {
- this.buffer(runtime.cls(classes.map(toConstant), classEscaping));
- } else {
- this.bufferExpression('jade.cls([' + classes.join(',') + '], ' + utils.stringify(classEscaping) + ')');
- }
- } else if (classes.length) {
- if (classes.every(isConstant)) {
- classes = utils.stringify(runtime.joinClasses(classes.map(toConstant).map(runtime.joinClasses).map(function (cls, i) {
- return classEscaping[i] ? runtime.escape(cls) : cls;
- })));
- } else {
- classes = '(jade_interp = ' + utils.stringify(classEscaping) + ',' +
- ' jade.joinClasses([' + classes.join(',') + '].map(jade.joinClasses).map(function (cls, i) {' +
- ' return jade_interp[i] ? jade.escape(cls) : cls' +
- ' }))' +
- ')';
- }
- if (classes.length)
- buf.push('"class": ' + classes);
- }
- return '{' + buf.join(',') + '}';
- }
- };
- },{"./doctypes":3,"./filters":4,"./nodes":16,"./runtime":24,"./utils":25,"character-parser":29,"constantinople":30,"void-elements":34}],3:[function(require,module,exports){
- 'use strict';
- module.exports = {
- 'default': '<!DOCTYPE html>'
- , 'xml': '<?xml version="1.0" encoding="utf-8" ?>'
- , 'transitional': '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">'
- , 'strict': '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">'
- , 'frameset': '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">'
- , '1.1': '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">'
- , 'basic': '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML Basic 1.1//EN" "http://www.w3.org/TR/xhtml-basic/xhtml-basic11.dtd">'
- , 'mobile': '<!DOCTYPE html PUBLIC "-//WAPFORUM//DTD XHTML Mobile 1.2//EN" "http://www.openmobilealliance.org/tech/DTD/xhtml-mobile12.dtd">'
- };
- },{}],4:[function(require,module,exports){
- 'use strict';
- module.exports = filter;
- function filter(name, str, options) {
- if (typeof filter[name] === 'function') {
- return filter[name](str, options);
- } else {
- throw new Error('unknown filter ":' + name + '"');
- }
- }
- },{}],5:[function(require,module,exports){
- 'use strict';
- module.exports = [
- 'a'
- , 'abbr'
- , 'acronym'
- , 'b'
- , 'br'
- , 'code'
- , 'em'
- , 'font'
- , 'i'
- , 'img'
- , 'ins'
- , 'kbd'
- , 'map'
- , 'samp'
- , 'small'
- , 'span'
- , 'strong'
- , 'sub'
- , 'sup'
- ];
- },{}],6:[function(require,module,exports){
- 'use strict';
- var utils = require('./utils');
- var characterParser = require('character-parser');
- /**
- * Initialize `Lexer` with the given `str`.
- *
- * @param {String} str
- * @param {String} filename
- * @api private
- */
- var Lexer = module.exports = function Lexer(str, filename) {
- this.input = str.replace(/\r\n|\r/g, '\n');
- this.filename = filename;
- this.deferredTokens = [];
- this.lastIndents = 0;
- this.lineno = 1;
- this.stash = [];
- this.indentStack = [];
- this.indentRe = null;
- this.pipeless = false;
- };
- function assertExpression(exp) {
- //this verifies that a JavaScript expression is valid
- Function('', 'return (' + exp + ')');
- }
- function assertNestingCorrect(exp) {
- //this verifies that code is properly nested, but allows
- //invalid JavaScript such as the contents of `attributes`
- var res = characterParser(exp)
- if (res.isNesting()) {
- throw new Error('Nesting must match on expression `' + exp + '`')
- }
- }
- /**
- * Lexer prototype.
- */
- Lexer.prototype = {
- /**
- * Construct a token with the given `type` and `val`.
- *
- * @param {String} type
- * @param {String} val
- * @return {Object}
- * @api private
- */
- tok: function(type, val){
- return {
- type: type
- , line: this.lineno
- , val: val
- }
- },
- /**
- * Consume the given `len` of input.
- *
- * @param {Number} len
- * @api private
- */
- consume: function(len){
- this.input = this.input.substr(len);
- },
- /**
- * Scan for `type` with the given `regexp`.
- *
- * @param {String} type
- * @param {RegExp} regexp
- * @return {Object}
- * @api private
- */
- scan: function(regexp, type){
- var captures;
- if (captures = regexp.exec(this.input)) {
- this.consume(captures[0].length);
- return this.tok(type, captures[1]);
- }
- },
- /**
- * Defer the given `tok`.
- *
- * @param {Object} tok
- * @api private
- */
- defer: function(tok){
- this.deferredTokens.push(tok);
- },
- /**
- * Lookahead `n` tokens.
- *
- * @param {Number} n
- * @return {Object}
- * @api private
- */
- lookahead: function(n){
- var fetch = n - this.stash.length;
- while (fetch-- > 0) this.stash.push(this.next());
- return this.stash[--n];
- },
- /**
- * Return the indexOf `(` or `{` or `[` / `)` or `}` or `]` delimiters.
- *
- * @return {Number}
- * @api private
- */
- bracketExpression: function(skip){
- skip = skip || 0;
- var start = this.input[skip];
- if (start != '(' && start != '{' && start != '[') throw new Error('unrecognized start character');
- var end = ({'(': ')', '{': '}', '[': ']'})[start];
- var range = characterParser.parseMax(this.input, {start: skip + 1});
- if (this.input[range.end] !== end) throw new Error('start character ' + start + ' does not match end character ' + this.input[range.end]);
- return range;
- },
- /**
- * Stashed token.
- */
- stashed: function() {
- return this.stash.length
- && this.stash.shift();
- },
- /**
- * Deferred token.
- */
- deferred: function() {
- return this.deferredTokens.length
- && this.deferredTokens.shift();
- },
- /**
- * end-of-source.
- */
- eos: function() {
- if (this.input.length) return;
- if (this.indentStack.length) {
- this.indentStack.shift();
- return this.tok('outdent');
- } else {
- return this.tok('eos');
- }
- },
- /**
- * Blank line.
- */
- blank: function() {
- var captures;
- if (captures = /^\n *\n/.exec(this.input)) {
- this.consume(captures[0].length - 1);
- ++this.lineno;
- if (this.pipeless) return this.tok('text', '');
- return this.next();
- }
- },
- /**
- * Comment.
- */
- comment: function() {
- var captures;
- if (captures = /^\/\/(-)?([^\n]*)/.exec(this.input)) {
- this.consume(captures[0].length);
- var tok = this.tok('comment', captures[2]);
- tok.buffer = '-' != captures[1];
- this.pipeless = true;
- return tok;
- }
- },
- /**
- * Interpolated tag.
- */
- interpolation: function() {
- if (/^#\{/.test(this.input)) {
- var match = this.bracketExpression(1);
- this.consume(match.end + 1);
- return this.tok('interpolation', match.src);
- }
- },
- /**
- * Tag.
- */
- tag: function() {
- var captures;
- if (captures = /^(\w[-:\w]*)(\/?)/.exec(this.input)) {
- this.consume(captures[0].length);
- var tok, name = captures[1];
- if (':' == name[name.length - 1]) {
- name = name.slice(0, -1);
- tok = this.tok('tag', name);
- this.defer(this.tok(':'));
- if (this.input[0] !== ' ') {
- console.warn('Warning: space required after `:` on line ' + this.lineno +
- ' of jade file "' + this.filename + '"');
- }
- while (' ' == this.input[0]) this.input = this.input.substr(1);
- } else {
- tok = this.tok('tag', name);
- }
- tok.selfClosing = !!captures[2];
- return tok;
- }
- },
- /**
- * Filter.
- */
- filter: function() {
- var tok = this.scan(/^:([\w\-]+)/, 'filter');
- if (tok) {
- this.pipeless = true;
- return tok;
- }
- },
- /**
- * Doctype.
- */
- doctype: function() {
- if (this.scan(/^!!! *([^\n]+)?/, 'doctype')) {
- throw new Error('`!!!` is deprecated, you must now use `doctype`');
- }
- var node = this.scan(/^(?:doctype) *([^\n]+)?/, 'doctype');
- if (node && node.val && node.val.trim() === '5') {
- throw new Error('`doctype 5` is deprecated, you must now use `doctype html`');
- }
- return node;
- },
- /**
- * Id.
- */
- id: function() {
- return this.scan(/^#([\w-]+)/, 'id');
- },
- /**
- * Class.
- */
- className: function() {
- return this.scan(/^\.([\w-]+)/, 'class');
- },
- /**
- * Text.
- */
- text: function() {
- return this.scan(/^(?:\| ?| )([^\n]+)/, 'text') ||
- this.scan(/^\|?( )/, 'text') ||
- this.scan(/^(<[^\n]*)/, 'text');
- },
- textFail: function () {
- var tok;
- if (tok = this.scan(/^([^\.\n][^\n]+)/, 'text')) {
- console.warn('Warning: missing space before text for line ' + this.lineno +
- ' of jade file "' + this.filename + '"');
- return tok;
- }
- },
- /**
- * Dot.
- */
- dot: function() {
- var match;
- if (match = this.scan(/^\./, 'dot')) {
- this.pipeless = true;
- return match;
- }
- },
- /**
- * Extends.
- */
- "extends": function() {
- return this.scan(/^extends? +([^\n]+)/, 'extends');
- },
- /**
- * Block prepend.
- */
- prepend: function() {
- var captures;
- if (captures = /^prepend +([^\n]+)/.exec(this.input)) {
- this.consume(captures[0].length);
- var mode = 'prepend'
- , name = captures[1]
- , tok = this.tok('block', name);
- tok.mode = mode;
- return tok;
- }
- },
- /**
- * Block append.
- */
- append: function() {
- var captures;
- if (captures = /^append +([^\n]+)/.exec(this.input)) {
- this.consume(captures[0].length);
- var mode = 'append'
- , name = captures[1]
- , tok = this.tok('block', name);
- tok.mode = mode;
- return tok;
- }
- },
- /**
- * Block.
- */
- block: function() {
- var captures;
- if (captures = /^block\b *(?:(prepend|append) +)?([^\n]+)/.exec(this.input)) {
- this.consume(captures[0].length);
- var mode = captures[1] || 'replace'
- , name = captures[2]
- , tok = this.tok('block', name);
- tok.mode = mode;
- return tok;
- }
- },
- /**
- * Mixin Block.
- */
- mixinBlock: function() {
- var captures;
- if (captures = /^block[ \t]*(\n|$)/.exec(this.input)) {
- this.consume(captures[0].length - captures[1].length);
- return this.tok('mixin-block');
- }
- },
- /**
- * Yield.
- */
- 'yield': function() {
- return this.scan(/^yield */, 'yield');
- },
- /**
- * Include.
- */
- include: function() {
- return this.scan(/^include +([^\n]+)/, 'include');
- },
- /**
- * Include with filter
- */
- includeFiltered: function() {
- var captures;
- if (captures = /^include:([\w\-]+)([\( ])/.exec(this.input)) {
- this.consume(captures[0].length - 1);
- var filter = captures[1];
- var attrs = captures[2] === '(' ? this.attrs() : null;
- if (!(captures[2] === ' ' || this.input[0] === ' ')) {
- throw new Error('expected space after include:filter but got ' + utils.stringify(this.input[0]));
- }
- captures = /^ *([^\n]+)/.exec(this.input);
- if (!captures || captures[1].trim() === '') {
- throw new Error('missing path for include:filter');
- }
- this.consume(captures[0].length);
- var path = captures[1];
- var tok = this.tok('include', path);
- tok.filter = filter;
- tok.attrs = attrs;
- return tok;
- }
- },
- /**
- * Case.
- */
- "case": function() {
- return this.scan(/^case +([^\n]+)/, 'case');
- },
- /**
- * When.
- */
- when: function() {
- return this.scan(/^when +([^:\n]+)/, 'when');
- },
- /**
- * Default.
- */
- "default": function() {
- return this.scan(/^default */, 'default');
- },
- /**
- * Call mixin.
- */
- call: function(){
- var tok, captures;
- if (captures = /^\+(\s*)(([-\w]+)|(#\{))/.exec(this.input)) {
- // try to consume simple or interpolated call
- if (captures[3]) {
- // simple call
- this.consume(captures[0].length);
- tok = this.tok('call', captures[3]);
- } else {
- // interpolated call
- var match = this.bracketExpression(2 + captures[1].length);
- this.consume(match.end + 1);
- assertExpression(match.src);
- tok = this.tok('call', '#{'+match.src+'}');
- }
- // Check for args (not attributes)
- if (captures = /^ *\(/.exec(this.input)) {
- var range = this.bracketExpression(captures[0].length - 1);
- if (!/^\s*[-\w]+ *=/.test(range.src)) { // not attributes
- this.consume(range.end + 1);
- tok.args = range.src;
- }
- if (tok.args) {
- assertExpression('[' + tok.args + ']');
- }
- }
- return tok;
- }
- },
- /**
- * Mixin.
- */
- mixin: function(){
- var captures;
- if (captures = /^mixin +([-\w]+)(?: *\((.*)\))? */.exec(this.input)) {
- this.consume(captures[0].length);
- var tok = this.tok('mixin', captures[1]);
- tok.args = captures[2];
- return tok;
- }
- },
- /**
- * Conditional.
- */
- conditional: function() {
- var captures;
- if (captures = /^(if|unless|else if|else)\b([^\n]*)/.exec(this.input)) {
- this.consume(captures[0].length);
- var type = captures[1]
- var js = captures[2];
- var isIf = false;
- var isElse = false;
- switch (type) {
- case 'if':
- assertExpression(js)
- js = 'if (' + js + ')';
- isIf = true;
- break;
- case 'unless':
- assertExpression(js)
- js = 'if (!(' + js + '))';
- isIf = true;
- break;
- case 'else if':
- assertExpression(js)
- js = 'else if (' + js + ')';
- isIf = true;
- isElse = true;
- break;
- case 'else':
- if (js && js.trim()) {
- throw new Error('`else` cannot have a condition, perhaps you meant `else if`');
- }
- js = 'else';
- isElse = true;
- break;
- }
- var tok = this.tok('code', js);
- tok.isElse = isElse;
- tok.isIf = isIf;
- tok.requiresBlock = true;
- return tok;
- }
- },
- /**
- * While.
- */
- "while": function() {
- var captures;
- if (captures = /^while +([^\n]+)/.exec(this.input)) {
- this.consume(captures[0].length);
- assertExpression(captures[1])
- var tok = this.tok('code', 'while (' + captures[1] + ')');
- tok.requiresBlock = true;
- return tok;
- }
- },
- /**
- * Each.
- */
- each: function() {
- var captures;
- if (captures = /^(?:- *)?(?:each|for) +([a-zA-Z_$][\w$]*)(?: *, *([a-zA-Z_$][\w$]*))? * in *([^\n]+)/.exec(this.input)) {
- this.consume(captures[0].length);
- var tok = this.tok('each', captures[1]);
- tok.key = captures[2] || '$index';
- assertExpression(captures[3])
- tok.code = captures[3];
- return tok;
- }
- },
- /**
- * Code.
- */
- code: function() {
- var captures;
- if (captures = /^(!?=|-)[ \t]*([^\n]+)/.exec(this.input)) {
- this.consume(captures[0].length);
- var flags = captures[1];
- captures[1] = captures[2];
- var tok = this.tok('code', captures[1]);
- tok.escape = flags.charAt(0) === '=';
- tok.buffer = flags.charAt(0) === '=' || flags.charAt(1) === '=';
- if (tok.buffer) assertExpression(captures[1])
- return tok;
- }
- },
- /**
- * Block code.
- */
- blockCode: function() {
- var captures;
- if (captures = /^-\n/.exec(this.input)) {
- this.consume(captures[0].length - 1);
- var tok = this.tok('blockCode');
- this.pipeless = true;
- return tok;
- }
- },
- /**
- * Attributes.
- */
- attrs: function() {
- if ('(' == this.input.charAt(0)) {
- var index = this.bracketExpression().end
- , str = this.input.substr(1, index-1)
- , tok = this.tok('attrs');
- assertNestingCorrect(str);
- var quote = '';
- var interpolate = function (attr) {
- return attr.replace(/(\\)?#\{(.+)/g, function(_, escape, expr){
- if (escape) return _;
- try {
- var range = characterParser.parseMax(expr);
- if (expr[range.end] !== '}') return _.substr(0, 2) + interpolate(_.substr(2));
- assertExpression(range.src)
- return quote + " + (" + range.src + ") + " + quote + interpolate(expr.substr(range.end + 1));
- } catch (ex) {
- return _.substr(0, 2) + interpolate(_.substr(2));
- }
- });
- }
- this.consume(index + 1);
- tok.attrs = [];
- var escapedAttr = true
- var key = '';
- var val = '';
- var interpolatable = '';
- var state = characterParser.defaultState();
- var loc = 'key';
- var isEndOfAttribute = function (i) {
- if (key.trim() === '') return false;
- if (i === str.length) return true;
- if (loc === 'key') {
- if (str[i] === ' ' || str[i] === '\n') {
- for (var x = i; x < str.length; x++) {
- if (str[x] != ' ' && str[x] != '\n') {
- if (str[x] === '=' || str[x] === '!' || str[x] === ',') return false;
- else return true;
- }
- }
- }
- return str[i] === ','
- } else if (loc === 'value' && !state.isNesting()) {
- try {
- assertExpression(val);
- if (str[i] === ' ' || str[i] === '\n') {
- for (var x = i; x < str.length; x++) {
- if (str[x] != ' ' && str[x] != '\n') {
- if (characterParser.isPunctuator(str[x]) && str[x] != '"' && str[x] != "'") return false;
- else return true;
- }
- }
- }
- return str[i] === ',';
- } catch (ex) {
- return false;
- }
- }
- }
- this.lineno += str.split("\n").length - 1;
- for (var i = 0; i <= str.length; i++) {
- if (isEndOfAttribute(i)) {
- val = val.trim();
- if (val) assertExpression(val)
- key = key.trim();
- key = key.replace(/^['"]|['"]$/g, '');
- tok.attrs.push({
- name: key,
- val: '' == val ? true : val,
- escaped: escapedAttr
- });
- key = val = '';
- loc = 'key';
- escapedAttr = false;
- } else {
- switch (loc) {
- case 'key-char':
- if (str[i] === quote) {
- loc = 'key';
- if (i + 1 < str.length && [' ', ',', '!', '=', '\n'].indexOf(str[i + 1]) === -1)
- throw new Error('Unexpected character ' + str[i + 1] + ' expected ` `, `\\n`, `,`, `!` or `=`');
- } else {
- key += str[i];
- }
- break;
- case 'key':
- if (key === '' && (str[i] === '"' || str[i] === "'")) {
- loc = 'key-char';
- quote = str[i];
- } else if (str[i] === '!' || str[i] === '=') {
- escapedAttr = str[i] !== '!';
- if (str[i] === '!') i++;
- if (str[i] !== '=') throw new Error('Unexpected character ' + str[i] + ' expected `=`');
- loc = 'value';
- state = characterParser.defaultState();
- } else {
- key += str[i]
- }
- break;
- case 'value':
- state = characterParser.parseChar(str[i], state);
- if (state.isString()) {
- loc = 'string';
- quote = str[i];
- interpolatable = str[i];
- } else {
- val += str[i];
- }
- break;
- case 'string':
- state = characterParser.parseChar(str[i], state);
- interpolatable += str[i];
- if (!state.isString()) {
- loc = 'value';
- val += interpolate(interpolatable);
- }
- break;
- }
- }
- }
- if ('/' == this.input.charAt(0)) {
- this.consume(1);
- tok.selfClosing = true;
- }
- return tok;
- }
- },
- /**
- * &attributes block
- */
- attributesBlock: function () {
- var captures;
- if (/^&attributes\b/.test(this.input)) {
- this.consume(11);
- var args = this.bracketExpression();
- this.consume(args.end + 1);
- return this.tok('&attributes', args.src);
- }
- },
- /**
- * Indent | Outdent | Newline.
- */
- indent: function() {
- var captures, re;
- // established regexp
- if (this.indentRe) {
- captures = this.indentRe.exec(this.input);
- // determine regexp
- } else {
- // tabs
- re = /^\n(\t*) */;
- captures = re.exec(this.input);
- // spaces
- if (captures && !captures[1].length) {
- re = /^\n( *)/;
- captures = re.exec(this.input);
- }
- // established
- if (captures && captures[1].length) this.indentRe = re;
- }
- if (captures) {
- var tok
- , indents = captures[1].length;
- ++this.lineno;
- this.consume(indents + 1);
- if (' ' == this.input[0] || '\t' == this.input[0]) {
- throw new Error('Invalid indentation, you can use tabs or spaces but not both');
- }
- // blank line
- if ('\n' == this.input[0]) {
- this.pipeless = false;
- return this.tok('newline');
- }
- // outdent
- if (this.indentStack.length && indents < this.indentStack[0]) {
- while (this.indentStack.length && this.indentStack[0] > indents) {
- this.stash.push(this.tok('outdent'));
- this.indentStack.shift();
- }
- tok = this.stash.pop();
- // indent
- } else if (indents && indents != this.indentStack[0]) {
- this.indentStack.unshift(indents);
- tok = this.tok('indent', indents);
- // newline
- } else {
- tok = this.tok('newline');
- }
- this.pipeless = false;
- return tok;
- }
- },
- /**
- * Pipe-less text consumed only when
- * pipeless is true;
- */
- pipelessText: function() {
- if (!this.pipeless) return;
- var captures, re;
- // established regexp
- if (this.indentRe) {
- captures = this.indentRe.exec(this.input);
- // determine regexp
- } else {
- // tabs
- re = /^\n(\t*) */;
- captures = re.exec(this.input);
- // spaces
- if (captures && !captures[1].length) {
- re = /^\n( *)/;
- captures = re.exec(this.input);
- }
- // established
- if (captures && captures[1].length) this.indentRe = re;
- }
- var indents = captures && captures[1].length;
- if (indents && (this.indentStack.length === 0 || indents > this.indentStack[0])) {
- var indent = captures[1];
- var line;
- var tokens = [];
- var isMatch;
- do {
- // text has `\n` as a prefix
- var i = this.input.substr(1).indexOf('\n');
- if (-1 == i) i = this.input.length - 1;
- var str = this.input.substr(1, i);
- isMatch = str.substr(0, indent.length) === indent || !str.trim();
- if (isMatch) {
- // consume test along with `\n` prefix if match
- this.consume(str.length + 1);
- ++this.lineno;
- tokens.push(str.substr(indent.length));
- }
- } while(this.input.length && isMatch);
- while (this.input.length === 0 && tokens[tokens.length - 1] === '') tokens.pop();
- return this.tok('pipeless-text', tokens);
- }
- },
- /**
- * ':'
- */
- colon: function() {
- var good = /^: +/.test(this.input);
- var res = this.scan(/^: */, ':');
- if (res && !good) {
- console.warn('Warning: space required after `:` on line ' + this.lineno +
- ' of jade file "' + this.filename + '"');
- }
- return res;
- },
- fail: function () {
- throw new Error('unexpected text ' + this.input.substr(0, 5));
- },
- /**
- * Return the next token object, or those
- * previously stashed by lookahead.
- *
- * @return {Object}
- * @api private
- */
- advance: function(){
- return this.stashed()
- || this.next();
- },
- /**
- * Return the next token object.
- *
- * @return {Object}
- * @api private
- */
- next: function() {
- return this.deferred()
- || this.blank()
- || this.eos()
- || this.pipelessText()
- || this.yield()
- || this.doctype()
- || this.interpolation()
- || this["case"]()
- || this.when()
- || this["default"]()
- || this["extends"]()
- || this.append()
- || this.prepend()
- || this.block()
- || this.mixinBlock()
- || this.include()
- || this.includeFiltered()
- || this.mixin()
- || this.call()
- || this.conditional()
- || this.each()
- || this["while"]()
- || this.tag()
- || this.filter()
- || this.blockCode()
- || this.code()
- || this.id()
- || this.className()
- || this.attrs()
- || this.attributesBlock()
- || this.indent()
- || this.text()
- || this.comment()
- || this.colon()
- || this.dot()
- || this.textFail()
- || this.fail();
- }
- };
- },{"./utils":25,"character-parser":29}],7:[function(require,module,exports){
- 'use strict';
- var Node = require('./node');
- /**
- * Initialize a `Attrs` node.
- *
- * @api public
- */
- var Attrs = module.exports = function Attrs() {
- this.attributeNames = [];
- this.attrs = [];
- this.attributeBlocks = [];
- };
- // Inherit from `Node`.
- Attrs.prototype = Object.create(Node.prototype);
- Attrs.prototype.constructor = Attrs;
- Attrs.prototype.type = 'Attrs';
- /**
- * Set attribute `name` to `val`, keep in mind these become
- * part of a raw js object literal, so to quote a value you must
- * '"quote me"', otherwise or example 'user.name' is literal JavaScript.
- *
- * @param {String} name
- * @param {String} val
- * @param {Boolean} escaped
- * @return {Tag} for chaining
- * @api public
- */
- Attrs.prototype.setAttribute = function(name, val, escaped){
- if (name !== 'class' && this.attributeNames.indexOf(name) !== -1) {
- throw new Error('Duplicate attribute "' + name + '" is not allowed.');
- }
- this.attributeNames.push(name);
- this.attrs.push({ name: name, val: val, escaped: escaped });
- return this;
- };
- /**
- * Remove attribute `name` when present.
- *
- * @param {String} name
- * @api public
- */
- Attrs.prototype.removeAttribute = function(name){
- var err = new Error('attrs.removeAttribute is deprecated and will be removed in v2.0.0');
- console.warn(err.stack);
- for (var i = 0, len = this.attrs.length; i < len; ++i) {
- if (this.attrs[i] && this.attrs[i].name == name) {
- delete this.attrs[i];
- }
- }
- };
- /**
- * Get attribute value by `name`.
- *
- * @param {String} name
- * @return {String}
- * @api public
- */
- Attrs.prototype.getAttribute = function(name){
- var err = new Error('attrs.getAttribute is deprecated and will be removed in v2.0.0');
- console.warn(err.stack);
- for (var i = 0, len = this.attrs.length; i < len; ++i) {
- if (this.attrs[i] && this.attrs[i].name == name) {
- return this.attrs[i].val;
- }
- }
- };
- Attrs.prototype.addAttributes = function (src) {
- this.attributeBlocks.push(src);
- };
- },{"./node":20}],8:[function(require,module,exports){
- 'use strict';
- var Node = require('./node');
- /**
- * Initialize a `BlockComment` with the given `block`.
- *
- * @param {String} val
- * @param {Block} block
- * @param {Boolean} buffer
- * @api public
- */
- var BlockComment = module.exports = function BlockComment(val, block, buffer) {
- this.block = block;
- this.val = val;
- this.buffer = buffer;
- };
- // Inherit from `Node`.
- BlockComment.prototype = Object.create(Node.prototype);
- BlockComment.prototype.constructor = BlockComment;
- BlockComment.prototype.type = 'BlockComment';
- },{"./node":20}],9:[function(require,module,exports){
- 'use strict';
- var Node = require('./node');
- /**
- * Initialize a new `Block` with an optional `node`.
- *
- * @param {Node} node
- * @api public
- */
- var Block = module.exports = function Block(node){
- this.nodes = [];
- if (node) this.push(node);
- };
- // Inherit from `Node`.
- Block.prototype = Object.create(Node.prototype);
- Block.prototype.constructor = Block;
- Block.prototype.type = 'Block';
- /**
- * Block flag.
- */
- Block.prototype.isBlock = true;
- /**
- * Replace the nodes in `other` with the nodes
- * in `this` block.
- *
- * @param {Block} other
- * @api private
- */
- Block.prototype.replace = function(other){
- var err = new Error('block.replace is deprecated and will be removed in v2.0.0');
- console.warn(err.stack);
- other.nodes = this.nodes;
- };
- /**
- * Push the given `node`.
- *
- * @param {Node} node
- * @return {Number}
- * @api public
- */
- Block.prototype.push = function(node){
- return this.nodes.push(node);
- };
- /**
- * Check if this block is empty.
- *
- * @return {Boolean}
- * @api public
- */
- Block.prototype.isEmpty = function(){
- return 0 == this.nodes.length;
- };
- /**
- * Unshift the given `node`.
- *
- * @param {Node} node
- * @return {Number}
- * @api public
- */
- Block.prototype.unshift = function(node){
- return this.nodes.unshift(node);
- };
- /**
- * Return the "last" block, or the first `yield` node.
- *
- * @return {Block}
- * @api private
- */
- Block.prototype.includeBlock = function(){
- var ret = this
- , node;
- for (var i = 0, len = this.nodes.length; i < len; ++i) {
- node = this.nodes[i];
- if (node.yield) return node;
- else if (node.textOnly) continue;
- else if (node.includeBlock) ret = node.includeBlock();
- else if (node.block && !node.block.isEmpty()) ret = node.block.includeBlock();
- if (ret.yield) return ret;
- }
- return ret;
- };
- /**
- * Return a clone of this block.
- *
- * @return {Block}
- * @api private
- */
- Block.prototype.clone = function(){
- var err = new Error('block.clone is deprecated and will be removed in v2.0.0');
- console.warn(err.stack);
- var clone = new Block;
- for (var i = 0, len = this.nodes.length; i < len; ++i) {
- clone.push(this.nodes[i].clone());
- }
- return clone;
- };
- },{"./node":20}],10:[function(require,module,exports){
- 'use strict';
- var Node = require('./node');
- /**
- * Initialize a new `Case` with `expr`.
- *
- * @param {String} expr
- * @api public
- */
- var Case = exports = module.exports = function Case(expr, block){
- this.expr = expr;
- this.block = block;
- };
- // Inherit from `Node`.
- Case.prototype = Object.create(Node.prototype);
- Case.prototype.constructor = Case;
- Case.prototype.type = 'Case';
- var When = exports.When = function When(expr, block){
- this.expr = expr;
- this.block = block;
- this.debug = false;
- };
- // Inherit from `Node`.
- When.prototype = Object.create(Node.prototype);
- When.prototype.constructor = When;
- When.prototype.type = 'When';
- },{"./node":20}],11:[function(require,module,exports){
- 'use strict';
- var Node = require('./node');
- /**
- * Initialize a `Code` node with the given code `val`.
- * Code may also be optionally buffered and escaped.
- *
- * @param {String} val
- * @param {Boolean} buffer
- * @param {Boolean} escape
- * @api public
- */
- var Code = module.exports = function Code(val, buffer, escape) {
- this.val = val;
- this.buffer = buffer;
- this.escape = escape;
- if (val.match(/^ *else/)) this.debug = false;
- };
- // Inherit from `Node`.
- Code.prototype = Object.create(Node.prototype);
- Code.prototype.constructor = Code;
- Code.prototype.type = 'Code'; // prevent the minifiers removing this
- },{"./node":20}],12:[function(require,module,exports){
- 'use strict';
- var Node = require('./node');
- /**
- * Initialize a `Comment` with the given `val`, optionally `buffer`,
- * otherwise the comment may render in the output.
- *
- * @param {String} val
- * @param {Boolean} buffer
- * @api public
- */
- var Comment = module.exports = function Comment(val, buffer) {
- this.val = val;
- this.buffer = buffer;
- };
- // Inherit from `Node`.
- Comment.prototype = Object.create(Node.prototype);
- Comment.prototype.constructor = Comment;
- Comment.prototype.type = 'Comment';
- },{"./node":20}],13:[function(require,module,exports){
- 'use strict';
- var Node = require('./node');
- /**
- * Initialize a `Doctype` with the given `val`.
- *
- * @param {String} val
- * @api public
- */
- var Doctype = module.exports = function Doctype(val) {
- this.val = val;
- };
- // Inherit from `Node`.
- Doctype.prototype = Object.create(Node.prototype);
- Doctype.prototype.constructor = Doctype;
- Doctype.prototype.type = 'Doctype';
- },{"./node":20}],14:[function(require,module,exports){
- 'use strict';
- var Node = require('./node');
- /**
- * Initialize an `Each` node, representing iteration
- *
- * @param {String} obj
- * @param {String} val
- * @param {String} key
- * @param {Block} block
- * @api public
- */
- var Each = module.exports = function Each(obj, val, key, block) {
- this.obj = obj;
- this.val = val;
- this.key = key;
- this.block = block;
- };
- // Inherit from `Node`.
- Each.prototype = Object.create(Node.prototype);
- Each.prototype.constructor = Each;
- Each.prototype.type = 'Each';
- },{"./node":20}],15:[function(require,module,exports){
- 'use strict';
- var Node = require('./node');
- /**
- * Initialize a `Filter` node with the given
- * filter `name` and `block`.
- *
- * @param {String} name
- * @param {Block|Node} block
- * @api public
- */
- var Filter = module.exports = function Filter(name, block, attrs) {
- this.name = name;
- this.block = block;
- this.attrs = attrs;
- };
- // Inherit from `Node`.
- Filter.prototype = Object.create(Node.prototype);
- Filter.prototype.constructor = Filter;
- Filter.prototype.type = 'Filter';
- },{"./node":20}],16:[function(require,module,exports){
- 'use strict';
- exports.Node = require('./node');
- exports.Tag = require('./tag');
- exports.Code = require('./code');
- exports.Each = require('./each');
- exports.Case = require('./case');
- exports.Text = require('./text');
- exports.Block = require('./block');
- exports.MixinBlock = require('./mixin-block');
- exports.Mixin = require('./mixin');
- exports.Filter = require('./filter');
- exports.Comment = require('./comment');
- exports.Literal = require('./literal');
- exports.BlockComment = require('./block-comment');
- exports.Doctype = require('./doctype');
- },{"./block":9,"./block-comment":8,"./case":10,"./code":11,"./comment":12,"./doctype":13,"./each":14,"./filter":15,"./literal":17,"./mixin":19,"./mixin-block":18,"./node":20,"./tag":21,"./text":22}],17:[function(require,module,exports){
- 'use strict';
- var Node = require('./node');
- /**
- * Initialize a `Literal` node with the given `str.
- *
- * @param {String} str
- * @api public
- */
- var Literal = module.exports = function Literal(str) {
- this.str = str;
- };
- // Inherit from `Node`.
- Literal.prototype = Object.create(Node.prototype);
- Literal.prototype.constructor = Literal;
- Literal.prototype.type = 'Literal';
- },{"./node":20}],18:[function(require,module,exports){
- 'use strict';
- var Node = require('./node');
- /**
- * Initialize a new `Block` with an optional `node`.
- *
- * @param {Node} node
- * @api public
- */
- var MixinBlock = module.exports = function MixinBlock(){};
- // Inherit from `Node`.
- MixinBlock.prototype = Object.create(Node.prototype);
- MixinBlock.prototype.constructor = MixinBlock;
- MixinBlock.prototype.type = 'MixinBlock';
- },{"./node":20}],19:[function(require,module,exports){
- 'use strict';
- var Attrs = require('./attrs');
- /**
- * Initialize a new `Mixin` with `name` and `block`.
- *
- * @param {String} name
- * @param {String} args
- * @param {Block} block
- * @api public
- */
- var Mixin = module.exports = function Mixin(name, args, block, call){
- Attrs.call(this);
- this.name = name;
- this.args = args;
- this.block = block;
- this.call = call;
- };
- // Inherit from `Attrs`.
- Mixin.prototype = Object.create(Attrs.prototype);
- Mixin.prototype.constructor = Mixin;
- Mixin.prototype.type = 'Mixin';
- },{"./attrs":7}],20:[function(require,module,exports){
- 'use strict';
- var Node = module.exports = function Node(){};
- /**
- * Clone this node (return itself)
- *
- * @return {Node}
- * @api private
- */
- Node.prototype.clone = function(){
- var err = new Error('node.clone is deprecated and will be removed in v2.0.0');
- console.warn(err.stack);
- return this;
- };
- Node.prototype.type = '';
- },{}],21:[function(require,module,exports){
- 'use strict';
- var Attrs = require('./attrs');
- var Block = require('./block');
- var inlineTags = require('../inline-tags');
- /**
- * Initialize a `Tag` node with the given tag `name` and optional `block`.
- *
- * @param {String} name
- * @param {Block} block
- * @api public
- */
- var Tag = module.exports = function Tag(name, block) {
- Attrs.call(this);
- this.name = name;
- this.block = block || new Block;
- };
- // Inherit from `Attrs`.
- Tag.prototype = Object.create(Attrs.prototype);
- Tag.prototype.constructor = Tag;
- Tag.prototype.type = 'Tag';
- /**
- * Clone this tag.
- *
- * @return {Tag}
- * @api private
- */
- Tag.prototype.clone = function(){
- var err = new Error('tag.clone is deprecated and will be removed in v2.0.0');
- console.warn(err.stack);
- var clone = new Tag(this.name, this.block.clone());
- clone.line = this.line;
- clone.attrs = this.attrs;
- clone.textOnly = this.textOnly;
- return clone;
- };
- /**
- * Check if this tag is an inline tag.
- *
- * @return {Boolean}
- * @api private
- */
- Tag.prototype.isInline = function(){
- return ~inlineTags.indexOf(this.name);
- };
- /**
- * Check if this tag's contents can be inlined. Used for pretty printing.
- *
- * @return {Boolean}
- * @api private
- */
- Tag.prototype.canInline = function(){
- var nodes = this.block.nodes;
- function isInline(node){
- // Recurse if the node is a block
- if (node.isBlock) return node.nodes.every(isInline);
- return node.isText || (node.isInline && node.isInline());
- }
- // Empty tag
- if (!nodes.length) return true;
- // Text-only or inline-only tag
- if (1 == nodes.length) return isInline(nodes[0]);
- // Multi-line inline-only tag
- if (this.block.nodes.every(isInline)) {
- for (var i = 1, len = nodes.length; i < len; ++i) {
- if (nodes[i-1].isText && nodes[i].isText)
- return false;
- }
- return true;
- }
- // Mixed tag
- return false;
- };
- },{"../inline-tags":5,"./attrs":7,"./block":9}],22:[function(require,module,exports){
- 'use strict';
- var Node = require('./node');
- /**
- * Initialize a `Text` node with optional `line`.
- *
- * @param {String} line
- * @api public
- */
- var Text = module.exports = function Text(line) {
- this.val = line;
- };
- // Inherit from `Node`.
- Text.prototype = Object.create(Node.prototype);
- Text.prototype.constructor = Text;
- Text.prototype.type = 'Text';
- /**
- * Flag as text.
- */
- Text.prototype.isText = true;
- },{"./node":20}],23:[function(require,module,exports){
- 'use strict';
- var Lexer = require('./lexer');
- var nodes = require('./nodes');
- var utils = require('./utils');
- var filters = require('./filters');
- var path = require('path');
- var constantinople = require('constantinople');
- var parseJSExpression = require('character-parser').parseMax;
- var extname = path.extname;
- /**
- * Initialize `Parser` with the given input `str` and `filename`.
- *
- * @param {String} str
- * @param {String} filename
- * @param {Object} options
- * @api public
- */
- var Parser = exports = module.exports = function Parser(str, filename, options){
- //Strip any UTF-8 BOM off of the start of `str`, if it exists.
- this.input = str.replace(/^\uFEFF/, '');
- this.lexer = new Lexer(this.input, filename);
- this.filename = filename;
- this.blocks = {};
- this.mixins = {};
- this.options = options;
- this.contexts = [this];
- this.inMixin = 0;
- this.dependencies = [];
- this.inBlock = 0;
- };
- /**
- * Parser prototype.
- */
- Parser.prototype = {
- /**
- * Save original constructor
- */
- constructor: Parser,
- /**
- * Push `parser` onto the context stack,
- * or pop and return a `Parser`.
- */
- context: function(parser){
- if (parser) {
- this.contexts.push(parser);
- } else {
- return this.contexts.pop();
- }
- },
- /**
- * Return the next token object.
- *
- * @return {Object}
- * @api private
- */
- advance: function(){
- return this.lexer.advance();
- },
- /**
- * Single token lookahead.
- *
- * @return {Object}
- * @api private
- */
- peek: function() {
- return this.lookahead(1);
- },
- /**
- * Return lexer lineno.
- *
- * @return {Number}
- * @api private
- */
- line: function() {
- return this.lexer.lineno;
- },
- /**
- * `n` token lookahead.
- *
- * @param {Number} n
- * @return {Object}
- * @api private
- */
- lookahead: function(n){
- return this.lexer.lookahead(n);
- },
- /**
- * Parse input returning a string of js for evaluation.
- *
- * @return {String}
- * @api public
- */
- parse: function(){
- var block = new nodes.Block, parser;
- block.line = 0;
- block.filename = this.filename;
- while ('eos' != this.peek().type) {
- if ('newline' == this.peek().type) {
- this.advance();
- } else {
- var next = this.peek();
- var expr = this.parseExpr();
- expr.filename = expr.filename || this.filename;
- expr.line = next.line;
- block.push(expr);
- }
- }
- if (parser = this.extending) {
- this.context(parser);
- var ast = parser.parse();
- this.context();
- // hoist mixins
- for (var name in this.mixins)
- ast.unshift(this.mixins[name]);
- return ast;
- }
- if (!this.extending && !this.included && Object.keys(this.blocks).length){
- var blocks = [];
- utils.walkAST(block, function (node) {
- if (node.type === 'Block' && node.name) {
- blocks.push(node.name);
- }
- });
- Object.keys(this.blocks).forEach(function (name) {
- if (blocks.indexOf(name) === -1 && !this.blocks[name].isSubBlock) {
- console.warn('Warning: Unexpected block "'
- + name
- + '" '
- + ' on line '
- + this.blocks[name].line
- + ' of '
- + (this.blocks[name].filename)
- + '. This block is never used. This warning will be an error in v2.0.0');
- }
- }.bind(this));
- }
- return block;
- },
- /**
- * Expect the given type, or throw an exception.
- *
- * @param {String} type
- * @api private
- */
- expect: function(type){
- if (this.peek().type === type) {
- return this.advance();
- } else {
- throw new Error('expected "' + type + '", but got "' + this.peek().type + '"');
- }
- },
- /**
- * Accept the given `type`.
- *
- * @param {String} type
- * @api private
- */
- accept: function(type){
- if (this.peek().type === type) {
- return this.advance();
- }
- },
- /**
- * tag
- * | doctype
- * | mixin
- * | include
- * | filter
- * | comment
- * | text
- * | each
- * | code
- * | yield
- * | id
- * | class
- * | interpolation
- */
- parseExpr: function(){
- switch (this.peek().type) {
- case 'tag':
- return this.parseTag();
- case 'mixin':
- return this.parseMixin();
- case 'block':
- return this.parseBlock();
- case 'mixin-block':
- return this.parseMixinBlock();
- case 'case':
- return this.parseCase();
- case 'extends':
- return this.parseExtends();
- case 'include':
- return this.parseInclude();
- case 'doctype':
- return this.parseDoctype();
- case 'filter':
- return this.parseFilter();
- case 'comment':
- return this.parseComment();
- case 'text':
- return this.parseText();
- case 'each':
- return this.parseEach();
- case 'code':
- return this.parseCode();
- case 'blockCode':
- return this.parseBlockCode();
- case 'call':
- return this.parseCall();
- case 'interpolation':
- return this.parseInterpolation();
- case 'yield':
- this.advance();
- var block = new nodes.Block;
- block.yield = true;
- return block;
- case 'id':
- case 'class':
- var tok = this.advance();
- this.lexer.defer(this.lexer.tok('tag', 'div'));
- this.lexer.defer(tok);
- return this.parseExpr();
- default:
- throw new Error('unexpected token "' + this.peek().type + '"');
- }
- },
- /**
- * Text
- */
- parseText: function(){
- var tok = this.expect('text');
- var tokens = this.parseInlineTagsInText(tok.val);
- if (tokens.length === 1) return tokens[0];
- var node = new nodes.Block;
- for (var i = 0; i < tokens.length; i++) {
- node.push(tokens[i]);
- };
- return node;
- },
- /**
- * ':' expr
- * | block
- */
- parseBlockExpansion: function(){
- if (':' == this.peek().type) {
- this.advance();
- return new nodes.Block(this.parseExpr());
- } else {
- return this.block();
- }
- },
- /**
- * case
- */
- parseCase: function(){
- var val = this.expect('case').val;
- var node = new nodes.Case(val);
- node.line = this.line();
- var block = new nodes.Block;
- block.line = this.line();
- block.filename = this.filename;
- this.expect('indent');
- while ('outdent' != this.peek().type) {
- switch (this.peek().type) {
- case 'comment':
- case 'newline':
- this.advance();
- break;
- case 'when':
- block.push(this.parseWhen());
- break;
- case 'default':
- block.push(this.parseDefault());
- break;
- default:
- throw new Error('Unexpected token "' + this.peek().type
- + '", expected "when", "default" or "newline"');
- }
- }
- this.expect('outdent');
- node.block = block;
- return node;
- },
- /**
- * when
- */
- parseWhen: function(){
- var val = this.expect('when').val;
- if (this.peek().type !== 'newline')
- return new nodes.Case.When(val, this.parseBlockExpansion());
- else
- return new nodes.Case.When(val);
- },
- /**
- * default
- */
- parseDefault: function(){
- this.expect('default');
- return new nodes.Case.When('default', this.parseBlockExpansion());
- },
- /**
- * code
- */
- parseCode: function(afterIf){
- var tok = this.expect('code');
- var node = new nodes.Code(tok.val, tok.buffer, tok.escape);
- var block;
- node.line = this.line();
- // throw an error if an else does not have an if
- if (tok.isElse && !tok.hasIf) {
- throw new Error('Unexpected else without if');
- }
- // handle block
- block = 'indent' == this.peek().type;
- if (block) {
- node.block = this.block();
- }
- // handle missing block
- if (tok.requiresBlock && !block) {
- node.block = new nodes.Block();
- }
- // mark presense of if for future elses
- if (tok.isIf && this.peek().isElse) {
- this.peek().hasIf = true;
- } else if (tok.isIf && this.peek().type === 'newline' && this.lookahead(2).isElse) {
- this.lookahead(2).hasIf = true;
- }
- return node;
- },
- /**
- * block code
- */
- parseBlockCode: function(){
- var tok = this.expect('blockCode');
- var node;
- var body = this.peek();
- var text;
- if (body.type === 'pipeless-text') {
- this.advance();
- text = body.val.join('\n');
- } else {
- text = '';
- }
- node = new nodes.Code(text, false, false);
- return node;
- },
- /**
- * comment
- */
- parseComment: function(){
- var tok = this.expect('comment');
- var node;
- var block;
- if (block = this.parseTextBlock()) {
- node = new nodes.BlockComment(tok.val, block, tok.buffer);
- } else {
- node = new nodes.Comment(tok.val, tok.buffer);
- }
- node.line = this.line();
- return node;
- },
- /**
- * doctype
- */
- parseDoctype: function(){
- var tok = this.expect('doctype');
- var node = new nodes.Doctype(tok.val);
- node.line = this.line();
- return node;
- },
- /**
- * filter attrs? text-block
- */
- parseFilter: function(){
- var tok = this.expect('filter');
- var attrs = this.accept('attrs');
- var block;
- block = this.parseTextBlock() || new nodes.Block();
- var options = {};
- if (attrs) {
- attrs.attrs.forEach(function (attribute) {
- options[attribute.name] = constantinople.toConstant(attribute.val);
- });
- }
- var node = new nodes.Filter(tok.val, block, options);
- node.line = this.line();
- return node;
- },
- /**
- * each block
- */
- parseEach: function(){
- var tok = this.expect('each');
- var node = new nodes.Each(tok.code, tok.val, tok.key);
- node.line = this.line();
- node.block = this.block();
- if (this.peek().type == 'code' && this.peek().val == 'else') {
- this.advance();
- node.alternative = this.block();
- }
- return node;
- },
- /**
- * Resolves a path relative to the template for use in
- * includes and extends
- *
- * @param {String} path
- * @param {String} purpose Used in error messages.
- * @return {String}
- * @api private
- */
- resolvePath: function (path, purpose) {
- var p = require('path');
- var dirname = p.dirname;
- var basename = p.basename;
- var join = p.join;
- if (path[0] !== '/' && !this.filename)
- throw new Error('the "filename" option is required to use "' + purpose + '" with "relative" paths');
- if (path[0] === '/' && !this.options.basedir)
- throw new Error('the "basedir" option is required to use "' + purpose + '" with "absolute" paths');
- path = join(path[0] === '/' ? this.options.basedir : dirname(this.filename), path);
- if (basename(path).indexOf('.') === -1) path += '.jade';
- return path;
- },
- /**
- * 'extends' name
- */
- parseExtends: function(){
- var fs = require('fs');
- var path = this.resolvePath(this.expect('extends').val.trim(), 'extends');
- if ('.jade' != path.substr(-5)) path += '.jade';
- this.dependencies.push(path);
- var str = fs.readFileSync(path, 'utf8');
- var parser = new this.constructor(str, path, this.options);
- parser.dependencies = this.dependencies;
- parser.blocks = this.blocks;
- parser.included = this.included;
- parser.contexts = this.contexts;
- this.extending = parser;
- // TODO: null node
- return new nodes.Literal('');
- },
- /**
- * 'block' name block
- */
- parseBlock: function(){
- var block = this.expect('block');
- var mode = block.mode;
- var name = block.val.trim();
- var line = block.line;
- this.inBlock++;
- block = 'indent' == this.peek().type
- ? this.block()
- : new nodes.Block(new nodes.Literal(''));
- this.inBlock--;
- block.name = name;
- block.line = line;
- var prev = this.blocks[name] || {prepended: [], appended: []}
- if (prev.mode === 'replace') return this.blocks[name] = prev;
- var allNodes = prev.prepended.concat(block.nodes).concat(prev.appended);
- switch (mode) {
- case 'append':
- prev.appended = prev.parser === this ?
- prev.appended.concat(block.nodes) :
- block.nodes.concat(prev.appended);
- break;
- case 'prepend':
- prev.prepended = prev.parser === this ?
- block.nodes.concat(prev.prepended) :
- prev.prepended.concat(block.nodes);
- break;
- }
- block.nodes = allNodes;
- block.appended = prev.appended;
- block.prepended = prev.prepended;
- block.mode = mode;
- block.parser = this;
- block.isSubBlock = this.inBlock > 0;
- return this.blocks[name] = block;
- },
- parseMixinBlock: function () {
- var block = this.expect('mixin-block');
- if (!this.inMixin) {
- throw new Error('Anonymous blocks are not allowed unless they are part of a mixin.');
- }
- return new nodes.MixinBlock();
- },
- /**
- * include block?
- */
- parseInclude: function(){
- var fs = require('fs');
- var tok = this.expect('include');
- var path = this.resolvePath(tok.val.trim(), 'include');
- this.dependencies.push(path);
- // has-filter
- if (tok.filter) {
- var str = fs.readFileSync(path, 'utf8').replace(/\r/g, '');
- var options = {filename: path};
- if (tok.attrs) {
- tok.attrs.attrs.forEach(function (attribute) {
- options[attribute.name] = constantinople.toConstant(attribute.val);
- });
- }
- str = filters(tok.filter, str, options);
- return new nodes.Literal(str);
- }
- // non-jade
- if ('.jade' != path.substr(-5)) {
- var str = fs.readFileSync(path, 'utf8').replace(/\r/g, '');
- return new nodes.Literal(str);
- }
- var str = fs.readFileSync(path, 'utf8');
- var parser = new this.constructor(str, path, this.options);
- parser.dependencies = this.dependencies;
- parser.blocks = utils.merge({}, this.blocks);
- parser.included = true;
- parser.mixins = this.mixins;
- this.context(parser);
- var ast = parser.parse();
- this.context();
- ast.filename = path;
- if ('indent' == this.peek().type) {
- ast.includeBlock().push(this.block());
- }
- return ast;
- },
- /**
- * call ident block
- */
- parseCall: function(){
- var tok = this.expect('call');
- var name = tok.val;
- var args = tok.args;
- var mixin = new nodes.Mixin(name, args, new nodes.Block, true);
- this.tag(mixin);
- if (mixin.code) {
- mixin.block.push(mixin.code);
- mixin.code = null;
- }
- if (mixin.block.isEmpty()) mixin.block = null;
- return mixin;
- },
- /**
- * mixin block
- */
- parseMixin: function(){
- var tok = this.expect('mixin');
- var name = tok.val;
- var args = tok.args;
- var mixin;
- // definition
- if ('indent' == this.peek().type) {
- this.inMixin++;
- mixin = new nodes.Mixin(name, args, this.block(), false);
- this.mixins[name] = mixin;
- this.inMixin--;
- return mixin;
- // call
- } else {
- return new nodes.Mixin(name, args, null, true);
- }
- },
- parseInlineTagsInText: function (str) {
- var line = this.line();
- var match = /(\\)?#\[((?:.|\n)*)$/.exec(str);
- if (match) {
- if (match[1]) { // escape
- var text = new nodes.Text(str.substr(0, match.index) + '#[');
- text.line = line;
- var rest = this.parseInlineTagsInText(match[2]);
- if (rest[0].type === 'Text') {
- text.val += rest[0].val;
- rest.shift();
- }
- return [text].concat(rest);
- } else {
- var text = new nodes.Text(str.substr(0, match.index));
- text.line = line;
- var buffer = [text];
- var rest = match[2];
- var range = parseJSExpression(rest);
- var inner = new Parser(range.src, this.filename, this.options);
- buffer.push(inner.parse());
- return buffer.concat(this.parseInlineTagsInText(rest.substr(range.end + 1)));
- }
- } else {
- var text = new nodes.Text(str);
- text.line = line;
- return [text];
- }
- },
- /**
- * indent (text | newline)* outdent
- */
- parseTextBlock: function(){
- var block = new nodes.Block;
- block.line = this.line();
- var body = this.peek();
- if (body.type !== 'pipeless-text') return;
- this.advance();
- block.nodes = body.val.reduce(function (accumulator, text) {
- return accumulator.concat(this.parseInlineTagsInText(text));
- }.bind(this), []);
- return block;
- },
- /**
- * indent expr* outdent
- */
- block: function(){
- var block = new nodes.Block;
- block.line = this.line();
- block.filename = this.filename;
- this.expect('indent');
- while ('outdent' != this.peek().type) {
- if ('newline' == this.peek().type) {
- this.advance();
- } else {
- var expr = this.parseExpr();
- expr.filename = this.filename;
- block.push(expr);
- }
- }
- this.expect('outdent');
- return block;
- },
- /**
- * interpolation (attrs | class | id)* (text | code | ':')? newline* block?
- */
- parseInterpolation: function(){
- var tok = this.advance();
- var tag = new nodes.Tag(tok.val);
- tag.buffer = true;
- return this.tag(tag);
- },
- /**
- * tag (attrs | class | id)* (text | code | ':')? newline* block?
- */
- parseTag: function(){
- var tok = this.advance();
- var tag = new nodes.Tag(tok.val);
- tag.selfClosing = tok.selfClosing;
- return this.tag(tag);
- },
- /**
- * Parse tag.
- */
- tag: function(tag){
- tag.line = this.line();
- var seenAttrs = false;
- // (attrs | class | id)*
- out:
- while (true) {
- switch (this.peek().type) {
- case 'id':
- case 'class':
- var tok = this.advance();
- tag.setAttribute(tok.type, "'" + tok.val + "'");
- continue;
- case 'attrs':
- if (seenAttrs) {
- console.warn(this.filename + ', line ' + this.peek().line + ':\nYou should not have jade tags with multiple attributes.');
- }
- seenAttrs = true;
- var tok = this.advance();
- var attrs = tok.attrs;
- if (tok.selfClosing) tag.selfClosing = true;
- for (var i = 0; i < attrs.length; i++) {
- tag.setAttribute(attrs[i].name, attrs[i].val, attrs[i].escaped);
- }
- continue;
- case '&attributes':
- var tok = this.advance();
- tag.addAttributes(tok.val);
- break;
- default:
- break out;
- }
- }
- // check immediate '.'
- if ('dot' == this.peek().type) {
- tag.textOnly = true;
- this.advance();
- }
- // (text | code | ':')?
- switch (this.peek().type) {
- case 'text':
- tag.block.push(this.parseText());
- break;
- case 'code':
- tag.code = this.parseCode();
- break;
- case ':':
- this.advance();
- tag.block = new nodes.Block;
- tag.block.push(this.parseExpr());
- break;
- case 'newline':
- case 'indent':
- case 'outdent':
- case 'eos':
- case 'pipeless-text':
- break;
- default:
- throw new Error('Unexpected token `' + this.peek().type + '` expected `text`, `code`, `:`, `newline` or `eos`')
- }
- // newline*
- while ('newline' == this.peek().type) this.advance();
- // block?
- if (tag.textOnly) {
- tag.block = this.parseTextBlock() || new nodes.Block();
- } else if ('indent' == this.peek().type) {
- var block = this.block();
- for (var i = 0, len = block.nodes.length; i < len; ++i) {
- tag.block.push(block.nodes[i]);
- }
- }
- return tag;
- }
- };
- },{"./filters":4,"./lexer":6,"./nodes":16,"./utils":25,"character-parser":29,"constantinople":30,"fs":26,"path":27}],24:[function(require,module,exports){
- 'use strict';
- /**
- * Merge two attribute objects giving precedence
- * to values in object `b`. Classes are special-cased
- * allowing for arrays and merging/joining appropriately
- * resulting in a string.
- *
- * @param {Object} a
- * @param {Object} b
- * @return {Object} a
- * @api private
- */
- exports.merge = function merge(a, b) {
- if (arguments.length === 1) {
- var attrs = a[0];
- for (var i = 1; i < a.length; i++) {
- attrs = merge(attrs, a[i]);
- }
- return attrs;
- }
- var ac = a['class'];
- var bc = b['class'];
- if (ac || bc) {
- ac = ac || [];
- bc = bc || [];
- if (!Array.isArray(ac)) ac = [ac];
- if (!Array.isArray(bc)) bc = [bc];
- a['class'] = ac.concat(bc).filter(nulls);
- }
- for (var key in b) {
- if (key != 'class') {
- a[key] = b[key];
- }
- }
- return a;
- };
- /**
- * Filter null `val`s.
- *
- * @param {*} val
- * @return {Boolean}
- * @api private
- */
- function nulls(val) {
- return val != null && val !== '';
- }
- /**
- * join array as classes.
- *
- * @param {*} val
- * @return {String}
- */
- exports.joinClasses = joinClasses;
- function joinClasses(val) {
- return (Array.isArray(val) ? val.map(joinClasses) :
- (val && typeof val === 'object') ? Object.keys(val).filter(function (key) { return val[key]; }) :
- [val]).filter(nulls).join(' ');
- }
- /**
- * Render the given classes.
- *
- * @param {Array} classes
- * @param {Array.<Boolean>} escaped
- * @return {String}
- */
- exports.cls = function cls(classes, escaped) {
- var buf = [];
- for (var i = 0; i < classes.length; i++) {
- if (escaped && escaped[i]) {
- buf.push(exports.escape(joinClasses([classes[i]])));
- } else {
- buf.push(joinClasses(classes[i]));
- }
- }
- var text = joinClasses(buf);
- if (text.length) {
- return ' class="' + text + '"';
- } else {
- return '';
- }
- };
- exports.style = function (val) {
- if (val && typeof val === 'object') {
- return Object.keys(val).map(function (style) {
- return style + ':' + val[style];
- }).join(';');
- } else {
- return val;
- }
- };
- /**
- * Render the given attribute.
- *
- * @param {String} key
- * @param {String} val
- * @param {Boolean} escaped
- * @param {Boolean} terse
- * @return {String}
- */
- exports.attr = function attr(key, val, escaped, terse) {
- if (key === 'style') {
- val = exports.style(val);
- }
- if ('boolean' == typeof val || null == val) {
- if (val) {
- return ' ' + (terse ? key : key + '="' + key + '"');
- } else {
- return '';
- }
- } else if (0 == key.indexOf('data') && 'string' != typeof val) {
- if (JSON.stringify(val).indexOf('&') !== -1) {
- console.warn('Since Jade 2.0.0, ampersands (`&`) in data attributes ' +
- 'will be escaped to `&`');
- };
- if (val && typeof val.toISOString === 'function') {
- console.warn('Jade will eliminate the double quotes around dates in ' +
- 'ISO form after 2.0.0');
- }
- return ' ' + key + "='" + JSON.stringify(val).replace(/'/g, ''') + "'";
- } else if (escaped) {
- if (val && typeof val.toISOString === 'function') {
- console.warn('Jade will stringify dates in ISO form after 2.0.0');
- }
- return ' ' + key + '="' + exports.escape(val) + '"';
- } else {
- if (val && typeof val.toISOString === 'function') {
- console.warn('Jade will stringify dates in ISO form after 2.0.0');
- }
- return ' ' + key + '="' + val + '"';
- }
- };
- /**
- * Render the given attributes object.
- *
- * @param {Object} obj
- * @param {Object} escaped
- * @return {String}
- */
- exports.attrs = function attrs(obj, terse){
- var buf = [];
- var keys = Object.keys(obj);
- if (keys.length) {
- for (var i = 0; i < keys.length; ++i) {
- var key = keys[i]
- , val = obj[key];
- if ('class' == key) {
- if (val = joinClasses(val)) {
- buf.push(' ' + key + '="' + val + '"');
- }
- } else {
- buf.push(exports.attr(key, val, false, terse));
- }
- }
- }
- return buf.join('');
- };
- /**
- * Escape the given string of `html`.
- *
- * @param {String} html
- * @return {String}
- * @api private
- */
- var jade_encode_html_rules = {
- '&': '&',
- '<': '<',
- '>': '>',
- '"': '"'
- };
- var jade_match_html = /[&<>"]/g;
- function jade_encode_char(c) {
- return jade_encode_html_rules[c] || c;
- }
- exports.escape = jade_escape;
- function jade_escape(html){
- var result = String(html).replace(jade_match_html, jade_encode_char);
- if (result === '' + html) return html;
- else return result;
- };
- /**
- * Re-throw the given `err` in context to the
- * the jade in `filename` at the given `lineno`.
- *
- * @param {Error} err
- * @param {String} filename
- * @param {String} lineno
- * @api private
- */
- exports.rethrow = function rethrow(err, filename, lineno, str){
- if (!(err instanceof Error)) throw err;
- if ((typeof window != 'undefined' || !filename) && !str) {
- err.message += ' on line ' + lineno;
- throw err;
- }
- try {
- str = str || require('fs').readFileSync(filename, 'utf8')
- } catch (ex) {
- rethrow(err, null, lineno)
- }
- var context = 3
- , lines = str.split('\n')
- , start = Math.max(lineno - context, 0)
- , end = Math.min(lines.length, lineno + context);
- // Error context
- var context = lines.slice(start, end).map(function(line, i){
- var curr = i + start + 1;
- return (curr == lineno ? ' > ' : ' ')
- + curr
- + '| '
- + line;
- }).join('\n');
- // Alter exception message
- err.path = filename;
- err.message = (filename || 'Jade') + ':' + lineno
- + '\n' + context + '\n\n' + err.message;
- throw err;
- };
- exports.DebugItem = function DebugItem(lineno, filename) {
- this.lineno = lineno;
- this.filename = filename;
- }
- },{"fs":26}],25:[function(require,module,exports){
- 'use strict';
- /**
- * Merge `b` into `a`.
- *
- * @param {Object} a
- * @param {Object} b
- * @return {Object}
- * @api public
- */
- exports.merge = function(a, b) {
- for (var key in b) a[key] = b[key];
- return a;
- };
- exports.stringify = function(str) {
- return JSON.stringify(str)
- .replace(/\u2028/g, '\\u2028')
- .replace(/\u2029/g, '\\u2029');
- };
- exports.walkAST = function walkAST(ast, before, after) {
- before && before(ast);
- switch (ast.type) {
- case 'Block':
- ast.nodes.forEach(function (node) {
- walkAST(node, before, after);
- });
- break;
- case 'Case':
- case 'Each':
- case 'Mixin':
- case 'Tag':
- case 'When':
- case 'Code':
- ast.block && walkAST(ast.block, before, after);
- break;
- case 'Attrs':
- case 'BlockComment':
- case 'Comment':
- case 'Doctype':
- case 'Filter':
- case 'Literal':
- case 'MixinBlock':
- case 'Text':
- break;
- default:
- throw new Error('Unexpected node type ' + ast.type);
- break;
- }
- after && after(ast);
- };
- },{}],26:[function(require,module,exports){
- },{}],27:[function(require,module,exports){
- (function (process){
- // Copyright Joyent, Inc. and other Node contributors.
- //
- // Permission is hereby granted, free of charge, to any person obtaining a
- // copy of this software and associated documentation files (the
- // "Software"), to deal in the Software without restriction, including
- // without limitation the rights to use, copy, modify, merge, publish,
- // distribute, sublicense, and/or sell copies of the Software, and to permit
- // persons to whom the Software is furnished to do so, subject to the
- // following conditions:
- //
- // The above copyright notice and this permission notice shall be included
- // in all copies or substantial portions of the Software.
- //
- // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
- // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
- // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
- // USE OR OTHER DEALINGS IN THE SOFTWARE.
- // resolves . and .. elements in a path array with directory names there
- // must be no slashes, empty elements, or device names (c:\) in the array
- // (so also no leading and trailing slashes - it does not distinguish
- // relative and absolute paths)
- function normalizeArray(parts, allowAboveRoot) {
- // if the path tries to go above the root, `up` ends up > 0
- var up = 0;
- for (var i = parts.length - 1; i >= 0; i--) {
- var last = parts[i];
- if (last === '.') {
- parts.splice(i, 1);
- } else if (last === '..') {
- parts.splice(i, 1);
- up++;
- } else if (up) {
- parts.splice(i, 1);
- up--;
- }
- }
- // if the path is allowed to go above the root, restore leading ..s
- if (allowAboveRoot) {
- for (; up--; up) {
- parts.unshift('..');
- }
- }
- return parts;
- }
- // Split a filename into [root, dir, basename, ext], unix version
- // 'root' is just a slash, or nothing.
- var splitPathRe =
- /^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;
- var splitPath = function(filename) {
- return splitPathRe.exec(filename).slice(1);
- };
- // path.resolve([from ...], to)
- // posix version
- exports.resolve = function() {
- var resolvedPath = '',
- resolvedAbsolute = false;
- for (var i = arguments.length - 1; i >= -1 && !resolvedAbsolute; i--) {
- var path = (i >= 0) ? arguments[i] : process.cwd();
- // Skip empty and invalid entries
- if (typeof path !== 'string') {
- throw new TypeError('Arguments to path.resolve must be strings');
- } else if (!path) {
- continue;
- }
- resolvedPath = path + '/' + resolvedPath;
- resolvedAbsolute = path.charAt(0) === '/';
- }
- // At this point the path should be resolved to a full absolute path, but
- // handle relative paths to be safe (might happen when process.cwd() fails)
- // Normalize the path
- resolvedPath = normalizeArray(filter(resolvedPath.split('/'), function(p) {
- return !!p;
- }), !resolvedAbsolute).join('/');
- return ((resolvedAbsolute ? '/' : '') + resolvedPath) || '.';
- };
- // path.normalize(path)
- // posix version
- exports.normalize = function(path) {
- var isAbsolute = exports.isAbsolute(path),
- trailingSlash = substr(path, -1) === '/';
- // Normalize the path
- path = normalizeArray(filter(path.split('/'), function(p) {
- return !!p;
- }), !isAbsolute).join('/');
- if (!path && !isAbsolute) {
- path = '.';
- }
- if (path && trailingSlash) {
- path += '/';
- }
- return (isAbsolute ? '/' : '') + path;
- };
- // posix version
- exports.isAbsolute = function(path) {
- return path.charAt(0) === '/';
- };
- // posix version
- exports.join = function() {
- var paths = Array.prototype.slice.call(arguments, 0);
- return exports.normalize(filter(paths, function(p, index) {
- if (typeof p !== 'string') {
- throw new TypeError('Arguments to path.join must be strings');
- }
- return p;
- }).join('/'));
- };
- // path.relative(from, to)
- // posix version
- exports.relative = function(from, to) {
- from = exports.resolve(from).substr(1);
- to = exports.resolve(to).substr(1);
- function trim(arr) {
- var start = 0;
- for (; start < arr.length; start++) {
- if (arr[start] !== '') break;
- }
- var end = arr.length - 1;
- for (; end >= 0; end--) {
- if (arr[end] !== '') break;
- }
- if (start > end) return [];
- return arr.slice(start, end - start + 1);
- }
- var fromParts = trim(from.split('/'));
- var toParts = trim(to.split('/'));
- var length = Math.min(fromParts.length, toParts.length);
- var samePartsLength = length;
- for (var i = 0; i < length; i++) {
- if (fromParts[i] !== toParts[i]) {
- samePartsLength = i;
- break;
- }
- }
- var outputParts = [];
- for (var i = samePartsLength; i < fromParts.length; i++) {
- outputParts.push('..');
- }
- outputParts = outputParts.concat(toParts.slice(samePartsLength));
- return outputParts.join('/');
- };
- exports.sep = '/';
- exports.delimiter = ':';
- exports.dirname = function(path) {
- var result = splitPath(path),
- root = result[0],
- dir = result[1];
- if (!root && !dir) {
- // No dirname whatsoever
- return '.';
- }
- if (dir) {
- // It has a dirname, strip trailing slash
- dir = dir.substr(0, dir.length - 1);
- }
- return root + dir;
- };
- exports.basename = function(path, ext) {
- var f = splitPath(path)[2];
- // TODO: make this comparison case-insensitive on windows?
- if (ext && f.substr(-1 * ext.length) === ext) {
- f = f.substr(0, f.length - ext.length);
- }
- return f;
- };
- exports.extname = function(path) {
- return splitPath(path)[3];
- };
- function filter (xs, f) {
- if (xs.filter) return xs.filter(f);
- var res = [];
- for (var i = 0; i < xs.length; i++) {
- if (f(xs[i], i, xs)) res.push(xs[i]);
- }
- return res;
- }
- // String.prototype.substr - negative index don't work in IE8
- var substr = 'ab'.substr(-1) === 'b'
- ? function (str, start, len) { return str.substr(start, len) }
- : function (str, start, len) {
- if (start < 0) start = str.length + start;
- return str.substr(start, len);
- }
- ;
- }).call(this,require('_process'))
- },{"_process":28}],28:[function(require,module,exports){
- // shim for using process in browser
- var process = module.exports = {};
- var queue = [];
- var draining = false;
- var currentQueue;
- var queueIndex = -1;
- function cleanUpNextTick() {
- draining = false;
- if (currentQueue.length) {
- queue = currentQueue.concat(queue);
- } else {
- queueIndex = -1;
- }
- if (queue.length) {
- drainQueue();
- }
- }
- function drainQueue() {
- if (draining) {
- return;
- }
- var timeout = setTimeout(cleanUpNextTick);
- draining = true;
- var len = queue.length;
- while(len) {
- currentQueue = queue;
- queue = [];
- while (++queueIndex < len) {
- currentQueue[queueIndex].run();
- }
- queueIndex = -1;
- len = queue.length;
- }
- currentQueue = null;
- draining = false;
- clearTimeout(timeout);
- }
- process.nextTick = function (fun) {
- var args = new Array(arguments.length - 1);
- if (arguments.length > 1) {
- for (var i = 1; i < arguments.length; i++) {
- args[i - 1] = arguments[i];
- }
- }
- queue.push(new Item(fun, args));
- if (queue.length === 1 && !draining) {
- setTimeout(drainQueue, 0);
- }
- };
- // v8 likes predictible objects
- function Item(fun, array) {
- this.fun = fun;
- this.array = array;
- }
- Item.prototype.run = function () {
- this.fun.apply(null, this.array);
- };
- process.title = 'browser';
- process.browser = true;
- process.env = {};
- process.argv = [];
- process.version = ''; // empty string to avoid regexp issues
- process.versions = {};
- function noop() {}
- process.on = noop;
- process.addListener = noop;
- process.once = noop;
- process.off = noop;
- process.removeListener = noop;
- process.removeAllListeners = noop;
- process.emit = noop;
- process.binding = function (name) {
- throw new Error('process.binding is not supported');
- };
- // TODO(shtylman)
- process.cwd = function () { return '/' };
- process.chdir = function (dir) {
- throw new Error('process.chdir is not supported');
- };
- process.umask = function() { return 0; };
- },{}],29:[function(require,module,exports){
- exports = (module.exports = parse);
- exports.parse = parse;
- function parse(src, state, options) {
- options = options || {};
- state = state || exports.defaultState();
- var start = options.start || 0;
- var end = options.end || src.length;
- var index = start;
- while (index < end) {
- if (state.roundDepth < 0 || state.curlyDepth < 0 || state.squareDepth < 0) {
- throw new SyntaxError('Mismatched Bracket: ' + src[index - 1]);
- }
- exports.parseChar(src[index++], state);
- }
- return state;
- }
- exports.parseMax = parseMax;
- function parseMax(src, options) {
- options = options || {};
- var start = options.start || 0;
- var index = start;
- var state = exports.defaultState();
- while (state.roundDepth >= 0 && state.curlyDepth >= 0 && state.squareDepth >= 0) {
- if (index >= src.length) {
- throw new Error('The end of the string was reached with no closing bracket found.');
- }
- exports.parseChar(src[index++], state);
- }
- var end = index - 1;
- return {
- start: start,
- end: end,
- src: src.substring(start, end)
- };
- }
- exports.parseUntil = parseUntil;
- function parseUntil(src, delimiter, options) {
- options = options || {};
- var includeLineComment = options.includeLineComment || false;
- var start = options.start || 0;
- var index = start;
- var state = exports.defaultState();
- while (state.isString() || state.regexp || state.blockComment ||
- (!includeLineComment && state.lineComment) || !startsWith(src, delimiter, index)) {
- exports.parseChar(src[index++], state);
- }
- var end = index;
- return {
- start: start,
- end: end,
- src: src.substring(start, end)
- };
- }
- exports.parseChar = parseChar;
- function parseChar(character, state) {
- if (character.length !== 1) throw new Error('Character must be a string of length 1');
- state = state || exports.defaultState();
- state.src = state.src || '';
- state.src += character;
- var wasComment = state.blockComment || state.lineComment;
- var lastChar = state.history ? state.history[0] : '';
- if (state.regexpStart) {
- if (character === '/' || character == '*') {
- state.regexp = false;
- }
- state.regexpStart = false;
- }
- if (state.lineComment) {
- if (character === '\n') {
- state.lineComment = false;
- }
- } else if (state.blockComment) {
- if (state.lastChar === '*' && character === '/') {
- state.blockComment = false;
- }
- } else if (state.singleQuote) {
- if (character === '\'' && !state.escaped) {
- state.singleQuote = false;
- } else if (character === '\\' && !state.escaped) {
- state.escaped = true;
- } else {
- state.escaped = false;
- }
- } else if (state.doubleQuote) {
- if (character === '"' && !state.escaped) {
- state.doubleQuote = false;
- } else if (character === '\\' && !state.escaped) {
- state.escaped = true;
- } else {
- state.escaped = false;
- }
- } else if (state.regexp) {
- if (character === '/' && !state.escaped) {
- state.regexp = false;
- } else if (character === '\\' && !state.escaped) {
- state.escaped = true;
- } else {
- state.escaped = false;
- }
- } else if (lastChar === '/' && character === '/') {
- state.history = state.history.substr(1);
- state.lineComment = true;
- } else if (lastChar === '/' && character === '*') {
- state.history = state.history.substr(1);
- state.blockComment = true;
- } else if (character === '/' && isRegexp(state.history)) {
- state.regexp = true;
- state.regexpStart = true;
- } else if (character === '\'') {
- state.singleQuote = true;
- } else if (character === '"') {
- state.doubleQuote = true;
- } else if (character === '(') {
- state.roundDepth++;
- } else if (character === ')') {
- state.roundDepth--;
- } else if (character === '{') {
- state.curlyDepth++;
- } else if (character === '}') {
- state.curlyDepth--;
- } else if (character === '[') {
- state.squareDepth++;
- } else if (character === ']') {
- state.squareDepth--;
- }
- if (!state.blockComment && !state.lineComment && !wasComment) state.history = character + state.history;
- state.lastChar = character; // store last character for ending block comments
- return state;
- }
- exports.defaultState = function () { return new State() };
- function State() {
- this.lineComment = false;
- this.blockComment = false;
- this.singleQuote = false;
- this.doubleQuote = false;
- this.regexp = false;
- this.escaped = false;
- this.roundDepth = 0;
- this.curlyDepth = 0;
- this.squareDepth = 0;
- this.history = ''
- this.lastChar = ''
- }
- State.prototype.isString = function () {
- return this.singleQuote || this.doubleQuote;
- }
- State.prototype.isComment = function () {
- return this.lineComment || this.blockComment;
- }
- State.prototype.isNesting = function () {
- return this.isString() || this.isComment() || this.regexp || this.roundDepth > 0 || this.curlyDepth > 0 || this.squareDepth > 0
- }
- function startsWith(str, start, i) {
- return str.substr(i || 0, start.length) === start;
- }
- exports.isPunctuator = isPunctuator
- function isPunctuator(c) {
- if (!c) return true; // the start of a string is a punctuator
- var code = c.charCodeAt(0)
- switch (code) {
- case 46: // . dot
- case 40: // ( open bracket
- case 41: // ) close bracket
- case 59: // ; semicolon
- case 44: // , comma
- case 123: // { open curly brace
- case 125: // } close curly brace
- case 91: // [
- case 93: // ]
- case 58: // :
- case 63: // ?
- case 126: // ~
- case 37: // %
- case 38: // &
- case 42: // *:
- case 43: // +
- case 45: // -
- case 47: // /
- case 60: // <
- case 62: // >
- case 94: // ^
- case 124: // |
- case 33: // !
- case 61: // =
- return true;
- default:
- return false;
- }
- }
- exports.isKeyword = isKeyword
- function isKeyword(id) {
- return (id === 'if') || (id === 'in') || (id === 'do') || (id === 'var') || (id === 'for') || (id === 'new') ||
- (id === 'try') || (id === 'let') || (id === 'this') || (id === 'else') || (id === 'case') ||
- (id === 'void') || (id === 'with') || (id === 'enum') || (id === 'while') || (id === 'break') || (id === 'catch') ||
- (id === 'throw') || (id === 'const') || (id === 'yield') || (id === 'class') || (id === 'super') ||
- (id === 'return') || (id === 'typeof') || (id === 'delete') || (id === 'switch') || (id === 'export') ||
- (id === 'import') || (id === 'default') || (id === 'finally') || (id === 'extends') || (id === 'function') ||
- (id === 'continue') || (id === 'debugger') || (id === 'package') || (id === 'private') || (id === 'interface') ||
- (id === 'instanceof') || (id === 'implements') || (id === 'protected') || (id === 'public') || (id === 'static') ||
- (id === 'yield') || (id === 'let');
- }
- function isRegexp(history) {
- //could be start of regexp or divide sign
- history = history.replace(/^\s*/, '');
- //unless its an `if`, `while`, `for` or `with` it's a divide, so we assume it's a divide
- if (history[0] === ')') return false;
- //unless it's a function expression, it's a regexp, so we assume it's a regexp
- if (history[0] === '}') return true;
- //any punctuation means it's a regexp
- if (isPunctuator(history[0])) return true;
- //if the last thing was a keyword then it must be a regexp (e.g. `typeof /foo/`)
- if (/^\w+\b/.test(history) && isKeyword(/^\w+\b/.exec(history)[0].split('').reverse().join(''))) return true;
- return false;
- }
- },{}],30:[function(require,module,exports){
- 'use strict'
- var detect = require('acorn-globals');
- var lastSRC = '(null)';
- var lastRes = true;
- var lastConstants = undefined;
- module.exports = isConstant;
- function isConstant(src, constants) {
- src = '(' + src + ')';
- if (lastSRC === src && lastConstants === constants) return lastRes;
- lastSRC = src;
- lastConstants = constants;
- try {
- isExpression(src);
- return lastRes = (detect(src).filter(function (key) {
- return !constants || !(key.name in constants);
- }).length === 0);
- } catch (ex) {
- return lastRes = false;
- }
- }
- isConstant.isConstant = isConstant;
- isConstant.toConstant = toConstant;
- function toConstant(src, constants) {
- if (!isConstant(src, constants)) throw new Error(JSON.stringify(src) + ' is not constant.');
- return Function(Object.keys(constants || {}).join(','), 'return (' + src + ')').apply(null, Object.keys(constants || {}).map(function (key) {
- return constants[key];
- }));
- }
- function isExpression(src) {
- try {
- eval('throw "STOP"; (function () { return (' + src + '); })()');
- return false;
- }
- catch (err) {
- return err === 'STOP';
- }
- }
- },{"acorn-globals":31}],31:[function(require,module,exports){
- 'use strict';
- var acorn = require('acorn');
- var walk = require('acorn/dist/walk');
- // polyfill for https://github.com/marijnh/acorn/pull/231
- walk.base.ExportNamedDeclaration = walk.base.ExportDefaultDeclaration = function (node, st, c) {
- return c(node.declaration, st);
- };
- walk.base.ImportDefaultSpecifier = walk.base.ImportNamespaceSpecifier = function () {};
- function isScope(node) {
- return node.type === 'FunctionExpression' || node.type === 'FunctionDeclaration' || node.type === 'Program';
- }
- function isBlockScope(node) {
- return node.type === 'BlockStatement' || isScope(node);
- }
- function declaresArguments(node) {
- return node.type === 'FunctionExpression' || node.type === 'FunctionDeclaration' || node.type === 'ArrowFunction';
- }
- function declaresThis(node) {
- return node.type === 'FunctionExpression' || node.type === 'FunctionDeclaration';
- }
- function reallyParse(source) {
- try {
- return acorn.parse(source, {
- ecmaVersion: 6,
- allowReturnOutsideFunction: true,
- sourceType: 'module'
- });
- } catch (ex) {
- if (ex.name !== 'SyntaxError') {
- throw ex;
- }
- try {
- return acorn.parse(source, {
- ecmaVersion: 6,
- allowReturnOutsideFunction: true
- });
- } catch (ex) {
- if (ex.name !== 'SyntaxError') {
- throw ex;
- }
- return acorn.parse(source, {
- ecmaVersion: 5,
- allowReturnOutsideFunction: true
- });
- }
- }
- }
- module.exports = findGlobals;
- module.exports.parse = reallyParse;
- function findGlobals(source) {
- var globals = [];
- var ast = typeof source === 'string' ?
- ast = reallyParse(source) :
- source;
- if (!(ast && typeof ast === 'object' && ast.type === 'Program')) {
- throw new TypeError('Source must be either a string of JavaScript or an acorn AST');
- }
- var declareFunction = function (node) {
- var fn = node;
- fn.locals = fn.locals || {};
- node.params.forEach(function (node) {
- fn.locals[node.name] = true;
- });
- if (node.id) {
- fn.locals[node.id.name] = true;
- }
- }
- walk.ancestor(ast, {
- 'VariableDeclaration': function (node, parents) {
- var parent = null;
- for (var i = parents.length - 1; i >= 0 && parent === null; i--) {
- if (node.kind === 'var' ? isScope(parents[i]) : isBlockScope(parents[i])) {
- parent = parents[i];
- }
- }
- parent.locals = parent.locals || {};
- node.declarations.forEach(function (declaration) {
- parent.locals[declaration.id.name] = true;
- });
- },
- 'FunctionDeclaration': function (node, parents) {
- var parent = null;
- for (var i = parents.length - 2; i >= 0 && parent === null; i--) {
- if (isScope(parents[i])) {
- parent = parents[i];
- }
- }
- parent.locals = parent.locals || {};
- parent.locals[node.id.name] = true;
- declareFunction(node);
- },
- 'Function': declareFunction,
- 'TryStatement': function (node) {
- node.handler.body.locals = node.handler.body.locals || {};
- node.handler.body.locals[node.handler.param.name] = true;
- },
- 'ImportDefaultSpecifier': function (node) {
- if (node.local.type === 'Identifier') {
- ast.locals = ast.locals || {};
- ast.locals[node.local.name] = true;
- }
- },
- 'ImportSpecifier': function (node) {
- var id = node.local ? node.local : node.imported;
- if (id.type === 'Identifier') {
- ast.locals = ast.locals || {};
- ast.locals[id.name] = true;
- }
- },
- 'ImportNamespaceSpecifier': function (node) {
- if (node.local.type === 'Identifier') {
- ast.locals = ast.locals || {};
- ast.locals[node.local.name] = true;
- }
- }
- });
- walk.ancestor(ast, {
- 'Identifier': function (node, parents) {
- var name = node.name;
- if (name === 'undefined') return;
- for (var i = 0; i < parents.length; i++) {
- if (name === 'arguments' && declaresArguments(parents[i])) {
- return;
- }
- if (parents[i].locals && name in parents[i].locals) {
- return;
- }
- }
- node.parents = parents;
- globals.push(node);
- },
- ThisExpression: function (node, parents) {
- for (var i = 0; i < parents.length; i++) {
- if (declaresThis(parents[i])) {
- return;
- }
- }
- node.parents = parents;
- globals.push(node);
- }
- });
- var groupedGlobals = {};
- globals.forEach(function (node) {
- groupedGlobals[node.name] = (groupedGlobals[node.name] || []);
- groupedGlobals[node.name].push(node);
- });
- return Object.keys(groupedGlobals).sort().map(function (name) {
- return {name: name, nodes: groupedGlobals[name]};
- });
- }
- },{"acorn":32,"acorn/dist/walk":33}],32:[function(require,module,exports){
- (function (global){
- (function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.acorn = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(_dereq_,module,exports){
- // 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
- "use strict";
- exports.parse = 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.
- exports.parseExpressionAt = parseExpressionAt;
- // Acorn is organized as a tokenizer and a recursive-descent parser.
- // The `tokenize` export provides an interface to the tokenizer.
- exports.tokenizer = tokenizer;
- exports.__esModule = true;
- // 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/marijnh/acorn.git
- //
- // Please use the [github bug tracker][ghbt] to report issues.
- //
- // [ghbt]: https://github.com/marijnh/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 _state = _dereq_("./state");
- var Parser = _state.Parser;
- var _options = _dereq_("./options");
- var getOptions = _options.getOptions;
- _dereq_("./parseutil");
- _dereq_("./statement");
- _dereq_("./lval");
- _dereq_("./expression");
- exports.Parser = _state.Parser;
- exports.plugins = _state.plugins;
- exports.defaultOptions = _options.defaultOptions;
- var _location = _dereq_("./location");
- exports.SourceLocation = _location.SourceLocation;
- exports.getLineInfo = _location.getLineInfo;
- exports.Node = _dereq_("./node").Node;
- var _tokentype = _dereq_("./tokentype");
- exports.TokenType = _tokentype.TokenType;
- exports.tokTypes = _tokentype.types;
- var _tokencontext = _dereq_("./tokencontext");
- exports.TokContext = _tokencontext.TokContext;
- exports.tokContexts = _tokencontext.types;
- var _identifier = _dereq_("./identifier");
- exports.isIdentifierChar = _identifier.isIdentifierChar;
- exports.isIdentifierStart = _identifier.isIdentifierStart;
- exports.Token = _dereq_("./tokenize").Token;
- var _whitespace = _dereq_("./whitespace");
- exports.isNewLine = _whitespace.isNewLine;
- exports.lineBreak = _whitespace.lineBreak;
- exports.lineBreakG = _whitespace.lineBreakG;
- var version = "1.2.2";exports.version = version;
- function parse(input, options) {
- var p = parser(options, input);
- var startPos = p.pos,
- startLoc = p.options.locations && p.curPosition();
- p.nextToken();
- return p.parseTopLevel(p.options.program || p.startNodeAt(startPos, startLoc));
- }
- function parseExpressionAt(input, pos, options) {
- var p = parser(options, input, pos);
- p.nextToken();
- return p.parseExpression();
- }
- function tokenizer(input, options) {
- return parser(options, input);
- }
- function parser(options, input) {
- return new Parser(getOptions(options), String(input));
- }
- },{"./expression":6,"./identifier":7,"./location":8,"./lval":9,"./node":10,"./options":11,"./parseutil":12,"./state":13,"./statement":14,"./tokencontext":15,"./tokenize":16,"./tokentype":17,"./whitespace":19}],2:[function(_dereq_,module,exports){
- if (typeof Object.create === 'function') {
- // implementation from standard node.js 'util' module
- module.exports = function inherits(ctor, superCtor) {
- ctor.super_ = superCtor
- ctor.prototype = Object.create(superCtor.prototype, {
- constructor: {
- value: ctor,
- enumerable: false,
- writable: true,
- configurable: true
- }
- });
- };
- } else {
- // old school shim for old browsers
- module.exports = function inherits(ctor, superCtor) {
- ctor.super_ = superCtor
- var TempCtor = function () {}
- TempCtor.prototype = superCtor.prototype
- ctor.prototype = new TempCtor()
- ctor.prototype.constructor = ctor
- }
- }
- },{}],3:[function(_dereq_,module,exports){
- // shim for using process in browser
- var process = module.exports = {};
- var queue = [];
- var draining = false;
- function drainQueue() {
- if (draining) {
- return;
- }
- draining = true;
- var currentQueue;
- var len = queue.length;
- while(len) {
- currentQueue = queue;
- queue = [];
- var i = -1;
- while (++i < len) {
- currentQueue[i]();
- }
- len = queue.length;
- }
- draining = false;
- }
- process.nextTick = function (fun) {
- queue.push(fun);
- if (!draining) {
- setTimeout(drainQueue, 0);
- }
- };
- process.title = 'browser';
- process.browser = true;
- process.env = {};
- process.argv = [];
- process.version = ''; // empty string to avoid regexp issues
- process.versions = {};
- function noop() {}
- process.on = noop;
- process.addListener = noop;
- process.once = noop;
- process.off = noop;
- process.removeListener = noop;
- process.removeAllListeners = noop;
- process.emit = noop;
- process.binding = function (name) {
- throw new Error('process.binding is not supported');
- };
- // TODO(shtylman)
- process.cwd = function () { return '/' };
- process.chdir = function (dir) {
- throw new Error('process.chdir is not supported');
- };
- process.umask = function() { return 0; };
- },{}],4:[function(_dereq_,module,exports){
- module.exports = function isBuffer(arg) {
- return arg && typeof arg === 'object'
- && typeof arg.copy === 'function'
- && typeof arg.fill === 'function'
- && typeof arg.readUInt8 === 'function';
- }
- },{}],5:[function(_dereq_,module,exports){
- (function (process,global){
- // Copyright Joyent, Inc. and other Node contributors.
- //
- // Permission is hereby granted, free of charge, to any person obtaining a
- // copy of this software and associated documentation files (the
- // "Software"), to deal in the Software without restriction, including
- // without limitation the rights to use, copy, modify, merge, publish,
- // distribute, sublicense, and/or sell copies of the Software, and to permit
- // persons to whom the Software is furnished to do so, subject to the
- // following conditions:
- //
- // The above copyright notice and this permission notice shall be included
- // in all copies or substantial portions of the Software.
- //
- // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
- // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
- // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
- // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
- // USE OR OTHER DEALINGS IN THE SOFTWARE.
- var formatRegExp = /%[sdj%]/g;
- exports.format = function(f) {
- if (!isString(f)) {
- var objects = [];
- for (var i = 0; i < arguments.length; i++) {
- objects.push(inspect(arguments[i]));
- }
- return objects.join(' ');
- }
- var i = 1;
- var args = arguments;
- var len = args.length;
- var str = String(f).replace(formatRegExp, function(x) {
- if (x === '%%') return '%';
- if (i >= len) return x;
- switch (x) {
- case '%s': return String(args[i++]);
- case '%d': return Number(args[i++]);
- case '%j':
- try {
- return JSON.stringify(args[i++]);
- } catch (_) {
- return '[Circular]';
- }
- default:
- return x;
- }
- });
- for (var x = args[i]; i < len; x = args[++i]) {
- if (isNull(x) || !isObject(x)) {
- str += ' ' + x;
- } else {
- str += ' ' + inspect(x);
- }
- }
- return str;
- };
- // Mark that a method should not be used.
- // Returns a modified function which warns once by default.
- // If --no-deprecation is set, then it is a no-op.
- exports.deprecate = function(fn, msg) {
- // Allow for deprecating things in the process of starting up.
- if (isUndefined(global.process)) {
- return function() {
- return exports.deprecate(fn, msg).apply(this, arguments);
- };
- }
- if (process.noDeprecation === true) {
- return fn;
- }
- var warned = false;
- function deprecated() {
- if (!warned) {
- if (process.throwDeprecation) {
- throw new Error(msg);
- } else if (process.traceDeprecation) {
- console.trace(msg);
- } else {
- console.error(msg);
- }
- warned = true;
- }
- return fn.apply(this, arguments);
- }
- return deprecated;
- };
- var debugs = {};
- var debugEnviron;
- exports.debuglog = function(set) {
- if (isUndefined(debugEnviron))
- debugEnviron = process.env.NODE_DEBUG || '';
- set = set.toUpperCase();
- if (!debugs[set]) {
- if (new RegExp('\\b' + set + '\\b', 'i').test(debugEnviron)) {
- var pid = process.pid;
- debugs[set] = function() {
- var msg = exports.format.apply(exports, arguments);
- console.error('%s %d: %s', set, pid, msg);
- };
- } else {
- debugs[set] = function() {};
- }
- }
- return debugs[set];
- };
- /**
- * Echos the value of a value. Trys to print the value out
- * in the best way possible given the different types.
- *
- * @param {Object} obj The object to print out.
- * @param {Object} opts Optional options object that alters the output.
- */
- /* legacy: obj, showHidden, depth, colors*/
- function inspect(obj, opts) {
- // default options
- var ctx = {
- seen: [],
- stylize: stylizeNoColor
- };
- // legacy...
- if (arguments.length >= 3) ctx.depth = arguments[2];
- if (arguments.length >= 4) ctx.colors = arguments[3];
- if (isBoolean(opts)) {
- // legacy...
- ctx.showHidden = opts;
- } else if (opts) {
- // got an "options" object
- exports._extend(ctx, opts);
- }
- // set default options
- if (isUndefined(ctx.showHidden)) ctx.showHidden = false;
- if (isUndefined(ctx.depth)) ctx.depth = 2;
- if (isUndefined(ctx.colors)) ctx.colors = false;
- if (isUndefined(ctx.customInspect)) ctx.customInspect = true;
- if (ctx.colors) ctx.stylize = stylizeWithColor;
- return formatValue(ctx, obj, ctx.depth);
- }
- exports.inspect = inspect;
- // http://en.wikipedia.org/wiki/ANSI_escape_code#graphics
- inspect.colors = {
- 'bold' : [1, 22],
- 'italic' : [3, 23],
- 'underline' : [4, 24],
- 'inverse' : [7, 27],
- 'white' : [37, 39],
- 'grey' : [90, 39],
- 'black' : [30, 39],
- 'blue' : [34, 39],
- 'cyan' : [36, 39],
- 'green' : [32, 39],
- 'magenta' : [35, 39],
- 'red' : [31, 39],
- 'yellow' : [33, 39]
- };
- // Don't use 'blue' not visible on cmd.exe
- inspect.styles = {
- 'special': 'cyan',
- 'number': 'yellow',
- 'boolean': 'yellow',
- 'undefined': 'grey',
- 'null': 'bold',
- 'string': 'green',
- 'date': 'magenta',
- // "name": intentionally not styling
- 'regexp': 'red'
- };
- function stylizeWithColor(str, styleType) {
- var style = inspect.styles[styleType];
- if (style) {
- return '\u001b[' + inspect.colors[style][0] + 'm' + str +
- '\u001b[' + inspect.colors[style][1] + 'm';
- } else {
- return str;
- }
- }
- function stylizeNoColor(str, styleType) {
- return str;
- }
- function arrayToHash(array) {
- var hash = {};
- array.forEach(function(val, idx) {
- hash[val] = true;
- });
- return hash;
- }
- function formatValue(ctx, value, recurseTimes) {
- // Provide a hook for user-specified inspect functions.
- // Check that value is an object with an inspect function on it
- if (ctx.customInspect &&
- value &&
- isFunction(value.inspect) &&
- // Filter out the util module, it's inspect function is special
- value.inspect !== exports.inspect &&
- // Also filter out any prototype objects using the circular check.
- !(value.constructor && value.constructor.prototype === value)) {
- var ret = value.inspect(recurseTimes, ctx);
- if (!isString(ret)) {
- ret = formatValue(ctx, ret, recurseTimes);
- }
- return ret;
- }
- // Primitive types cannot have properties
- var primitive = formatPrimitive(ctx, value);
- if (primitive) {
- return primitive;
- }
- // Look up the keys of the object.
- var keys = Object.keys(value);
- var visibleKeys = arrayToHash(keys);
- if (ctx.showHidden) {
- keys = Object.getOwnPropertyNames(value);
- }
- // IE doesn't make error fields non-enumerable
- // http://msdn.microsoft.com/en-us/library/ie/dww52sbt(v=vs.94).aspx
- if (isError(value)
- && (keys.indexOf('message') >= 0 || keys.indexOf('description') >= 0)) {
- return formatError(value);
- }
- // Some type of object without properties can be shortcutted.
- if (keys.length === 0) {
- if (isFunction(value)) {
- var name = value.name ? ': ' + value.name : '';
- return ctx.stylize('[Function' + name + ']', 'special');
- }
- if (isRegExp(value)) {
- return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
- }
- if (isDate(value)) {
- return ctx.stylize(Date.prototype.toString.call(value), 'date');
- }
- if (isError(value)) {
- return formatError(value);
- }
- }
- var base = '', array = false, braces = ['{', '}'];
- // Make Array say that they are Array
- if (isArray(value)) {
- array = true;
- braces = ['[', ']'];
- }
- // Make functions say that they are functions
- if (isFunction(value)) {
- var n = value.name ? ': ' + value.name : '';
- base = ' [Function' + n + ']';
- }
- // Make RegExps say that they are RegExps
- if (isRegExp(value)) {
- base = ' ' + RegExp.prototype.toString.call(value);
- }
- // Make dates with properties first say the date
- if (isDate(value)) {
- base = ' ' + Date.prototype.toUTCString.call(value);
- }
- // Make error with message first say the error
- if (isError(value)) {
- base = ' ' + formatError(value);
- }
- if (keys.length === 0 && (!array || value.length == 0)) {
- return braces[0] + base + braces[1];
- }
- if (recurseTimes < 0) {
- if (isRegExp(value)) {
- return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');
- } else {
- return ctx.stylize('[Object]', 'special');
- }
- }
- ctx.seen.push(value);
- var output;
- if (array) {
- output = formatArray(ctx, value, recurseTimes, visibleKeys, keys);
- } else {
- output = keys.map(function(key) {
- return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array);
- });
- }
- ctx.seen.pop();
- return reduceToSingleString(output, base, braces);
- }
- function formatPrimitive(ctx, value) {
- if (isUndefined(value))
- return ctx.stylize('undefined', 'undefined');
- if (isString(value)) {
- var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '')
- .replace(/'/g, "\\'")
- .replace(/\\"/g, '"') + '\'';
- return ctx.stylize(simple, 'string');
- }
- if (isNumber(value))
- return ctx.stylize('' + value, 'number');
- if (isBoolean(value))
- return ctx.stylize('' + value, 'boolean');
- // For some reason typeof null is "object", so special case here.
- if (isNull(value))
- return ctx.stylize('null', 'null');
- }
- function formatError(value) {
- return '[' + Error.prototype.toString.call(value) + ']';
- }
- function formatArray(ctx, value, recurseTimes, visibleKeys, keys) {
- var output = [];
- for (var i = 0, l = value.length; i < l; ++i) {
- if (hasOwnProperty(value, String(i))) {
- output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
- String(i), true));
- } else {
- output.push('');
- }
- }
- keys.forEach(function(key) {
- if (!key.match(/^\d+$/)) {
- output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,
- key, true));
- }
- });
- return output;
- }
- function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) {
- var name, str, desc;
- desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] };
- if (desc.get) {
- if (desc.set) {
- str = ctx.stylize('[Getter/Setter]', 'special');
- } else {
- str = ctx.stylize('[Getter]', 'special');
- }
- } else {
- if (desc.set) {
- str = ctx.stylize('[Setter]', 'special');
- }
- }
- if (!hasOwnProperty(visibleKeys, key)) {
- name = '[' + key + ']';
- }
- if (!str) {
- if (ctx.seen.indexOf(desc.value) < 0) {
- if (isNull(recurseTimes)) {
- str = formatValue(ctx, desc.value, null);
- } else {
- str = formatValue(ctx, desc.value, recurseTimes - 1);
- }
- if (str.indexOf('\n') > -1) {
- if (array) {
- str = str.split('\n').map(function(line) {
- return ' ' + line;
- }).join('\n').substr(2);
- } else {
- str = '\n' + str.split('\n').map(function(line) {
- return ' ' + line;
- }).join('\n');
- }
- }
- } else {
- str = ctx.stylize('[Circular]', 'special');
- }
- }
- if (isUndefined(name)) {
- if (array && key.match(/^\d+$/)) {
- return str;
- }
- name = JSON.stringify('' + key);
- if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) {
- name = name.substr(1, name.length - 2);
- name = ctx.stylize(name, 'name');
- } else {
- name = name.replace(/'/g, "\\'")
- .replace(/\\"/g, '"')
- .replace(/(^"|"$)/g, "'");
- name = ctx.stylize(name, 'string');
- }
- }
- return name + ': ' + str;
- }
- function reduceToSingleString(output, base, braces) {
- var numLinesEst = 0;
- var length = output.reduce(function(prev, cur) {
- numLinesEst++;
- if (cur.indexOf('\n') >= 0) numLinesEst++;
- return prev + cur.replace(/\u001b\[\d\d?m/g, '').length + 1;
- }, 0);
- if (length > 60) {
- return braces[0] +
- (base === '' ? '' : base + '\n ') +
- ' ' +
- output.join(',\n ') +
- ' ' +
- braces[1];
- }
- return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1];
- }
- // NOTE: These type checking functions intentionally don't use `instanceof`
- // because it is fragile and can be easily faked with `Object.create()`.
- function isArray(ar) {
- return Array.isArray(ar);
- }
- exports.isArray = isArray;
- function isBoolean(arg) {
- return typeof arg === 'boolean';
- }
- exports.isBoolean = isBoolean;
- function isNull(arg) {
- return arg === null;
- }
- exports.isNull = isNull;
- function isNullOrUndefined(arg) {
- return arg == null;
- }
- exports.isNullOrUndefined = isNullOrUndefined;
- function isNumber(arg) {
- return typeof arg === 'number';
- }
- exports.isNumber = isNumber;
- function isString(arg) {
- return typeof arg === 'string';
- }
- exports.isString = isString;
- function isSymbol(arg) {
- return typeof arg === 'symbol';
- }
- exports.isSymbol = isSymbol;
- function isUndefined(arg) {
- return arg === void 0;
- }
- exports.isUndefined = isUndefined;
- function isRegExp(re) {
- return isObject(re) && objectToString(re) === '[object RegExp]';
- }
- exports.isRegExp = isRegExp;
- function isObject(arg) {
- return typeof arg === 'object' && arg !== null;
- }
- exports.isObject = isObject;
- function isDate(d) {
- return isObject(d) && objectToString(d) === '[object Date]';
- }
- exports.isDate = isDate;
- function isError(e) {
- return isObject(e) &&
- (objectToString(e) === '[object Error]' || e instanceof Error);
- }
- exports.isError = isError;
- function isFunction(arg) {
- return typeof arg === 'function';
- }
- exports.isFunction = isFunction;
- function isPrimitive(arg) {
- return arg === null ||
- typeof arg === 'boolean' ||
- typeof arg === 'number' ||
- typeof arg === 'string' ||
- typeof arg === 'symbol' || // ES6 symbol
- typeof arg === 'undefined';
- }
- exports.isPrimitive = isPrimitive;
- exports.isBuffer = _dereq_('./support/isBuffer');
- function objectToString(o) {
- return Object.prototype.toString.call(o);
- }
- function pad(n) {
- return n < 10 ? '0' + n.toString(10) : n.toString(10);
- }
- var months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep',
- 'Oct', 'Nov', 'Dec'];
- // 26 Feb 16:19:34
- function timestamp() {
- var d = new Date();
- var time = [pad(d.getHours()),
- pad(d.getMinutes()),
- pad(d.getSeconds())].join(':');
- return [d.getDate(), months[d.getMonth()], time].join(' ');
- }
- // log is just a thin wrapper to console.log that prepends a timestamp
- exports.log = function() {
- console.log('%s - %s', timestamp(), exports.format.apply(exports, arguments));
- };
- /**
- * Inherit the prototype methods from one constructor into another.
- *
- * The Function.prototype.inherits from lang.js rewritten as a standalone
- * function (not on Function.prototype). NOTE: If this file is to be loaded
- * during bootstrapping this function needs to be rewritten using some native
- * functions as prototype setup using normal JavaScript does not work as
- * expected during bootstrapping (see mirror.js in r114903).
- *
- * @param {function} ctor Constructor function which needs to inherit the
- * prototype.
- * @param {function} superCtor Constructor function to inherit prototype from.
- */
- exports.inherits = _dereq_('inherits');
- exports._extend = function(origin, add) {
- // Don't do anything if add isn't an object
- if (!add || !isObject(add)) return origin;
- var keys = Object.keys(add);
- var i = keys.length;
- while (i--) {
- origin[keys[i]] = add[keys[i]];
- }
- return origin;
- };
- function hasOwnProperty(obj, prop) {
- return Object.prototype.hasOwnProperty.call(obj, prop);
- }
- }).call(this,_dereq_('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
- },{"./support/isBuffer":4,"_process":3,"inherits":2}],6:[function(_dereq_,module,exports){
- // 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
- "use strict";
- var tt = _dereq_("./tokentype").types;
- var Parser = _dereq_("./state").Parser;
- var reservedWords = _dereq_("./identifier").reservedWords;
- var has = _dereq_("./util").has;
- var pp = 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.checkPropClash = function (prop, propHash) {
- if (this.options.ecmaVersion >= 6) return;
- var key = prop.key,
- name = undefined;
- switch (key.type) {
- case "Identifier":
- name = key.name;break;
- case "Literal":
- name = String(key.value);break;
- default:
- return;
- }
- var kind = prop.kind || "init",
- other = undefined;
- if (has(propHash, name)) {
- other = propHash[name];
- var isGetSet = kind !== "init";
- if ((this.strict || isGetSet) && other[kind] || !(isGetSet ^ other.init)) this.raise(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.parseExpression = function (noIn, refShorthandDefaultPos) {
- var startPos = this.start,
- startLoc = this.startLoc;
- var expr = this.parseMaybeAssign(noIn, refShorthandDefaultPos);
- if (this.type === tt.comma) {
- var node = this.startNodeAt(startPos, startLoc);
- node.expressions = [expr];
- while (this.eat(tt.comma)) node.expressions.push(this.parseMaybeAssign(noIn, refShorthandDefaultPos));
- return this.finishNode(node, "SequenceExpression");
- }
- return expr;
- };
- // Parse an assignment expression. This includes applications of
- // operators like `+=`.
- pp.parseMaybeAssign = function (noIn, refShorthandDefaultPos, afterLeftParse) {
- if (this.type == tt._yield && this.inGenerator) return this.parseYield();
- var failOnShorthandAssign = undefined;
- if (!refShorthandDefaultPos) {
- refShorthandDefaultPos = { start: 0 };
- failOnShorthandAssign = true;
- } else {
- failOnShorthandAssign = false;
- }
- var startPos = this.start,
- startLoc = this.startLoc;
- if (this.type == tt.parenL || this.type == tt.name) this.potentialArrowAt = this.start;
- var left = this.parseMaybeConditional(noIn, refShorthandDefaultPos);
- 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 === tt.eq ? this.toAssignable(left) : left;
- refShorthandDefaultPos.start = 0; // reset because shorthand default was used correctly
- this.checkLVal(left);
- this.next();
- node.right = this.parseMaybeAssign(noIn);
- return this.finishNode(node, "AssignmentExpression");
- } else if (failOnShorthandAssign && refShorthandDefaultPos.start) {
- this.unexpected(refShorthandDefaultPos.start);
- }
- return left;
- };
- // Parse a ternary conditional (`?:`) operator.
- pp.parseMaybeConditional = function (noIn, refShorthandDefaultPos) {
- var startPos = this.start,
- startLoc = this.startLoc;
- var expr = this.parseExprOps(noIn, refShorthandDefaultPos);
- if (refShorthandDefaultPos && refShorthandDefaultPos.start) return expr;
- if (this.eat(tt.question)) {
- var node = this.startNodeAt(startPos, startLoc);
- node.test = expr;
- node.consequent = this.parseMaybeAssign();
- this.expect(tt.colon);
- node.alternate = this.parseMaybeAssign(noIn);
- return this.finishNode(node, "ConditionalExpression");
- }
- return expr;
- };
- // Start the precedence parser.
- pp.parseExprOps = function (noIn, refShorthandDefaultPos) {
- var startPos = this.start,
- startLoc = this.startLoc;
- var expr = this.parseMaybeUnary(refShorthandDefaultPos);
- if (refShorthandDefaultPos && refShorthandDefaultPos.start) return expr;
- return 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.parseExprOp = function (left, leftStartPos, leftStartLoc, minPrec, noIn) {
- var prec = this.type.binop;
- if (Array.isArray(leftStartPos)) {
- if (this.options.locations && noIn === undefined) {
- // shift arguments to left by one
- noIn = minPrec;
- minPrec = leftStartLoc;
- // flatten leftStartPos
- leftStartLoc = leftStartPos[1];
- leftStartPos = leftStartPos[0];
- }
- }
- if (prec != null && (!noIn || this.type !== tt._in)) {
- if (prec > minPrec) {
- var node = this.startNodeAt(leftStartPos, leftStartLoc);
- node.left = left;
- node.operator = this.value;
- var op = this.type;
- this.next();
- var startPos = this.start,
- startLoc = this.startLoc;
- node.right = this.parseExprOp(this.parseMaybeUnary(), startPos, startLoc, prec, noIn);
- this.finishNode(node, op === tt.logicalOR || op === tt.logicalAND ? "LogicalExpression" : "BinaryExpression");
- return this.parseExprOp(node, leftStartPos, leftStartLoc, minPrec, noIn);
- }
- }
- return left;
- };
- // Parse unary operators, both prefix and postfix.
- pp.parseMaybeUnary = function (refShorthandDefaultPos) {
- if (this.type.prefix) {
- var node = this.startNode(),
- update = this.type === tt.incDec;
- node.operator = this.value;
- node.prefix = true;
- this.next();
- node.argument = this.parseMaybeUnary();
- if (refShorthandDefaultPos && refShorthandDefaultPos.start) this.unexpected(refShorthandDefaultPos.start);
- if (update) this.checkLVal(node.argument);else if (this.strict && node.operator === "delete" && node.argument.type === "Identifier") this.raise(node.start, "Deleting local variable in strict mode");
- return this.finishNode(node, update ? "UpdateExpression" : "UnaryExpression");
- }
- var startPos = this.start,
- startLoc = this.startLoc;
- var expr = this.parseExprSubscripts(refShorthandDefaultPos);
- if (refShorthandDefaultPos && refShorthandDefaultPos.start) return expr;
- while (this.type.postfix && !this.canInsertSemicolon()) {
- var node = this.startNodeAt(startPos, startLoc);
- node.operator = this.value;
- node.prefix = false;
- node.argument = expr;
- this.checkLVal(expr);
- this.next();
- expr = this.finishNode(node, "UpdateExpression");
- }
- return expr;
- };
- // Parse call, dot, and `[]`-subscript expressions.
- pp.parseExprSubscripts = function (refShorthandDefaultPos) {
- var startPos = this.start,
- startLoc = this.startLoc;
- var expr = this.parseExprAtom(refShorthandDefaultPos);
- if (refShorthandDefaultPos && refShorthandDefaultPos.start) return expr;
- return this.parseSubscripts(expr, startPos, startLoc);
- };
- pp.parseSubscripts = function (base, startPos, startLoc, noCalls) {
- if (Array.isArray(startPos)) {
- if (this.options.locations && noCalls === undefined) {
- // shift arguments to left by one
- noCalls = startLoc;
- // flatten startPos
- startLoc = startPos[1];
- startPos = startPos[0];
- }
- }
- for (;;) {
- if (this.eat(tt.dot)) {
- var node = this.startNodeAt(startPos, startLoc);
- node.object = base;
- node.property = this.parseIdent(true);
- node.computed = false;
- base = this.finishNode(node, "MemberExpression");
- } else if (this.eat(tt.bracketL)) {
- var node = this.startNodeAt(startPos, startLoc);
- node.object = base;
- node.property = this.parseExpression();
- node.computed = true;
- this.expect(tt.bracketR);
- base = this.finishNode(node, "MemberExpression");
- } else if (!noCalls && this.eat(tt.parenL)) {
- var node = this.startNodeAt(startPos, startLoc);
- node.callee = base;
- node.arguments = this.parseExprList(tt.parenR, false);
- base = this.finishNode(node, "CallExpression");
- } else if (this.type === tt.backQuote) {
- var node = this.startNodeAt(startPos, startLoc);
- node.tag = base;
- node.quasi = this.parseTemplate();
- base = this.finishNode(node, "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.parseExprAtom = function (refShorthandDefaultPos) {
- var node = undefined,
- canBeArrow = this.potentialArrowAt == this.start;
- switch (this.type) {
- case tt._this:
- case tt._super:
- var type = this.type === tt._this ? "ThisExpression" : "Super";
- node = this.startNode();
- this.next();
- return this.finishNode(node, type);
- case tt._yield:
- if (this.inGenerator) this.unexpected();
- case tt.name:
- var startPos = this.start,
- startLoc = this.startLoc;
- var id = this.parseIdent(this.type !== tt.name);
- if (canBeArrow && !this.canInsertSemicolon() && this.eat(tt.arrow)) return this.parseArrowExpression(this.startNodeAt(startPos, startLoc), [id]);
- return id;
- case tt.regexp:
- var value = this.value;
- node = this.parseLiteral(value.value);
- node.regex = { pattern: value.pattern, flags: value.flags };
- return node;
- case tt.num:case tt.string:
- return this.parseLiteral(this.value);
- case tt._null:case tt._true:case tt._false:
- node = this.startNode();
- node.value = this.type === tt._null ? null : this.type === tt._true;
- node.raw = this.type.keyword;
- this.next();
- return this.finishNode(node, "Literal");
- case tt.parenL:
- return this.parseParenAndDistinguishExpression(canBeArrow);
- case tt.bracketL:
- node = this.startNode();
- this.next();
- // check whether this is array comprehension or regular array
- if (this.options.ecmaVersion >= 7 && this.type === tt._for) {
- return this.parseComprehension(node, false);
- }
- node.elements = this.parseExprList(tt.bracketR, true, true, refShorthandDefaultPos);
- return this.finishNode(node, "ArrayExpression");
- case tt.braceL:
- return this.parseObj(false, refShorthandDefaultPos);
- case tt._function:
- node = this.startNode();
- this.next();
- return this.parseFunction(node, false);
- case tt._class:
- return this.parseClass(this.startNode(), false);
- case tt._new:
- return this.parseNew();
- case tt.backQuote:
- return this.parseTemplate();
- default:
- this.unexpected();
- }
- };
- pp.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.parseParenExpression = function () {
- this.expect(tt.parenL);
- var val = this.parseExpression();
- this.expect(tt.parenR);
- return val;
- };
- pp.parseParenAndDistinguishExpression = function (canBeArrow) {
- var startPos = this.start,
- startLoc = this.startLoc,
- val = undefined;
- if (this.options.ecmaVersion >= 6) {
- this.next();
- if (this.options.ecmaVersion >= 7 && this.type === tt._for) {
- return this.parseComprehension(this.startNodeAt(startPos, startLoc), true);
- }
- var innerStartPos = this.start,
- innerStartLoc = this.startLoc;
- var exprList = [],
- first = true;
- var refShorthandDefaultPos = { start: 0 },
- spreadStart = undefined,
- innerParenStart = undefined;
- while (this.type !== tt.parenR) {
- first ? first = false : this.expect(tt.comma);
- if (this.type === tt.ellipsis) {
- spreadStart = this.start;
- exprList.push(this.parseParenItem(this.parseRest()));
- break;
- } else {
- if (this.type === tt.parenL && !innerParenStart) {
- innerParenStart = this.start;
- }
- exprList.push(this.parseMaybeAssign(false, refShorthandDefaultPos, this.parseParenItem));
- }
- }
- var innerEndPos = this.start,
- innerEndLoc = this.startLoc;
- this.expect(tt.parenR);
- if (canBeArrow && !this.canInsertSemicolon() && this.eat(tt.arrow)) {
- if (innerParenStart) this.unexpected(innerParenStart);
- return this.parseParenArrowList(startPos, startLoc, exprList);
- }
- if (!exprList.length) this.unexpected(this.lastTokStart);
- if (spreadStart) this.unexpected(spreadStart);
- if (refShorthandDefaultPos.start) this.unexpected(refShorthandDefaultPos.start);
- 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.parseParenItem = function (item) {
- return item;
- };
- pp.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
- var empty = [];
- pp.parseNew = function () {
- var node = this.startNode();
- var meta = this.parseIdent(true);
- if (this.options.ecmaVersion >= 6 && this.eat(tt.dot)) {
- node.meta = meta;
- node.property = this.parseIdent(true);
- if (node.property.name !== "target") this.raise(node.property.start, "The only valid meta property for new is new.target");
- return this.finishNode(node, "MetaProperty");
- }
- var startPos = this.start,
- startLoc = this.startLoc;
- node.callee = this.parseSubscripts(this.parseExprAtom(), startPos, startLoc, true);
- if (this.eat(tt.parenL)) node.arguments = this.parseExprList(tt.parenR, false);else node.arguments = empty;
- return this.finishNode(node, "NewExpression");
- };
- // Parse template expression.
- pp.parseTemplateElement = function () {
- var elem = this.startNode();
- elem.value = {
- raw: this.input.slice(this.start, this.end),
- cooked: this.value
- };
- this.next();
- elem.tail = this.type === tt.backQuote;
- return this.finishNode(elem, "TemplateElement");
- };
- pp.parseTemplate = function () {
- var node = this.startNode();
- this.next();
- node.expressions = [];
- var curElt = this.parseTemplateElement();
- node.quasis = [curElt];
- while (!curElt.tail) {
- this.expect(tt.dollarBraceL);
- node.expressions.push(this.parseExpression());
- this.expect(tt.braceR);
- node.quasis.push(curElt = this.parseTemplateElement());
- }
- this.next();
- return this.finishNode(node, "TemplateLiteral");
- };
- // Parse an object literal or binding pattern.
- pp.parseObj = function (isPattern, refShorthandDefaultPos) {
- var node = this.startNode(),
- first = true,
- propHash = {};
- node.properties = [];
- this.next();
- while (!this.eat(tt.braceR)) {
- if (!first) {
- this.expect(tt.comma);
- if (this.afterTrailingComma(tt.braceR)) break;
- } else first = false;
- var prop = this.startNode(),
- isGenerator = undefined,
- startPos = undefined,
- startLoc = undefined;
- if (this.options.ecmaVersion >= 6) {
- prop.method = false;
- prop.shorthand = false;
- if (isPattern || refShorthandDefaultPos) {
- startPos = this.start;
- startLoc = this.startLoc;
- }
- if (!isPattern) isGenerator = this.eat(tt.star);
- }
- this.parsePropertyName(prop);
- this.parsePropertyValue(prop, isPattern, isGenerator, startPos, startLoc, refShorthandDefaultPos);
- this.checkPropClash(prop, propHash);
- node.properties.push(this.finishNode(prop, "Property"));
- }
- return this.finishNode(node, isPattern ? "ObjectPattern" : "ObjectExpression");
- };
- pp.parsePropertyValue = function (prop, isPattern, isGenerator, startPos, startLoc, refShorthandDefaultPos) {
- if (this.eat(tt.colon)) {
- prop.value = isPattern ? this.parseMaybeDefault(this.start, this.startLoc) : this.parseMaybeAssign(false, refShorthandDefaultPos);
- prop.kind = "init";
- } else if (this.options.ecmaVersion >= 6 && this.type === tt.parenL) {
- if (isPattern) this.unexpected();
- prop.kind = "init";
- prop.method = true;
- prop.value = this.parseMethod(isGenerator);
- } else if (this.options.ecmaVersion >= 5 && !prop.computed && prop.key.type === "Identifier" && (prop.key.name === "get" || prop.key.name === "set") && (this.type != tt.comma && this.type != tt.braceR)) {
- if (isGenerator || isPattern) this.unexpected();
- prop.kind = prop.key.name;
- this.parsePropertyName(prop);
- prop.value = this.parseMethod(false);
- } else if (this.options.ecmaVersion >= 6 && !prop.computed && prop.key.type === "Identifier") {
- prop.kind = "init";
- if (isPattern) {
- if (this.isKeyword(prop.key.name) || this.strict && (reservedWords.strictBind(prop.key.name) || reservedWords.strict(prop.key.name)) || !this.options.allowReserved && this.isReservedWord(prop.key.name)) this.raise(prop.key.start, "Binding " + prop.key.name);
- prop.value = this.parseMaybeDefault(startPos, startLoc, prop.key);
- } else if (this.type === tt.eq && refShorthandDefaultPos) {
- if (!refShorthandDefaultPos.start) refShorthandDefaultPos.start = this.start;
- prop.value = this.parseMaybeDefault(startPos, startLoc, prop.key);
- } else {
- prop.value = prop.key;
- }
- prop.shorthand = true;
- } else this.unexpected();
- };
- pp.parsePropertyName = function (prop) {
- if (this.options.ecmaVersion >= 6) {
- if (this.eat(tt.bracketL)) {
- prop.computed = true;
- prop.key = this.parseMaybeAssign();
- this.expect(tt.bracketR);
- return prop.key;
- } else {
- prop.computed = false;
- }
- }
- return prop.key = this.type === tt.num || this.type === tt.string ? this.parseExprAtom() : this.parseIdent(true);
- };
- // Initialize empty function node.
- pp.initFunction = function (node) {
- node.id = null;
- if (this.options.ecmaVersion >= 6) {
- node.generator = false;
- node.expression = false;
- }
- };
- // Parse object or class method.
- pp.parseMethod = function (isGenerator) {
- var node = this.startNode();
- this.initFunction(node);
- this.expect(tt.parenL);
- node.params = this.parseBindingList(tt.parenR, false, false);
- var allowExpressionBody = undefined;
- if (this.options.ecmaVersion >= 6) {
- node.generator = isGenerator;
- allowExpressionBody = true;
- } else {
- allowExpressionBody = false;
- }
- this.parseFunctionBody(node, allowExpressionBody);
- return this.finishNode(node, "FunctionExpression");
- };
- // Parse arrow function expression with given parameters.
- pp.parseArrowExpression = function (node, params) {
- this.initFunction(node);
- node.params = this.toAssignableList(params, true);
- this.parseFunctionBody(node, true);
- return this.finishNode(node, "ArrowFunctionExpression");
- };
- // Parse function body and check parameters.
- pp.parseFunctionBody = function (node, allowExpression) {
- var isExpression = allowExpression && this.type !== tt.braceL;
- if (isExpression) {
- node.body = this.parseMaybeAssign();
- node.expression = true;
- } else {
- // Start a new scope with regard to labels and the `inFunction`
- // flag (restore them to their old value afterwards).
- var oldInFunc = this.inFunction,
- oldInGen = this.inGenerator,
- oldLabels = this.labels;
- this.inFunction = true;this.inGenerator = node.generator;this.labels = [];
- node.body = this.parseBlock(true);
- node.expression = false;
- this.inFunction = oldInFunc;this.inGenerator = oldInGen;this.labels = oldLabels;
- }
- // 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 (this.strict || !isExpression && node.body.body.length && this.isUseStrict(node.body.body[0])) {
- var nameHash = {},
- oldStrict = this.strict;
- this.strict = true;
- if (node.id) this.checkLVal(node.id, true);
- for (var i = 0; i < node.params.length; i++) {
- this.checkLVal(node.params[i], true, nameHash);
- }this.strict = oldStrict;
- }
- };
- // 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.parseExprList = function (close, allowTrailingComma, allowEmpty, refShorthandDefaultPos) {
- var elts = [],
- first = true;
- while (!this.eat(close)) {
- if (!first) {
- this.expect(tt.comma);
- if (allowTrailingComma && this.afterTrailingComma(close)) break;
- } else first = false;
- if (allowEmpty && this.type === tt.comma) {
- elts.push(null);
- } else {
- if (this.type === tt.ellipsis) elts.push(this.parseSpread(refShorthandDefaultPos));else elts.push(this.parseMaybeAssign(false, refShorthandDefaultPos));
- }
- }
- return elts;
- };
- // Parse the next token as an identifier. If `liberal` is true (used
- // when parsing properties), it will also convert keywords into
- // identifiers.
- pp.parseIdent = function (liberal) {
- var node = this.startNode();
- if (liberal && this.options.allowReserved == "never") liberal = false;
- if (this.type === tt.name) {
- if (!liberal && (!this.options.allowReserved && this.isReservedWord(this.value) || this.strict && reservedWords.strict(this.value) && (this.options.ecmaVersion >= 6 || this.input.slice(this.start, this.end).indexOf("\\") == -1))) this.raise(this.start, "The keyword '" + this.value + "' is reserved");
- node.name = this.value;
- } else if (liberal && this.type.keyword) {
- node.name = this.type.keyword;
- } else {
- this.unexpected();
- }
- this.next();
- return this.finishNode(node, "Identifier");
- };
- // Parses yield expression inside generator.
- pp.parseYield = function () {
- var node = this.startNode();
- this.next();
- if (this.type == tt.semi || this.canInsertSemicolon() || this.type != tt.star && !this.type.startsExpr) {
- node.delegate = false;
- node.argument = null;
- } else {
- node.delegate = this.eat(tt.star);
- node.argument = this.parseMaybeAssign();
- }
- return this.finishNode(node, "YieldExpression");
- };
- // Parses array and generator comprehensions.
- pp.parseComprehension = function (node, isGenerator) {
- node.blocks = [];
- while (this.type === tt._for) {
- var block = this.startNode();
- this.next();
- this.expect(tt.parenL);
- block.left = this.parseBindingAtom();
- this.checkLVal(block.left, true);
- this.expectContextual("of");
- block.right = this.parseExpression();
- this.expect(tt.parenR);
- node.blocks.push(this.finishNode(block, "ComprehensionBlock"));
- }
- node.filter = this.eat(tt._if) ? this.parseParenExpression() : null;
- node.body = this.parseExpression();
- this.expect(isGenerator ? tt.parenR : tt.bracketR);
- node.generator = isGenerator;
- return this.finishNode(node, "ComprehensionExpression");
- };
- },{"./identifier":7,"./state":13,"./tokentype":17,"./util":18}],7:[function(_dereq_,module,exports){
- // Test whether a given character code starts an identifier.
- "use strict";
- exports.isIdentifierStart = isIdentifierStart;
- // Test whether a given character is part of an identifier.
- exports.isIdentifierChar = isIdentifierChar;
- exports.__esModule = true;
- // This is a trick taken from Esprima. It turns out that, on
- // non-Chrome browsers, to check whether a string is in a set, a
- // predicate containing a big ugly `switch` statement is faster than
- // a regular expression, and on Chrome the two are about on par.
- // This function uses `eval` (non-lexical) to produce such a
- // predicate from a space-separated string of words.
- //
- // It starts by sorting the words by length.
- function makePredicate(words) {
- words = words.split(" ");
- var f = "",
- cats = [];
- out: for (var i = 0; i < words.length; ++i) {
- for (var j = 0; j < cats.length; ++j) {
- if (cats[j][0].length == words[i].length) {
- cats[j].push(words[i]);
- continue out;
- }
- }cats.push([words[i]]);
- }
- function compareTo(arr) {
- if (arr.length == 1) {
- return f += "return str === " + JSON.stringify(arr[0]) + ";";
- }f += "switch(str){";
- for (var i = 0; i < arr.length; ++i) {
- f += "case " + JSON.stringify(arr[i]) + ":";
- }f += "return true}return false;";
- }
- // When there are more than three length categories, an outer
- // switch first dispatches on the lengths, to save on comparisons.
- if (cats.length > 3) {
- cats.sort(function (a, b) {
- return b.length - a.length;
- });
- f += "switch(str.length){";
- for (var i = 0; i < cats.length; ++i) {
- var cat = cats[i];
- f += "case " + cat[0].length + ":";
- compareTo(cat);
- }
- f += "}"
- // Otherwise, simply generate a flat `switch` statement.
- ;
- } else {
- compareTo(words);
- }
- return new Function("str", f);
- }
- // Reserved word lists for various dialects of the language
- var reservedWords = {
- 3: makePredicate("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: makePredicate("class enum extends super const export import"),
- 6: makePredicate("enum await"),
- strict: makePredicate("implements interface let package private protected public static yield"),
- strictBind: makePredicate("eval arguments")
- };
- exports.reservedWords = reservedWords;
- // 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: makePredicate(ecma5AndLessKeywords),
- 6: makePredicate(ecma5AndLessKeywords + " let const class extends export import yield super")
- };
- exports.keywords = keywords;
- // ## 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 `tools/generate-identifier-regex.js`.
- var nonASCIIidentifierStartChars = "ªµºÀ-ÖØ-öø-ˁˆ-ˑˠ-ˤˬˮͰ-ʹͶͷͺ-ͽͿΆΈ-ΊΌΎ-ΡΣ-ϵϷ-ҁҊ-ԯԱ-Ֆՙա-ևא-תװ-ײؠ-يٮٯٱ-ۓەۥۦۮۯۺ-ۼۿܐܒ-ܯݍ-ޥޱߊ-ߪߴߵߺࠀ-ࠕࠚࠤࠨࡀ-ࡘࢠ-ࢲऄ-हऽॐक़-ॡॱ-ঀঅ-ঌএঐও-নপ-রলশ-হঽৎড়ঢ়য়-ৡৰৱਅ-ਊਏਐਓ-ਨਪ-ਰਲਲ਼ਵਸ਼ਸਹਖ਼-ੜਫ਼ੲ-ੴઅ-ઍએ-ઑઓ-નપ-રલળવ-હઽૐૠૡଅ-ଌଏଐଓ-ନପ-ରଲଳଵ-ହଽଡ଼ଢ଼ୟ-ୡୱஃஅ-ஊஎ-ஐஒ-கஙசஜஞடணதந-பம-ஹௐఅ-ఌఎ-ఐఒ-నప-హఽౘౙౠౡಅ-ಌಎ-ಐಒ-ನಪ-ಳವ-ಹಽೞೠೡೱೲഅ-ഌഎ-ഐഒ-ഺഽൎൠൡൺ-ൿඅ-ඖක-නඳ-රලව-ෆก-ะาำเ-ๆກຂຄງຈຊຍດ-ທນ-ຟມ-ຣລວສຫອ-ະາຳຽເ-ໄໆໜ-ໟༀཀ-ཇཉ-ཬྈ-ྌက-ဪဿၐ-ၕၚ-ၝၡၥၦၮ-ၰၵ-ႁႎႠ-ჅჇჍა-ჺჼ-ቈቊ-ቍቐ-ቖቘቚ-ቝበ-ኈኊ-ኍነ-ኰኲ-ኵኸ-ኾዀዂ-ዅወ-ዖዘ-ጐጒ-ጕጘ-ፚᎀ-ᎏᎠ-Ᏼᐁ-ᙬᙯ-ᙿᚁ-ᚚᚠ-ᛪᛮ-ᛸᜀ-ᜌᜎ-ᜑᜠ-ᜱᝀ-ᝑᝠ-ᝬᝮ-ᝰក-ឳៗៜᠠ-ᡷᢀ-ᢨᢪᢰ-ᣵᤀ-ᤞᥐ-ᥭᥰ-ᥴᦀ-ᦫᧁ-ᧇᨀ-ᨖᨠ-ᩔᪧᬅ-ᬳᭅ-ᭋᮃ-ᮠᮮᮯᮺ-ᯥᰀ-ᰣᱍ-ᱏᱚ-ᱽᳩ-ᳬᳮ-ᳱᳵᳶᴀ-ᶿḀ-ἕἘ-Ἕἠ-ὅὈ-Ὅὐ-ὗὙὛὝὟ-ώᾀ-ᾴᾶ-ᾼιῂ-ῄῆ-ῌῐ-ΐῖ-Ίῠ-Ῥῲ-ῴῶ-ῼⁱⁿₐ-ₜℂℇℊ-ℓℕ℘-ℝℤΩℨK-ℹℼ-ℿⅅ-ⅉⅎⅠ-ↈⰀ-Ⱞⰰ-ⱞⱠ-ⳤⳫ-ⳮⳲⳳⴀ-ⴥⴧⴭⴰ-ⵧⵯⶀ-ⶖⶠ-ⶦⶨ-ⶮⶰ-ⶶⶸ-ⶾⷀ-ⷆⷈ-ⷎⷐ-ⷖⷘ-ⷞ々-〇〡-〩〱-〵〸-〼ぁ-ゖ゛-ゟァ-ヺー-ヿㄅ-ㄭㄱ-ㆎㆠ-ㆺㇰ-ㇿ㐀-䶵一-鿌ꀀ-ꒌꓐ-ꓽꔀ-ꘌꘐ-ꘟꘪꘫꙀ-ꙮꙿ-ꚝꚠ-ꛯꜗ-ꜟꜢ-ꞈꞋ-ꞎꞐ-ꞭꞰꞱꟷ-ꠁꠃ-ꠅꠇ-ꠊꠌ-ꠢꡀ-ꡳꢂ-ꢳꣲ-ꣷꣻꤊ-ꤥꤰ-ꥆꥠ-ꥼꦄ-ꦲꧏꧠ-ꧤꧦ-ꧯꧺ-ꧾꨀ-ꨨꩀ-ꩂꩄ-ꩋꩠ-ꩶꩺꩾ-ꪯꪱꪵꪶꪹ-ꪽꫀꫂꫛ-ꫝꫠ-ꫪꫲ-ꫴꬁ-ꬆꬉ-ꬎꬑ-ꬖꬠ-ꬦꬨ-ꬮꬰ-ꭚꭜ-ꭟꭤꭥꯀ-ꯢ가-힣ힰ-ퟆퟋ-ퟻ豈-舘並-龎ff-stﬓ-ﬗיִײַ-ﬨשׁ-זּטּ-לּמּנּסּףּפּצּ-ﮱﯓ-ﴽﵐ-ﶏﶒ-ﷇﷰ-ﷻﹰ-ﹴﹶ-ﻼA-Za-zヲ-하-ᅦᅧ-ᅬᅭ-ᅲᅳ-ᅵ";
- var nonASCIIidentifierChars = "·̀-ͯ·҃-֑҇-ׇֽֿׁׂׅׄؐ-ًؚ-٩ٰۖ-ۜ۟-۪ۤۧۨ-ۭ۰-۹ܑܰ-݊ަ-ް߀-߉߫-߳ࠖ-࠙ࠛ-ࠣࠥ-ࠧࠩ-࡙࠭-࡛ࣤ-ःऺ-़ा-ॏ॑-ॗॢॣ०-९ঁ-ঃ়া-ৄেৈো-্ৗৢৣ০-৯ਁ-ਃ਼ਾ-ੂੇੈੋ-੍ੑ੦-ੱੵઁ-ઃ઼ા-ૅે-ૉો-્ૢૣ૦-૯ଁ-ଃ଼ା-ୄେୈୋ-୍ୖୗୢୣ୦-୯ஂா-ூெ-ைொ-்ௗ௦-௯ఀ-ఃా-ౄె-ైొ-్ౕౖౢౣ౦-౯ಁ-ಃ಼ಾ-ೄೆ-ೈೊ-್ೕೖೢೣ೦-೯ഁ-ഃാ-ൄെ-ൈൊ-്ൗൢൣ൦-൯ංඃ්ා-ුූෘ-ෟ෦-෯ෲෳัิ-ฺ็-๎๐-๙ັິ-ູົຼ່-ໍ໐-໙༘༙༠-༩༹༵༷༾༿ཱ-྄྆྇ྍ-ྗྙ-ྼ࿆ါ-ှ၀-၉ၖ-ၙၞ-ၠၢ-ၤၧ-ၭၱ-ၴႂ-ႍႏ-ႝ፝-፟፩-፱ᜒ-᜔ᜲ-᜴ᝒᝓᝲᝳ឴-៓៝០-៩᠋-᠍᠐-᠙ᢩᤠ-ᤫᤰ-᤻᥆-᥏ᦰ-ᧀᧈᧉ᧐-᧚ᨗ-ᨛᩕ-ᩞ᩠-᩿᩼-᪉᪐-᪙᪰-᪽ᬀ-ᬄ᬴-᭄᭐-᭙᭫-᭳ᮀ-ᮂᮡ-ᮭ᮰-᮹᯦-᯳ᰤ-᰷᱀-᱉᱐-᱙᳐-᳔᳒-᳨᳭ᳲ-᳴᳸᳹᷀-᷵᷼-᷿‿⁀⁔⃐-⃥⃜⃡-⃰⳯-⵿⳱ⷠ-〪ⷿ-゙゚〯꘠-꘩꙯ꙴ-꙽ꚟ꛰꛱ꠂ꠆ꠋꠣ-ꠧꢀꢁꢴ-꣄꣐-꣙꣠-꣱꤀-꤉ꤦ-꤭ꥇ-꥓ꦀ-ꦃ꦳-꧀꧐-꧙ꧥ꧰-꧹ꨩ-ꨶꩃꩌꩍ꩐-꩙ꩻ-ꩽꪰꪲ-ꪴꪷꪸꪾ꪿꫁ꫫ-ꫯꫵ꫶ꯣ-ꯪ꯬꯭꯰-꯹ﬞ︀-️︠-︭︳︴﹍-﹏0-9_";
- 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 tools/generate-identifier-regex.js
- var astralIdentifierStartCodes = [0, 11, 2, 25, 2, 18, 2, 1, 2, 14, 3, 13, 35, 122, 70, 52, 268, 28, 4, 48, 48, 31, 17, 26, 6, 37, 11, 29, 3, 35, 5, 7, 2, 4, 43, 157, 99, 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, 98, 21, 11, 25, 71, 55, 7, 1, 65, 0, 16, 3, 2, 2, 2, 26, 45, 28, 4, 28, 36, 7, 2, 27, 28, 53, 11, 21, 11, 18, 14, 17, 111, 72, 955, 52, 76, 44, 33, 24, 27, 35, 42, 34, 4, 0, 13, 47, 15, 3, 22, 0, 38, 17, 2, 24, 133, 46, 39, 7, 3, 1, 3, 21, 2, 6, 2, 1, 2, 4, 4, 0, 32, 4, 287, 47, 21, 1, 2, 0, 185, 46, 82, 47, 21, 0, 60, 42, 502, 63, 32, 0, 449, 56, 1288, 920, 104, 110, 2962, 1070, 13266, 568, 8, 30, 114, 29, 19, 47, 17, 3, 32, 20, 6, 18, 881, 68, 12, 0, 67, 12, 16481, 1, 3071, 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, 1340, 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, 16355, 541];
- var astralIdentifierCodes = [509, 0, 227, 0, 150, 4, 294, 9, 1368, 2, 2, 1, 6, 3, 41, 2, 5, 0, 166, 1, 1306, 2, 54, 14, 32, 9, 16, 3, 46, 10, 54, 9, 7, 2, 37, 13, 2, 9, 52, 0, 13, 2, 49, 13, 16, 9, 83, 11, 168, 11, 6, 9, 8, 2, 57, 0, 2, 6, 3, 1, 3, 2, 10, 0, 11, 1, 3, 6, 4, 4, 316, 19, 13, 9, 214, 6, 3, 8, 112, 16, 16, 9, 82, 12, 9, 9, 535, 9, 20855, 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, 4305, 6, 792618, 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 = 65536;
- 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;
- }
- }
- }
- 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 <= 65535) {
- return code >= 170 && nonASCIIidentifierStart.test(String.fromCharCode(code));
- }if (astral === false) {
- return false;
- }return isInAstralSet(code, astralIdentifierStartCodes);
- }
- 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 <= 65535) {
- return code >= 170 && nonASCIIidentifier.test(String.fromCharCode(code));
- }if (astral === false) {
- return false;
- }return isInAstralSet(code, astralIdentifierStartCodes) || isInAstralSet(code, astralIdentifierCodes);
- }
- },{}],8:[function(_dereq_,module,exports){
- "use strict";
- var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } };
- // 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.
- exports.getLineInfo = getLineInfo;
- exports.__esModule = true;
- var Parser = _dereq_("./state").Parser;
- var lineBreakG = _dereq_("./whitespace").lineBreakG;
- var deprecate = _dereq_("util").deprecate;
- // These are used when `options.locations` is on, for the
- // `startLoc` and `endLoc` properties.
- var Position = exports.Position = (function () {
- function Position(line, col) {
- _classCallCheck(this, Position);
- this.line = line;
- this.column = col;
- }
- Position.prototype.offset = function offset(n) {
- return new Position(this.line, this.column + n);
- };
- return Position;
- })();
- var SourceLocation = exports.SourceLocation = function SourceLocation(p, start, end) {
- _classCallCheck(this, SourceLocation);
- this.start = start;
- this.end = end;
- if (p.sourceFile !== null) this.source = p.sourceFile;
- };
- 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);
- }
- }
- }
- var pp = 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.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.curPosition = function () {
- return new Position(this.curLine, this.pos - this.lineStart);
- };
- pp.markPosition = function () {
- return this.options.locations ? [this.start, this.startLoc] : this.start;
- };
- },{"./state":13,"./whitespace":19,"util":5}],9:[function(_dereq_,module,exports){
- "use strict";
- var tt = _dereq_("./tokentype").types;
- var Parser = _dereq_("./state").Parser;
- var reservedWords = _dereq_("./identifier").reservedWords;
- var has = _dereq_("./util").has;
- var pp = Parser.prototype;
- // Convert existing expression atom to assignable pattern
- // if possible.
- pp.toAssignable = function (node, isBinding) {
- if (this.options.ecmaVersion >= 6 && node) {
- switch (node.type) {
- case "Identifier":
- case "ObjectPattern":
- case "ArrayPattern":
- case "AssignmentPattern":
- break;
- case "ObjectExpression":
- node.type = "ObjectPattern";
- for (var i = 0; i < node.properties.length; i++) {
- var prop = node.properties[i];
- if (prop.kind !== "init") this.raise(prop.key.start, "Object pattern can't contain getter or setter");
- this.toAssignable(prop.value, isBinding);
- }
- break;
- case "ArrayExpression":
- node.type = "ArrayPattern";
- this.toAssignableList(node.elements, isBinding);
- break;
- case "AssignmentExpression":
- if (node.operator === "=") {
- node.type = "AssignmentPattern";
- } else {
- this.raise(node.left.end, "Only '=' operator can be used for specifying default value.");
- }
- break;
- case "ParenthesizedExpression":
- node.expression = this.toAssignable(node.expression, isBinding);
- break;
- case "MemberExpression":
- if (!isBinding) break;
- default:
- this.raise(node.start, "Assigning to rvalue");
- }
- }
- return node;
- };
- // Convert list of expression atoms to binding list.
- pp.toAssignableList = function (exprList, isBinding) {
- var end = exprList.length;
- if (end) {
- var last = exprList[end - 1];
- if (last && last.type == "RestElement") {
- --end;
- } else if (last && last.type == "SpreadElement") {
- last.type = "RestElement";
- var arg = last.argument;
- this.toAssignable(arg, isBinding);
- if (arg.type !== "Identifier" && arg.type !== "MemberExpression" && arg.type !== "ArrayPattern") this.unexpected(arg.start);
- --end;
- }
- }
- for (var i = 0; i < end; i++) {
- var elt = exprList[i];
- if (elt) this.toAssignable(elt, isBinding);
- }
- return exprList;
- };
- // Parses spread element.
- pp.parseSpread = function (refShorthandDefaultPos) {
- var node = this.startNode();
- this.next();
- node.argument = this.parseMaybeAssign(refShorthandDefaultPos);
- return this.finishNode(node, "SpreadElement");
- };
- pp.parseRest = function () {
- var node = this.startNode();
- this.next();
- node.argument = this.type === tt.name || this.type === tt.bracketL ? this.parseBindingAtom() : this.unexpected();
- return this.finishNode(node, "RestElement");
- };
- // Parses lvalue (assignable) atom.
- pp.parseBindingAtom = function () {
- if (this.options.ecmaVersion < 6) return this.parseIdent();
- switch (this.type) {
- case tt.name:
- return this.parseIdent();
- case tt.bracketL:
- var node = this.startNode();
- this.next();
- node.elements = this.parseBindingList(tt.bracketR, true, true);
- return this.finishNode(node, "ArrayPattern");
- case tt.braceL:
- return this.parseObj(true);
- default:
- this.unexpected();
- }
- };
- pp.parseBindingList = function (close, allowEmpty, allowTrailingComma) {
- var elts = [],
- first = true;
- while (!this.eat(close)) {
- if (first) first = false;else this.expect(tt.comma);
- if (allowEmpty && this.type === tt.comma) {
- elts.push(null);
- } else if (allowTrailingComma && this.afterTrailingComma(close)) {
- break;
- } else if (this.type === tt.ellipsis) {
- var rest = this.parseRest();
- this.parseBindingListItem(rest);
- elts.push(rest);
- this.expect(close);
- break;
- } else {
- var elem = this.parseMaybeDefault(this.start, this.startLoc);
- this.parseBindingListItem(elem);
- elts.push(elem);
- }
- }
- return elts;
- };
- pp.parseBindingListItem = function (param) {
- return param;
- };
- // Parses assignment pattern around given atom if possible.
- pp.parseMaybeDefault = function (startPos, startLoc, left) {
- if (Array.isArray(startPos)) {
- if (this.options.locations && noCalls === undefined) {
- // shift arguments to left by one
- left = startLoc;
- // flatten startPos
- startLoc = startPos[1];
- startPos = startPos[0];
- }
- }
- left = left || this.parseBindingAtom();
- if (!this.eat(tt.eq)) return left;
- var node = this.startNodeAt(startPos, startLoc);
- node.operator = "=";
- 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.
- pp.checkLVal = function (expr, isBinding, checkClashes) {
- switch (expr.type) {
- case "Identifier":
- if (this.strict && (reservedWords.strictBind(expr.name) || reservedWords.strict(expr.name))) this.raise(expr.start, (isBinding ? "Binding " : "Assigning to ") + expr.name + " in strict mode");
- if (checkClashes) {
- if (has(checkClashes, expr.name)) this.raise(expr.start, "Argument name clash in strict mode");
- checkClashes[expr.name] = true;
- }
- break;
- case "MemberExpression":
- if (isBinding) this.raise(expr.start, (isBinding ? "Binding" : "Assigning to") + " member expression");
- break;
- case "ObjectPattern":
- for (var i = 0; i < expr.properties.length; i++) {
- this.checkLVal(expr.properties[i].value, isBinding, checkClashes);
- }break;
- case "ArrayPattern":
- for (var i = 0; i < expr.elements.length; i++) {
- var elem = expr.elements[i];
- if (elem) this.checkLVal(elem, isBinding, checkClashes);
- }
- break;
- case "AssignmentPattern":
- this.checkLVal(expr.left, isBinding, checkClashes);
- break;
- case "RestElement":
- this.checkLVal(expr.argument, isBinding, checkClashes);
- break;
- case "ParenthesizedExpression":
- this.checkLVal(expr.expression, isBinding, checkClashes);
- break;
- default:
- this.raise(expr.start, (isBinding ? "Binding" : "Assigning to") + " rvalue");
- }
- };
- },{"./identifier":7,"./state":13,"./tokentype":17,"./util":18}],10:[function(_dereq_,module,exports){
- "use strict";
- var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } };
- exports.__esModule = true;
- var Parser = _dereq_("./state").Parser;
- var SourceLocation = _dereq_("./location").SourceLocation;
- // Start an AST node, attaching a start offset.
- var pp = Parser.prototype;
- var Node = exports.Node = function Node() {
- _classCallCheck(this, Node);
- };
- pp.startNode = function () {
- var node = new Node();
- node.start = this.start;
- if (this.options.locations) node.loc = new SourceLocation(this, this.startLoc);
- if (this.options.directSourceFile) node.sourceFile = this.options.directSourceFile;
- if (this.options.ranges) node.range = [this.start, 0];
- return node;
- };
- pp.startNodeAt = function (pos, loc) {
- var node = new Node();
- if (Array.isArray(pos)) {
- if (this.options.locations && loc === undefined) {
- // flatten pos
- loc = pos[1];
- pos = pos[0];
- }
- }
- node.start = pos;
- if (this.options.locations) node.loc = new SourceLocation(this, loc);
- if (this.options.directSourceFile) node.sourceFile = this.options.directSourceFile;
- if (this.options.ranges) node.range = [pos, 0];
- return node;
- };
- // Finish an AST node, adding `type` and `end` properties.
- pp.finishNode = function (node, type) {
- node.type = type;
- node.end = this.lastTokEnd;
- if (this.options.locations) node.loc.end = this.lastTokEndLoc;
- if (this.options.ranges) node.range[1] = this.lastTokEnd;
- return node;
- };
- // Finish node at given position
- pp.finishNodeAt = function (node, type, pos, loc) {
- node.type = type;
- if (Array.isArray(pos)) {
- if (this.options.locations && loc === undefined) {
- // flatten pos
- loc = pos[1];
- pos = pos[0];
- }
- }
- node.end = pos;
- if (this.options.locations) node.loc.end = loc;
- if (this.options.ranges) node.range[1] = pos;
- return node;
- };
- },{"./location":8,"./state":13}],11:[function(_dereq_,module,exports){
- // Interpret and default an options object
- "use strict";
- exports.getOptions = getOptions;
- exports.__esModule = true;
- var _util = _dereq_("./util");
- var has = _util.has;
- var isArray = _util.isArray;
- var SourceLocation = _dereq_("./location").SourceLocation;
- // 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, or 5, or 6. This influences support for strict
- // mode, the set of reserved words, support for getters and
- // setters and other features.
- ecmaVersion: 5,
- // Source type ("script" or "module") for different semantics
- 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 not enforced. Disable
- // `allowReserved` to enforce them. When this option has the
- // value "never", reserved words and keywords can also not be
- // used as property names.
- allowReserved: true,
- // 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, 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 tokenize() returns. 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: {}
- };exports.defaultOptions = defaultOptions;
- function getOptions(opts) {
- var options = {};
- for (var opt in defaultOptions) {
- options[opt] = opts && has(opts, opt) ? opts[opt] : defaultOptions[opt];
- }if (isArray(options.onToken)) {
- (function () {
- 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);
- };
- }
- },{"./location":8,"./util":18}],12:[function(_dereq_,module,exports){
- "use strict";
- var tt = _dereq_("./tokentype").types;
- var Parser = _dereq_("./state").Parser;
- var lineBreak = _dereq_("./whitespace").lineBreak;
- var pp = Parser.prototype;
- // ## Parser utilities
- // Test whether a statement node is the string literal `"use strict"`.
- pp.isUseStrict = function (stmt) {
- return this.options.ecmaVersion >= 5 && stmt.type === "ExpressionStatement" && stmt.expression.type === "Literal" && stmt.expression.value === "use strict";
- };
- // 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 === tt.name && this.value === name;
- };
- // Consumes contextual keyword if possible.
- pp.eatContextual = function (name) {
- return this.value === name && this.eat(tt.name);
- };
- // 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 === tt.eof || this.type === tt.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(tt.semi) && !this.insertSemicolon()) this.unexpected();
- };
- pp.afterTrailingComma = function (tokType) {
- if (this.type == tokType) {
- if (this.options.onTrailingComma) this.options.onTrailingComma(this.lastTokStart, this.lastTokStartLoc);
- 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");
- };
- },{"./state":13,"./tokentype":17,"./whitespace":19}],13:[function(_dereq_,module,exports){
- "use strict";
- exports.Parser = Parser;
- exports.__esModule = true;
- var _identifier = _dereq_("./identifier");
- var reservedWords = _identifier.reservedWords;
- var keywords = _identifier.keywords;
- var tt = _dereq_("./tokentype").types;
- var lineBreak = _dereq_("./whitespace").lineBreak;
- function Parser(options, input, startPos) {
- this.options = options;
- this.sourceFile = this.options.sourceFile || null;
- this.isKeyword = keywords[this.options.ecmaVersion >= 6 ? 6 : 5];
- this.isReservedWord = reservedWords[this.options.ecmaVersion];
- this.input = input;
- // Load plugins
- this.loadPlugins(this.options.plugins);
- // Set up token state
- // The current position of the tokenizer in the input.
- if (startPos) {
- this.pos = startPos;
- this.lineStart = Math.max(0, this.input.lastIndexOf("\n", startPos));
- 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 = tt.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 = null;
- // 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.strict = this.inModule = this.options.sourceType === "module";
- // Used to signify the start of a potential arrow function
- this.potentialArrowAt = -1;
- // Flags to track whether we are in a function, a generator.
- this.inFunction = this.inGenerator = false;
- // Labels in scope.
- this.labels = [];
- // If enabled, skip leading hashbang line.
- if (this.pos === 0 && this.options.allowHashBang && this.input.slice(0, 2) === "#!") this.skipLineComment(2);
- }
- Parser.prototype.extend = function (name, f) {
- this[name] = f(this[name]);
- };
- // Registered plugins
- var plugins = {};
- exports.plugins = plugins;
- Parser.prototype.loadPlugins = function (plugins) {
- for (var _name in plugins) {
- var plugin = exports.plugins[_name];
- if (!plugin) throw new Error("Plugin '" + _name + "' not found");
- plugin(this, plugins[_name]);
- }
- };
- },{"./identifier":7,"./tokentype":17,"./whitespace":19}],14:[function(_dereq_,module,exports){
- "use strict";
- var tt = _dereq_("./tokentype").types;
- var Parser = _dereq_("./state").Parser;
- var lineBreak = _dereq_("./whitespace").lineBreak;
- var pp = 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.parseTopLevel = function (node) {
- var first = true;
- if (!node.body) node.body = [];
- while (this.type !== tt.eof) {
- var stmt = this.parseStatement(true, true);
- node.body.push(stmt);
- if (first && this.isUseStrict(stmt)) this.setStrict(true);
- first = false;
- }
- this.next();
- if (this.options.ecmaVersion >= 6) {
- node.sourceType = this.options.sourceType;
- }
- return this.finishNode(node, "Program");
- };
- var loopLabel = { kind: "loop" },
- switchLabel = { kind: "switch" };
- // 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.parseStatement = function (declaration, topLevel) {
- var starttype = this.type,
- node = this.startNode();
- // 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 tt._break:case tt._continue:
- return this.parseBreakContinueStatement(node, starttype.keyword);
- case tt._debugger:
- return this.parseDebuggerStatement(node);
- case tt._do:
- return this.parseDoStatement(node);
- case tt._for:
- return this.parseForStatement(node);
- case tt._function:
- if (!declaration && this.options.ecmaVersion >= 6) this.unexpected();
- return this.parseFunctionStatement(node);
- case tt._class:
- if (!declaration) this.unexpected();
- return this.parseClass(node, true);
- case tt._if:
- return this.parseIfStatement(node);
- case tt._return:
- return this.parseReturnStatement(node);
- case tt._switch:
- return this.parseSwitchStatement(node);
- case tt._throw:
- return this.parseThrowStatement(node);
- case tt._try:
- return this.parseTryStatement(node);
- case tt._let:case tt._const:
- if (!declaration) this.unexpected(); // NOTE: falls through to _var
- case tt._var:
- return this.parseVarStatement(node, starttype);
- case tt._while:
- return this.parseWhileStatement(node);
- case tt._with:
- return this.parseWithStatement(node);
- case tt.braceL:
- return this.parseBlock();
- case tt.semi:
- return this.parseEmptyStatement(node);
- case tt._export:
- case tt._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 === tt._import ? this.parseImport(node) : this.parseExport(node);
- // 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:
- var maybeName = this.value,
- expr = this.parseExpression();
- if (starttype === tt.name && expr.type === "Identifier" && this.eat(tt.colon)) return this.parseLabeledStatement(node, maybeName, expr);else return this.parseExpressionStatement(node, expr);
- }
- };
- pp.parseBreakContinueStatement = function (node, keyword) {
- var isBreak = keyword == "break";
- this.next();
- if (this.eat(tt.semi) || this.insertSemicolon()) node.label = null;else if (this.type !== tt.name) this.unexpected();else {
- node.label = this.parseIdent();
- this.semicolon();
- }
- // Verify that there is an actual destination to break or
- // continue to.
- for (var i = 0; i < this.labels.length; ++i) {
- var lab = this.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.parseDebuggerStatement = function (node) {
- this.next();
- this.semicolon();
- return this.finishNode(node, "DebuggerStatement");
- };
- pp.parseDoStatement = function (node) {
- this.next();
- this.labels.push(loopLabel);
- node.body = this.parseStatement(false);
- this.labels.pop();
- this.expect(tt._while);
- node.test = this.parseParenExpression();
- if (this.options.ecmaVersion >= 6) this.eat(tt.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.parseForStatement = function (node) {
- this.next();
- this.labels.push(loopLabel);
- this.expect(tt.parenL);
- if (this.type === tt.semi) return this.parseFor(node, null);
- if (this.type === tt._var || this.type === tt._let || this.type === tt._const) {
- var _init = this.startNode(),
- varKind = this.type;
- this.next();
- this.parseVar(_init, true, varKind);
- this.finishNode(_init, "VariableDeclaration");
- if ((this.type === tt._in || this.options.ecmaVersion >= 6 && this.isContextual("of")) && _init.declarations.length === 1 && !(varKind !== tt._var && _init.declarations[0].init)) return this.parseForIn(node, _init);
- return this.parseFor(node, _init);
- }
- var refShorthandDefaultPos = { start: 0 };
- var init = this.parseExpression(true, refShorthandDefaultPos);
- if (this.type === tt._in || this.options.ecmaVersion >= 6 && this.isContextual("of")) {
- this.toAssignable(init);
- this.checkLVal(init);
- return this.parseForIn(node, init);
- } else if (refShorthandDefaultPos.start) {
- this.unexpected(refShorthandDefaultPos.start);
- }
- return this.parseFor(node, init);
- };
- pp.parseFunctionStatement = function (node) {
- this.next();
- return this.parseFunction(node, true);
- };
- pp.parseIfStatement = function (node) {
- this.next();
- node.test = this.parseParenExpression();
- node.consequent = this.parseStatement(false);
- node.alternate = this.eat(tt._else) ? this.parseStatement(false) : null;
- return this.finishNode(node, "IfStatement");
- };
- pp.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(tt.semi) || this.insertSemicolon()) node.argument = null;else {
- node.argument = this.parseExpression();this.semicolon();
- }
- return this.finishNode(node, "ReturnStatement");
- };
- pp.parseSwitchStatement = function (node) {
- this.next();
- node.discriminant = this.parseParenExpression();
- node.cases = [];
- this.expect(tt.braceL);
- this.labels.push(switchLabel);
- // Statements under must be grouped (by label) in SwitchCase
- // nodes. `cur` is used to keep the node that we are currently
- // adding statements to.
- for (var cur, sawDefault; this.type != tt.braceR;) {
- if (this.type === tt._case || this.type === tt._default) {
- var isCase = this.type === tt._case;
- if (cur) this.finishNode(cur, "SwitchCase");
- node.cases.push(cur = this.startNode());
- cur.consequent = [];
- this.next();
- if (isCase) {
- cur.test = this.parseExpression();
- } else {
- if (sawDefault) this.raise(this.lastTokStart, "Multiple default clauses");
- sawDefault = true;
- cur.test = null;
- }
- this.expect(tt.colon);
- } else {
- if (!cur) this.unexpected();
- cur.consequent.push(this.parseStatement(true));
- }
- }
- if (cur) this.finishNode(cur, "SwitchCase");
- this.next(); // Closing brace
- this.labels.pop();
- return this.finishNode(node, "SwitchStatement");
- };
- pp.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.parseTryStatement = function (node) {
- this.next();
- node.block = this.parseBlock();
- node.handler = null;
- if (this.type === tt._catch) {
- var clause = this.startNode();
- this.next();
- this.expect(tt.parenL);
- clause.param = this.parseBindingAtom();
- this.checkLVal(clause.param, true);
- this.expect(tt.parenR);
- clause.guard = null;
- clause.body = this.parseBlock();
- node.handler = this.finishNode(clause, "CatchClause");
- }
- node.guardedHandlers = empty;
- node.finalizer = this.eat(tt._finally) ? this.parseBlock() : null;
- if (!node.handler && !node.finalizer) this.raise(node.start, "Missing catch or finally clause");
- return this.finishNode(node, "TryStatement");
- };
- pp.parseVarStatement = function (node, kind) {
- this.next();
- this.parseVar(node, false, kind);
- this.semicolon();
- return this.finishNode(node, "VariableDeclaration");
- };
- pp.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.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.parseEmptyStatement = function (node) {
- this.next();
- return this.finishNode(node, "EmptyStatement");
- };
- pp.parseLabeledStatement = function (node, maybeName, expr) {
- for (var i = 0; i < this.labels.length; ++i) {
- if (this.labels[i].name === maybeName) this.raise(expr.start, "Label '" + maybeName + "' is already declared");
- }var kind = this.type.isLoop ? "loop" : this.type === tt._switch ? "switch" : null;
- this.labels.push({ name: maybeName, kind: kind });
- node.body = this.parseStatement(true);
- this.labels.pop();
- node.label = expr;
- return this.finishNode(node, "LabeledStatement");
- };
- pp.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.parseBlock = function (allowStrict) {
- var node = this.startNode(),
- first = true,
- oldStrict = undefined;
- node.body = [];
- this.expect(tt.braceL);
- while (!this.eat(tt.braceR)) {
- var stmt = this.parseStatement(true);
- node.body.push(stmt);
- if (first && allowStrict && this.isUseStrict(stmt)) {
- oldStrict = this.strict;
- this.setStrict(this.strict = true);
- }
- first = false;
- }
- if (oldStrict === false) this.setStrict(false);
- 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.parseFor = function (node, init) {
- node.init = init;
- this.expect(tt.semi);
- node.test = this.type === tt.semi ? null : this.parseExpression();
- this.expect(tt.semi);
- node.update = this.type === tt.parenR ? null : this.parseExpression();
- this.expect(tt.parenR);
- 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.parseForIn = function (node, init) {
- var type = this.type === tt._in ? "ForInStatement" : "ForOfStatement";
- this.next();
- node.left = init;
- node.right = this.parseExpression();
- this.expect(tt.parenR);
- node.body = this.parseStatement(false);
- this.labels.pop();
- return this.finishNode(node, type);
- };
- // Parse a list of variable declarations.
- pp.parseVar = function (node, isFor, kind) {
- node.declarations = [];
- node.kind = kind.keyword;
- for (;;) {
- var decl = this.startNode();
- this.parseVarId(decl);
- if (this.eat(tt.eq)) {
- decl.init = this.parseMaybeAssign(isFor);
- } else if (kind === tt._const && !(this.type === tt._in || this.options.ecmaVersion >= 6 && this.isContextual("of"))) {
- this.unexpected();
- } else if (decl.id.type != "Identifier" && !(isFor && (this.type === tt._in || this.isContextual("of")))) {
- this.raise(this.lastTokEnd, "Complex binding patterns require an initialization value");
- } else {
- decl.init = null;
- }
- node.declarations.push(this.finishNode(decl, "VariableDeclarator"));
- if (!this.eat(tt.comma)) break;
- }
- return node;
- };
- pp.parseVarId = function (decl) {
- decl.id = this.parseBindingAtom();
- this.checkLVal(decl.id, true);
- };
- // Parse a function declaration or literal (depending on the
- // `isStatement` parameter).
- pp.parseFunction = function (node, isStatement, allowExpressionBody) {
- this.initFunction(node);
- if (this.options.ecmaVersion >= 6) node.generator = this.eat(tt.star);
- if (isStatement || this.type === tt.name) node.id = this.parseIdent();
- this.parseFunctionParams(node);
- this.parseFunctionBody(node, allowExpressionBody);
- return this.finishNode(node, isStatement ? "FunctionDeclaration" : "FunctionExpression");
- };
- pp.parseFunctionParams = function (node) {
- this.expect(tt.parenL);
- node.params = this.parseBindingList(tt.parenR, false, false);
- };
- // Parse a class declaration or literal (depending on the
- // `isStatement` parameter).
- pp.parseClass = function (node, isStatement) {
- this.next();
- this.parseClassId(node, isStatement);
- this.parseClassSuper(node);
- var classBody = this.startNode();
- var hadConstructor = false;
- classBody.body = [];
- this.expect(tt.braceL);
- while (!this.eat(tt.braceR)) {
- if (this.eat(tt.semi)) continue;
- var method = this.startNode();
- var isGenerator = this.eat(tt.star);
- var isMaybeStatic = this.type === tt.name && this.value === "static";
- this.parsePropertyName(method);
- method["static"] = isMaybeStatic && this.type !== tt.parenL;
- if (method["static"]) {
- if (isGenerator) this.unexpected();
- isGenerator = this.eat(tt.star);
- this.parsePropertyName(method);
- }
- method.kind = "method";
- if (!method.computed) {
- var key = method.key;
- var isGetSet = false;
- if (!isGenerator && key.type === "Identifier" && this.type !== tt.parenL && (key.name === "get" || key.name === "set")) {
- isGetSet = true;
- method.kind = key.name;
- key = this.parsePropertyName(method);
- }
- if (!method["static"] && (key.type === "Identifier" && key.name === "constructor" || key.type === "Literal" && key.value === "constructor")) {
- if (hadConstructor) this.raise(key.start, "Duplicate constructor in the same class");
- if (isGetSet) this.raise(key.start, "Constructor can't have get/set modifier");
- if (isGenerator) this.raise(key.start, "Constructor can't be a generator");
- method.kind = "constructor";
- hadConstructor = true;
- }
- }
- this.parseClassMethod(classBody, method, isGenerator);
- }
- node.body = this.finishNode(classBody, "ClassBody");
- return this.finishNode(node, isStatement ? "ClassDeclaration" : "ClassExpression");
- };
- pp.parseClassMethod = function (classBody, method, isGenerator) {
- method.value = this.parseMethod(isGenerator);
- classBody.body.push(this.finishNode(method, "MethodDefinition"));
- };
- pp.parseClassId = function (node, isStatement) {
- node.id = this.type === tt.name ? this.parseIdent() : isStatement ? this.unexpected() : null;
- };
- pp.parseClassSuper = function (node) {
- node.superClass = this.eat(tt._extends) ? this.parseExprSubscripts() : null;
- };
- // Parses module export declaration.
- pp.parseExport = function (node) {
- this.next();
- // export * from '...'
- if (this.eat(tt.star)) {
- this.expectContextual("from");
- node.source = this.type === tt.string ? this.parseExprAtom() : this.unexpected();
- this.semicolon();
- return this.finishNode(node, "ExportAllDeclaration");
- }
- if (this.eat(tt._default)) {
- // export default ...
- var expr = this.parseMaybeAssign();
- var needsSemi = true;
- if (expr.type == "FunctionExpression" || expr.type == "ClassExpression") {
- needsSemi = false;
- if (expr.id) {
- expr.type = expr.type == "FunctionExpression" ? "FunctionDeclaration" : "ClassDeclaration";
- }
- }
- node.declaration = expr;
- if (needsSemi) this.semicolon();
- return this.finishNode(node, "ExportDefaultDeclaration");
- }
- // export var|const|let|function|class ...
- if (this.shouldParseExportStatement()) {
- node.declaration = this.parseStatement(true);
- node.specifiers = [];
- node.source = null;
- } else {
- // export { x, y as z } [from '...']
- node.declaration = null;
- node.specifiers = this.parseExportSpecifiers();
- if (this.eatContextual("from")) {
- node.source = this.type === tt.string ? this.parseExprAtom() : this.unexpected();
- } else {
- node.source = null;
- }
- this.semicolon();
- }
- return this.finishNode(node, "ExportNamedDeclaration");
- };
- pp.shouldParseExportStatement = function () {
- return this.type.keyword;
- };
- // Parses a comma-separated list of module exports.
- pp.parseExportSpecifiers = function () {
- var nodes = [],
- first = true;
- // export { x, y as z } [from '...']
- this.expect(tt.braceL);
- while (!this.eat(tt.braceR)) {
- if (!first) {
- this.expect(tt.comma);
- if (this.afterTrailingComma(tt.braceR)) break;
- } else first = false;
- var node = this.startNode();
- node.local = this.parseIdent(this.type === tt._default);
- node.exported = this.eatContextual("as") ? this.parseIdent(true) : node.local;
- nodes.push(this.finishNode(node, "ExportSpecifier"));
- }
- return nodes;
- };
- // Parses import declaration.
- pp.parseImport = function (node) {
- this.next();
- // import '...'
- if (this.type === tt.string) {
- node.specifiers = empty;
- node.source = this.parseExprAtom();
- node.kind = "";
- } else {
- node.specifiers = this.parseImportSpecifiers();
- this.expectContextual("from");
- node.source = this.type === tt.string ? this.parseExprAtom() : this.unexpected();
- }
- this.semicolon();
- return this.finishNode(node, "ImportDeclaration");
- };
- // Parses a comma-separated list of module imports.
- pp.parseImportSpecifiers = function () {
- var nodes = [],
- first = true;
- if (this.type === tt.name) {
- // import defaultObj, { x, y as z } from '...'
- var node = this.startNode();
- node.local = this.parseIdent();
- this.checkLVal(node.local, true);
- nodes.push(this.finishNode(node, "ImportDefaultSpecifier"));
- if (!this.eat(tt.comma)) return nodes;
- }
- if (this.type === tt.star) {
- var node = this.startNode();
- this.next();
- this.expectContextual("as");
- node.local = this.parseIdent();
- this.checkLVal(node.local, true);
- nodes.push(this.finishNode(node, "ImportNamespaceSpecifier"));
- return nodes;
- }
- this.expect(tt.braceL);
- while (!this.eat(tt.braceR)) {
- if (!first) {
- this.expect(tt.comma);
- if (this.afterTrailingComma(tt.braceR)) break;
- } else first = false;
- var node = this.startNode();
- node.imported = this.parseIdent(true);
- node.local = this.eatContextual("as") ? this.parseIdent() : node.imported;
- this.checkLVal(node.local, true);
- nodes.push(this.finishNode(node, "ImportSpecifier"));
- }
- return nodes;
- };
- },{"./state":13,"./tokentype":17,"./whitespace":19}],15:[function(_dereq_,module,exports){
- "use strict";
- var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } };
- exports.__esModule = true;
- // 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 Parser = _dereq_("./state").Parser;
- var tt = _dereq_("./tokentype").types;
- var lineBreak = _dereq_("./whitespace").lineBreak;
- var TokContext = exports.TokContext = function TokContext(token, isExpr, preserveSpace, override) {
- _classCallCheck(this, TokContext);
- this.token = token;
- this.isExpr = isExpr;
- this.preserveSpace = preserveSpace;
- this.override = override;
- };
- var types = {
- b_stat: new TokContext("{", false),
- b_expr: new TokContext("{", true),
- b_tmpl: new TokContext("${", true),
- p_stat: new TokContext("(", false),
- p_expr: new TokContext("(", true),
- q_tmpl: new TokContext("`", true, true, function (p) {
- return p.readTmplToken();
- }),
- f_expr: new TokContext("function", true)
- };
- exports.types = types;
- var pp = Parser.prototype;
- pp.initialContext = function () {
- return [types.b_stat];
- };
- pp.braceIsBlock = function (prevType) {
- var parent = undefined;
- if (prevType === tt.colon && (parent = this.curContext()).token == "{") return !parent.isExpr;
- if (prevType === tt._return) return lineBreak.test(this.input.slice(this.lastTokEnd, this.start));
- if (prevType === tt._else || prevType === tt.semi || prevType === tt.eof) return true;
- if (prevType == tt.braceL) return this.curContext() === types.b_stat;
- return !this.exprAllowed;
- };
- pp.updateContext = function (prevType) {
- var update = undefined,
- type = this.type;
- if (type.keyword && prevType == tt.dot) this.exprAllowed = false;else if (update = type.updateContext) update.call(this, prevType);else this.exprAllowed = type.beforeExpr;
- };
- // Token-specific context update code
- tt.parenR.updateContext = tt.braceR.updateContext = function () {
- if (this.context.length == 1) {
- this.exprAllowed = true;
- return;
- }
- var out = this.context.pop();
- if (out === types.b_stat && this.curContext() === types.f_expr) {
- this.context.pop();
- this.exprAllowed = false;
- } else if (out === types.b_tmpl) {
- this.exprAllowed = true;
- } else {
- this.exprAllowed = !out.isExpr;
- }
- };
- tt.braceL.updateContext = function (prevType) {
- this.context.push(this.braceIsBlock(prevType) ? types.b_stat : types.b_expr);
- this.exprAllowed = true;
- };
- tt.dollarBraceL.updateContext = function () {
- this.context.push(types.b_tmpl);
- this.exprAllowed = true;
- };
- tt.parenL.updateContext = function (prevType) {
- var statementParens = prevType === tt._if || prevType === tt._for || prevType === tt._with || prevType === tt._while;
- this.context.push(statementParens ? types.p_stat : types.p_expr);
- this.exprAllowed = true;
- };
- tt.incDec.updateContext = function () {};
- tt._function.updateContext = function () {
- if (this.curContext() !== types.b_stat) this.context.push(types.f_expr);
- this.exprAllowed = false;
- };
- tt.backQuote.updateContext = function () {
- if (this.curContext() === types.q_tmpl) this.context.pop();else this.context.push(types.q_tmpl);
- this.exprAllowed = false;
- };
- // tokExprAllowed stays unchanged
- },{"./state":13,"./tokentype":17,"./whitespace":19}],16:[function(_dereq_,module,exports){
- "use strict";
- var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } };
- exports.__esModule = true;
- var _identifier = _dereq_("./identifier");
- var isIdentifierStart = _identifier.isIdentifierStart;
- var isIdentifierChar = _identifier.isIdentifierChar;
- var _tokentype = _dereq_("./tokentype");
- var tt = _tokentype.types;
- var keywordTypes = _tokentype.keywords;
- var Parser = _dereq_("./state").Parser;
- var SourceLocation = _dereq_("./location").SourceLocation;
- var _whitespace = _dereq_("./whitespace");
- var lineBreak = _whitespace.lineBreak;
- var lineBreakG = _whitespace.lineBreakG;
- var isNewLine = _whitespace.isNewLine;
- var nonASCIIwhitespace = _whitespace.nonASCIIwhitespace;
- // 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 = exports.Token = function Token(p) {
- _classCallCheck(this, Token);
- 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 = Parser.prototype;
- // Are we running under Rhino?
- var isRhino = typeof Packages !== "undefined";
- // Move to the next token
- pp.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.getToken = function () {
- this.next();
- return new Token(this);
- };
- // If we're in an ES6 environment, make parsers iterable
- if (typeof Symbol !== "undefined") pp[Symbol.iterator] = function () {
- var self = this;
- return { next: function next() {
- var token = self.getToken();
- return {
- done: token.type === tt.eof,
- value: token
- };
- } };
- };
- // Toggle strict mode. Re-reads the next number or string to please
- // pedantic tests (`"use strict"; 010;` should fail).
- pp.setStrict = function (strict) {
- this.strict = strict;
- if (this.type !== tt.num && this.type !== tt.string) return;
- this.pos = this.start;
- if (this.options.locations) {
- while (this.pos < this.lineStart) {
- this.lineStart = this.input.lastIndexOf("\n", this.lineStart - 2) + 1;
- --this.curLine;
- }
- }
- this.nextToken();
- };
- pp.curContext = function () {
- return this.context[this.context.length - 1];
- };
- // Read a single token, updating the parser object's token-related
- // properties.
- pp.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(tt.eof);
- if (curContext.override) return curContext.override(this);else this.readToken(this.fullCharCodeAtPos());
- };
- pp.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.fullCharCodeAtPos = function () {
- var code = this.input.charCodeAt(this.pos);
- if (code <= 55295 || code >= 57344) return code;
- var next = this.input.charCodeAt(this.pos + 1);
- return (code << 10) + next - 56613888;
- };
- pp.skipBlockComment = function () {
- var startLoc = this.options.onComment && this.options.locations && 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 = undefined;
- while ((match = lineBreakG.exec(this.input)) && match.index < this.pos) {
- ++this.curLine;
- this.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.options.locations && this.curPosition());
- };
- pp.skipLineComment = function (startSkip) {
- var start = this.pos;
- var startLoc = this.options.onComment && this.options.locations && this.curPosition();
- var ch = this.input.charCodeAt(this.pos += startSkip);
- while (this.pos < this.input.length && ch !== 10 && ch !== 13 && ch !== 8232 && ch !== 8233) {
- ++this.pos;
- ch = this.input.charCodeAt(this.pos);
- }
- if (this.options.onComment) this.options.onComment(false, this.input.slice(start + startSkip, this.pos), start, this.pos, startLoc, this.options.locations && this.curPosition());
- };
- // Called at the start of the parse and after every token. Skips
- // whitespace and comments, and.
- pp.skipSpace = function () {
- while (this.pos < this.input.length) {
- var ch = this.input.charCodeAt(this.pos);
- if (ch === 32) {
- // ' '
- ++this.pos;
- } else if (ch === 13) {
- ++this.pos;
- var next = this.input.charCodeAt(this.pos);
- if (next === 10) {
- ++this.pos;
- }
- if (this.options.locations) {
- ++this.curLine;
- this.lineStart = this.pos;
- }
- } else if (ch === 10 || ch === 8232 || ch === 8233) {
- ++this.pos;
- if (this.options.locations) {
- ++this.curLine;
- this.lineStart = this.pos;
- }
- } else if (ch > 8 && ch < 14) {
- ++this.pos;
- } else if (ch === 47) {
- // '/'
- var next = this.input.charCodeAt(this.pos + 1);
- if (next === 42) {
- // '*'
- this.skipBlockComment();
- } else if (next === 47) {
- // '/'
- this.skipLineComment(2);
- } else break;
- } else if (ch === 160) {
- // '\xa0'
- ++this.pos;
- } else if (ch >= 5760 && nonASCIIwhitespace.test(String.fromCharCode(ch))) {
- ++this.pos;
- } else {
- break;
- }
- }
- };
- // 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.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.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(tt.ellipsis);
- } else {
- ++this.pos;
- return this.finishToken(tt.dot);
- }
- };
- pp.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(tt.assign, 2);
- return this.finishOp(tt.slash, 1);
- };
- pp.readToken_mult_modulo = function (code) {
- // '%*'
- var next = this.input.charCodeAt(this.pos + 1);
- if (next === 61) return this.finishOp(tt.assign, 2);
- return this.finishOp(code === 42 ? tt.star : tt.modulo, 1);
- };
- pp.readToken_pipe_amp = function (code) {
- // '|&'
- var next = this.input.charCodeAt(this.pos + 1);
- if (next === code) return this.finishOp(code === 124 ? tt.logicalOR : tt.logicalAND, 2);
- if (next === 61) return this.finishOp(tt.assign, 2);
- return this.finishOp(code === 124 ? tt.bitwiseOR : tt.bitwiseAND, 1);
- };
- pp.readToken_caret = function () {
- // '^'
- var next = this.input.charCodeAt(this.pos + 1);
- if (next === 61) return this.finishOp(tt.assign, 2);
- return this.finishOp(tt.bitwiseXOR, 1);
- };
- pp.readToken_plus_min = function (code) {
- // '+-'
- var next = this.input.charCodeAt(this.pos + 1);
- if (next === code) {
- if (next == 45 && this.input.charCodeAt(this.pos + 2) == 62 && lineBreak.test(this.input.slice(this.lastTokEnd, this.pos))) {
- // A `-->` line comment
- this.skipLineComment(3);
- this.skipSpace();
- return this.nextToken();
- }
- return this.finishOp(tt.incDec, 2);
- }
- if (next === 61) return this.finishOp(tt.assign, 2);
- return this.finishOp(tt.plusMin, 1);
- };
- pp.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(tt.assign, size + 1);
- return this.finishOp(tt.bitShift, size);
- }
- if (next == 33 && code == 60 && this.input.charCodeAt(this.pos + 2) == 45 && this.input.charCodeAt(this.pos + 3) == 45) {
- if (this.inModule) this.unexpected();
- // `<!--`, an XML-style comment that should be interpreted as a line comment
- this.skipLineComment(4);
- this.skipSpace();
- return this.nextToken();
- }
- if (next === 61) size = this.input.charCodeAt(this.pos + 2) === 61 ? 3 : 2;
- return this.finishOp(tt.relational, size);
- };
- pp.readToken_eq_excl = function (code) {
- // '=!'
- var next = this.input.charCodeAt(this.pos + 1);
- if (next === 61) return this.finishOp(tt.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(tt.arrow);
- }
- return this.finishOp(code === 61 ? tt.eq : tt.prefix, 1);
- };
- pp.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(tt.parenL);
- case 41:
- ++this.pos;return this.finishToken(tt.parenR);
- case 59:
- ++this.pos;return this.finishToken(tt.semi);
- case 44:
- ++this.pos;return this.finishToken(tt.comma);
- case 91:
- ++this.pos;return this.finishToken(tt.bracketL);
- case 93:
- ++this.pos;return this.finishToken(tt.bracketR);
- case 123:
- ++this.pos;return this.finishToken(tt.braceL);
- case 125:
- ++this.pos;return this.finishToken(tt.braceR);
- case 58:
- ++this.pos;return this.finishToken(tt.colon);
- case 63:
- ++this.pos;return this.finishToken(tt.question);
- case 96:
- // '`'
- if (this.options.ecmaVersion < 6) break;
- ++this.pos;
- return this.finishToken(tt.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(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(tt.prefix, 1);
- }
- this.raise(this.pos, "Unexpected character '" + codePointToString(code) + "'");
- };
- pp.finishOp = function (type, size) {
- var str = this.input.slice(this.pos, this.pos + size);
- this.pos += size;
- return this.finishToken(type, str);
- };
- var regexpUnicodeSupport = false;
- try {
- new RegExp("", "u");regexpUnicodeSupport = true;
- } catch (e) {}
- // Parse a regular expression. Some context-awareness is necessary,
- // since a '/' inside a '[]' set does not end the expression.
- pp.readRegexp = function () {
- var escaped = undefined,
- inClass = undefined,
- start = this.pos;
- for (;;) {
- if (this.pos >= this.input.length) this.raise(start, "Unterminated regular expression");
- var ch = this.input.charAt(this.pos);
- if (lineBreak.test(ch)) this.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.pos;
- }
- var content = this.input.slice(start, this.pos);
- ++this.pos;
- // Need to use `readWord1` because '\uXXXX' sequences are allowed
- // here (don't ask).
- var mods = this.readWord1();
- var tmp = content;
- if (mods) {
- var validFlags = /^[gmsiy]*$/;
- if (this.options.ecmaVersion >= 6) validFlags = /^[gmsiyu]*$/;
- if (!validFlags.test(mods)) this.raise(start, "Invalid regular expression flag");
- if (mods.indexOf("u") >= 0 && !regexpUnicodeSupport) {
- // Replace each astral symbol and every Unicode escape sequence that
- // possibly represents an astral symbol or a paired surrogate with a
- // single ASCII symbol to avoid throwing on regular expressions that
- // are only valid in combination with the `/u` flag.
- // Note: replacing with the ASCII symbol `x` might cause false
- // negatives in unlikely scenarios. For example, `[\u{61}-b]` is a
- // perfectly valid pattern that is equivalent to `[a-b]`, but it would
- // be replaced by `[x-b]` which throws an error.
- tmp = tmp.replace(/\\u([a-fA-F0-9]{4})|\\u\{([0-9a-fA-F]+)\}|[\uD800-\uDBFF][\uDC00-\uDFFF]/g, "x");
- }
- }
- // Detect invalid regular expressions.
- var value = null;
- // Rhino's regular expression parser is flaky and throws uncatchable exceptions,
- // so don't do detection if we are running under Rhino
- if (!isRhino) {
- try {
- new RegExp(tmp);
- } catch (e) {
- if (e instanceof SyntaxError) this.raise(start, "Error parsing regular expression: " + e.message);
- this.raise(e);
- }
- // Get a regular expression object for this pattern-flag pair, or `null` in
- // case the current environment doesn't support the flags it uses.
- try {
- value = new RegExp(content, mods);
- } catch (err) {}
- }
- return this.finishToken(tt.regexp, { pattern: content, flags: mods, 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.readInt = function (radix, len) {
- var start = this.pos,
- total = 0;
- for (var i = 0, e = len == null ? Infinity : len; i < e; ++i) {
- var code = this.input.charCodeAt(this.pos),
- val = undefined;
- 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.pos;
- total = total * radix + val;
- }
- if (this.pos === start || len != null && this.pos - start !== len) return null;
- return total;
- };
- pp.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(tt.num, val);
- };
- // Read an integer, octal integer, or floating-point number.
- pp.readNumber = function (startsWithDot) {
- var start = this.pos,
- isFloat = false,
- octal = this.input.charCodeAt(this.pos) === 48;
- if (!startsWithDot && this.readInt(10) === null) this.raise(start, "Invalid number");
- if (this.input.charCodeAt(this.pos) === 46) {
- ++this.pos;
- this.readInt(10);
- isFloat = true;
- }
- var next = this.input.charCodeAt(this.pos);
- if (next === 69 || next === 101) {
- // 'eE'
- next = this.input.charCodeAt(++this.pos);
- if (next === 43 || next === 45) ++this.pos; // '+-'
- if (this.readInt(10) === null) this.raise(start, "Invalid number");
- isFloat = true;
- }
- if (isIdentifierStart(this.fullCharCodeAtPos())) this.raise(this.pos, "Identifier directly after number");
- var str = this.input.slice(start, this.pos),
- val = undefined;
- if (isFloat) val = parseFloat(str);else if (!octal || str.length === 1) val = parseInt(str, 10);else if (/[89]/.test(str) || this.strict) this.raise(start, "Invalid number");else val = parseInt(str, 8);
- return this.finishToken(tt.num, val);
- };
- // Read a string value, interpreting backslash-escapes.
- pp.readCodePoint = function () {
- var ch = this.input.charCodeAt(this.pos),
- code = undefined;
- if (ch === 123) {
- if (this.options.ecmaVersion < 6) this.unexpected();
- ++this.pos;
- code = this.readHexChar(this.input.indexOf("}", this.pos) - this.pos);
- ++this.pos;
- if (code > 1114111) this.unexpected();
- } else {
- code = this.readHexChar(4);
- }
- return code;
- };
- function codePointToString(code) {
- // UTF-16 Decoding
- if (code <= 65535) {
- return String.fromCharCode(code);
- }return String.fromCharCode((code - 65536 >> 10) + 55296, (code - 65536 & 1023) + 56320);
- }
- pp.readString = function (quote) {
- var out = "",
- chunkStart = ++this.pos;
- for (;;) {
- if (this.pos >= this.input.length) this.raise(this.start, "Unterminated string constant");
- var ch = this.input.charCodeAt(this.pos);
- if (ch === quote) break;
- if (ch === 92) {
- // '\'
- out += this.input.slice(chunkStart, this.pos);
- out += this.readEscapedChar();
- chunkStart = this.pos;
- } else {
- if (isNewLine(ch)) this.raise(this.start, "Unterminated string constant");
- ++this.pos;
- }
- }
- out += this.input.slice(chunkStart, this.pos++);
- return this.finishToken(tt.string, out);
- };
- // Reads template string tokens.
- pp.readTmplToken = function () {
- var out = "",
- chunkStart = this.pos;
- for (;;) {
- if (this.pos >= this.input.length) this.raise(this.start, "Unterminated template");
- var ch = this.input.charCodeAt(this.pos);
- if (ch === 96 || ch === 36 && this.input.charCodeAt(this.pos + 1) === 123) {
- // '`', '${'
- if (this.pos === this.start && this.type === tt.template) {
- if (ch === 36) {
- this.pos += 2;
- return this.finishToken(tt.dollarBraceL);
- } else {
- ++this.pos;
- return this.finishToken(tt.backQuote);
- }
- }
- out += this.input.slice(chunkStart, this.pos);
- return this.finishToken(tt.template, out);
- }
- if (ch === 92) {
- // '\'
- out += this.input.slice(chunkStart, this.pos);
- out += this.readEscapedChar();
- chunkStart = this.pos;
- } else if (isNewLine(ch)) {
- out += this.input.slice(chunkStart, this.pos);
- ++this.pos;
- if (ch === 13 && this.input.charCodeAt(this.pos) === 10) {
- ++this.pos;
- out += "\n";
- } else {
- out += String.fromCharCode(ch);
- }
- if (this.options.locations) {
- ++this.curLine;
- this.lineStart = this.pos;
- }
- chunkStart = this.pos;
- } else {
- ++this.pos;
- }
- }
- };
- // Used to read escaped characters
- pp.readEscapedChar = function () {
- var ch = this.input.charCodeAt(++this.pos);
- var octal = /^[0-7]+/.exec(this.input.slice(this.pos, this.pos + 3));
- if (octal) octal = octal[0];
- while (octal && parseInt(octal, 8) > 255) octal = octal.slice(0, -1);
- if (octal === "0") octal = null;
- ++this.pos;
- if (octal) {
- if (this.strict) this.raise(this.pos - 2, "Octal literal in strict mode");
- this.pos += octal.length - 1;
- return String.fromCharCode(parseInt(octal, 8));
- } else {
- 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 48:
- return "\u0000"; // 0 -> '\0'
- 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:
- return String.fromCharCode(ch);
- }
- }
- };
- // Used to read character escape sequences ('\x', '\u', '\U').
- pp.readHexChar = function (len) {
- var n = this.readInt(16, len);
- if (n === null) this.raise(this.start, "Bad character escape sequence");
- return n;
- };
- // 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.
- var containsEsc;
- // Read an identifier, and return it as a string. Sets `containsEsc`
- // to whether the word contained a '\u' escape.
- //
- // Incrementally adds only escaped chars, adding other chunks as-is
- // as a micro-optimization.
- pp.readWord1 = function () {
- containsEsc = false;
- var word = "",
- first = true,
- chunkStart = this.pos;
- var astral = this.options.ecmaVersion >= 6;
- while (this.pos < this.input.length) {
- var ch = this.fullCharCodeAtPos();
- if (isIdentifierChar(ch, astral)) {
- this.pos += ch <= 65535 ? 1 : 2;
- } else if (ch === 92) {
- // "\"
- containsEsc = true;
- word += this.input.slice(chunkStart, this.pos);
- var escStart = this.pos;
- if (this.input.charCodeAt(++this.pos) != 117) // "u"
- this.raise(this.pos, "Expecting Unicode escape sequence \\uXXXX");
- ++this.pos;
- var esc = this.readCodePoint();
- if (!(first ? isIdentifierStart : isIdentifierChar)(esc, astral)) this.raise(escStart, "Invalid Unicode escape");
- word += codePointToString(esc);
- chunkStart = this.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.readWord = function () {
- var word = this.readWord1();
- var type = tt.name;
- if ((this.options.ecmaVersion >= 6 || !containsEsc) && this.isKeyword(word)) type = keywordTypes[word];
- return this.finishToken(type, word);
- };
- },{"./identifier":7,"./location":8,"./state":13,"./tokentype":17,"./whitespace":19}],17:[function(_dereq_,module,exports){
- "use strict";
- var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } };
- exports.__esModule = true;
- // ## 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).
- //
- // `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 = exports.TokenType = function TokenType(label) {
- var conf = arguments[1] === undefined ? {} : arguments[1];
- _classCallCheck(this, TokenType);
- 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 },
- startsExpr = { startsExpr: true };
- 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"),
- 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("prefix", { 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)
- };
- exports.types = types;
- // Map keyword names to token types.
- var keywords = {};
- exports.keywords = keywords;
- // Succinct definitions of keyword token types
- function kw(name) {
- var options = arguments[1] === undefined ? {} : arguments[1];
- options.keyword = name;
- keywords[name] = types["_" + name] = new TokenType(name, options);
- }
- kw("break");
- kw("case", beforeExpr);
- kw("catch");
- kw("continue");
- kw("debugger");
- kw("default");
- kw("do", { isLoop: true });
- kw("else", beforeExpr);
- kw("finally");
- kw("for", { isLoop: true });
- kw("function", startsExpr);
- kw("if");
- kw("return", beforeExpr);
- kw("switch");
- kw("throw", beforeExpr);
- kw("try");
- kw("var");
- kw("let");
- kw("const");
- kw("while", { isLoop: true });
- kw("with");
- kw("new", { beforeExpr: true, startsExpr: true });
- kw("this", startsExpr);
- kw("super", startsExpr);
- kw("class");
- kw("extends", beforeExpr);
- kw("export");
- kw("import");
- kw("yield", { beforeExpr: true, startsExpr: true });
- kw("null", startsExpr);
- kw("true", startsExpr);
- kw("false", startsExpr);
- kw("in", { beforeExpr: true, binop: 7 });
- kw("instanceof", { beforeExpr: true, binop: 7 });
- kw("typeof", { beforeExpr: true, prefix: true, startsExpr: true });
- kw("void", { beforeExpr: true, prefix: true, startsExpr: true });
- kw("delete", { beforeExpr: true, prefix: true, startsExpr: true });
- },{}],18:[function(_dereq_,module,exports){
- "use strict";
- exports.isArray = isArray;
- // Checks if an object has a property.
- exports.has = has;
- exports.__esModule = true;
- function isArray(obj) {
- return Object.prototype.toString.call(obj) === "[object Array]";
- }
- function has(obj, propName) {
- return Object.prototype.hasOwnProperty.call(obj, propName);
- }
- },{}],19:[function(_dereq_,module,exports){
- "use strict";
- exports.isNewLine = isNewLine;
- exports.__esModule = 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/;
- exports.lineBreak = lineBreak;
- var lineBreakG = new RegExp(lineBreak.source, "g");
- exports.lineBreakG = lineBreakG;
- function isNewLine(code) {
- return code === 10 || code === 13 || code === 8232 || code == 8233;
- }
- var nonASCIIwhitespace = /[\u1680\u180e\u2000-\u200a\u202f\u205f\u3000\ufeff]/;
- exports.nonASCIIwhitespace = nonASCIIwhitespace;
- },{}]},{},[1])(1)
- });
- }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
- },{}],33:[function(require,module,exports){
- (function (global){
- (function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}(g.acorn || (g.acorn = {})).walk = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(_dereq_,module,exports){
- "use strict";
- var _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } };
- // AST walker module for Mozilla Parser API compatible trees
- // A simple walk is one where you simply specify callbacks to be
- // called on specific nodes. The last two arguments are optional. A
- // simple use would be
- //
- // walk.simple(myTree, {
- // Expression: function(node) { ... }
- // });
- //
- // to do something with all expressions. All Parser API node types
- // can be used to identify node types, as well as Expression,
- // Statement, and ScopeBody, which denote categories of nodes.
- //
- // The base argument can be used to pass a custom (recursive)
- // walker, and state can be used to give this walked an initial
- // state.
- exports.simple = simple;
- // An ancestor walk builds up an array of ancestor nodes (including
- // the current node) and passes them to the callback as the state parameter.
- exports.ancestor = ancestor;
- // A recursive walk is one where your functions override the default
- // walkers. They can modify and replace the state parameter that's
- // threaded through the walk, and can opt how and whether to walk
- // their child nodes (by calling their third argument on these
- // nodes).
- exports.recursive = recursive;
- // Find a node with a given start, end, and type (all are optional,
- // null can be used as wildcard). Returns a {node, state} object, or
- // undefined when it doesn't find a matching node.
- exports.findNodeAt = findNodeAt;
- // Find the innermost node of a given type that contains the given
- // position. Interface similar to findNodeAt.
- exports.findNodeAround = findNodeAround;
- // Find the outermost matching node after a given position.
- exports.findNodeAfter = findNodeAfter;
- // Find the outermost matching node before a given position.
- exports.findNodeBefore = findNodeBefore;
- // Used to create a custom walker. Will fill in all missing node
- // type properties with the defaults.
- exports.make = make;
- exports.__esModule = true;
- function simple(node, visitors, base, state) {
- if (!base) base = exports.base;(function c(node, st, override) {
- var type = override || node.type,
- found = visitors[type];
- base[type](node, st, c);
- if (found) found(node, st);
- })(node, state);
- }
- function ancestor(node, visitors, base, state) {
- if (!base) base = exports.base;
- if (!state) state = [];(function c(node, st, override) {
- var type = override || node.type,
- found = visitors[type];
- if (node != st[st.length - 1]) {
- st = st.slice();
- st.push(node);
- }
- base[type](node, st, c);
- if (found) found(node, st);
- })(node, state);
- }
- function recursive(node, state, funcs, base) {
- var visitor = funcs ? exports.make(funcs, base) : base;(function c(node, st, override) {
- visitor[override || node.type](node, st, c);
- })(node, state);
- }
- function makeTest(test) {
- if (typeof test == "string") {
- return function (type) {
- return type == test;
- };
- } else if (!test) {
- return function () {
- return true;
- };
- } else {
- return test;
- }
- }
- var Found = function Found(node, state) {
- _classCallCheck(this, Found);
- this.node = node;this.state = state;
- };
- function findNodeAt(node, start, end, test, base, state) {
- test = makeTest(test);
- if (!base) base = exports.base;
- try {
- ;(function c(node, st, override) {
- var type = override || node.type;
- if ((start == null || node.start <= start) && (end == null || node.end >= end)) base[type](node, st, c);
- if (test(type, node) && (start == null || node.start == start) && (end == null || node.end == end)) throw new Found(node, st);
- })(node, state);
- } catch (e) {
- if (e instanceof Found) {
- return e;
- }throw e;
- }
- }
- function findNodeAround(node, pos, test, base, state) {
- test = makeTest(test);
- if (!base) base = exports.base;
- try {
- ;(function c(node, st, override) {
- var type = override || node.type;
- if (node.start > pos || node.end < pos) {
- return;
- }base[type](node, st, c);
- if (test(type, node)) throw new Found(node, st);
- })(node, state);
- } catch (e) {
- if (e instanceof Found) {
- return e;
- }throw e;
- }
- }
- function findNodeAfter(node, pos, test, base, state) {
- test = makeTest(test);
- if (!base) base = exports.base;
- try {
- ;(function c(node, st, override) {
- if (node.end < pos) {
- return;
- }var type = override || node.type;
- if (node.start >= pos && test(type, node)) throw new Found(node, st);
- base[type](node, st, c);
- })(node, state);
- } catch (e) {
- if (e instanceof Found) {
- return e;
- }throw e;
- }
- }
- function findNodeBefore(node, pos, test, base, state) {
- test = makeTest(test);
- if (!base) base = exports.base;
- var max = undefined;(function c(node, st, override) {
- if (node.start > pos) {
- return;
- }var type = override || node.type;
- if (node.end <= pos && (!max || max.node.end < node.end) && test(type, node)) max = new Found(node, st);
- base[type](node, st, c);
- })(node, state);
- return max;
- }
- function make(funcs, base) {
- if (!base) base = exports.base;
- var visitor = {};
- for (var type in base) visitor[type] = base[type];
- for (var type in funcs) visitor[type] = funcs[type];
- return visitor;
- }
- function skipThrough(node, st, c) {
- c(node, st);
- }
- function ignore(_node, _st, _c) {}
- // Node walkers.
- var base = {};
- exports.base = base;
- base.Program = base.BlockStatement = function (node, st, c) {
- for (var i = 0; i < node.body.length; ++i) {
- c(node.body[i], st, "Statement");
- }
- };
- base.Statement = skipThrough;
- base.EmptyStatement = ignore;
- base.ExpressionStatement = base.ParenthesizedExpression = function (node, st, c) {
- return c(node.expression, st, "Expression");
- };
- base.IfStatement = function (node, st, c) {
- c(node.test, st, "Expression");
- c(node.consequent, st, "Statement");
- if (node.alternate) c(node.alternate, st, "Statement");
- };
- base.LabeledStatement = function (node, st, c) {
- return c(node.body, st, "Statement");
- };
- base.BreakStatement = base.ContinueStatement = ignore;
- base.WithStatement = function (node, st, c) {
- c(node.object, st, "Expression");
- c(node.body, st, "Statement");
- };
- base.SwitchStatement = function (node, st, c) {
- c(node.discriminant, st, "Expression");
- for (var i = 0; i < node.cases.length; ++i) {
- var cs = node.cases[i];
- if (cs.test) c(cs.test, st, "Expression");
- for (var j = 0; j < cs.consequent.length; ++j) {
- c(cs.consequent[j], st, "Statement");
- }
- }
- };
- base.ReturnStatement = base.YieldExpression = function (node, st, c) {
- if (node.argument) c(node.argument, st, "Expression");
- };
- base.ThrowStatement = base.SpreadElement = base.RestElement = function (node, st, c) {
- return c(node.argument, st, "Expression");
- };
- base.TryStatement = function (node, st, c) {
- c(node.block, st, "Statement");
- if (node.handler) c(node.handler.body, st, "ScopeBody");
- if (node.finalizer) c(node.finalizer, st, "Statement");
- };
- base.WhileStatement = base.DoWhileStatement = function (node, st, c) {
- c(node.test, st, "Expression");
- c(node.body, st, "Statement");
- };
- base.ForStatement = function (node, st, c) {
- if (node.init) c(node.init, st, "ForInit");
- if (node.test) c(node.test, st, "Expression");
- if (node.update) c(node.update, st, "Expression");
- c(node.body, st, "Statement");
- };
- base.ForInStatement = base.ForOfStatement = function (node, st, c) {
- c(node.left, st, "ForInit");
- c(node.right, st, "Expression");
- c(node.body, st, "Statement");
- };
- base.ForInit = function (node, st, c) {
- if (node.type == "VariableDeclaration") c(node, st);else c(node, st, "Expression");
- };
- base.DebuggerStatement = ignore;
- base.FunctionDeclaration = function (node, st, c) {
- return c(node, st, "Function");
- };
- base.VariableDeclaration = function (node, st, c) {
- for (var i = 0; i < node.declarations.length; ++i) {
- var decl = node.declarations[i];
- if (decl.init) c(decl.init, st, "Expression");
- }
- };
- base.Function = function (node, st, c) {
- return c(node.body, st, "ScopeBody");
- };
- base.ScopeBody = function (node, st, c) {
- return c(node, st, "Statement");
- };
- base.Expression = skipThrough;
- base.ThisExpression = base.Super = base.MetaProperty = ignore;
- base.ArrayExpression = base.ArrayPattern = function (node, st, c) {
- for (var i = 0; i < node.elements.length; ++i) {
- var elt = node.elements[i];
- if (elt) c(elt, st, "Expression");
- }
- };
- base.ObjectExpression = base.ObjectPattern = function (node, st, c) {
- for (var i = 0; i < node.properties.length; ++i) {
- c(node.properties[i], st);
- }
- };
- base.FunctionExpression = base.ArrowFunctionExpression = base.FunctionDeclaration;
- base.SequenceExpression = base.TemplateLiteral = function (node, st, c) {
- for (var i = 0; i < node.expressions.length; ++i) {
- c(node.expressions[i], st, "Expression");
- }
- };
- base.UnaryExpression = base.UpdateExpression = function (node, st, c) {
- c(node.argument, st, "Expression");
- };
- base.BinaryExpression = base.AssignmentExpression = base.AssignmentPattern = base.LogicalExpression = function (node, st, c) {
- c(node.left, st, "Expression");
- c(node.right, st, "Expression");
- };
- base.ConditionalExpression = function (node, st, c) {
- c(node.test, st, "Expression");
- c(node.consequent, st, "Expression");
- c(node.alternate, st, "Expression");
- };
- base.NewExpression = base.CallExpression = function (node, st, c) {
- c(node.callee, st, "Expression");
- if (node.arguments) for (var i = 0; i < node.arguments.length; ++i) {
- c(node.arguments[i], st, "Expression");
- }
- };
- base.MemberExpression = function (node, st, c) {
- c(node.object, st, "Expression");
- if (node.computed) c(node.property, st, "Expression");
- };
- base.ExportNamedDeclaration = base.ExportDefaultDeclaration = function (node, st, c) {
- return c(node.declaration, st);
- };
- base.ImportDeclaration = function (node, st, c) {
- for (var i = 0; i < node.specifiers.length; i++) {
- c(node.specifiers[i], st);
- }
- };
- base.ImportSpecifier = base.ImportDefaultSpecifier = base.ImportNamespaceSpecifier = base.Identifier = base.Literal = ignore;
- base.TaggedTemplateExpression = function (node, st, c) {
- c(node.tag, st, "Expression");
- c(node.quasi, st);
- };
- base.ClassDeclaration = base.ClassExpression = function (node, st, c) {
- if (node.superClass) c(node.superClass, st, "Expression");
- for (var i = 0; i < node.body.body.length; i++) {
- c(node.body.body[i], st);
- }
- };
- base.MethodDefinition = base.Property = function (node, st, c) {
- if (node.computed) c(node.key, st, "Expression");
- c(node.value, st, "Expression");
- };
- base.ComprehensionExpression = function (node, st, c) {
- for (var i = 0; i < node.blocks.length; i++) {
- c(node.blocks[i].right, st, "Expression");
- }c(node.body, st, "Expression");
- };
- },{}]},{},[1])(1)
- });
- }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
- },{}],34:[function(require,module,exports){
- /**
- * This file automatically generated from `pre-publish.js`.
- * Do not manually edit.
- */
- module.exports = {
- "area": true,
- "base": true,
- "br": true,
- "col": true,
- "embed": true,
- "hr": true,
- "img": true,
- "input": true,
- "keygen": true,
- "link": true,
- "menuitem": true,
- "meta": true,
- "param": true,
- "source": true,
- "track": true,
- "wbr": true
- };
- },{}],35:[function(require,module,exports){
- 'use strict';
- var detect = require('acorn-globals');
- var acorn = require('acorn');
- var walk = require('acorn/dist/walk');
- // polyfill for https://github.com/marijnh/acorn/pull/231
- walk.base.ExportNamedDeclaration = walk.base.ExportDefaultDeclaration = function (node, st, c) {
- return c(node.declaration, st);
- };
- walk.base.ImportDefaultSpecifier = walk.base.ImportNamespaceSpecifier = function () {};
- // hacky fix for https://github.com/marijnh/acorn/issues/227
- function reallyParse(source) {
- try {
- return acorn.parse(source, {
- ecmaVersion: 5,
- allowReturnOutsideFunction: true
- });
- } catch (ex) {
- if (ex.name !== 'SyntaxError') {
- throw ex;
- }
- return acorn.parse(source, {
- ecmaVersion: 6,
- allowReturnOutsideFunction: true
- });
- }
- }
- module.exports = addWith
- /**
- * Mimic `with` as far as possible but at compile time
- *
- * @param {String} obj The object part of a with expression
- * @param {String} src The body of the with expression
- * @param {Array.<String>} exclude A list of variable names to explicitly exclude
- */
- function addWith(obj, src, exclude) {
- obj = obj + ''
- src = src + ''
- exclude = exclude || []
- exclude = exclude.concat(detect(obj).map(function (global) { return global.name; }))
- var vars = detect(src).map(function (global) { return global.name; })
- .filter(function (v) {
- return exclude.indexOf(v) === -1
- })
- if (vars.length === 0) return src
- var declareLocal = ''
- var local = 'locals_for_with'
- var result = 'result_of_with'
- if (/^[a-zA-Z0-9$_]+$/.test(obj)) {
- local = obj
- } else {
- while (vars.indexOf(local) != -1 || exclude.indexOf(local) != -1) {
- local += '_'
- }
- declareLocal = 'var ' + local + ' = (' + obj + ')'
- }
- while (vars.indexOf(result) != -1 || exclude.indexOf(result) != -1) {
- result += '_'
- }
- var inputVars = vars.map(function (v) {
- return JSON.stringify(v) + ' in ' + local + '?' +
- local + '.' + v + ':' +
- 'typeof ' + v + '!=="undefined"?' + v + ':undefined'
- })
- src = '(function (' + vars.join(', ') + ') {' +
- src +
- '}.call(this' + inputVars.map(function (v) { return ',' + v; }).join('') + '))'
- return ';' + declareLocal + ';' + unwrapReturns(src, result) + ';'
- }
- /**
- * Take a self calling function, and unwrap it such that return inside the function
- * results in return outside the function
- *
- * @param {String} src Some JavaScript code representing a self-calling function
- * @param {String} result A temporary variable to store the result in
- */
- function unwrapReturns(src, result) {
- var originalSource = src
- var hasReturn = false
- var ast = reallyParse(src)
- var ref
- src = src.split('')
- // get a reference to the function that was inserted to add an inner context
- if ((ref = ast.body).length !== 1
- || (ref = ref[0]).type !== 'ExpressionStatement'
- || (ref = ref.expression).type !== 'CallExpression'
- || (ref = ref.callee).type !== 'MemberExpression' || ref.computed !== false || ref.property.name !== 'call'
- || (ref = ref.object).type !== 'FunctionExpression')
- throw new Error('AST does not seem to represent a self-calling function')
- var fn = ref
- walk.recursive(ast, null, {
- Function: function (node, st, c) {
- if (node === fn) {
- c(node.body, st, "ScopeBody");
- }
- },
- ReturnStatement: function (node) {
- hasReturn = true
- replace(node, 'return {value: ' + source(node.argument) + '};');
- }
- });
- function source(node) {
- return src.slice(node.start, node.end).join('')
- }
- function replace(node, str) {
- for (var i = node.start; i < node.end; i++) {
- src[i] = ''
- }
- src[node.start] = str
- }
- if (!hasReturn) return originalSource
- else return 'var ' + result + '=' + src.join('') + ';if (' + result + ') return ' + result + '.value'
- }
- },{"acorn":37,"acorn-globals":36,"acorn/dist/walk":38}],36:[function(require,module,exports){
- arguments[4][31][0].apply(exports,arguments)
- },{"acorn":37,"acorn/dist/walk":38,"dup":31}],37:[function(require,module,exports){
- arguments[4][32][0].apply(exports,arguments)
- },{"dup":32}],38:[function(require,module,exports){
- arguments[4][33][0].apply(exports,arguments)
- },{"dup":33}]},{},[1])(1)
- });
|